I am creating a complex metronome app using Ionic and Web Audio API.
At certain points, the metronome could be playing 10+ 'beats' a second.
This essentially calls this function 10 times+ a second.
function playSound(e, name) {
var buffer = audioBuffers[name];
var source = audioContext.createBufferSource();
var gain = audioContext.createGain();
source.connect(gain);
gain.connect(audioContext.destination);
gain.gain.value = 1;
source.buffer = buffer;
source.connect(audioContext.destination);
sched.nextTick(e.playbackTime, () => {
source.start(0);
});
}
The user can choose multiple samples, so I fetch them all first once and store the buffer in an array to improve performance instead of making a XMLHttpRequest() every time.
The issue is that when playing at these higher rates the playback gets odd and sometimes goes out of sync. I am using https://github.com/mohayonao/web-audio-scheduler which works lovely so I know its not a timing issue.
If I swap out the sample playback for a basic oscillator:
function oscillator(e) {
const t0 = e.playbackTime;
const t1 = t0 + 0.4;
const osc = audioContext.createOscillator();
const amp = audioContext.createGain();
osc.frequency.value = 1000;
osc.start(t0);
osc.stop(t1);
osc.connect(amp);
amp.gain.setValueAtTime(1, t0);
amp.gain.exponentialRampToValueAtTime(1e-6, t1);
amp.connect(masterGain);
sched.nextTick(t1, () => {
osc.disconnect();
amp.disconnect();
});
}
Performance is fine no matter what tempo. Is there any improvements I can make to the sample playback to help improve performance?