我正在尝试从.wav文件中读取数据.
import wave
wr = wave.open("~/01 Road.wav", 'r')
# sample width is 2 bytes
# number of channels is 2
wave_data = wr.readframes(1)
print(wave_data)
Run Code Online (Sandbox Code Playgroud)
这给出了:
b'\x00\x00\x00\x00'
Run Code Online (Sandbox Code Playgroud)
这是这首歌的"第一帧".这4个字节显然对应于每帧的(2个通道*2字节采样宽度)字节,但每个字节对应的是什么?
特别是,我试图将其转换为单声道振幅信号.
Wil*_*man 16
如果您想了解"框架"是什么,则必须阅读波形文件格式的标准.例如:https://web.archive.org/web/20140221054954/http://home.roadrunner.com/~jgglatt/tech/wave.htm
从该文件:
意图"播放"的样本点,即同时发送到数模转换器(DAC)的样本点统称为样本帧.在我们的立体声波形示例中,每两个采样点构成另一个采样帧.下面针对该立体声示例说明了这一点.
sample sample sample
frame 0 frame 1 frame N
_____ _____ _____ _____ _____ _____
| ch1 | ch2 | ch1 | ch2 | . . . | ch1 | ch2 |
|_____|_____|_____|_____| |_____|_____|
_____
| | = one sample point
|_____|
Run Code Online (Sandbox Code Playgroud)
要转换为单声道,你可以做这样的事情,
import wave
def stereo_to_mono(hex1, hex2):
"""average two hex string samples"""
return hex((ord(hex1) + ord(hex2))/2)
wr = wave.open('piano2.wav','r')
nchannels, sampwidth, framerate, nframes, comptype, compname = wr.getparams()
ww = wave.open('piano_mono.wav','wb')
ww.setparams((1,sampwidth,framerate,nframes,comptype,compname))
frames = wr.readframes(wr.getnframes()-1)
new_frames = ''
for (s1, s2) in zip(frames[0::2],frames[1::2]):
new_frames += stereo_to_mono(s1,s2)[2:].zfill(2).decode('hex')
ww.writeframes(new_frames)
Run Code Online (Sandbox Code Playgroud)
从立体声到单声道都没有明确的方法.你可以放下一个频道.上面,我正在平均渠道.这一切都取决于您的应用程序.
对于 wav 文件 IO,我更喜欢使用 scipy。读取 wav 文件可能有点大材小用,但通常在读取 wav 文件后,进行下游处理会更容易。
import scipy.io.wavfile
fs1, y1 = scipy.io.wavfile.read(filename)
Run Code Online (Sandbox Code Playgroud)
从这里开始,数据 y1 将有 N 个样本长,并且将有 Z 列,其中每列对应一个通道。要转换为单声道 wav 文件,您无需说明您希望如何进行转换。你可以取平均值,或者你想要的任何其他值。对于一般用途
monoChannel = y1.mean(axis=1)
Run Code Online (Sandbox Code Playgroud)