Как написать 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)