问题
I want to capture audio (in my case from getUserMedia
) and play it back. I'm able to push a bunch of AudioBuffers to an array like so:
var recorder = audio_context.createJavaScriptNode(256, 2, 2);
recorder.onaudioprocess = function(e) {
recorded.push(e.inputBuffer.getChannelData(0));
// or just:
// recorded.push(e.inputBuffer);
};
recorder.connect(audio_context.destination);
But then how do I play the buffers in the recorded
array?
A way to merge these into one buffer and play it with createBufferSource
?
A different approach altogether?
回答1:
Once you're done recording the audio, you should be able to do the following:
var bufferIndex = 0;
recorder.onaudioprocess = function (e) {
var outputData = e.outputbuffer.getChannelData(0);
var recordedData = recorded[bufferIndex];
for (var i = 0; i < recordedData.length; i++) {
outputData[i] = recordedData[i];
});
bufferIndex++;
}
(You can probably make that simpler/cleaner; this was just for illustration purposes)
回答2:
In my opinion, the simplest way to do this is, as you suggested, merging them into a single AudioBuffer and playing that through an AudioBufferSourceNode. I would start by creating a new AudioBuffer object via the context.createBuffer
method, specifically the version that takes numberOfChannels, length, and sampleRate as arguments. To calculate length (which is in seconds), you'll need to know the size of all your sample arrays combined... you may want to simply keep a running total of this as you capture them (something like recLength += currentBuffer.length
). You can then determine the length by dividing the total number of samples by the sample rate. Sample rate can be determined via context.sampleRate
.
Once you've created a new AudioBuffer object with the proper parameters, you simply need to copy the arrays you've saved (your recorded
array) into the AudioBuffer's channel data array. This is a fairly simple two step process:
- Retrieve the underlying channel data via the AudioBuffer's
getChannelData(channel)
method - Iterate through your
recorded
array and copy your saved data into the channel data array via the.set(array, offset)
method (see the MDN Float32Array docs for more info). Your code would look something likechannelData.set(currArray, currOffset)
withcurrOffset
increasing by the length of each stored array.
Note: if you're recording two channels of audio, you'll have two arrays of recorded samples and you'll have to perform the above two steps for each channel (0 and 1), copying over the corresponding array.
If done correctly, you'll have an AudioBuffer which you can slot into an AudioBufferSourceNode and play back as you see fit.
来源:https://stackoverflow.com/questions/13128107/play-back-generated-sounds