Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions internal_filesystem/lib/mpos/audio/audiomanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,38 @@ 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.

Args:
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 = []
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down
29 changes: 26 additions & 3 deletions internal_filesystem/lib/mpos/board/odroid_go.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
Loading