Another experimental sound change.
This commit is contained in:
49
sound.py
49
sound.py
@@ -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
|
||||
|
Reference in New Issue
Block a user