4

我已将我的问题隔离到最低限度:读取 WAV 文件,然后立即将其写回。尽管输入是音乐,但输出是噪音。这让我很困惑。这是代码:

import scipy.io.wavfile as wavfile
rate, data = wavfile.read("myinput.wav")
wavfile.write("myoutput.wav", rate, data)

大概我在做一些非常愚蠢的事情。有人可以告诉我如何让它工作吗?

PS在读入和写出之间添加“打印数据”会产生......

[ 889195140  456589342  2605824 ...,  221785355 1292756287  873860659]
4

2 回答 2

2

通过一些额外的转换,您可以将 24 位 WAV 文件与wave标准库中的模块一起使用。

import wave
import numpy as np
from contextlib import closing

def pcm24to32(data, nchannels=1):
    temp = np.zeros((len(data) / 3, 4), dtype='b')
    temp[:, 1:] = np.frombuffer(data, dtype='b').reshape(-1, 3)
    return temp.view('<i4').reshape(-1, nchannels)

def pcm2float(sig, dtype=np.float64):
    sig = np.asarray(sig)  # make sure it's a NumPy array
    assert sig.dtype.kind == 'i', "'sig' must be an array of signed integers!"
    dtype = np.dtype(dtype)  # allow string input (e.g. 'f')

    # Note that 'min' has a greater (by 1) absolute value than 'max'!
    # Therefore, we use 'min' here to avoid clipping.
    return sig.astype(dtype) / dtype.type(-np.iinfo(sig.dtype).min)

with closing(wave.open('my_24bit_input.wav')) as w:
    framerate = w.getframerate()
    nframes = w.getnframes()
    nchannels = w.getnchannels()
    width = w.getsampwidth()
    data = w.readframes(nframes)

assert width == 3

pcm = pcm24to32(data, nchannels)

# You can also use np.float64, if you prefer:
normalized = pcm2float(pcm, np.float32)

我创建了一个包含更多信息的 IPython 笔记本

当然,您也可以使用scikits.audiolab,但请注意,当前(版本 0.11.0)在使用!以外的类型时存在错误( https://github.com/cournape/audiolab/issues/3 )np.float64

您也可以尝试https://github.com/bastibe/PySoundFile,但我自己(还)没有尝试过。

于 2013-11-06T08:59:33.850 回答
0

感谢您提供许多有用的意见。

我不知道 24 位问题,但四处搜索我看到了许多与此问题相关的线程和建议的修复。对我来说,我将按照用户 LMO 在链接中描述的方式使用 scikits.audiolab,我通过 MacPorts 和 easy_install 在我的 Mac 上使用 Python 2.7。

sudo port install libsndfile; sudo easy_install-2.7 scikits.audiolab

然后最终代码使用 audiolab 进行读入(可以使它对写入执行相同的操作)...

import scipy.io.wavfile as wavfile
import numpy as np
from scikits.audiolab import Sndfile
f = Sndfile("myinput.wav", 'r')
data = np.array(f.read_frames(f.nframes), dtype=np.float64)
f.close()
rate = f.samplerate;
wavfile.write("myoutput.wav", rate, data)

这适用于有问题的文件和许多其他文件。

于 2013-11-06T01:03:24.530 回答