使用wavio Python 3.5读取24位WAV

时间:2016-09-30 18:52:49

标签: python numpy wav

我正在使用WarrenWeckesser的wavio因为我需要在python中读取24位wav文件。我拥有的wav文件是由一些工具生成的,我试图在没有任何规范化或缩放的情况下获取原始值。

在wavio模块中,完成工作的代码是:

    if sampwidth == 3:
        a = _np.empty((num_samples, nchannels, 4), dtype=_np.uint8)
        raw_bytes = _np.fromstring(data, dtype=_np.uint8)
        a[:, :, :sampwidth] = raw_bytes.reshape(-1, nchannels, sampwidth)
        a[:, :, sampwidth:] = (a[:, :, sampwidth - 1:sampwidth] >> 7) * 255
        result = a.view('<i4').reshape(a.shape[:-1]

有人可以解释它实际上在做什么(我对numpy和数组切片相对较新)。我理解其中的大部分但我不明白这里发生了什么:

    a[:, :, sampwidth:] = (a[:, :, sampwidth - 1:sampwidth] >> 7) * 255

在我的情况下,它执行从24位到32位的转换,但我无法确定它是缩放数据,还是简单地将其填充而不更改任何原始值。

1 个答案:

答案 0 :(得分:1)

a的形状为(num_samples, nchannels, 4)sampwidth == 3,因此该行与

相同
a[:, :, 3:] = (a[:, :, 2:3] >> 7) * 255

相同
a[:, :, 3] = (a[:, :, 2] >> 7) * 255

我们可以对外部两个循环进行开发:

for i in range(num_samples):
    for j in range(nchannels):
        a[i, j, 3] = (a[i, j, 2] >> 7) * 255

a的dtype是_np.uint8,因此a[...] >> 7只能在值<128时给出0,或者当它是≥128时给出1,所以上面变为:

for i in range(num_samples):
    for j in range(nchannels):
        v = a[i, j, 2]
        a[i, j, 3] = 255 if v >= 128 else 0

如果数据是24位小端整数,则相当于将sign-extension转换为32位。