此问题已解决-请参阅底部的解决方案。
在使用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,1000
和maxTime=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毫秒的淡入淡出也足以避免爆裂。