diff --git a/internal_filesystem/lib/mpos/audio/audiomanager.py b/internal_filesystem/lib/mpos/audio/audiomanager.py index 35e0ce7c..a51ab7b8 100644 --- a/internal_filesystem/lib/mpos/audio/audiomanager.py +++ b/internal_filesystem/lib/mpos/audio/audiomanager.py @@ -31,8 +31,15 @@ class AudioManager: STREAM_ALARM = 2 # Alarms/alerts (highest priority) _instance = None # Singleton instance - - def __init__(self, i2s_pins=None, buzzer_instance=None, adc_mic_pin=None): + + def __init__( + self, + i2s_pins=None, + buzzer_instance=None, + adc_mic_pin=None, + pre_playback=None, + post_playback=None, + ): """ Initialize AudioManager instance with optional hardware configuration. @@ -40,17 +47,22 @@ def __init__(self, i2s_pins=None, buzzer_instance=None, adc_mic_pin=None): i2s_pins: Dict with 'sck', 'ws', 'sd' pin numbers (for I2S/WAV playback) buzzer_instance: PWM instance for buzzer (for RTTTL playback) adc_mic_pin: GPIO pin number for ADC microphone (for ADC recording) + pre_playback: Optional callback called before starting playback + post_playback: Optional callback called after stopping playback """ if AudioManager._instance: return AudioManager._instance = self - self._i2s_pins = i2s_pins # I2S pin configuration dict (created per-stream) - self._buzzer_instance = buzzer_instance # PWM buzzer instance - self._adc_mic_pin = adc_mic_pin # ADC microphone pin - self._current_stream = None # Currently playing stream - self._current_recording = None # Currently recording stream - self._volume = 50 # System volume (0-100) + self._i2s_pins = i2s_pins # I2S pin configuration dict (created per-stream) + self._buzzer_instance = buzzer_instance # PWM buzzer instance + self._adc_mic_pin = adc_mic_pin # ADC microphone pin + self.pre_playback = pre_playback + self.post_playback = post_playback + + self._current_stream = None # Currently playing stream + self._current_recording = None # Currently recording stream + self._volume = 50 # System volume (0-100) # Build status message capabilities = [] @@ -60,7 +72,7 @@ def __init__(self, i2s_pins=None, buzzer_instance=None, adc_mic_pin=None): capabilities.append("Buzzer (RTTTL)") if adc_mic_pin: capabilities.append(f"ADC Mic (Pin {adc_mic_pin})") - + if capabilities: print(f"AudioManager initialized: {', '.join(capabilities)}") else: @@ -123,6 +135,11 @@ def _playback_thread(self, stream): stream: Stream instance (WAVStream or RTTTLStream) """ self._current_stream = stream + if self.pre_playback: + try: + self.pre_playback() + except Exception as e: + print(f"AudioManager: pre_playback callback error: {e}") try: # Run synchronous playback in this thread @@ -134,6 +151,12 @@ def _playback_thread(self, stream): if self._current_stream == stream: self._current_stream = None + if self.post_playback: + try: + self.post_playback() + except Exception as e: + print(f"AudioManager: post_playback callback error: {e}") + def play_wav(self, file_path, stream_type=None, volume=None, on_complete=None): """ Play WAV file via I2S. diff --git a/internal_filesystem/lib/mpos/board/odroid_go.py b/internal_filesystem/lib/mpos/board/odroid_go.py index 4aac438d..e9e87dca 100644 --- a/internal_filesystem/lib/mpos/board/odroid_go.py +++ b/internal_filesystem/lib/mpos/board/odroid_go.py @@ -62,9 +62,32 @@ print("odroid_go.py init buzzer") buzzer = PWM(Pin(BUZZER_PIN, Pin.OUT, value=1), duty=5) -dac_pin = Pin(BUZZER_DAC_PIN, Pin.OUT, value=1) -dac_pin.value(1) # Unmute -AudioManager(i2s_pins=None, buzzer_instance=buzzer) + + +class BuzzerCallbacks: + __slots__ = ("dac_pin",) + + def __init__(self): + self.dac_pin = Pin(BUZZER_DAC_PIN, Pin.OUT, value=1) + + def unmute(self): + print("Unmute buzzer") + self.dac_pin.value(1) # Unmute + + def mute(self): + print("Mute buzzer") + self.dac_pin.value(0) # Mute + + +buzzer_callbacks = BuzzerCallbacks() +AudioManager( + i2s_pins=None, + buzzer_instance=buzzer, + # The buzzer makes noise when it's unmuted, to avoid this we + # mute it after playback and vice versa unmute it before playback: + pre_playback=buzzer_callbacks.unmute, + post_playback=buzzer_callbacks.mute, +) AudioManager.set_volume(40) AudioManager.play_rtttl("Star Trek:o=4,d=20,b=200:8f.,a#,4d#6.,8d6,a#.,g.,c6.,4f6") while AudioManager.is_playing():