Another experimental sound change.

This commit is contained in:
Storm Dragon
2025-09-19 00:44:25 -04:00
parent 6daa243710
commit d364ce28ef
3 changed files with 49 additions and 16 deletions

View File

@@ -19,20 +19,44 @@ from .services import VolumeService
# Global instance for backward compatibility
volumeService = VolumeService.get_instance()
# Global channel manager for explicit channel assignment
_next_channel_index = 1
def get_available_channel():
"""Get next available channel using explicit assignment instead of pygame's auto-selection."""
global _next_channel_index
# Try to find an idle channel starting from next_channel_index
for _ in range(47): # Try all available channels (1-47, skip 0 reserved for cutscenes)
channel = pygame.mixer.Channel(_next_channel_index)
if not channel.get_busy():
result = _next_channel_index
_next_channel_index = (_next_channel_index % 47) + 1 # Cycle 1-47
return pygame.mixer.Channel(result)
_next_channel_index = (_next_channel_index % 47) + 1
# If all channels busy, force stop the current one and use it
channel = pygame.mixer.Channel(_next_channel_index)
channel.stop()
pygame.event.pump() # Force immediate cleanup
result = _next_channel_index
_next_channel_index = (_next_channel_index % 47) + 1
return pygame.mixer.Channel(result)
def play_sound_with_retry(sound, loop=False, max_retries=3):
"""Play a sound with retry logic, returns (channel, success)."""
"""Play a sound with explicit channel assignment instead of pygame auto-selection."""
for attempt in range(max_retries):
# pygame automatically finds channels and forces allocation if needed
channel = sound.play(-1 if loop else 0)
if channel:
try:
# Use explicit channel assignment instead of pygame's automatic selection
channel = get_available_channel()
channel.play(sound, -1 if loop else 0)
return channel, True
# If still failed after retries
if attempt == max_retries - 1:
print(f"Sound playback failed after {max_retries} attempts")
return None, False
except Exception as e:
if attempt == max_retries - 1:
print(f"Sound playback failed after {max_retries} attempts: {e}")
return None, False
return None, False
@@ -487,9 +511,10 @@ def play_sound(sound_or_name, volume=1.0, loop=False, playerPos=None, objPos=Non
# Case 3: Direct pygame.Sound
elif isinstance(sound_or_name, pygame.mixer.Sound):
channel = sound_or_name.play(-1 if loop else 0)
if channel:
channel.set_volume(volume * volumeService.get_sfx_volume())
# Use explicit channel assignment instead of pygame auto-selection
channel = get_available_channel()
channel.play(sound_or_name, -1 if loop else 0)
channel.set_volume(volume * volumeService.get_sfx_volume())
return channel
# Case 4: Sound name with dictionary