Как писать стерео 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()

person Jonathan    schedule 03.09.2010    source источник
comment
Поставь nchannels = 2 для начала ;)   -  person ChrisF    schedule 03.09.2010


Ответы (3)


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

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

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

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

person Alex Martelli    schedule 03.09.2010
comment
Я лично вижу, как они идут ↑ ↑ ↓ ↓ ← → ← → B A, но это может быть только я. - person Jill-Jênn Vie; 19.06.2013
comment
Ссылка на ссылку мертва. :( Вот это с машины обратного пути для справки: web.archive.org/web/20141226210234/www.sonicspot.com/guide/ - person Cameron Bielstein; 02.05.2019

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

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()
person gimel    schedule 03.09.2010

Другой вариант — использовать библиотеки SciPy и NumPy. В приведенном ниже примере мы создаем файл стереофонической волны, в котором левый канал имеет низкочастотный тон, а правый канал имеет более высокочастотный тон.

Чтобы установить SciPy, см.: https://pypi.org/project/scipy/

import numpy as np
from scipy.io import wavfile

# User input
duration=5.0
toneFrequency_left=500 #Hz (20,000 Hz max value)
toneFrequency_right=1200 #Hz (20,000 Hz max value)

# Constants
samplingFrequency=48000

# Generate Tones
time_x=np.arange(0, duration, 1.0/float(samplingFrequency))
toneLeft_y=np.cos(2.0 * np.pi * toneFrequency_left * time_x)
toneRight_y=np.cos(2.0 * np.pi * toneFrequency_right * time_x)

# A 2D array where the left and right tones are contained in their respective rows
tone_y_stereo=np.vstack((toneLeft_y, toneRight_y))

# Reshape 2D array so that the left and right tones are contained in their respective columns
tone_y_stereo=tone_y_stereo.transpose()

# Produce an audio file that contains stereo sound
wavfile.write('stereoAudio.wav', samplingFrequency, tone_y_stereo)

Примечания по окружающей среде

Используемая версия Python 3.7.1

  • Питон 3.7.1
  • Научная версия 1.1.0
person David M. Helmuth    schedule 18.05.2020