如何用Python编写24位WAV文件?

时间:2013-05-27 06:09:51

标签: python wav

我想使用Python 2.7从-1到1之间的浮点值数组生成一个24位WAV格式的音频文件。我不能使用scipy.io.wavfile.write,因为它只支持16或32位。 Python自己的wave模块的文档没有指定它采用的数据格式。

在Python中可以这样做吗?

7 个答案:

答案 0 :(得分:3)

另一个选项可以在wavio中找到(也在PyPI上:https://pypi.python.org/pypi/wavio),这是我创建的一个小模块,用于解决尚未支持24位WAV文件的scipy问题。文件wavio.py包含函数write,它将numpy数组写入WAV文件。要编写24位文件,请使用参数sampwidth=3wavio唯一的依赖是numpy; wavio使用标准库wave来处理WAV文件格式。

例如,

In [21]: import numpy as np

In [22]: import wavio

In [23]: rate = 22050             # samples per second

In [24]: T = 3                    # sample duration (seconds)

In [25]: f = 440.0                # sound frequency (Hz)

In [26]: t = np.linspace(0, T, T*rate, endpoint=False)

In [27]: sig = np.sin(2 * np.pi * f * t)

In [28]: wavio.write("sine24.wav", sig, rate, sampwidth=3)

答案 1 :(得分:3)

2年前我已经submitted an answer to this question,我建议scikits.audiolab

与此同时,情况已经发生变化,现在有一个可用的库,它更容易使用,也更容易安装,它甚至还带有自己的Windows {和{3}}库和OSX副本(在Linux上,无论如何都很容易安装):libsndfile

如果安装了CFFI和NumPy,只需运行

即可安装PySoundFile
pip install soundfile --user

编写24位WAV文件很简单:

import soundfile as sf
sf.write('my_24bit_file.wav', my_audio_data, 44100, 'PCM_24')

在此示例中,my_audio_data必须是包含dtype 'float64''float32''int32''int16'的NumPy数组。

BTW,我做了一个PySoundFile,我试图比较许多可用的Python库来读/写声音文件。

答案 2 :(得分:2)

尝试wave模块:

In [1]: import wave

In [2]: w = wave.open('foo.wav', 'w') # open for writing

In [3]: w.setsampwidth(3) # 3 bytes/sample

Python只能打包2和4个大小的整数。所以你可以在int32上使用带有dtype的numpy数组,并使用列表推导来获得每个整数的3/4字节:

In [14]: d = np.array([1,2,3,4], dtype=np.int32)

In [15]: d
Out[15]: array([1, 2, 3, 4], dtype=int32)

In [16]: [d.data[i:i+3] for i in range(0,len(d)*d.dtype.itemsize, d.dtype.itemsize)]
Out[16]: ['\x01\x00\x00', '\x02\x00\x00', '\x03\x00\x00', '\x04\x00\x00']

答案 3 :(得分:2)

使用wave模块,Wave_write.writeframes函数希望将WAV数据打包成小端格式的3字节字符串。以下代码可以解决这个问题:

import wave
from contextlib import closing
import struct

def wavwrite_24(fname, fs, data):
    data_as_bytes = (struct.pack('<i', int(samp*(2**23-1))) for samp in data)
    with closing(wave.open(fname, 'wb')) as wavwriter:
        wavwriter.setnchannels(1)
        wavwriter.setsampwidth(3)
        wavwriter.setframerate(fs)
        for data_bytes in data_as_bytes:
            wavwriter.writeframes(data_bytes[0:3])

答案 4 :(得分:2)

您应该尝试scikits.audiolab

import numpy as np
from scikits.audiolab import Sndfile, Format

sig = np.array([0, 1, 0, -1, 0], dtype=np.float32)
f = Sndfile('test_pcm24.wav', 'w', Format('wav', 'pcm24'), 1, 44100)
f.write_frames(sig)
f.close()  # use contextlib.closing in real code

再次阅读:

f = Sndfile('test_pcm24.wav')
sig = f.read_frames(f.nframes, dtype=np.float32)
f.close()  # use contextlib.closing in real code

scikits.audiolab使用libsndfile,因此除了WAV文件外,您还可以使用FLAC,OGG和更多文件格式。

答案 5 :(得分:0)

以下是case的更新版本,其中添加:

  • 24位.wav文件支持读/写,
  • 访问提示标记,
  • 提示标记标签,
  • 其他一些元数据,如音高(如果已定义)等。

wavfile.py (enhanced)

答案 6 :(得分:0)

利用ffmpeg在WAV编解码器之间互换,下面是示例代码

command = "ffmpeg -i input.wav -ar 22050 output.wav"
subprocess.call(command, shell=True)