include portaudio header, lower volume by default

This commit is contained in:
Anthony Samms
2025-09-16 14:43:25 -04:00
parent de3a334cf6
commit c29c3ab5e6
2 changed files with 1286 additions and 33 deletions

View File

@@ -140,13 +140,13 @@ class AudioEngine:
self.audio_device_ready = False self.audio_device_ready = False
def list_host_apis(self): def list_host_apis(self):
lib.list_host_apis() lib.list_host_apis() # type: ignore
def init_audio_device(self) -> bool: def init_audio_device(self) -> bool:
"""Initialize the audio device""" """Initialize the audio device"""
try: try:
lib.init_audio_device(self.device_type, self.target_sample_rate) lib.init_audio_device(self.device_type, self.target_sample_rate) # type: ignore
self.audio_device_ready = lib.is_audio_device_ready() self.audio_device_ready = lib.is_audio_device_ready() # type: ignore
if self.audio_device_ready: if self.audio_device_ready:
print("Audio device initialized successfully") print("Audio device initialized successfully")
return self.audio_device_ready return self.audio_device_ready
@@ -163,7 +163,7 @@ class AudioEngine:
for music_id in list(self.music_streams.keys()): for music_id in list(self.music_streams.keys()):
self.unload_music_stream(music_id) self.unload_music_stream(music_id)
lib.close_audio_device() lib.close_audio_device() # type: ignore
self.audio_device_ready = False self.audio_device_ready = False
print("Audio device closed") print("Audio device closed")
except Exception as e: except Exception as e:
@@ -171,24 +171,24 @@ class AudioEngine:
def is_audio_device_ready(self) -> bool: def is_audio_device_ready(self) -> bool:
"""Check if audio device is ready""" """Check if audio device is ready"""
return lib.is_audio_device_ready() return lib.is_audio_device_ready() # type: ignore
def set_master_volume(self, volume: float) -> None: def set_master_volume(self, volume: float) -> None:
"""Set master volume (0.0 to 1.0)""" """Set master volume (0.0 to 1.0)"""
lib.set_master_volume(max(0.0, min(1.0, volume))) lib.set_master_volume(max(0.0, min(1.0, volume))) # type: ignore
def get_master_volume(self) -> float: def get_master_volume(self) -> float:
"""Get master volume""" """Get master volume"""
return lib.get_master_volume() return lib.get_master_volume() # type: ignore
# Sound management # Sound management
def load_sound(self, file_path: Path) -> str: def load_sound(self, file_path: Path) -> str:
"""Load a sound file and return sound ID""" """Load a sound file and return sound ID"""
try: try:
file_path_str = str(file_path).encode('utf-8') file_path_str = str(file_path).encode('utf-8')
sound = lib.load_sound(file_path_str) sound = lib.load_sound(file_path_str) # type: ignore
if lib.is_sound_valid(sound): if lib.is_sound_valid(sound): # type: ignore
sound_id = f"sound_{self.sound_counter}" sound_id = f"sound_{self.sound_counter}"
self.sounds[sound_id] = sound self.sounds[sound_id] = sound
self.sound_counter += 1 self.sound_counter += 1
@@ -204,7 +204,7 @@ class AudioEngine:
def unload_sound(self, sound_id: str) -> None: def unload_sound(self, sound_id: str) -> None:
"""Unload a sound""" """Unload a sound"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.unload_sound(self.sounds[sound_id]) lib.unload_sound(self.sounds[sound_id]) # type: ignore
del self.sounds[sound_id] del self.sounds[sound_id]
def unload_all_sounds(self) -> None: def unload_all_sounds(self) -> None:
@@ -215,44 +215,44 @@ class AudioEngine:
def play_sound(self, sound_id: str) -> None: def play_sound(self, sound_id: str) -> None:
"""Play a sound""" """Play a sound"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.play_sound(self.sounds[sound_id]) lib.play_sound(self.sounds[sound_id]) # type: ignore
def stop_sound(self, sound_id: str) -> None: def stop_sound(self, sound_id: str) -> None:
"""Stop a sound""" """Stop a sound"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.stop_sound(self.sounds[sound_id]) lib.stop_sound(self.sounds[sound_id]) # type: ignore
def pause_sound(self, sound_id: str) -> None: def pause_sound(self, sound_id: str) -> None:
"""Pause a sound""" """Pause a sound"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.pause_sound(self.sounds[sound_id]) lib.pause_sound(self.sounds[sound_id]) # type: ignore
def resume_sound(self, sound_id: str) -> None: def resume_sound(self, sound_id: str) -> None:
"""Resume a sound""" """Resume a sound"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.resume_sound(self.sounds[sound_id]) lib.resume_sound(self.sounds[sound_id]) # type: ignore
def is_sound_valid(self, sound_id: str) -> bool: def is_sound_valid(self, sound_id: str) -> bool:
"""Check if sound is valid""" """Check if sound is valid"""
if sound_id in self.sounds: if sound_id in self.sounds:
return lib.is_sound_valid(self.sounds[sound_id]) return lib.is_sound_valid(self.sounds[sound_id]) # type: ignore
return False return False
def is_sound_playing(self, sound_id: str) -> bool: def is_sound_playing(self, sound_id: str) -> bool:
"""Check if sound is playing""" """Check if sound is playing"""
if sound_id in self.sounds: if sound_id in self.sounds:
return lib.is_sound_playing(self.sounds[sound_id]) return lib.is_sound_playing(self.sounds[sound_id]) # type: ignore
return False return False
def set_sound_volume(self, sound_id: str, volume: float) -> None: def set_sound_volume(self, sound_id: str, volume: float) -> None:
"""Set sound volume""" """Set sound volume"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.set_sound_volume(self.sounds[sound_id], max(0.0, volume)) lib.set_sound_volume(self.sounds[sound_id], max(0.0, volume)) # type: ignore
def set_sound_pan(self, sound_id: str, pan: float) -> None: def set_sound_pan(self, sound_id: str, pan: float) -> None:
"""Set sound pan (0.0 = left, 0.5 = center, 1.0 = right)""" """Set sound pan (0.0 = left, 0.5 = center, 1.0 = right)"""
if sound_id in self.sounds: if sound_id in self.sounds:
lib.set_sound_pan(self.sounds[sound_id], max(0.0, min(1.0, pan))) lib.set_sound_pan(self.sounds[sound_id], max(0.0, min(1.0, pan))) # type: ignore
def normalize_sound(self, sound_id: str, rms: float) -> None: def normalize_sound(self, sound_id: str, rms: float) -> None:
"""Normalize sound - Note: This would need to be implemented in C""" """Normalize sound - Note: This would need to be implemented in C"""
@@ -265,9 +265,9 @@ class AudioEngine:
"""Load a music stream and return music ID""" """Load a music stream and return music ID"""
try: try:
file_path_str = str(file_path).encode('utf-8') file_path_str = str(file_path).encode('utf-8')
music = lib.load_music_stream(file_path_str) music = lib.load_music_stream(file_path_str) # type: ignore
if lib.is_music_valid(music): if lib.is_music_valid(music): # type: ignore
music_id = f"music_{self.music_counter}" music_id = f"music_{self.music_counter}"
self.music_streams[music_id] = music self.music_streams[music_id] = music
self.music_counter += 1 self.music_counter += 1
@@ -288,60 +288,61 @@ class AudioEngine:
def unload_music_stream(self, music_id: str) -> None: def unload_music_stream(self, music_id: str) -> None:
"""Unload a music stream""" """Unload a music stream"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.unload_music_stream(self.music_streams[music_id]) lib.unload_music_stream(self.music_streams[music_id]) # type: ignore
del self.music_streams[music_id] del self.music_streams[music_id]
def is_music_valid(self, music_id: str) -> bool: def is_music_valid(self, music_id: str) -> bool:
"""Check if music is valid""" """Check if music is valid"""
if music_id in self.music_streams: if music_id in self.music_streams:
return lib.is_music_valid(self.music_streams[music_id]) return lib.is_music_valid(self.music_streams[music_id]) # type: ignore
return False return False
def play_music_stream(self, music_id: str) -> None: def play_music_stream(self, music_id: str) -> None:
"""Play a music stream""" """Play a music stream"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.play_music_stream(self.music_streams[music_id]) lib.seek_music_stream(self.music_streams[music_id], 0) # type: ignore
lib.play_music_stream(self.music_streams[music_id]) # type: ignore
def stop_music_stream(self, music_id: str) -> None: def stop_music_stream(self, music_id: str) -> None:
"""Stop a music stream""" """Stop a music stream"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.stop_music_stream(self.music_streams[music_id]) lib.stop_music_stream(self.music_streams[music_id]) # type: ignore
def pause_music_stream(self, music_id: str) -> None: def pause_music_stream(self, music_id: str) -> None:
"""Pause a music stream""" """Pause a music stream"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.pause_music_stream(self.music_streams[music_id]) lib.pause_music_stream(self.music_streams[music_id]) # type: ignore
def resume_music_stream(self, music_id: str) -> None: def resume_music_stream(self, music_id: str) -> None:
"""Resume a music stream""" """Resume a music stream"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.resume_music_stream(self.music_streams[music_id]) lib.resume_music_stream(self.music_streams[music_id]) # type: ignore
def is_music_stream_playing(self, music_id: str) -> bool: def is_music_stream_playing(self, music_id: str) -> bool:
"""Check if music stream is playing""" """Check if music stream is playing"""
if music_id in self.music_streams: if music_id in self.music_streams:
return lib.is_music_stream_playing(self.music_streams[music_id]) return lib.is_music_stream_playing(self.music_streams[music_id]) # type: ignore
return False return False
def seek_music_stream(self, music_id: str, position: float) -> None: def seek_music_stream(self, music_id: str, position: float) -> None:
"""Seek music stream to position in seconds""" """Seek music stream to position in seconds"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.seek_music_stream(self.music_streams[music_id], position) lib.seek_music_stream(self.music_streams[music_id], position) # type: ignore
def update_music_stream(self, music_id: str) -> None: def update_music_stream(self, music_id: str) -> None:
"""Update music stream (fill buffers)""" """Update music stream (fill buffers)"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.update_music_stream(self.music_streams[music_id]) lib.update_music_stream(self.music_streams[music_id]) # type: ignore
def set_music_volume(self, music_id: str, volume: float) -> None: def set_music_volume(self, music_id: str, volume: float) -> None:
"""Set music volume""" """Set music volume"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.set_music_volume(self.music_streams[music_id], max(0.0, min(1.0, volume))) lib.set_music_volume(self.music_streams[music_id], max(0.0, min(1.0, volume))) # type: ignore
def set_music_pan(self, music_id: str, pan: float) -> None: def set_music_pan(self, music_id: str, pan: float) -> None:
"""Set music pan""" """Set music pan"""
if music_id in self.music_streams: if music_id in self.music_streams:
lib.set_music_pan(self.music_streams[music_id], max(0.0, min(1.0, pan))) lib.set_music_pan(self.music_streams[music_id], max(0.0, min(1.0, pan))) # type: ignore
def normalize_music_stream(self, music_id: str, rms: float) -> None: def normalize_music_stream(self, music_id: str, rms: float) -> None:
"""Normalize music stream - would need C implementation""" """Normalize music stream - would need C implementation"""
@@ -350,14 +351,15 @@ class AudioEngine:
def get_music_time_length(self, music_id: str) -> float: def get_music_time_length(self, music_id: str) -> float:
"""Get total music length in seconds""" """Get total music length in seconds"""
if music_id in self.music_streams: if music_id in self.music_streams:
return lib.get_music_time_length(self.music_streams[music_id]) return lib.get_music_time_length(self.music_streams[music_id]) # type: ignore
return 0.0 return 0.0
def get_music_time_played(self, music_id: str) -> float: def get_music_time_played(self, music_id: str) -> float:
"""Get current music position in seconds""" """Get current music position in seconds"""
if music_id in self.music_streams: if music_id in self.music_streams:
return lib.get_music_time_played(self.music_streams[music_id]) return lib.get_music_time_played(self.music_streams[music_id]) # type: ignore
return 0.0 return 0.0
# Create the global audio instance # Create the global audio instance
audio = AudioEngine(get_config()["audio"]["device_type"], get_config()["audio"]["sample_rate"]) audio = AudioEngine(get_config()["audio"]["device_type"], get_config()["audio"]["sample_rate"])
audio.set_master_volume(0.75)

1251
libs/audio/portaudio.h Normal file

File diff suppressed because it is too large Load Diff