play back generated sounds

南笙酒味 提交于 2019-12-07 19:39:49

问题


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:

  1. Retrieve the underlying channel data via the AudioBuffer's getChannelData(channel) method
  2. 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 like channelData.set(currArray, currOffset) with currOffset 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!