问题
I want to detect an audio signal (morse code) on specific frequencies using web audio. I retrieve the frequency data using an analyser node's getFloatFrequencyData
function.
Now the problem: Using setInterval()
to regularly sample the frequency data is not regular enough: the callback gets executed a few milliseconds earlier or later than expected.
How can I retrieve the analyser's frequency data regularly exactly every few miliseconds? I would prefer using the built-in analyser node's FFT functionality instead of resorting to manually processing the audio data via e.g. Goertzel algorithm.
Code sample with the problematic setInterval()
:
// Analyse microphone audio frequencies:
function onStream(stream) {
let audioCtx = new(window.AudioContext || window.webkitAudioContext)(),
source = audioCtx.createMediaStreamSource(stream),
analyser = audioCtx.createAnalyser(),
fft = new Float32Array(analyser.frequencyBinCount);
source.connect(analyser);
// Doesn't execute exactly every 100ms as needed - what to do?
setInterval(() => {
analyser.getFloatFrequencyData(fft);
console.log(performance.now(), fft[0]);
}, 100);
}
navigator.mediaDevices.getUserMedia({audio: true}).then(onStream);
回答1:
Yeah, you can't really use an analyzer. There's too much uncertainty in when it will get run, and you can't guarantee precisely when it will run. You're better off using a ScriptProcessor for now (AudioWorklet eventually), and doing the FFT (or other recognition code) yourself.
来源:https://stackoverflow.com/questions/43191204/web-audio-analyser-node-run-at-regular-interval