簡體   English   中英

使用WebAudioApi對Javascript中的音頻PCM數據進行上采樣

[英]Upsampling Audio PCM-data in Javascript with WebAudioApi

對於一個項目,我正在通過Java服務器上的WebSockets檢索實時音頻流。 在服務器上,我以8位帶符號字節值(其中兩個字節組成一個采樣)的形式處理16Bit / 8000hz / mono中的采樣。 但是,在瀏覽器上,支持的最低采樣率是22050 Hz。 因此,我的想法是“簡單地”將現有的8000升采樣至32000 Hz,這是受支持的,在我看來,這很容易計算。

到目前為止,我已經嘗試了線性上采樣余弦插值 ,但是都沒有用。 除了聽起來確實失真之外,第一個還添加了一些咔嗒聲。 我在Chrome中使用WebAudioAPI可能也會遇到麻煩,但至少聲音正在播放並且幾乎無法識別其應有的狀態。 所以我猜沒有編解碼器或字節序問題。

這是接收到帶有聲音數據的二進制數據包時執行的完整代碼。 為了簡單起見,我一直在創建新的緩沖區和緩沖源(是的,對性能沒有好處)。 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);

終於找到了解決方案。 從16Bit到Float的轉換是錯誤的,只需要

floatBuffer8000[i]=j/32767.0;

此外,向API提供大量小樣本也無法正常工作,因此您需要緩沖一些樣本並一起​​播放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM