2016-09-02 42 views
5

我在我的燒瓶應用程序中將音頻從客戶端傳輸到服務器,但收到的音頻質量很差。這爲什麼會降低音頻質量?

在客戶端,我預處理音頻緩衝器如下:

this.node.onaudioprocess = function(e){ 
     var buf = e.inputBuffer.getChannelData(0); 
     var out = new Int16Array(buf.length); 
     for (var i = 0; i < buf.length; i++){ 
     var s = Math.max(-1, Math.min(1, buf[i])); 
     out[i] = s < 0 ? s * 0x8000 : s * 0x7FFF; 
     } 
     socket.emit('audio event',{data: out}) 
     return; 
} 

在服務器端,我接收所述音頻如下:

audio_file = open('tempfile.raw', 'w') 

@socketio.on('audio event') 
def audio_message(message): 
    dat = [v[1] for v in sorted(message['data'].iteritems())] 
    n = len(dat) 
    byteval = struct.pack('<'+str(n)+'h',*dat) 
    audio_file.write(byteval) 

但得到的音頻聲音的金屬,中斷和嘈雜。以下是得到的波形的樣子:

received wave sample

凡在我的代碼在音頻質量失去了什麼?如何在沒有質量損失的情況下傳輸音頻?

回答

2

我對你如何處理音頻的第一印象是它實時工作太慢。

在客戶端上,您遍歷每個樣本,應用邊界檢查(您是否真的需要這樣做?),然後將float32轉換爲int16格式,對每個樣本應用條件和乘法。

然後在服務器端,通過每個樣本做了另一個循環,只是爲了將樣本放入一個列表中(不是已經以列表形式發送給您的數據?)。然後才把這個列表打包成寫入磁盤的二進制數組。

這只是寫了一個緩衝區很多工作,你可能會丟失數據。

以下是我建議您嘗試的操作:刪除所有轉換並查看是否可以通過本機float32格式獲取數據流經系統。使用socket.io,您可以發送直接從客戶端打包的float32數據。沒有經過測試,但我相信socket.emit('audio event',{data: buf.buffer})將直接發送二進制有效負載,並且不會進行客戶端轉換。然後在服務器上,message['data']將是一個二進制有效載荷,您可以直接寫入磁盤。要檢查數據是否看起來不錯,可以使用導入原始對話框中的32位浮點選項來使用大膽性。

一旦你得到原始float32數據的工作,如果你需要另一種格式的數據,你可以看到是否添加一個轉換(希望只在一個地方)仍然允許你保持實時。我懷疑你可能需要在C/C++中編寫這種轉換,因爲對於這種類型的Python來說太慢了。如果你正在走這條路,那麼看看Cython可能是個好主意。

+0

buf.buffer中發生了什麼樣的轉換?這是否將float32array轉換爲二進制緩衝區? – user2212461

+0

不,「緩衝區」屬性返回數組的底層二進制結構,不進行任何轉換。請參閱JavaScript類型數組的文檔:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays。 – Miguel