Как написать 24-битный WAV файл в Python?
Я хочу создать 24-битный аудиофайл WAV-формата с использованием Python 2.7 из массива значений с плавающей запятой между -1 и 1. Я не могу использовать scipy.io.wavfile.write, поскольку он поддерживает только 16 или 32 бита. Документация для собственного wave модуля Python не определяет формат данных, который требуется.
Так можно ли это сделать в Python?
Ответы
Ответ 1
Еще одна опция доступна в wavio
(также на PyPI: https://pypi.python.org/pypi/wavio), небольшой модуль, который я создал в качестве рабочего процесса, к проблеме scipy, еще не поддерживающей 24-битные WAV файлы. Файл wavio.py
содержит функцию write
, которая записывает массив numpy в WAV файл. Чтобы записать 24-битный файл, используйте аргумент sampwidth=3
. Единственная зависимость wavio
- 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)
Ответ 2
Я уже представил ответ на этот вопрос 2 года назад, где я рекомендовал scikits. Audiolab.
В то же время ситуация изменилась, и теперь есть доступная библиотека, которая намного проще в использовании и намного проще в установке, она даже поставляется с собственной копией libsndfile библиотека для Windows и OSX (в Linux это легко установить в любом случае): PySoundFile
Если у вас установлены 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
должен быть массивом NumPy с dtype
'float64'
, 'float32'
, 'int32'
или 'int16'
.
Кстати, я сделал обзорную страницу, где я попытался сравнить многие доступные библиотеки Python для чтения/записи звуковых файлов.
Ответ 3
Попробуйте модуль 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 размерах укусов. Таким образом, вы можете использовать массив numpy с dtype на int32 и использовать понимание списка, чтобы получить 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']
Ответ 4
Используя модуль wave
, функция Wave_write.writeframes
ожидает, что данные WAV будут упакованы в 3-байтовую строку в формате little-endian. Следующий код делает трюк:
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])
Ответ 5
Вы должны попробовать 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 и некоторые другие форматы файлов.
Ответ 6
Вот обновленная версия scipy.io.wavfile
, которая добавляет:
- Поддержка 24-бит .wav файлов для чтения/записи,
- доступ к меткам метки,
- метки метки метки,
- некоторые другие метаданные, такие как шаг (если они определены) и т.д.
wavfile.py(улучшено)
Ответ 7
Используйте ffmpeg для обмена между кодеками WAV, ниже приведен пример кода
command = "ffmpeg -i input.wav -ar 22050 output.wav"
subprocess.call(command, shell=True)