python - example - pygame.Sound.get_num_channels no es exacto
pygame mixer (1)
Estoy usando pygame + Twisted. Hice una clase de envoltura de Sound
, cuyas partes relevantes están aquí:
class Sound(object):
def __init__(self, sound):
self.sound = sound
self._status_task = task.LoopingCall(self._check_status)
self._status_task.start(0.05)
def _check_status(self):
chans = self.sound.get_num_channels()
if chans > 0:
logger.debug("''%s'' playing on %d channels",
self.filename, chans)
def play(self):
self.sound.play()
Sin embargo, lo que ocurre es que, una vez que se reproduce el sonido, .get_num_channels()
devuelve un número positivo, por ejemplo:
2013-07-08 15:13:30,502-DEBUG-engine.sound - ''sounds/foo.wav'' playing on 2 channels
2013-07-08 15:13:30,503-DEBUG-engine.sound - ''sounds/bar.wav'' playing on 1 channels
2013-07-08 15:13:30,546-DEBUG-engine.sound - ''sounds/foo.wav'' playing on 2 channels
2013-07-08 15:13:30,558-DEBUG-engine.sound - ''sounds/bar.wav'' playing on 1 channels
2013-07-08 15:13:30,602-DEBUG-engine.sound - ''sounds/foo.wav'' playing on 2 channels
¿Por qué es este el caso?
Lo pregunto porque a veces el sonido no funciona en absoluto cuando lo digo y estoy tratando de llegar al fondo de eso. Me imagino que entender esto podría ayudar con ese error.
En mi experiencia get_num_channels () cuenta todos los canales que tienen el sonido asignado, incluso si han terminado de reproducirse.
Una solución sería ir y verificar si estos canales todavía están "ocupados". Puede cambiar su método _check_status a este, para tener en cuenta si los canales están activos:
def _check_status(self):
chans = self.sound.get_num_channels()
if chans > 0:
logger.debug("''%s'' assigned to %d channels", self.filename, chans)
active_chans = 0
for i in range(pygame.mixer.get_num_channels()):
channel = pygame.mixer.Channel(i)
if channel.get_sound() == self.sound and channel.get_busy():
active_chans += 1
logger.debug("''%s'' actively playing on %d channels", self.filename, active_chans)
Y dos funciones auxiliares que podrían ser útiles para cualquier otra persona que experimente este problema:
def get_num_active_channels(sound):
"""
Returns the number of pygame.mixer.Channel that are actively playing the sound.
"""
active_channels = 0
if sound.get_num_channels() > 0:
for i in range(pygame.mixer.get_num_channels()):
channel = pygame.mixer.Channel(i)
if channel.get_sound() == sound and channel.get_busy():
active_channels += 1
return active_channels
def get_active_channel(sound):
"""
Returns the first pygame.mixer.Channel that we find that is actively playing the sound.
"""
if sound.get_num_channels() > 0:
for i in range(pygame.mixer.get_num_channels()):
channel = pygame.mixer.Channel(i)
if channel.get_sound() == sound and channel.get_busy()
return channel
return None