如何在Python中编写立体声wav文件?

18
以下代码将简单正弦波以400Hz的频率写入独立声道的WAV文件。要生成一个立体声WAV文件,应如何更改此代码?第二个通道应以不同的频率生成。
以下代码将简单正弦波以400Hz的频率写入独立声道的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
设置 nchannels = 2 作为一个起始值 ;) - ChrisF
3个回答

11

使用其他频率/通道构建一个并行的sine_list_y列表,将nchannels=2设置为输出循环中使用for s, t in zip(sine_list_x, sine_list_y):作为标题从句,正文有两个writeframes调用——一个是为了s,一个是为了t。即两个通道对应的帧在文件中“交替”出现。

详细描述所有可能的WAV文件格式,请参见例如页面,并引用:

多通道数字音频样本以交错的波形数据形式存储,这意味着一个多通道(例如立体声和环绕声)波形文件的音频样本在前进到下一个样本时间之前通过循环处理每个通道的音频样本进行存储。这样做是为了让音频文件可以在整个文件读取之前播放或流式传输。当从磁盘播放大文件(可能无法完全适合内存)或通过互联网流式传输文件时,这非常方便。下面的图表中的值将按照列出的顺序(从上到下)存储在Wave文件中。

以下表格清楚地显示了通道样本向左、向右、向左、向右等的走向。


3

如果需要生成一个立体声的 .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()

2
另一种选择是使用SciPy和NumPy库。在下面的示例中,我们生成一个立体声波形文件,其中左声道具有低频音,而右声道具有高频音。(注意:使用VLC播放器播放音频)
要安装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

  • Python 3.7.1
  • SciPy 1.1.0

1
当我尝试播放你的代码生成的音频文件时,Windows媒体播放器和Groove音乐播放器都会抛出不支持的编解码器错误:0xc00d5212。你使用了哪个播放器? - Naktis
@Naktis,我只测试了VLC播放器和Apple Quicktime。此外,我刚刚测试了在Windows机器上使用VLC播放器时生成的文件是否按预期播放。您可以在此处免费下载VLC播放器:https://www.videolan.org - David M. Helmuth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接