Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually put pcm data into AudioBuffer

So I've pulled the channel data out of an AudioBuffer and sent it via transferable object to a web worker to do some processing on it, and now I want to put it back in. Do I really have to copy it back in like this?

var myData = new Float32Array(audioBuf.length);
var chanData = audioBuf.getChannelData(0);

for ( var n = 0; n < chanData.length; n++ ) {
    chanData[n] = myData[n];
}

I'm really hoping there is some way to just change out the ArrayBuffer each of the AudioBuffer channels reference. Something like...

audioBuf.channel[0].buffer = myData.buffer;

...would be wonderfully simple and effective, but seemingly does not exist. Is there any way at all like this to change the reference and avoid copying the data?

EDIT: With a little further investigation, I see the problem of using the web audio API with transferable objects is even more annoying. When you transfer the array buffers to the worker, the underlying array buffers of the AudioBuffer are cleared, I believe making even a copy operation through the Float32Array returned by getChannelData impossible. The only way I can see to accomplish what I want right now is to abandon the original AudioBuffer, create an entirely new AudioBuffer and then copy my data into it. Really??

like image 280
Rob Allsopp Avatar asked Feb 22 '14 17:02

Rob Allsopp


2 Answers

We recently added two new methods on AudioBuffer, from which use copyFromChannel could be useful to you. It does what it says on the tin (put an ArrayBuffer in a channel of an AudioBuffer), maybe saving a copy in the process (the reasons and condition to avoid the copy are explained here).

I believe it's only implemented in Firefox for the moment, but I haven't checked.

like image 81
padenot Avatar answered Nov 19 '22 23:11

padenot


I struggled with this all day, so I figured I should share my solution.

var PCM = [0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1];


var room = new window.AudioContext();
var sampleRate = 44100;
var channels = 1;

var audioBuffer = room.createBuffer(channels, 0, sampleRate);

var channelObject = audioBuffer.getChannelData(0);

var audioBufferDataArray = channelObject.data;


// actual code to set the data

audioBuffer.length = PCM.length; // optional

for(var i=0; i<PCM.length; i++){
    audioBufferDataArray[i] = PCM[i];
}
like image 4
Wray Bowling Avatar answered Nov 19 '22 23:11

Wray Bowling