diff --git a/CONTEXT.md b/CONTEXT.md index 1e90e4d..b4e7cfc 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -62,20 +62,21 @@ printed enclosure, speakers. Work until those arrive is limited to what the Pi, `opencv-python-headless==4.10.0.84` with `numpy<2` (system NumPy stays 1.26.4 for ROS), and `robot-env.sh` puts the venv first on `PYTHONPATH`; YuNet also needs input sides that are multiples of 32. Tested on a sample image and on a live frame (one face found, upright, no flip needed). -- **Audio: card works, microphones read digital silence (open).** The stock `wm8960-soundcard` - overlay fails every stream with `wm8960: No MCLK configured` on Ubuntu 24.04: it puts the 12.288 MHz - fixed clock on the sound card's codec link, but the codec driver reads `mclk` from its own node. +- **Audio capture works (verified 2026-10-04).** The stock `wm8960-soundcard` overlay fails every + stream with `wm8960: No MCLK configured` on Ubuntu 24.04: it puts the 12.288 MHz fixed clock on the + sound card's codec link, but the codec driver reads `mclk` from its own node. `pi/overlays/hermes-wm8960.dts` is the stock overlay plus `clocks`/`clock-names` on the codec node; `pi/install-audio-overlay.sh` compiles it to `/boot/firmware/overlays/hermes-wm8960.dtbo`, sets - `dtparam=audio=off` and `dtoverlay=hermes-wm8960`. With it, capture opens at 8-48 kHz. Address - the card by name (`hw:CARD=wm8960soundcard,DEV=0`): its index changes (it was card 1, then 0). - But every recording is exactly zero (no noise floor), with every mixer path on and gains maxed. - Checked: DAPM shows ADCs, input mixers, boost mixers and LINPUT1/RINPUT1 on; registers - `R25=0xfc`, `R47=0x30`, `R32/33=0x108`; MCLK 12.288 MHz and BCLK 1.536 MHz running; GPIO18-21 in - `alt0` for the I2S; setting `ALRCGPIO` (R9 bit 6) over I2C made no difference. Not yet checked: - the HAT's hardware **Audio ON/OFF slide switch** position, MICBIAS, a DAC-to-ADC loopback. - `Left/Right Input Mixer Boost Switch` default to off and must be turned on for the mic path. - No speakers on hand, so playback is untested. + `dtparam=audio=off` and `dtoverlay=hermes-wm8960`. Capture then opens at 8-48 kHz. Address the + card by name (`hw:CARD=wm8960soundcard,DEV=0`): its index changes (it was card 1, then 0). +- **The HAT's hardware Audio ON/OFF slide switch (right edge, by the "Audio" label) must be ON.** + With it off, the codec still answers on I2C and every software check looks right, but all + recordings are exactly zero. That cost an hour of debugging; check it first. +- Mixer: `Left/Right Input Mixer Boost Switch` default to off and must be on. Settings in use: + Capture 47/47 (+18 dB), `Left/Right Input Boost Mixer LINPUT1/RINPUT1` volume 1, input mixer boost + on. Singing at arm's length: RMS -34 to -49 dBFS, peaks -18 dBFS, no clipping, channels within + 1-2 dB. Saved with `alsactl store` and exported as `pi/wm8960_asound.state`; restoring at boot is + not yet verified. No speakers on hand, so playback is untested. - Not done: PWM (waits for servos). Ask before rebooting the Pi. ## Package 0b (USB link): Pi side and talos side working diff --git a/pi/wm8960_asound.state b/pi/wm8960_asound.state new file mode 100644 index 0000000..214f2e6 --- /dev/null +++ b/pi/wm8960_asound.state @@ -0,0 +1,702 @@ +state.wm8960soundcard { + control.1 { + iface MIXER + name 'Capture Volume' + value.0 47 + value.1 47 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 63' + dbmin -1725 + dbmax 3000 + dbvalue.0 1800 + dbvalue.1 1800 + } + } + control.2 { + iface MIXER + name 'Capture Volume ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.3 { + iface MIXER + name 'Capture Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.4 { + iface MIXER + name 'Left Input Boost Mixer LINPUT3 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.5 { + iface MIXER + name 'Left Input Boost Mixer LINPUT2 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.6 { + iface MIXER + name 'Right Input Boost Mixer RINPUT3 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.7 { + iface MIXER + name 'Right Input Boost Mixer RINPUT2 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.8 { + iface MIXER + name 'Right Input Boost Mixer RINPUT1 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 1300 + } + } + control.9 { + iface MIXER + name 'Left Input Boost Mixer LINPUT1 Volume' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 1300 + } + } + control.10 { + iface MIXER + name 'Playback Volume' + value.0 215 + value.1 215 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 0 + dbvalue.0 -2000 + dbvalue.1 -2000 + } + } + control.11 { + iface MIXER + name 'Headphone Playback Volume' + value.0 101 + value.1 101 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 -2000 + dbvalue.1 -2000 + } + } + control.12 { + iface MIXER + name 'Headphone Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.13 { + iface MIXER + name 'Speaker Playback Volume' + value.0 101 + value.1 101 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 -2000 + dbvalue.1 -2000 + } + } + control.14 { + iface MIXER + name 'Speaker Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.15 { + iface MIXER + name 'Speaker DC Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.16 { + iface MIXER + name 'Speaker AC Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.17 { + iface MIXER + name 'PCM Playback -6dB Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.18 { + iface MIXER + name 'ADC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.19 { + iface MIXER + name 'ADC High Pass Filter Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.20 { + iface MIXER + name 'DAC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.21 { + iface MIXER + name 'DAC Deemphasis Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.22 { + iface MIXER + name '3D Filter Upper Cut-Off' + value High + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 High + item.1 Low + } + } + control.23 { + iface MIXER + name '3D Filter Lower Cut-Off' + value Low + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Low + item.1 High + } + } + control.24 { + iface MIXER + name '3D Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.25 { + iface MIXER + name '3D Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.26 { + iface MIXER + name 'ALC Function' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 Right + item.2 Left + item.3 Stereo + } + } + control.27 { + iface MIXER + name 'ALC Max Gain' + value 7 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.28 { + iface MIXER + name 'ALC Target' + value 4 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.29 { + iface MIXER + name 'ALC Min Gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.30 { + iface MIXER + name 'ALC Hold Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.31 { + iface MIXER + name 'ALC Mode' + value ALC + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 ALC + item.1 Limiter + } + } + control.32 { + iface MIXER + name 'ALC Decay' + value 3 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.33 { + iface MIXER + name 'ALC Attack' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.34 { + iface MIXER + name 'Noise Gate Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.35 { + iface MIXER + name 'Noise Gate Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.36 { + iface MIXER + name 'ADC PCM Capture Volume' + value.0 195 + value.1 195 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 3000 + dbvalue.0 0 + dbvalue.1 0 + } + } + control.37 { + iface MIXER + name 'Left Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.38 { + iface MIXER + name 'Left Output Mixer LINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.39 { + iface MIXER + name 'Right Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.40 { + iface MIXER + name 'Right Output Mixer RINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.41 { + iface MIXER + name 'ADC Data Output Select' + value 'Left Data = Left ADC; Right Data = Right ADC' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Left Data = Left ADC; Right Data = Right ADC' + item.1 'Left Data = Left ADC; Right Data = Left ADC' + item.2 'Left Data = Right ADC; Right Data = Right ADC' + item.3 'Left Data = Right ADC; Right Data = Left ADC' + } + } + control.42 { + iface MIXER + name 'DAC Mono Mix' + value Stereo + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Stereo + item.1 Mono + } + } + control.43 { + iface MIXER + name 'DAC Filter Characteristics' + value Normal + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Normal + item.1 Sloping + } + } + control.44 { + iface MIXER + name 'Left Boost Mixer LINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.45 { + iface MIXER + name 'Left Boost Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.46 { + iface MIXER + name 'Left Boost Mixer LINPUT1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.47 { + iface MIXER + name 'Right Boost Mixer RINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.48 { + iface MIXER + name 'Right Boost Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.49 { + iface MIXER + name 'Right Boost Mixer RINPUT1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.50 { + iface MIXER + name 'Left Input Mixer Boost Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.51 { + iface MIXER + name 'Right Input Mixer Boost Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.52 { + iface MIXER + name 'Left Output Mixer PCM Playback Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.53 { + iface MIXER + name 'Left Output Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.54 { + iface MIXER + name 'Left Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.55 { + iface MIXER + name 'Right Output Mixer PCM Playback Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.56 { + iface MIXER + name 'Right Output Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.57 { + iface MIXER + name 'Right Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.58 { + iface MIXER + name 'Mono Output Mixer Left Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.59 { + iface MIXER + name 'Mono Output Mixer Right Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +}