简体   繁体   中英

Prevent “popping” at end of sound in Pygame.mixer

This has been solved - see solution at bottom.

While using pygame.mixer, every time a sound finishes playing (whether queued in a channel, not queued but still played via a channel, or played directly via Sound.play() ), an audible "popping" noise can be heard. Is there any way to prevent this?

Example code:

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()

Update: Fading the sound out causes no noticeable difference. Tested by using mixer.fadeout(fadeTime) , Sound.fadeout(fadeTime) , and Sound.play(0,maxTime,fadeTime) for fadeTime=1,10,100,200,1000 and maxTime=0,1,10,100,1000 .

Update 2: Neither mixer.stop() nor mixer.pause() remove the popping sound.

Update 3: Implementing a manual fadeout by slowly reducing the volume is effective with sufficiently slow fade times, however it is ineffective for fade times of less than about .1 seconds. Furthermore, during the fade time, there is a series of smaller "clicks", which, while quieter than the original, remain audible and are more numerous than the original "popping". Test code, which was appended to the end of the original code:

while snd.get_volume():
     snd.set_volume(snd.get_volume()-0.005)
     pygame.time.wait(5)

FINAL SOLUTION: Thanks to user msw, was able to remove "popping" by implementing a manual fadeout within the raw audio data. if i>40900: freq1=int(freq1*(41000-i)/100.0) was added to the generation loop - this approximately 0.0024 second fade time was just about the shortest that could be used before "popping" occurred. The example code has been updated with the fixed code.

This is known as the "dread audio cliff of noise".

When you have a digital signal which is higher than 0 and you abruptly cut it off, the waveform must plummet to 0. As people who deal with analog signals will tell you, the digital cliff has (in principle) all frequencies present at some amplitude. This transition sounds like a "pop" by the time it gets to the speakers.

Almost all audio is mastered so that the amplitude is faded to zero by the time the sample ends. If your sample doesn't have this characteristic, fade the sample to zero upon playback. As was noted by the OP, even a 2.5 millisecond fade can be enough to avoid the pop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM