每次循环播放 wav 文件时,如何消除烦人的 'snap' 噪音?

How can I remove an annoying 'snap' noise each time I loop a wav file?

我正在尝试创建一个简单的可控且非阻塞的循环 wavplayer。以下 class 使用 simpleaudio 创建的作品有效,但是,在音频的每个循环之间有一个短暂的停顿和明显的 popping/snapping 噪音。老实说,我不确定是什么原因造成的,我也不确定除了完全使用不同的音频模块之外我还能如何修复它。有什么建议吗?

import simpleaudio as sa
from threading import Thread

class WavPlayer(Thread):
    def __init__(self,filepath,loop=False):

        self.loop = loop
        self.wav_obj = sa.WaveObject.from_wave_file(filepath)
        self.play_obj = None

        Thread.__init__(self)

    def run(self):
        self.play_obj = self.wav_obj.play() #initialize play buffer and play once

        while self.loop is True:
            if not self.play_obj.is_playing():
                print("played again")
                self.play_obj = self.wav_obj.play()

    def terminate(self):
        print("music terminated")
        self.play_obj.stop()
        self.loop = False
        self.join()

main_loop = WavPlayer("main_loop.wav",True)
menu_loop = WavPlayer("menu.wav",True)

main_loop.start()
z = input("Enter to end theme looping")
main_loop.loop = False

z = input("Enter to terminate music")
main_loop.terminate()

print("playing next song")
menu_loop.start()

cont = ''
while cont != 'n':
    cont = input("continue testing non-blocking? enter n to stop: ")

menu_loop.terminate()

Filedropper link to menu_loop wav file

Filedropper link to main_loop wav file

我在编写一个从有限数量的样本中生成无限长音符的调音器时遇到了同样的问题(我使用了 pyaudio,调音符是一种非常简单的声音,它使流行音乐非常显而易见,但补救措施要容易得多)。

如果你像这样循环一个 wave 对象:

   **                    **
       *              *      *
         *          *          *
           *      *              *
              **                    **

...您会听到砰的一声,因为最后一个样本和第一个样本之间的差异很大。删除一些样本直到最后一个和第一个样本匹配将消除流行音乐(simpleaudio 允许您将样本读入 numpy 数组,然后您可以(稍微)截断直到第一个和最后一个样本匹配).

在过零处切割是这种情况的一个特例,请参阅 this discussion。当然,一些声音库可能已经在零交叉处截断了您的样本。

在您不厌其烦地扩展您的程序以将样本转换为 numpy 数组并截断它们之前,您首先可以尝试使用像 Audacity 这样的声音编辑器并手动完成,然后聆听结果。