2017-05-09 262 views
1

我有一些由javascript HTML5 web audio api生成的數據。它生成Float32Array,這是一個32位浮點數組,位於-1和1之間。我使用websocket將數據流式傳輸到服務器。將32位浮點轉換爲16位PCM範圍

我需要將-32768和+32767(16位有符號整數)之間的32位浮點數轉換爲16位PCM範圍。這樣就可以將數據用作wav文件。

我在轉換時遇到問題。我懷疑答案是使用結構模塊,但我無法得到正確的格式。

+1

'struct'模塊不能在這些類型之間直接轉換。它只能將32位浮點值解壓縮到Python浮點數中,並將Python int打包爲16位整數。它也不會做你需要的範圍轉換。 –

回答

3

這裏的一個示例的Python 2.7程序,讀取包含原始的32位浮點音頻樣本文件並創建包含的那些樣品轉化的16位帶符號的整數個樣本的WAV文件:

import sys 
import array 
import struct 
import wave 

def convert(fin, fout, chunk_size = 1024 * 1024): 
    chunk_size *= 4 # convert from samples to bytes 

    waveout = wave.open(fout, "wb") 
    waveout.setparams((1, 2, 44100, 0, "NONE", "")) 

    while True: 
     raw_floats = fin.read(chunk_size) 
     if raw_floats == "": 
      return 
     floats = array.array('f', raw_floats) 
     samples = [sample * 32767 
        for sample in floats] 
     raw_ints = struct.pack("<%dh" % len(samples), *samples) 
     waveout.writeframes(raw_ints) 

convert(open(sys.argv[1], "rb"), open(sys.argv[2], "wb")) 

代碼使用array.array將32位浮點數樣本轉換爲Python浮點數,因爲它應該比struct.unpack快一點。它也使用本機機器字節順序,就像Float32Array一樣。無法使用array.array創建16位整數採樣,因爲它們需要使用小端字節順序,而不管本機的機器順序如何。範圍轉換由簡單的Python代碼處理。

+0

感謝您的幫助。我簡化了代碼:https://gist.github.com/richtier/6b05b2bb3ceff20f3d9557227b8789c6,但是當我使用這裏定義的字節時:https://pastebin.com/raw/yCQ8Bg5w我得到他錯誤'結構.error:所需的參數不是整數'在這一點'samples'看起來像例如'[505.00430237688124,487.5382216461003,471.0005183443427,440.09429602883756]',這很有意義,因爲'samples'仍然是漂浮物列表 – rikAtee

+0

@rikAtee什麼版本你用的是Python嗎? –

+0

3.5.2 當我添加以下內容時,我認爲它開始表現自己:'samples = [int(sample * 32767)for sample in floats]' – rikAtee

相關問題