此问题已解决-请参阅底部的解决方案。

在使用pygame.mixer时,每当声音结束播放(无论是在通道中排队,未排队但仍通过通道播放还是直接通过Sound.play()播放)时,都可以听到“爆裂”声。有什么办法可以防止这种情况?

示例代码:

import math
import pygame
import array

pygame.mixer.init()

rawArr=[]
for i in range(41000):
    freq1=int(math.sin(i/220.0*math.pi*2)*32767.0)
    if i>40900: freq1=int(freq1*(41000-i)/100.0) #Solution - see Final Solution
    rawArr.append(freq1)

sndArr=array.array('h',rawArr)

snd=pygame.mixer.Sound(sndArr)

snd.play()

更新:淡出声音不会造成明显差异。通过将mixer.fadeout(fadeTime)Sound.fadeout(fadeTime)使用Sound.play(0,maxTime,fadeTime)fadeTime=1,10,100,200,1000maxTime=0,1,10,100,1000进行测试。

更新2:mixer.stop()mixer.pause()都不能消除弹出声音。

更新3:通过缓慢减小音量来实现手动淡入效果,但在足够慢的淡入时间下是有效的,但是对于少于约0.1秒的淡入时间则无效。此外,在淡入淡出期间,有一系列较小的“喀哒”声,虽然比原始“寂静”声低,但仍可听见并且比原始“爆裂声”还多。测试代码,该代码附加到原始代码的末尾:
while snd.get_volume():
     snd.set_volume(snd.get_volume()-0.005)
     pygame.time.wait(5)

最终解决方案:感谢msw用户,能够通过在原始音频数据中实现手动淡出来消除“爆裂”。 if i>40900: freq1=int(freq1*(41000-i)/100.0)已添加到生成循环-大约0.0024秒的淡入时间大约是“弹出”发生之前可以使用的最短时间。示例代码已使用固定代码更新。

最佳答案

这被称为“噪音的可怕音频悬崖”。

当您的数字信号大于0并突然中断时,波形必须骤降为0。处理模拟信号的人会告诉您,数字悬崖(原则上)具有以一定幅度出现的所有频率。到达扬声器时,这种过渡听起来像是“流行”。

几乎所有音频都被掌握,以便在采样结束时将幅度衰减为零。如果您的样本没有此特性,则在播放时将样本淡入零。正如OP所指出的,即使是2.5毫秒的淡入淡出也足以避免爆裂。

08-26 23:33