使用python编辑wav文件

4 python audio

在wav文件中的每个单词之间,我有完全的沉默(我用Hex工作室检查,沉默用0表示).

如何切断非静音?

我正在使用python进行编程.

谢谢!

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处观察到一定数量的帧.


ffh*_*dad 6

我一直在为我正在研究的项目做一些关于这个主题的研究,我遇到了提供解决方案的一些问题,即确定沉默的方法是不正确的."更正确"的实施将是:

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)的采样点.


Ste*_*202 1

我对此没有经验,但看看标准库中存在的Wave模块。这可能会做你想做的事。否则,您必须将文件作为字节流读取,并切出 0 字节序列(但您不能只切出所有 0 字节,因为这会使文件无效...)