Sov*_*iut 17
Python有一个wav模块.您可以使用它打开一个wav文件进行读取,并使用`getframes(1)'命令逐帧浏览文件.
import wave
w = wave.open('beeps.wav', 'r')
for i in range():
frame = w.readframes(1)
Run Code Online (Sandbox Code Playgroud)
返回的帧将是一个字符串,其中包含十六进制值.如果文件是立体声,结果将看起来像这样(4个字节):
'\xe2\xff\xe2\xff'
Run Code Online (Sandbox Code Playgroud)
如果是单声道,它将有一半数据(2个字节):
'\xe2\xff'
Run Code Online (Sandbox Code Playgroud)
每个通道长2个字节,因为音频是16位.如果是8位,则每个通道只有一个字节.您可以使用该getsampwidth()
方法来确定这一点.此外,getchannels()
将确定其单声道或立体声.
您可以遍历这些字节以查看它们是否都等于零,这意味着两个通道都是静默的.在下面的示例中,我使用ord()
函数将'\xe2'
十六进制值转换为整数.
import wave
w = wave.open('beeps.wav', 'r')
for i in range(w.getnframes()):
### read 1 frame and the position will updated ###
frame = w.readframes(1)
all_zero = True
for j in range(len(frame)):
# check if amplitude is greater than 0
if ord(frame[j]) > 0:
all_zero = False
break
if all_zero:
# perform your cut here
print 'silence found at frame %s' % w.tell()
print 'silence found at second %s' % (w.tell()/w..getframerate())
Run Code Online (Sandbox Code Playgroud)
值得注意的是,单帧静音不一定表示空的空间,因为幅度可能越过0标记正常频率.因此,建议在确定该区域实际上是否为静音之前,在0处观察到一定数量的帧.
我一直在为我正在研究的项目做一些关于这个主题的研究,我遇到了提供解决方案的一些问题,即确定沉默的方法是不正确的."更正确"的实施将是:
import struct
import wave
wave_file = wave.open("sound_file.wav", "r")
for i in range(wave_file.getnframes()):
# read a single frame and advance to next frame
current_frame = wave_file.readframes(1)
# check for silence
silent = True
# wave frame samples are stored in little endian**
# this example works for a single channel 16-bit per sample encoding
unpacked_signed_value = struct.unpack("<h", current_frame) # *
if abs(unpacked_signed_value[0]) > 500:
silent = False
if silent:
print "Frame %s is silent." % wave_file.tell()
else
print "Frame %s is not silent." % wave_file.tell()
Run Code Online (Sandbox Code Playgroud)
*Struct Unpacking
在这里很有用:https://docs.python.org/2/library/struct.html
**我发现一个很好的参考资料,解释了处理不同大小的位编码和多个通道的波形文件格式:http://www.piclist.com/techref/io/serial/midi/wave.html
在readframes(x)方法返回的字符串对象的第一个元素上使用Python中的内置ord()函数将无法正常工作.
另一个关键点是多通道音频是交错的,因此处理通道需要一些额外的逻辑.同样,上面的链接详细介绍了这一点.
希望这可以帮助将来的某个人.
以下是该链接中的一些更重要的要点,以及我发现的有用之处.
数据组织
所有数据都以8位字节存储,以Intel 80x86(即小端)格式排列.多字节值的字节首先与低位(即最低有效)字节一起存储.数据位如下(即,顶部显示位数):
7 6 5 4 3 2 1 0
+-----------------------+
char: | lsb msb |
+-----------------------+
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8
+-----------------------+-----------------------+
short: | lsb byte 0 | byte 1 msb |
+-----------------------+-----------------------+
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
+-----------------------+-----------------------+-----------------------+-----------------------+
long: | lsb byte 0 | byte 1 | byte 2 | byte 3 msb |
+-----------------------+-----------------------+-----------------------+-----------------------+
Run Code Online (Sandbox Code Playgroud)
交错
对于多声道声音(例如,立体声波形),来自每个声道的单个采样点是交错的.例如,假设立体声(即2声道)波形.不是先存储左通道的所有采样点,然后再存储右通道的所有采样点,而是将两个通道的采样点"混合"在一起.您将存储左通道的第一个采样点.接下来,您将存储右通道的第一个采样点.接下来,您将存储左通道的第二个采样点.接下来,您将存储右通道的第二个采样点,依此类推,在存储每个通道的下一个采样点之间交替.这就是交错数据的含义; 您依次存储每个通道的下一个采样点,以便连续存储意图"播放"(即发送到DAC)的采样点.
归档时间: |
|
查看次数: |
20418 次 |
最近记录: |