in src/toMidi.ts [549:586]
export function addPitchBendsToNoteEvents(
contours: number[][],
notes: NoteEvent[],
nBinsTolerance: number = 25,
): NoteEvent[] {
const windowLength = nBinsTolerance * 2 + 1;
const freqGaussian = gaussian(windowLength, 5);
return notes.map(note => {
const freqIdx = Math.floor(
Math.round(midiPitchToContourBin(note.pitchMidi)),
);
const freqStartIdx = Math.max(freqIdx - nBinsTolerance, 0);
const freqEndIdx = Math.min(
N_FREQ_BINS_CONTOURS,
freqIdx + nBinsTolerance + 1,
);
const freqGuassianSubMatrix = freqGaussian.slice(
Math.max(0, nBinsTolerance - freqIdx),
windowLength -
Math.max(0, freqIdx - (N_FREQ_BINS_CONTOURS - nBinsTolerance - 1)),
);
const pitchBendSubmatrix = contours
.slice(note.startFrame, note.startFrame + note.durationFrames)
.map(d =>
d
.slice(freqStartIdx, freqEndIdx)
.map((v, col) => v * freqGuassianSubMatrix[col]),
);
const pbShift = nBinsTolerance - Math.max(0, nBinsTolerance - freqIdx);
const bends = argMaxAxis1(pitchBendSubmatrix).map(v => v - pbShift);
return {
...note,
pitchBends: bends,
};
});
}