[英]24-bit audio sample into int32 array (little-endian WAV file)
I read a 24-bit mono audio .wav file into an array of type <i4
( <i3
doesn't exist) 我将24位单声道音频.wav文件读入了
<i4
类型的数组( <i3
不存在)
data = numpy.fromfile(fid, dtype=`<i4`, count=size//3)
What should I do in order to get the audio samples properly ? 我该怎么做才能正确获取音频样本? Should I swap bytes order of something like this, how ?
我应该像这样交换字节顺序吗?
You can convert the data into a numpy array of uint8
, then add the 0 to each sample by using reshape
and hstack
; 您可以将数据转换为
uint8
的numpy数组,然后使用reshape
和hstack
将0添加到每个样本;
In [1]: import numpy as np
I'm using a generated sequence here as an example. 我在这里以生成的序列为例。
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))
Reshape allows you to group the samples: 整形可让您对样本进行分组:
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)
Make the zeros that have to be added. 使必须添加的零。
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)
Now we add the zeroes. 现在我们添加零。 Assuming you're using a little-endian system, the added zero goes at the front, to scale the data.
假设您使用的是little-endian系统,则添加的零在最前面,以缩放数据。
(I hope I got this endianness stuff right. If the sample now sounds very faint, I got it wrong and you need to use (a,b)
instead of (b,a)
) (我希望我对这种字节序的东西是正确的。如果样本现在听起来很模糊,我就弄错了,您需要使用
(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)
Reshape it back. 重塑它。
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)
Convert to bytes: 转换为字节:
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')
Now you have 4-byte samples. 现在,您有4个字节的样本。
Here is the solution for reading 24 bits files (thanks to Warren Weckesser's gist https://gist.github.com/WarrenWeckesser/7461781 ) : 这是读取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])
This can be directly inserted in def _read_data_chunk(fid, noc, bits):
( scipy\\io\\wavfile.py
). 这可以直接插入
def _read_data_chunk(fid, noc, bits):
scipy\\io\\wavfile.py
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.