手动将pcm数据放入AudioBuffer

时间:2014-02-22 17:34:04

标签: javascript web-audio

所以我从AudioBuffer中提取了频道数据并通过可转移对象将其发送给网络工作人员对其进行处理,现在我想把它重新插入。我真的有吗要像这样复制吗?

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

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

我真的希望有一些方法可以更改每个ArrayBuffer频道参考的AudioBuffer。有点像...

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

......简单而有效,但看似不存在。有没有像这样的方法来更改引用并避免复制数据?

编辑:经过进一步调查,我发现将web音频API与可转移对象一起使用的问题更令人讨厌。将数组缓冲区传输到worker时,AudioBuffer的基础数组缓冲区被清除,我相信甚至不能通过Float32Array返回的getChannelData进行复制操作。我现在能够看到完成我想要的唯一方法就是放弃原来的AudioBuffer,创建一个全新的AudioBuffer,然后将我的数据复制到其中。真??

4 个答案:

答案 0 :(得分:2)

我们最近在AudioBuffer上添加了两个新方法,使用copyFromChannel可能对您有用。它完成它在锡上所说的内容(将一个ArrayBuffer放在一个AudioBuffer的通道中),也许在这个过程中保存一个副本(解释了避免副本的原因和条件here)。

我相信它目前仅在Firefox中实现,但我还没有检查过。

答案 1 :(得分:2)

我整天都在努力,所以我想我应该分享我的解决方案。

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];
}

答案 2 :(得分:1)

一些事情:

1)有一种非常低成本的方法可以将数据从一个类型数组复制到另一个类型数组,而不需要你经历循环的麻烦。

var copy = new Float32Array(orig.length);
copy.set(orig);

2)清除AudioBuffer的问题只是Web worker(https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects))的可转移对象规范的一部分。这是他们保证线程安全的唯一方法。如果两个线程同时访问同一个对象,它们都可以改变它,并且你最终会遇到各种各样的疯狂。

我不完全确定为什么你对创建新AudioBuffer并将数据复制到其中的前景如此恼火。您可以在2行中为单声道缓冲区执行此操作。 3行立体声。通过设置启动和运行Web工作人员所需的所有样板,您已经完成了更多的工作。

无论如何,如果你能提供一些关于你的应用程序以及它正在做什么的更多细节,我很乐意提出一些建议。

答案 3 :(得分:0)

你太近了!您想要的方法是AudioBuffer.copyToChannel()

这会将您的Float32Array复制到音频缓冲节点,如下所示:

var myData = new Float32Array(audioBuf.length);

//copy mydata to first channel

audioBuf.copyToChannel( myData , 0 , 0 );

文档深入:

https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer/copyToChannel

希望这会有所帮助