Как написать стерео wav файлы в Python?

Следующий код записывает простой синус на частоте 400 Гц в монофонический WAV файл. Как этот код должен быть изменен для создания WAV файла стерео. Второй канал должен быть на другой частоте.

import math
import wave
import struct

freq = 440.0
data_size = 40000
fname = "WaveTest.wav"
frate = 11025.0  # framerate as a float
amp = 64000.0     # multiplier for amplitude

sine_list_x = []
for x in range(data_size):
    sine_list_x.append(math.sin(2*math.pi*freq*(x/frate)))

wav_file = wave.open(fname, "w")

nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"

wav_file.setparams((nchannels, sampwidth, framerate, nframes,
    comptype, compname))

for s in sine_list_x:
    # write the audio frames to file
    wav_file.writeframes(struct.pack('h', int(s*amp/2)))

wav_file.close()

Ответ 1

Создайте параллельный список sine_list_y с другой частотой/каналом, установите nchannels=2, а в выходном цикле используйте for s, t in zip(sine_list_x, sine_list_y): в качестве предложения заголовка и тело с двумя вызовами writeframes - одно для s, один для t. IOW, соответствующие кадры для двух каналов "чередуются" в файле.

См. эта страница для подробного описания всех возможных форматов WAV файлов, и я цитирую:

Многоканальные цифровые звуковые образцы хранятся в виде данных с чересстрочной волной что просто означает, что звук образцы многоканального (например, стерео и объемный) волновой файл хранятся путем циклического воспроизведения звука выборки для каждого канала до продвигаясь к следующему времени выборки. Это делается для того, чтобы аудиофайлы могут воспроизводиться или транслироваться до весь файл можно прочитать. Это удобно при воспроизведении большого файла с диска (которые могут не полностью вписаться в памяти) или потоковой передачи файла по Интернет. Значения на диаграмме ниже будет храниться в файле Wave в том порядке, в котором они перечислены в Столбец значений (сверху вниз).

а в следующей таблице четко показаны образцы каналов, идущие влево, вправо, влево, вправо,...

Ответ 2

Для примера, создающего файл стерео .wav, см. test_wave.py module. Тест производит файл с нулевым значением. Вы можете изменить, вставив переменные значения выборки.

nchannels = 2
sampwidth = 2
framerate = 8000
nframes = 100

# ...

    def test_it(self):
        self.f = wave.open(TESTFN, 'wb')
        self.f.setnchannels(nchannels)
        self.f.setsampwidth(sampwidth)
        self.f.setframerate(framerate)
        self.f.setnframes(nframes)
        output = '\0' * nframes * nchannels * sampwidth
        self.f.writeframes(output)
        self.f.close()