對於一個項目,我通過從Java服務器的WebSockets檢索實時音頻流。在服務器上,我以8位有符號字節值(兩個字節組成一個樣本)的形式處理16Bit/8000hz/mono的樣本。但是,在瀏覽器中,支持的最低採樣率爲22050赫茲。所以我的想法是「簡單地」將現有的8000升級到32000赫茲,這在我看來很容易計算。升頻音頻PCM數據在Javascript與WebAudioApi
到目前爲止,我已經試過linear upsampling和cosine interpolation,但都沒有奏效。除了聽起來真的扭曲之外,第一個還增加了一些點擊聲音。我在Chrome中也可能遇到WebAudioAPI的問題,但至少聲音在播放,並且幾乎不可辨認。所以我想沒有codec或endianess問題。
下面是當接收到帶有聲音數據的二進制數據包被執行的完整代碼。爲了簡單起見,我一直在創建新的緩衝區和緩衝區資源(是的,對性能沒有好處)。 data
是一個ArrayBuffer。首先,我將樣品轉換爲Float,然後我進行上採樣。
//endianess-aware buffer view
var bufferView=new DataView(data),
//the audio buffer to set for output
buffer=_audioContext.createBuffer(1,640,32000),
//reference to underlying buffer array
buf=buffer.getChannelData(0),
floatBuffer8000=new Float32Array(160);
//16Bit => Float
for(var i=0,j=null;i<160;i++){
j=bufferView.getInt16(i*2,false);
floatBuffer8000[i]=(j>0)?j/32767:j/-32767;
}
//convert 8000 => 32000
var point1,point2,point3,point4,mu=0.2,mu2=(1-Math.cos(mu*Math.PI))/2;
for(var i=0,j=0;i<160;i++){
//index for dst buffer
j=i*4;
//the points to interpolate between
point1=floatBuffer8000[i];
point2=(i<159)?floatBuffer8000[i+1]:point1;
point3=(i<158)?floatBuffer8000[i+2]:point1;
point4=(i<157)?floatBuffer8000[i+3]:point1;
//interpolate
point2=(point1*(1-mu2)+point2*mu2);
point3=(point2*(1-mu2)+point3*mu2);
point4=(point3*(1-mu2)+point4*mu2);
//put data into buffer
buf[j]=point1;
buf[j+1]=point2;
buf[j+2]=point3;
buf[j+3]=point4;
}
//playback
var node=_audioContext.createBufferSource(0);
node.buffer=buffer;
node.connect(_audioContext.destination);
node.noteOn(_audioContext.currentTime);
我怎樣才能將任何一個採樣率轉換爲另一個採樣率?不僅8000到32000 – noamtcohen