Published
Edited
Sep 7, 2022
2 forks
Insert cell
Insert cell
BasicPitch = import("https://cdn.skypack.dev/@spotify/basic-pitch@1.0.1?min")
Insert cell
BasicPitch
Insert cell
audioCtx = new AudioContext({
// This samplerate is required by basic-pitch
sampleRate: 22050
})
Insert cell
// Small workaround to make audioBuffer mutable in Observable
ab = {
return { audioBuffer: undefined };
}
Insert cell
// from here: https://github.com/spotify/basic-pitch-ts/tree/main/test_data
test_data_c_major = FileAttachment("test_data_C_major.mp3")
Insert cell
audioCtx.decodeAudioData(
// fs.readFileSync(/* Path to audio file */),
await test_data_c_major.arrayBuffer(),

async (_audioBuffer) => {
ab.audioBuffer = _audioBuffer;
},
() => {}
)
Insert cell
notes = {
while (ab === undefined || ab.audioBuffer === undefined) {
console.log("waiting for audio to load");
await new Promise((r) => setTimeout(r, 10));
}

const frames = [];
const onsets = [];
const contours = [];
let pct = 0;
const model = "https://unpkg.com/@spotify/basic-pitch@1.0.1/model/model.json";
const basicPitch = new BasicPitch.BasicPitch(model);
await basicPitch.evaluateModel(
ab.audioBuffer,
(f, o, c) => {
frames.push(...f);
onsets.push(...o);
contours.push(...c);
},
(p) => {
pct = p;
}
);

const notes = BasicPitch.noteFramesToTime(
BasicPitch.addPitchBendsToNoteEvents(
contours,
BasicPitch.outputToNotesPoly(frames, onsets, 0.25, 0.25, 5)
)
);
return notes;
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more