From 38ef123f07ce83aff8fa50ebb12e3091aac6e533 Mon Sep 17 00:00:00 2001 From: Cam Gorrie Date: Thu, 17 Sep 2026 23:52:02 -0400 Subject: [PATCH 1/2] Strip out responsibility for audio card seed; requires pistomp-audio 1.1.0 --- CHANGELOG.md | 2 + modalapistomp.py | 2 - pistomp/audiocard.py | 29 +- pistomp/audioinjector.py | 3 - pistomp/hifiberry.py | 3 - pistomp/iqaudiocodec.py | 30 +- setup/audio/audioinjector.state | 166 ---- setup/audio/hifiberry.state | 278 ------- setup/audio/iqaudiocodec.state | 1312 ------------------------------- util/change-audio-card.sh | 33 +- 10 files changed, 36 insertions(+), 1822 deletions(-) delete mode 100644 setup/audio/audioinjector.state delete mode 100644 setup/audio/hifiberry.state delete mode 100644 setup/audio/iqaudiocodec.state diff --git a/CHANGELOG.md b/CHANGELOG.md index 721388f82..893547212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- ALSA state seeding moved to firstboot/recovery (pistomp-audio `seed.sh`). `change-audio-card.sh` forwards to it. ## [v3.3.2] - 2026-09-08 ### Changed diff --git a/modalapistomp.py b/modalapistomp.py index 3ac03ac97..8c99997ed 100755 --- a/modalapistomp.py +++ b/modalapistomp.py @@ -105,10 +105,8 @@ def main(): is_emulator = args.host[0] in EMULATOR_HOSTS if not is_emulator: - # Audio Card Config - doing this early so audio passes ASAP factory = Audiocardfactory.Audiocardfactory(cwd) audiocard = factory.create() - audiocard.restore() # MIDI initialization # Prompts user for MIDI input port, unless a valid port number or name diff --git a/pistomp/audiocard.py b/pistomp/audiocard.py index 8f8ff7430..0d2677bc4 100755 --- a/pistomp/audiocard.py +++ b/pistomp/audiocard.py @@ -16,7 +16,6 @@ # along with pi-stomp. If not, see . import logging -import mmap import os import re import subprocess @@ -36,8 +35,7 @@ class Audiocard: cwd: str card_index: int = 0 config_file: str = "/var/lib/alsa/asound.state" # global config used by alsamixer, etc. - initial_config_file: str | None = None # use this if common config_file loading fails - initial_config_name: str | None = None + bypass: bool = False _store_at: float | None = None @@ -55,31 +53,6 @@ class Audiocard: def __init__(self, cwd: str) -> None: self.cwd = cwd - def restore(self): - # If the global config_file either doesn't exist, doesn't contain the name of our audiocard, or fails restore, - # read initial_config_file (our backup). This will be the case on first boot after install. - # Subsequent boots will likely use the global config_file since initial_config_file settings will get - # appended if a 'alsactl store' operation occurs or the system has a clean shutdown - conf_files = [self.config_file, self.initial_config_file] - for fname in conf_files: - if os.access(fname, os.R_OK) is True: - try: - looking_for = bytes(("state.%s" % self.initial_config_name), "utf-8") - f = open(fname) - with f as text: - s = mmap.mmap(text.fileno(), 0, access=mmap.ACCESS_READ) - if s.find(looking_for) != -1: - logging.info("restoring audio card settings from: %s" % fname) - subprocess.run(["/usr/sbin/alsactl", "-f", fname, "--no-lock", "--no-ucm", "restore"]) - f.close() - # If the file loaded was not the global, then save it so it will be next time - if fname is not self.config_file: - self.store() - break - f.close() - except Exception: - logging.error("Failed trying to restore audio card settings from: %s" % fname) - def store(self): # /var/lib/alsa/asound.state is root:root; this process runs as the # unprivileged pistomp user, so alsactl needs sudo to lock and write it. diff --git a/pistomp/audioinjector.py b/pistomp/audioinjector.py index 429c1ea87..ca5069142 100755 --- a/pistomp/audioinjector.py +++ b/pistomp/audioinjector.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . -import os import pistomp.audiocard as audiocard @@ -23,7 +22,5 @@ class Audioinjector(audiocard.Audiocard): def __init__(self, cwd): super(Audioinjector, self).__init__(cwd) - self.initial_config_file = os.path.join(cwd, 'setup', 'audio', 'audioinjector.state') - self.initial_config_name = 'audioinjectorpi' self.CAPTURE_VOLUME = 'Capture' self.MASTER = 'Master' \ No newline at end of file diff --git a/pistomp/hifiberry.py b/pistomp/hifiberry.py index e805b5bd5..7275e578c 100755 --- a/pistomp/hifiberry.py +++ b/pistomp/hifiberry.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . -import os import pistomp.audiocard as audiocard @@ -23,7 +22,5 @@ class Hifiberry(audiocard.Audiocard): def __init__(self, cwd): super(Hifiberry, self).__init__(cwd) - self.initial_config_file = os.path.join(cwd, 'setup', 'audio', 'hifiberry.state') - self.initial_config_name = 'sndrpihifiberry' self.CAPTURE_VOLUME = 'Digital' self.MASTER = None diff --git a/pistomp/iqaudiocodec.py b/pistomp/iqaudiocodec.py index 414a58595..e11eb5245 100755 --- a/pistomp/iqaudiocodec.py +++ b/pistomp/iqaudiocodec.py @@ -15,32 +15,28 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . -import os import pistomp.audiocard as audiocard class IQaudioCodec(audiocard.Audiocard): - def __init__(self, cwd): super(IQaudioCodec, self).__init__(cwd) - self.initial_config_file = os.path.join(cwd, 'setup', 'audio', 'iqaudiocodec.state') - self.initial_config_name = 'IQaudIOCODEC' - self.CAPTURE_VOLUME = 'Aux' - self.MASTER = 'Headphone' # Changed to headphone to allow digital control of output. + self.CAPTURE_VOLUME = "Aux" + self.MASTER = "Headphone" # Changed to headphone to allow digital control of output. self.DAC_EQ = "DAC EQ" - self.EQ_1 = 'DAC EQ1' - self.EQ_2 = 'DAC EQ2' - self.EQ_3 = 'DAC EQ3' - self.EQ_4 = 'DAC EQ4' - self.EQ_5 = 'DAC EQ5' + self.EQ_1 = "DAC EQ1" + self.EQ_2 = "DAC EQ2" + self.EQ_3 = "DAC EQ3" + self.EQ_4 = "DAC EQ4" + self.EQ_5 = "DAC EQ5" self.bypass_left = False self.bypass_right = False self._init_bypass() def _init_bypass(self): - self.bypass_left = not self.get_switch_parameter('Mixout Left DAC Left') - self.bypass_right = not self.get_switch_parameter('Mixout Right DAC Right') + self.bypass_left = not self.get_switch_parameter("Mixout Left DAC Left") + self.bypass_right = not self.get_switch_parameter("Mixout Right DAC Right") def get_bypass_left(self) -> bool: return self.bypass_left @@ -50,10 +46,10 @@ def get_bypass_right(self) -> bool: def set_bypass_left(self, bypass): self.bypass_left = bypass - self.set_switch_parameter('Mixout Left Aux Left', self.bypass_left, store=False) - self.set_switch_parameter('Mixout Left DAC Left', not self.bypass_left) + self.set_switch_parameter("Mixout Left Aux Left", self.bypass_left, store=False) + self.set_switch_parameter("Mixout Left DAC Left", not self.bypass_left) def set_bypass_right(self, bypass): self.bypass_right = bypass - self.set_switch_parameter('Mixout Right Aux Right', self.bypass_right, store=False) - self.set_switch_parameter('Mixout Right DAC Right', not self.bypass_right) \ No newline at end of file + self.set_switch_parameter("Mixout Right Aux Right", self.bypass_right, store=False) + self.set_switch_parameter("Mixout Right DAC Right", not self.bypass_right) diff --git a/setup/audio/audioinjector.state b/setup/audio/audioinjector.state deleted file mode 100644 index c2b975c32..000000000 --- a/setup/audio/audioinjector.state +++ /dev/null @@ -1,166 +0,0 @@ -state.audioinjectorpi { - control.1 { - iface MIXER - name 'Master Playback Volume' - value.0 121 - value.1 121 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -9999999 - dbmax 600 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.2 { - iface MIXER - name 'Master Playback ZC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.3 { - iface MIXER - name 'Capture Volume' - value.0 23 - value.1 23 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 31' - dbmin -3450 - dbmax 1200 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.4 { - iface MIXER - name 'Line Capture Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.5 { - iface MIXER - name 'Mic Boost Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 1' - dbmin 0 - dbmax 2000 - dbvalue.0 0 - } - } - control.6 { - iface MIXER - name 'Mic Capture Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Sidetone Playback Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin -1500 - dbmax -600 - dbvalue.0 -1500 - } - } - control.8 { - iface MIXER - name 'ADC High Pass Filter Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.9 { - iface MIXER - name 'Store DC Offset Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.10 { - iface MIXER - name 'Playback Deemphasis Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.11 { - iface MIXER - name 'Output Mixer Line Bypass Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.12 { - iface MIXER - name 'Output Mixer Mic Sidetone Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.13 { - iface MIXER - name 'Output Mixer HiFi Playback Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.14 { - iface MIXER - name 'Input Mux' - value 'Line In' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'Line In' - item.1 Mic - } - } -} diff --git a/setup/audio/hifiberry.state b/setup/audio/hifiberry.state deleted file mode 100644 index 6a716562f..000000000 --- a/setup/audio/hifiberry.state +++ /dev/null @@ -1,278 +0,0 @@ -state.sndrpihifiberry { - control.1 { - iface MIXER - name 'Digital Playback Volume' - value.0 205 - value.1 205 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 207' - dbmin -9999999 - dbmax 0 - dbvalue.0 -100 - dbvalue.1 -100 - } - } - control.2 { - iface MIXER - name 'Analogue Playback Volume' - value.0 1 - value.1 1 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 1' - dbmin -600 - dbmax 0 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.3 { - iface MIXER - name 'Analogue Playback Boost Volume' - value.0 0 - value.1 0 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 1' - dbmin 0 - dbmax 80 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.4 { - iface MIXER - name 'Digital Playback Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.5 { - iface MIXER - name 'Deemphasis Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.6 { - iface MIXER - name 'DSP Program' - value 'FIR interpolation with de-emphasis' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'FIR interpolation with de-emphasis' - item.1 'Low latency IIR with de-emphasis' - item.2 'High attenuation with de-emphasis' - item.3 'Fixed process flow' - item.4 'Ringing-less low latency FIR' - } - } - control.7 { - iface MIXER - name 'Clock Missing Period' - value '1s' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1s' - item.1 '2s' - item.2 '3s' - item.3 '4s' - item.4 '5s' - item.5 '6s' - item.6 '7s' - item.7 '8s' - } - } - control.8 { - iface MIXER - name 'Auto Mute Time Left' - value '21ms' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '21ms' - item.1 '106ms' - item.2 '213ms' - item.3 '533ms' - item.4 '1.07s' - item.5 '2.13s' - item.6 '5.33s' - item.7 '10.66s' - } - } - control.9 { - iface MIXER - name 'Auto Mute Time Right' - value '21ms' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '21ms' - item.1 '106ms' - item.2 '213ms' - item.3 '533ms' - item.4 '1.07s' - item.5 '2.13s' - item.6 '5.33s' - item.7 '10.66s' - } - } - control.10 { - iface MIXER - name 'Auto Mute Mono Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.11 { - iface MIXER - name 'Auto Mute Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.12 { - iface MIXER - name 'Volume Ramp Down Rate' - value '1 sample/update' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1 sample/update' - item.1 '2 samples/update' - item.2 '4 samples/update' - item.3 Immediate - } - } - control.13 { - iface MIXER - name 'Volume Ramp Down Step' - value '1dB/step' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '4dB/step' - item.1 '2dB/step' - item.2 '1dB/step' - item.3 '0.5dB/step' - } - } - control.14 { - iface MIXER - name 'Volume Ramp Up Rate' - value '1 sample/update' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1 sample/update' - item.1 '2 samples/update' - item.2 '4 samples/update' - item.3 Immediate - } - } - control.15 { - iface MIXER - name 'Volume Ramp Up Step' - value '1dB/step' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '4dB/step' - item.1 '2dB/step' - item.2 '1dB/step' - item.3 '0.5dB/step' - } - } - control.16 { - iface MIXER - name 'Volume Ramp Down Emergency Rate' - value '1 sample/update' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1 sample/update' - item.1 '2 samples/update' - item.2 '4 samples/update' - item.3 Immediate - } - } - control.17 { - iface MIXER - name 'Volume Ramp Down Emergency Step' - value '4dB/step' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '4dB/step' - item.1 '2dB/step' - item.2 '1dB/step' - item.3 '0.5dB/step' - } - } - control.18 { - iface MIXER - name 'Max Overclock PLL' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 20' - } - } - control.19 { - iface MIXER - name 'Max Overclock DSP' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 40' - } - } - control.20 { - iface MIXER - name 'Max Overclock DAC' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 40' - } - } -} diff --git a/setup/audio/iqaudiocodec.state b/setup/audio/iqaudiocodec.state deleted file mode 100644 index afa4d7bbb..000000000 --- a/setup/audio/iqaudiocodec.state +++ /dev/null @@ -1,1312 +0,0 @@ -state.IQaudIOCODEC { - control.1 { - iface MIXER - name 'Mic 1 Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - dbmin -600 - dbmax 3600 - dbvalue.0 -600 - } - } - control.2 { - iface MIXER - name 'Mic 2 Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - dbmin -600 - dbmax 3600 - dbvalue.0 -600 - } - } - control.3 { - iface MIXER - name 'Aux Volume' - value.0 47 - value.1 47 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 63' - dbmin -5400 - dbmax 1500 - dbvalue.0 -900 - dbvalue.1 -900 - } - } - control.4 { - iface MIXER - name 'Mixin PGA Volume' - value.0 2 - value.1 2 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - dbmin -450 - dbmax 1800 - dbvalue.0 -150 - dbvalue.1 -150 - } - } - control.5 { - iface MIXER - name 'ADC Volume' - value.0 111 - value.1 111 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -9999999 - dbmax 1125 - dbvalue.0 -75 - dbvalue.1 -75 - } - } - control.6 { - iface MIXER - name 'DAC Volume' - value.0 114 - value.1 114 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -9999999 - dbmax 1125 - dbvalue.0 150 - dbvalue.1 150 - } - } - control.7 { - iface MIXER - name 'Headphone Volume' - value.0 54 - value.1 54 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 63' - dbmin -5700 - dbmax 600 - dbvalue.0 -300 - dbvalue.1 -300 - } - } - control.8 { - iface MIXER - name 'Lineout Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - dbmin -4800 - dbmax 1500 - dbvalue.0 -4800 - } - } - control.9 { - iface MIXER - name 'DAC EQ Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.10 { - iface MIXER - name 'DAC EQ1 Volume' - value 13 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -1050 - dbmax 1200 - dbvalue.0 900 - } - } - control.11 { - iface MIXER - name 'DAC EQ2 Volume' - value 13 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -1050 - dbmax 1200 - dbvalue.0 900 - } - } - control.12 { - iface MIXER - name 'DAC EQ3 Volume' - value 13 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -1050 - dbmax 1200 - dbvalue.0 900 - } - } - control.13 { - iface MIXER - name 'DAC EQ4 Volume' - value 13 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -1050 - dbmax 1200 - dbvalue.0 900 - } - } - control.14 { - iface MIXER - name 'DAC EQ5 Volume' - value 13 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -1050 - dbmax 1200 - dbvalue.0 900 - } - } - control.15 { - iface MIXER - name 'ADC HPF Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.16 { - iface MIXER - name 'ADC HPF Cutoff' - value Fs/24000 - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 Fs/24000 - item.1 Fs/12000 - item.2 Fs/6000 - item.3 Fs/3000 - } - } - control.17 { - iface MIXER - name 'ADC Voice Mode Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.18 { - iface MIXER - name 'ADC Voice Cutoff' - value '2.5Hz' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '2.5Hz' - item.1 '25Hz' - item.2 '50Hz' - item.3 '100Hz' - item.4 '150Hz' - item.5 '200Hz' - item.6 '300Hz' - item.7 '400Hz' - } - } - control.19 { - iface MIXER - name 'DAC HPF Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.20 { - iface MIXER - name 'DAC HPF Cutoff' - value Fs/24000 - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 Fs/24000 - item.1 Fs/12000 - item.2 Fs/6000 - item.3 Fs/3000 - } - } - control.21 { - iface MIXER - name 'DAC Voice Mode Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.22 { - iface MIXER - name 'DAC Voice Cutoff' - value '2.5Hz' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '2.5Hz' - item.1 '25Hz' - item.2 '50Hz' - item.3 '100Hz' - item.4 '150Hz' - item.5 '200Hz' - item.6 '300Hz' - item.7 '400Hz' - } - } - control.23 { - iface MIXER - name 'Mic 1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.24 { - iface MIXER - name 'Mic 2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.25 { - iface MIXER - name 'Aux Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.26 { - iface MIXER - name 'Mixin PGA Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.27 { - iface MIXER - name 'ADC Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.28 { - iface MIXER - name 'Headphone Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.29 { - iface MIXER - name 'Lineout Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.30 { - iface MIXER - name 'DAC Soft Mute Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.31 { - iface MIXER - name 'DAC Soft Mute Rate' - value '1' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1' - item.1 '2' - item.2 '4' - item.3 '8' - item.4 '16' - item.5 '32' - item.6 '64' - } - } - control.32 { - iface MIXER - name 'Aux ZC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.33 { - iface MIXER - name 'Mixin PGA ZC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.34 { - iface MIXER - name 'Headphone ZC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.35 { - iface MIXER - name 'ToneGen Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin -4500 - dbmax 0 - dbvalue.0 -4500 - } - } - control.36 { - iface MIXER - name 'ToneGen DTMF Key' - value '0' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '0' - item.1 '1' - item.2 '2' - item.3 '3' - item.4 '4' - item.5 '5' - item.6 '6' - item.7 '7' - item.8 '8' - item.9 '9' - item.10 A - item.11 B - item.12 C - item.13 D - item.14 '*' - item.15 '#' - } - } - control.37 { - iface MIXER - name 'ToneGen DTMF Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.38 { - iface MIXER - name 'ToneGen Start' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.39 { - iface MIXER - name 'ToneGen Sinewave Gen Type' - value Sum - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 Sum - item.1 SWG1 - item.2 SWG2 - item.3 Sum - } - } - control.40 { - iface MIXER - name 'ToneGen Sinewave1 Freq' - value 5461 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 65535' - } - } - control.41 { - iface MIXER - name 'ToneGen Sinewave2 Freq' - value 16384 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 65535' - } - } - control.42 { - iface MIXER - name 'ToneGen On Time' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - } - } - control.43 { - iface MIXER - name 'ToneGen Off Time' - value 1 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - } - } - control.44 { - iface MIXER - name 'Aux Gain Ramping Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.45 { - iface MIXER - name 'Mixin Gain Ramping Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.46 { - iface MIXER - name 'ADC Gain Ramping Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.47 { - iface MIXER - name 'DAC Gain Ramping Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.48 { - iface MIXER - name 'Headphone Gain Ramping Switch' - value.0 true - value.1 true - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.49 { - iface MIXER - name 'Lineout Gain Ramping Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.50 { - iface MIXER - name 'Gain Ramping Rate' - value 'nominal rate * 8' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'nominal rate * 8' - item.1 'nominal rate * 16' - item.2 'nominal rate / 16' - item.3 'nominal rate / 32' - } - } - control.51 { - iface MIXER - name 'DAC NG Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.52 { - iface MIXER - name 'DAC NG Setup Time' - value '256 samples' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '256 samples' - item.1 '512 samples' - item.2 '1024 samples' - item.3 '2048 samples' - } - } - control.53 { - iface MIXER - name 'DAC NG Rampup Rate' - value '0.02 ms/dB' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '0.02 ms/dB' - item.1 '0.16 ms/dB' - } - } - control.54 { - iface MIXER - name 'DAC NG Rampdown Rate' - value '0.64 ms/dB' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '0.64 ms/dB' - item.1 '20.48 ms/dB' - } - } - control.55 { - iface MIXER - name 'DAC NG OFF Threshold' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - } - } - control.56 { - iface MIXER - name 'DAC NG ON Threshold' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - } - } - control.57 { - iface MIXER - name 'DAC Mono Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.58 { - iface MIXER - name 'DAC Invert Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.59 { - iface MIXER - name 'DMIC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.60 { - iface MIXER - name 'ALC Switch' - value.0 false - value.1 false - comment { - access 'read write' - type BOOLEAN - count 2 - } - } - control.61 { - iface MIXER - name 'ALC Attack Rate' - value '44/fs' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '44/fs' - item.1 '88/fs' - item.2 '176/fs' - item.3 '352/fs' - item.4 '704/fs' - item.5 '1408/fs' - item.6 '2816/fs' - item.7 '5632/fs' - item.8 '11264/fs' - item.9 '22528/fs' - item.10 '45056/fs' - item.11 '90112/fs' - item.12 '180224/fs' - } - } - control.62 { - iface MIXER - name 'ALC Release Rate' - value '176/fs' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '176/fs' - item.1 '352/fs' - item.2 '704/fs' - item.3 '1408/fs' - item.4 '2816/fs' - item.5 '5632/fs' - item.6 '11264/fs' - item.7 '22528/fs' - item.8 '45056/fs' - item.9 '90112/fs' - item.10 '180224/fs' - } - } - control.63 { - iface MIXER - name 'ALC Hold Time' - value '62/fs' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '62/fs' - item.1 '124/fs' - item.2 '248/fs' - item.3 '496/fs' - item.4 '992/fs' - item.5 '1984/fs' - item.6 '3968/fs' - item.7 '7936/fs' - item.8 '15872/fs' - item.9 '31744/fs' - item.10 '63488/fs' - item.11 '126976/fs' - item.12 '253952/fs' - item.13 '507904/fs' - item.14 '1015808/fs' - item.15 '2031616/fs' - } - } - control.64 { - iface MIXER - name 'ALC Integ Attack Rate' - value '1/4' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1/4' - item.1 '1/16' - item.2 '1/256' - item.3 '1/65536' - } - } - control.65 { - iface MIXER - name 'ALC Integ Release Rate' - value '1/4' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 '1/4' - item.1 '1/16' - item.2 '1/256' - item.3 '1/65536' - } - } - control.66 { - iface MIXER - name 'ALC Noise Threshold Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - dbmin -9450 - dbmax 0 - dbvalue.0 -9450 - } - } - control.67 { - iface MIXER - name 'ALC Min Threshold Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - dbmin -9450 - dbmax 0 - dbvalue.0 -9450 - } - } - control.68 { - iface MIXER - name 'ALC Max Threshold Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 63' - dbmin -9450 - dbmax 0 - dbvalue.0 -9450 - } - } - control.69 { - iface MIXER - name 'ALC Max Attenuation Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin 0 - dbmax 9000 - dbvalue.0 0 - } - } - control.70 { - iface MIXER - name 'ALC Max Gain Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 15' - dbmin 0 - dbmax 9000 - dbvalue.0 0 - } - } - control.71 { - iface MIXER - name 'ALC Min Analog Gain Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - dbmin -9999999 - dbmax 3600 - dbvalue.0 -9999999 - } - } - control.72 { - iface MIXER - name 'ALC Max Analog Gain Volume' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 7' - dbmin -9999999 - dbmax 3600 - dbvalue.0 -9999999 - } - } - control.73 { - iface MIXER - name 'ALC Anticlip Mode Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.74 { - iface MIXER - name 'ALC Anticlip Level' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 127' - } - } - control.75 { - iface MIXER - name 'HP Jack Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.76 { - iface MIXER - name 'MIC Jack Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.77 { - iface MIXER - name 'Onboard MIC Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.78 { - iface MIXER - name 'AUX Jack Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.79 { - iface MIXER - name 'Mic 1 Amp Source MUX' - value Differential - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 Differential - item.1 MIC_P - item.2 MIC_N - } - } - control.80 { - iface MIXER - name 'Mic 2 Amp Source MUX' - value Differential - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 Differential - item.1 MIC_P - item.2 MIC_N - } - } - control.81 { - iface MIXER - name 'Mixin Left Aux Left Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.82 { - iface MIXER - name 'Mixin Left Mic 1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.83 { - iface MIXER - name 'Mixin Left Mic 2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.84 { - iface MIXER - name 'Mixin Left Mixin Right Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.85 { - iface MIXER - name 'Mixin Right Aux Right Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.86 { - iface MIXER - name 'Mixin Right Mic 2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.87 { - iface MIXER - name 'Mixin Right Mic 1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.88 { - iface MIXER - name 'Mixin Right Mixin Left Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.89 { - iface MIXER - name 'DAI Left Source MUX' - value 'ADC Left' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'ADC Left' - item.1 'ADC Right' - item.2 'DAI Input Left' - item.3 'DAI Input Right' - } - } - control.90 { - iface MIXER - name 'DAI Right Source MUX' - value 'ADC Right' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'ADC Left' - item.1 'ADC Right' - item.2 'DAI Input Left' - item.3 'DAI Input Right' - } - } - control.91 { - iface MIXER - name 'DAC Left Source MUX' - value 'DAI Input Left' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'ADC Output Left' - item.1 'ADC Output Right' - item.2 'DAI Input Left' - item.3 'DAI Input Right' - } - } - control.92 { - iface MIXER - name 'DAC Right Source MUX' - value 'DAI Input Right' - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 'ADC Output Left' - item.1 'ADC Output Right' - item.2 'DAI Input Left' - item.3 'DAI Input Right' - } - } - control.93 { - iface MIXER - name 'Mixout Left Aux Left Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.94 { - iface MIXER - name 'Mixout Left Mixin Left Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.95 { - iface MIXER - name 'Mixout Left Mixin Right Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.96 { - iface MIXER - name 'Mixout Left DAC Left Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.97 { - iface MIXER - name 'Mixout Left Aux Left Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.98 { - iface MIXER - name 'Mixout Left Mixin Left Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.99 { - iface MIXER - name 'Mixout Left Mixin Right Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.100 { - iface MIXER - name 'Mixout Right Aux Right Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.101 { - iface MIXER - name 'Mixout Right Mixin Right Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.102 { - iface MIXER - name 'Mixout Right Mixin Left Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.103 { - iface MIXER - name 'Mixout Right DAC Right Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.104 { - iface MIXER - name 'Mixout Right Aux Right Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.105 { - iface MIXER - name 'Mixout Right Mixin Right Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.106 { - iface MIXER - name 'Mixout Right Mixin Left Invert Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } -} diff --git a/util/change-audio-card.sh b/util/change-audio-card.sh index e5b5b4c73..aa89fe479 100755 --- a/util/change-audio-card.sh +++ b/util/change-audio-card.sh @@ -17,16 +17,26 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . +# Select the pi-Stomp audio card for the next boot. +# +# Usage: change-audio-card.sh +# overlay: iqaudio-codec | hifiberry-dacplusadc | audioinjector-wm8731-audio +# +# Enables the dtoverlay for the selected card (and disables the other known +# cards) in /boot/firmware/config.txt, then seeds the matching known-good +# ALSA state via pistomp-audio's seed.sh so the next boot starts with a +# working mixer configuration. +# +# The overlay name is the only key in the chain: recovery's +# AUDIO_CARD_OVERLAYS, the menu selection, this script, and seed.sh all pass +# it unchanged. Keep the lists in step: pistomp-recovery constants.py, +# change-audio-card.sh, seed.sh, and the image's config.txt. + +set -euo pipefail + cards=("audioinjector-wm8731-audio" "iqaudio-codec" "hifiberry-dacplusadc") config_file=/boot/firmware/config.txt -state_file=/var/lib/alsa/asound.state - -if [ -e "$config_file" ]; then - echo "Modifying $config_file" -else - config_file=/boot/config.txt - echo "Modifying $config_file" -fi +seed=/usr/lib/pistomp/alsa/seed.sh if [ $# -eq 0 ]; then PS3="Select a card: " @@ -39,12 +49,10 @@ else opt=$1 fi -# Enable the dtoverlay for the selected card, comment out the others card_found=0 for c in ${cards[@]}; do if [[ "$opt" == "$c" ]]; then sudo sed -i "s/^\s*#dtoverlay=$c/dtoverlay=$c/" ${config_file} - echo "$c card enabled in ${config_file}" card_found=1 else sudo sed -i "s/^\s*dtoverlay=$c/#dtoverlay=$c/" ${config_file} @@ -52,8 +60,7 @@ for c in ${cards[@]}; do done if [[ ${card_found} -eq 1 ]]; then - # remove the state file so that the card specific state file will be loaded next time modalapistomp starts - sudo rm -f ${state_file} + sudo ${seed} "$opt" echo "*******************************" echo "* Reconfiguration complete. *" @@ -65,4 +72,4 @@ if [[ ${card_found} -eq 1 ]]; then else echo "$opt is not a known card" exit 1 -fi +fi \ No newline at end of file From 04e90fa8796dfd17afccb1001144d4956f0327c8 Mon Sep 17 00:00:00 2001 From: Cam Gorrie Date: Fri, 18 Sep 2026 00:04:25 -0400 Subject: [PATCH 2/2] Fix ruff error --- pistomp/audiocard.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pistomp/audiocard.py b/pistomp/audiocard.py index 0d2677bc4..9b9d1a83f 100755 --- a/pistomp/audiocard.py +++ b/pistomp/audiocard.py @@ -16,7 +16,6 @@ # along with pi-stomp. If not, see . import logging -import os import re import subprocess import time