You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
AudioFlinger framework: simplify import, use singleton class
This commit is contained in:
+3
-1
@@ -1,10 +1,12 @@
|
||||
0.5.3
|
||||
0.6.0
|
||||
=====
|
||||
- AppStore app: add Settings screen to choose backend
|
||||
- Camera app: fix aspect ratio for higher resolutions
|
||||
- WiFi app: check "hidden" in EditNetwork
|
||||
- Wifi app: add support for scanning wifi QR codes to "Add Network"
|
||||
- Make "Power Off" button on desktop exit completely
|
||||
- App framework: simplify MANIFEST.JSON
|
||||
- AudioFlinger framework: simplify import, use singleton class
|
||||
- Create new SettingsActivity and SettingActivity framework so apps can easily add settings screens with just a few lines of code
|
||||
- Improve robustness by catching unhandled app exceptions
|
||||
- Improve robustness with custom exception that does not deinit() the TaskHandler
|
||||
|
||||
@@ -2,7 +2,7 @@ import machine
|
||||
import os
|
||||
import time
|
||||
|
||||
from mpos import Activity, Intent, sdcard, get_event_name, audio as AudioFlinger
|
||||
from mpos import Activity, Intent, sdcard, get_event_name, AudioFlinger
|
||||
|
||||
class MusicPlayer(Activity):
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
from mpos import Activity, ui, audio as AudioFlinger
|
||||
from mpos import Activity, ui, AudioFlinger
|
||||
|
||||
|
||||
def _makedirs(path):
|
||||
|
||||
@@ -5,6 +5,7 @@ from .config import SharedPreferences
|
||||
from .net.connectivity_manager import ConnectivityManager
|
||||
from .net import download_manager as DownloadManager
|
||||
from .net.wifi_service import WifiService
|
||||
from .audio.audioflinger import AudioFlinger
|
||||
from .content.intent import Intent
|
||||
from .activity_navigator import ActivityNavigator
|
||||
from .content.package_manager import PackageManager
|
||||
@@ -61,7 +62,7 @@ __all__ = [
|
||||
"App",
|
||||
"Activity",
|
||||
"SharedPreferences",
|
||||
"ConnectivityManager", "DownloadManager", "WifiService", "Intent",
|
||||
"ConnectivityManager", "DownloadManager", "WifiService", "AudioFlinger", "Intent",
|
||||
"ActivityNavigator", "PackageManager", "TaskManager",
|
||||
# Common activities
|
||||
"ChooserActivity", "ViewActivity", "ShareActivity",
|
||||
|
||||
@@ -2,37 +2,36 @@
|
||||
# Android-inspired audio routing with priority-based audio focus
|
||||
# Simple routing: play_wav() -> I2S, play_rtttl() -> buzzer, record_wav() -> I2S mic
|
||||
|
||||
from . import audioflinger
|
||||
from .audioflinger import AudioFlinger
|
||||
|
||||
# Re-export main API
|
||||
from .audioflinger import (
|
||||
# Stream types (for priority-based audio focus)
|
||||
STREAM_MUSIC,
|
||||
STREAM_NOTIFICATION,
|
||||
STREAM_ALARM,
|
||||
# Create singleton instance
|
||||
_instance = AudioFlinger.get()
|
||||
|
||||
# Core playback functions
|
||||
init,
|
||||
play_wav,
|
||||
play_rtttl,
|
||||
stop,
|
||||
pause,
|
||||
resume,
|
||||
set_volume,
|
||||
get_volume,
|
||||
is_playing,
|
||||
# Re-export stream type constants for convenience
|
||||
STREAM_MUSIC = AudioFlinger.STREAM_MUSIC
|
||||
STREAM_NOTIFICATION = AudioFlinger.STREAM_NOTIFICATION
|
||||
STREAM_ALARM = AudioFlinger.STREAM_ALARM
|
||||
|
||||
# Recording functions
|
||||
record_wav,
|
||||
is_recording,
|
||||
|
||||
# Hardware availability checks
|
||||
has_i2s,
|
||||
has_buzzer,
|
||||
has_microphone,
|
||||
)
|
||||
# Re-export main API from singleton instance for backward compatibility
|
||||
init = _instance.init
|
||||
play_wav = _instance.play_wav
|
||||
play_rtttl = _instance.play_rtttl
|
||||
stop = _instance.stop
|
||||
pause = _instance.pause
|
||||
resume = _instance.resume
|
||||
set_volume = _instance.set_volume
|
||||
get_volume = _instance.get_volume
|
||||
is_playing = _instance.is_playing
|
||||
record_wav = _instance.record_wav
|
||||
is_recording = _instance.is_recording
|
||||
has_i2s = _instance.has_i2s
|
||||
has_buzzer = _instance.has_buzzer
|
||||
has_microphone = _instance.has_microphone
|
||||
|
||||
__all__ = [
|
||||
# Class
|
||||
'AudioFlinger',
|
||||
|
||||
# Stream types
|
||||
'STREAM_MUSIC',
|
||||
'STREAM_NOTIFICATION',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -291,7 +291,7 @@ mpos.sdcard.init(spi_bus, cs_pin=14)
|
||||
|
||||
# === AUDIO HARDWARE ===
|
||||
from machine import PWM, Pin
|
||||
import mpos.audio.audioflinger as AudioFlinger
|
||||
from mpos import AudioFlinger
|
||||
|
||||
# Initialize buzzer (GPIO 46)
|
||||
buzzer = PWM(Pin(46), freq=550, duty=0)
|
||||
|
||||
@@ -96,7 +96,7 @@ def adc_to_voltage(adc_value):
|
||||
mpos.battery_voltage.init_adc(999, adc_to_voltage)
|
||||
|
||||
# === AUDIO HARDWARE ===
|
||||
import mpos.audio.audioflinger as AudioFlinger
|
||||
from mpos import AudioFlinger
|
||||
|
||||
# Desktop builds have no real audio hardware, but we simulate microphone
|
||||
# recording with a 440Hz sine wave for testing WAV file generation
|
||||
|
||||
@@ -111,7 +111,7 @@ except Exception as e:
|
||||
print(f"Warning: powering off camera got exception: {e}")
|
||||
|
||||
# === AUDIO HARDWARE ===
|
||||
import mpos.audio.audioflinger as AudioFlinger
|
||||
from mpos import AudioFlinger
|
||||
|
||||
# Note: Waveshare board has no buzzer or I2S audio
|
||||
AudioFlinger.init()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CURRENT_OS_VERSION = "0.5.3"
|
||||
CURRENT_OS_VERSION = "0.6.0"
|
||||
|
||||
# Unique string that defines the hardware, used by OSUpdate and the About app
|
||||
_hardware_id = "missing-hardware-info"
|
||||
|
||||
Regular → Executable
@@ -20,7 +20,7 @@ inject_mocks({
|
||||
})
|
||||
|
||||
# Now import the module to test
|
||||
import mpos.audio.audioflinger as AudioFlinger
|
||||
from mpos.audio.audioflinger import AudioFlinger
|
||||
|
||||
|
||||
class TestAudioFlinger(unittest.TestCase):
|
||||
@@ -45,8 +45,9 @@ class TestAudioFlinger(unittest.TestCase):
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test that AudioFlinger initializes correctly."""
|
||||
self.assertEqual(AudioFlinger._i2s_pins, self.i2s_pins)
|
||||
self.assertEqual(AudioFlinger._buzzer_instance, self.buzzer)
|
||||
af = AudioFlinger.get()
|
||||
self.assertEqual(af._i2s_pins, self.i2s_pins)
|
||||
self.assertEqual(af._buzzer_instance, self.buzzer)
|
||||
|
||||
def test_has_i2s(self):
|
||||
"""Test has_i2s() returns correct value."""
|
||||
@@ -134,7 +135,8 @@ class TestAudioFlinger(unittest.TestCase):
|
||||
|
||||
def test_audio_focus_check_no_current_stream(self):
|
||||
"""Test audio focus allows playback when no stream is active."""
|
||||
result = AudioFlinger._check_audio_focus(AudioFlinger.STREAM_MUSIC)
|
||||
af = AudioFlinger.get()
|
||||
result = af._check_audio_focus(AudioFlinger.STREAM_MUSIC)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_volume_default_value(self):
|
||||
@@ -156,7 +158,8 @@ class TestAudioFlingerRecording(unittest.TestCase):
|
||||
self.i2s_pins_no_mic = {'sck': 2, 'ws': 47, 'sd': 16}
|
||||
|
||||
# Reset state
|
||||
AudioFlinger._current_recording = None
|
||||
af = AudioFlinger.get()
|
||||
af._current_recording = None
|
||||
AudioFlinger.set_volume(70)
|
||||
|
||||
AudioFlinger.init(
|
||||
|
||||
Reference in New Issue
Block a user