feat(audio): Focusrite 2i2 stereo JACK config for 4CM
Adds: - AudioConfig.mode field: 'mono' (default) or 'stereo_4cm' - capture_channels / playback_channels properties for dynamic JACK -i/-o counts - FOCUSRITE_PROFILES dict with focusrite_2i2_3gen entry - AudioSystem.channel_mapping_help() static method - stereo_4cm port auto-connect wiring (4 cable method) - Systemd service content uses dynamic channel counts - Default config YAML includes 'mode: mono' - 11 new tests (31 total pass) - Focusrite 4CM wiring docs in docs/config-audio.md
This commit is contained in:
@@ -10,6 +10,7 @@ from system.audio import (
|
||||
AudioSystem,
|
||||
LATENCY_PROFILES,
|
||||
I2S_CONFIGS,
|
||||
FOCUSRITE_PROFILES,
|
||||
CONFIG_TXT,
|
||||
JACK_SERVICE_PATH,
|
||||
LIMITS_CONF,
|
||||
@@ -187,6 +188,73 @@ def test_systemd_service_content_custom_device():
|
||||
assert "-dhw:2,0" in content
|
||||
|
||||
|
||||
# ── Mode / stereo_4cm tests ───────────────────────────────────────
|
||||
|
||||
|
||||
def test_audio_config_mode_default():
|
||||
cfg = AudioConfig()
|
||||
assert cfg.mode == "mono"
|
||||
|
||||
|
||||
def test_audio_config_mode_stereo_4cm():
|
||||
cfg = AudioConfig(mode="stereo_4cm")
|
||||
assert cfg.mode == "stereo_4cm"
|
||||
|
||||
|
||||
def test_audio_config_channel_counts_mono():
|
||||
cfg = AudioConfig(mode="mono")
|
||||
assert cfg.capture_channels == 1
|
||||
assert cfg.playback_channels == 1
|
||||
|
||||
|
||||
def test_audio_config_channel_counts_stereo_4cm():
|
||||
cfg = AudioConfig(mode="stereo_4cm")
|
||||
assert cfg.capture_channels == 2
|
||||
assert cfg.playback_channels == 2
|
||||
|
||||
|
||||
def test_audio_config_focusrite_profile_hit():
|
||||
cfg = AudioConfig(hat_type="focusrite_2i2_3gen")
|
||||
prof = cfg.focusrite_profile
|
||||
assert prof is not None
|
||||
desc, cap, play = prof
|
||||
assert "Focusrite" in desc
|
||||
assert cap == 2
|
||||
assert play == 2
|
||||
|
||||
|
||||
def test_audio_config_focusrite_profile_miss():
|
||||
cfg = AudioConfig()
|
||||
assert cfg.focusrite_profile is None
|
||||
|
||||
|
||||
def test_focusrite_profiles_entries():
|
||||
for key, (desc, cap, play) in FOCUSRITE_PROFILES.items():
|
||||
assert len(desc) > 10
|
||||
assert isinstance(cap, int) and cap > 0
|
||||
assert isinstance(play, int) and play > 0
|
||||
|
||||
|
||||
def test_channel_mapping_help_mono():
|
||||
mapping = AudioSystem.channel_mapping_help("mono")
|
||||
assert len(mapping) == 1
|
||||
assert mapping[0]["capture_port"] == "system:capture_1"
|
||||
assert mapping[0]["playback_port"] == "system:playback_1"
|
||||
|
||||
|
||||
def test_channel_mapping_help_stereo_4cm():
|
||||
mapping = AudioSystem.channel_mapping_help("stereo_4cm")
|
||||
assert len(mapping) == 2
|
||||
assert "Guitar" in mapping[0]["description"]
|
||||
assert "FX Send" in mapping[1]["description"]
|
||||
|
||||
|
||||
def test_channel_mapping_help_unknown():
|
||||
import pytest
|
||||
with pytest.raises(ValueError, match="Unknown mode"):
|
||||
AudioSystem.channel_mapping_help("bogus")
|
||||
|
||||
|
||||
# ── Module exports ────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user