diff --git a/display.py b/display.py index 4862913..de78b94 100644 --- a/display.py +++ b/display.py @@ -46,10 +46,10 @@ def initialize_gui(gameTitle): # Initialize audio system if not already done if not pygame.mixer.get_init(): - pygame.mixer.pre_init(44100, -16, 2, 4096) + pygame.mixer.pre_init(44100, -16, 2, 4096, allowedchanges=0) pygame.mixer.init() pygame.mixer.set_num_channels(32) - pygame.mixer.set_reserved(0) # Reserve channel for cut scenes + pygame.mixer.set_reserved(1) # Reserve channel 0 for cutscenes # Enable key repeat for volume controls pygame.key.set_repeat(500, 100) diff --git a/sound.py b/sound.py index 55959f1..86120c1 100644 --- a/sound.py +++ b/sound.py @@ -33,25 +33,22 @@ def find_silent_channels(): return silent_channels def find_available_channel(): - """Find an available channel, prioritizing silent channels over stopping active ones.""" - # Try to find an idle channel first - for n in range(pygame.mixer.get_num_channels()): - channel = pygame.mixer.Channel(n) - if not channel.get_busy(): + """Find an available channel using pygame's built-in method.""" + # Try to find an idle channel first, or force stop the longest running sound + channel = pygame.mixer.find_channel(True) + + # If channel 0 was selected and it's reserved for cutscenes, try to use another + if channel and channel == pygame.mixer.Channel(0): + # Check if there's another available channel + alt_channel = pygame.mixer.find_channel(False) # Don't force + if alt_channel: + return alt_channel + # If no alternative and we need to force, check if channel 1+ exists + if pygame.mixer.get_num_channels() > 1: + channel = pygame.mixer.Channel(1) + channel.stop() return channel - # If no idle channels, look for silent ones to reclaim - silent_channels = find_silent_channels() - if silent_channels: - # Stop the first silent channel and return it - channel = silent_channels[0] - channel.stop() - return channel - - # If no silent channels, stop channel 1 as last resort (avoid channel 0 - reserved for cutscenes) - # This ensures sounds always play rather than being silently dropped - channel = pygame.mixer.Channel(1) - channel.stop() return channel def play_sound_with_retry(sound, loop=False, max_retries=3): @@ -116,7 +113,7 @@ class Sound: self.volumeService = volumeService or VolumeService.get_instance() if not pygame.mixer.get_init(): - pygame.mixer.pre_init(44100, -16, 2, 4096) + pygame.mixer.pre_init(44100, -16, 2, 4096, allowedchanges=0) pygame.mixer.init() pygame.mixer.set_num_channels(32) pygame.mixer.set_reserved(1) # Reserve channel 0 for cutscenes diff --git a/utils.py b/utils.py index 9eb866e..7f77639 100644 --- a/utils.py +++ b/utils.py @@ -149,7 +149,7 @@ class Game: pygame.display.set_caption(self.title) # Set up audio system - pygame.mixer.pre_init(44100, -16, 2, 1024) + pygame.mixer.pre_init(44100, -16, 2, 1024, allowedchanges=0) pygame.mixer.init() pygame.mixer.set_num_channels(32) pygame.mixer.set_reserved(0) # Reserve channel for cut scenes