将24位音频样本转换为int32数组(little-endian WAV文件)

时间:2013-12-06 22:49:35

标签: python audio numpy int endianness

我将24位单声道音频.wav文件读入<i4类型的数组中(<i3不存在)

data = numpy.fromfile(fid, dtype=`<i4`, count=size//3)

我应该怎么做才能正确获取音频样本?我应该交换这样的字节顺序,怎么样?

2 个答案:

答案 0 :(得分:1)

您可以将数据转换为uint8的numpy数组,然后使用reshapehstack为每个样本添加0;

In [1]: import numpy as np

我在这里使用生成的序列作为例子。

In [2]: a = np.array([1,2,3]*10, dtype=np.uint8)

In [3]: a
Out[3]: 
array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2,
       3, 1, 2, 3, 1, 2, 3], dtype=uint8)

In [4]: a = a.reshape((-1,3))

重塑可让您对样本进行分组:

In [5]: a
Out[5]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]], dtype=uint8)

制作必须添加的零。

In [6]: b = np.zeros(10, dtype=np.uint8).reshape((-1,1))

In [7]: b
Out[7]: 
array([[0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0],
       [0]], dtype=uint8)

现在我们添加零。假设您正在使用little-endian系统,则添加的零位于前面,以缩放数据。

(我希望我的这些字节顺序正确。如果现在的样本听起来很微弱,我说错了,你需要使用(a,b)代替(b,a)

In [8]: c = np.hstack((b, a))

In [9]: c
Out[9]: 
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]], dtype=uint8)

重新塑造它。

In [10]: c.reshape((1,-1))
Out[10]: 
array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1,
        2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]], dtype=uint8)

转换为字节:

In [11]: bytearray(c.reshape((1,-1)))
bytearray(b'\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03\x00\x01\x02\x03')

现在你有4个字节的样本。

答案 1 :(得分:1)

以下是读取24位文件的解决方案(感谢Warren Weckesser的要点https://gist.github.com/WarrenWeckesser/7461781):

data = numpy.fromfile(fid, dtype='u1', count=size) # first read byte per byte

a = numpy.empty((len(data)/3, 4), dtype=`u1`)
a[:, :3] = data.reshape((-1, 3))
a[:, 3:] = (a[:, 3 - 1:3] >> 7) * 255
data = a.view('<i4').reshape(a.shape[:-1])

这可以直接插入def _read_data_chunk(fid, noc, bits):scipy\io\wavfile.py)。