Files
voculinux/src/ui/audio_feedback.py
T
Jatin K MalikandGitHub 076ea78b4b Update documentation, standardize on WAV audio format, and improve attribution (#19)
* Remove MP3 sound files and update documentation to reflect WAV-only support

* Fix stale strings
2025-04-19 00:02:52 -05:00

132 lines
3.4 KiB
Python

"""
Audio feedback module for Vocalinux.
This module provides audio feedback for various recognition states.
"""
import logging
import os
import shutil
import subprocess
from pathlib import Path
logger = logging.getLogger(__name__)
# Find the resources directory relative to this module
MODULE_DIR = os.path.dirname(os.path.abspath(__file__))
PACKAGE_DIR = os.path.dirname(MODULE_DIR)
RESOURCES_DIR = os.path.join(os.path.dirname(PACKAGE_DIR), "resources")
SOUNDS_DIR = os.path.join(RESOURCES_DIR, "sounds")
# Sound file paths
START_SOUND = os.path.join(SOUNDS_DIR, "start_recording.wav")
STOP_SOUND = os.path.join(SOUNDS_DIR, "stop_recording.wav")
ERROR_SOUND = os.path.join(SOUNDS_DIR, "error.wav")
def _get_audio_player():
"""
Determine the best available audio player on the system.
Returns:
tuple: (player_command, supported_formats)
"""
# Check for PulseAudio paplay (preferred)
if shutil.which("paplay"):
return "paplay", ["wav"]
# Check for ALSA aplay
if shutil.which("aplay"):
return "aplay", ["wav"]
# Check for play (from SoX)
if shutil.which("play"):
return "play", ["wav"]
# Check for mplayer
if shutil.which("mplayer"):
return "mplayer", ["wav"]
# No suitable player found
logger.warning("No suitable audio player found for sound notifications")
return None, []
def _play_sound_file(sound_path):
"""
Play a sound file using the best available player.
Args:
sound_path: Path to the sound file
Returns:
bool: True if sound was played successfully, False otherwise
"""
if not os.path.exists(sound_path):
logger.warning(f"Sound file not found: {sound_path}")
return False
player, formats = _get_audio_player()
if not player:
return False
try:
if player == "paplay":
subprocess.Popen(
[player, sound_path],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
elif player == "aplay":
subprocess.Popen(
[player, "-q", sound_path],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
elif player == "mplayer":
subprocess.Popen(
[player, "-really-quiet", sound_path],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
elif player == "play":
subprocess.Popen(
[player, "-q", sound_path],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return True
except Exception as e:
logger.error(f"Failed to play sound {sound_path}: {e}")
return False
def play_start_sound():
"""
Play the sound for starting voice recognition.
Returns:
bool: True if sound was played successfully, False otherwise
"""
return _play_sound_file(START_SOUND)
def play_stop_sound():
"""
Play the sound for stopping voice recognition.
Returns:
bool: True if sound was played successfully, False otherwise
"""
return _play_sound_file(STOP_SOUND)
def play_error_sound():
"""
Play the sound for error notifications.
Returns:
bool: True if sound was played successfully, False otherwise
"""
return _play_sound_file(ERROR_SOUND)