2014-02-22 3 views
3

채널 데이터를 AudioBuffer에서 가져 와서 전송 가능한 객체를 통해 웹 작업자에게 전송하여 처리하고 있습니다. 이제 다시 넣으 려합니다. 정말이 복사해야합니까? 정말 바라고 있어요수동으로 pcm 데이터를 AudioBuffer에 넣으십시오.

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

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

그냥 AudioBuffer 채널 참조의 각을 ArrayBuffer을 변경할 수있는 몇 가지 방법이있다. 뭔가 ...

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

... 멋지고 간단하지만 효과적 일 수 있지만 외관상으로는 존재하지 않습니다. 이와 같이 참조를 변경하고 데이터 복사를 피할 수있는 방법이 있습니까?

편집 : 약간의 조사를 통해 웹 오디오 API를 전송 가능한 객체와 함께 사용하는 문제가 훨씬 더 성가시다. 배열 버퍼를 작업자에게 전송하면 AudioBuffer의 기본 배열 버퍼가 지워지고 Float32Array을 통해 복사 작업을 수행한다고해도 getChannelData이 반환하지 않습니다. 내가 지금 원하는 것을 성취하기 위해 볼 수있는 유일한 방법은 원래 AudioBuffer을 포기하고 완전히 새로운 AudioBuffer을 만든 다음 내 데이터를 복사하는 것입니다. 정말??

답변

1

몇 가지 : 루프의 두통를 진행하는 데 필요하지 않는 또 다른 한개에 입력 된 배열에서 데이터를 복사하기위한 매우 저가의 방법이있다

1). 당신의 오디오 버퍼의 문제는 클리어하기

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

2) 웹 근로자와 양도 객체 (https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects))에 대한 사양의 한 부분이다. 그것이 스레드 안전을 보장 할 수있는 유일한 방법입니다. 두 스레드가 같은 오브젝트에 동시에 액세스 할 수 있다면, 둘 다 스레드를 변경하면 모든 종류의 광적인 결과가 발생할 수 있습니다.

새로운 AudioBuffer을 생성하고 데이터를 복사 할 때 왜 그렇게 짜증이 났는지 잘 모르겠습니다. 모노 버퍼의 경우 2 줄로 할 수 있습니다. 스테레오 용 3 라인. 웹 작업자를 시작하고 운영하는 데 필요한 모든 상용구를 설정하여 이미 그 이상의 작업을 수행했습니다.

어쨌든 응용 프로그램과 그 기능에 대해 좀 더 구체적으로 설명 할 수 있다면 기꺼이 추천 해 드리겠습니다.

2

우리는 최근 AudioBuffer에 두 가지 새로운 메서드를 추가했습니다.이 메서드는 copyFromChannel이 유용 할 수 있습니다. 그것은 주석 (AudioBuffer의 채널에 ArrayBuffer 넣기)에서 말하는대로 처리합니다 (복사를 피하기위한 이유와 조건은 here입니다).

Firefox 용으로 만 구현 된 것 같습니다. 그러나 아직 확인하지 않았습니다.

+0

이것은 현재 최신 브라우저에서 널리 지원됩니다.또한'copyFromChannel' 메쏘드가 메인 쓰레드에서 추가 배열 할당을 필요로하지 않고'getChannelData'보다 약 2 배 빠릅니다. (transferables와 함께 직접적으로 사용될 수는 없지만, 채널 데이터가 놓여지면 (자), 배열이 null가되어,'getChannelData'에 의한 같은 추가 할당이 필요합니다. –

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