2016-03-09 67 views
0

我正在嘗試通過一個node.js(express)服務器上的websocket將音頻流式傳輸到Web瀏覽器。音頻來自iOS設備,是以4k採樣的16位單聲道wav文件(每秒4000個採樣點)。網絡音頻API - 實時流在塊之間點擊。

這裏是我的代碼:

服務器代碼:

webSocketServer.on('connection', function connection(client) { 
    client.on('message', function(message) { 
    webSocketServer.clients.forEach(function each(connection) { 
     connection.send(message, { binary: true } 
    ); 
    }); 
}); 

客戶端代碼:

webSocket = new WebSocket('ws://' + window.location.hostname + ':8080/'); 
webSocket.binaryType = 'arraybuffer' 
webSocket.onmessage = function(message) { 
    var arrayBuffer = message.data // wav from server, as arraybuffer 
    var source = audioContext.createBufferSource(); 
    audioContext.decodeAudioData(arrayBuffer, function(buffer){ 
    source.buffer = buffer 
    source.connect(audioContext.destination) 
    source.start(time); 
    time += source.buffer.duration 
    }, function(){ 
    console.log('error') 
    }) 
}; 

decodeAudioData()似乎是工作,但它返回的音頻緩衝器半我是長期待。 (例如,4000個樣本只會給我0.5秒的音頻,我原本以爲這是因爲wav是16位而不是32,但切換到32導致decodeAudioData()觸發它的錯誤回調。添加到成功回調:

source.playbackRate.value = 0.5 // play at half speed 
time += source.buffer.duration * 2 // double duration 

這得到定時工作完美,但我留下了一個問題:有一個聽得見的「咔嗒」或音頻數據塊之間的「流行」間隔出後。大約一秒(time += (source.buffer.duration * 2) + 1),我能夠發現點擊發生在每個塊的最開始處。

所以我的主要兩個頭部劃痕是:

1)爲什麼解碼音頻播放速度是我所期望的兩倍?對於Web Audio API,我的採樣率是否過低?爲什麼我無法解碼32位wav?

2)我對數字音頻工作站(ableton,邏輯)有一些經驗,我知道如果一個波從樣本回落到零或反之亦然(即:開始/結束一個正弦波在一個階段中)。這是怎麼回事?有沒有辦法解決這個問題?將每個單獨的樣本交叉淡化似乎很愚蠢。爲什麼每個組塊拾取的最後一個都沒有停止?

回答

1

1)我收到的音頻實際上是在2k的錯誤,但wav頭仍然說4k,因此雙倍速度的錯誤。

2)見Chris Wilsons answer here最後一段:

最後 - 這是行不通的好,如果聲音流不匹配默認音頻設備的採樣率;總會有點擊,因爲decodeAudioData將重新採樣到設備速率,這將不會有一個完美的持續時間。它會起作用,但是可能會有大塊的邊界處的點擊等工件。您需要一個尚未指定或實現的功能 - 可選的AudioContext採樣率 - 以解決此問題。

Brion Vibbers AudioFeeder.js很好的工作,沒有任何點擊,但需要原始的32位pcm數據。也要警惕upsampling artifacts