Another experimental sound change.
This commit is contained in:
43
sound.py
43
sound.py
@@ -19,19 +19,43 @@ 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
|
||||
except Exception as e:
|
||||
if attempt == max_retries - 1:
|
||||
print(f"Sound playback failed after {max_retries} attempts")
|
||||
print(f"Sound playback failed after {max_retries} attempts: {e}")
|
||||
return None, False
|
||||
|
||||
return None, False
|
||||
@@ -487,8 +511,9 @@ 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:
|
||||
# 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
|
||||
|
||||
|
@@ -289,14 +289,18 @@ def _play_dialog_sound(entry, dialog_config, sounds):
|
||||
if hasattr(sounds, 'sounds') and sound_to_play in sounds.sounds:
|
||||
# Sound class instance (like from libstormgames Sound class)
|
||||
sound_obj = sounds.sounds[sound_to_play]
|
||||
channel = sound_obj.play()
|
||||
from .sound import get_available_channel
|
||||
channel = get_available_channel()
|
||||
channel.play(sound_obj)
|
||||
sound_duration = sound_obj.get_length()
|
||||
if sound_duration > 0:
|
||||
pygame.time.wait(int(sound_duration * 1000))
|
||||
elif isinstance(sounds, dict) and sound_to_play in sounds:
|
||||
# Dictionary of pygame sound objects (like from initialize_gui)
|
||||
sound_obj = sounds[sound_to_play]
|
||||
channel = sound_obj.play()
|
||||
from .sound import get_available_channel
|
||||
channel = get_available_channel()
|
||||
channel.play(sound_obj)
|
||||
sound_duration = sound_obj.get_length()
|
||||
if sound_duration > 0:
|
||||
pygame.time.wait(int(sound_duration * 1000))
|
||||
|
8
utils.py
8
utils.py
@@ -476,7 +476,9 @@ def x_powerbar():
|
||||
leftVolume = (50 - position) / 100
|
||||
rightVolume = (position + 50) / 100
|
||||
tone = generate_tone(frequency)
|
||||
channel = tone.play()
|
||||
from .sound import get_available_channel
|
||||
channel = get_available_channel()
|
||||
channel.play(tone)
|
||||
channel.set_volume(leftVolume, rightVolume)
|
||||
|
||||
# Visual representation
|
||||
@@ -519,7 +521,9 @@ def y_powerbar():
|
||||
while True:
|
||||
frequency = 220 + (power * 5) # Adjust these values to change the pitch range
|
||||
tone = generate_tone(frequency)
|
||||
channel = tone.play()
|
||||
from .sound import get_available_channel
|
||||
channel = get_available_channel()
|
||||
channel.play(tone)
|
||||
|
||||
# Visual representation
|
||||
screen.fill((0, 0, 0))
|
||||
|
Reference in New Issue
Block a user