Skip to content

fix(audio): ES7210 mic PGA gain 21dB->12dB (ADC saturation)#40

Open
torlando-tech wants to merge 1 commit into
mainfrom
fix/mic-gain-saturation
Open

fix(audio): ES7210 mic PGA gain 21dB->12dB (ADC saturation)#40
torlando-tech wants to merge 1 commit into
mainfrom
fix/mic-gain-saturation

Conversation

@torlando-tech

Copy link
Copy Markdown
Owner

The ES7210 mic PGA initialized at the default micGain=7 (21 dB), which saturated the ADC: 0x8000 negative-rail spikes, an rms-7003 noise floor in silence, and a spectral-peak shift that masqueraded as a +17–25% pitch "warp". Drops it to GAIN_12DB (a pre-existing es7210.h enum) — a clean middle level: real signal, well below saturation.

Capture rate stays at main's 8 kHz. Part of the LXST voice investigation.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5

micGain default 7 (21dB) saturated the ADC: 0x8000 negative-rail spikes, an rms-7003 noise floor in silence, and a spectral-peak shift that masqueraded as a +17-25% pitch warp. 12dB (a pre-existing es7210.h enum) is a clean middle: real signal level, well below saturation. Rate stays at main's 8kHz.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes ADC saturation on the ES7210 mic array by replacing the raw micGain cast with the hardcoded constant GAIN_12DB, dropping the PGA from 21 dB to 12 dB. The root cause (0x8000 negative-rail spikes, rms-7003 noise floor, and pitch warp) is well-diagnosed and the gain level chosen is reasonable.

  • es7210_adc_set_gain() now always uses GAIN_12DB regardless of the micGain argument passed to init(), silently breaking the caller-visible API contract — any code that passes a specific gain value will have it ignored without error.
  • The lxst_audio.h header still documents micGain with the old default of 7 (21 dB) and presents the parameter as functional, which is now inaccurate.

Confidence Score: 3/5

The gain fix resolves a real hardware symptom, but the micGain parameter is now dead code — any caller passing a value other than the default will have it silently overridden by 12 dB.

The diagnostic reasoning and chosen gain level are sound, but the implementation discards the caller-supplied micGain argument with no warning, and the header still advertises the parameter as functional with the old 21 dB default. A downstream caller or test that relies on configurable gain will receive wrong behavior without any indication.

lib/lxst_audio/lxst_audio.cpp (hardcoded gain ignores parameter) and lib/lxst_audio/lxst_audio.h (stale default and doc comment for micGain)

Important Files Changed

Filename Overview
lib/lxst_audio/lxst_audio.cpp Hardcodes GAIN_12DB in es7210_adc_set_gain(), fixing ADC saturation, but silently drops the micGain parameter — callers supplying a non-default gain will have it ignored.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Caller
    participant LXSTAudio
    participant ES7210

    Caller->>LXSTAudio: "init(codec2Mode, micGain=7)"
    Note over LXSTAudio: micGain parameter received but NOT used
    LXSTAudio->>ES7210: es7210_adc_init()
    LXSTAudio->>ES7210: es7210_adc_config_i2s()
    LXSTAudio->>ES7210: "es7210_adc_set_gain(MIC1|MIC2|MIC3|MIC4, GAIN_12DB)"
    Note over ES7210: Hardcoded 12 dB — micGain ignored
    LXSTAudio->>ES7210: es7210_adc_ctrl_state(START)
    LXSTAudio-->>Caller: init returns true
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Caller
    participant LXSTAudio
    participant ES7210

    Caller->>LXSTAudio: "init(codec2Mode, micGain=7)"
    Note over LXSTAudio: micGain parameter received but NOT used
    LXSTAudio->>ES7210: es7210_adc_init()
    LXSTAudio->>ES7210: es7210_adc_config_i2s()
    LXSTAudio->>ES7210: "es7210_adc_set_gain(MIC1|MIC2|MIC3|MIC4, GAIN_12DB)"
    Note over ES7210: Hardcoded 12 dB — micGain ignored
    LXSTAudio->>ES7210: es7210_adc_ctrl_state(START)
    LXSTAudio-->>Caller: init returns true
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
lib/lxst_audio/lxst_audio.cpp:61
**`micGain` parameter silently ignored**

`GAIN_12DB` is now hardcoded, so any caller that passes a non-default `micGain` to `init()` will always get 12 dB, silently. For example, `audio.init(CODEC2_MODE_1600, 3)` (9 dB) or any diagnostic path that tries to sweep gain levels will have the value discarded with no warning. The `init()` signature and its `@param micGain` doc in `lxst_audio.h` still advertise the parameter as functional (`0-14, default 7 = 21dB`), making this a silent API contract break. Either remove/default-away the parameter in the header, or apply the enum cast back: `(es7210_gain_value_t)micGain` with `micGain`'s default changed to `4` (i.e., `GAIN_12DB`) in `lxst_audio.h`.

Reviews (1): Last reviewed commit: "fix(audio): ES7210 mic PGA gain 21dB->12..." | Re-trigger Greptile

(es7210_input_mics_t)(ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2 |
ES7210_INPUT_MIC3 | ES7210_INPUT_MIC4),
(es7210_gain_value_t)micGain);
GAIN_12DB);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 micGain parameter silently ignored

GAIN_12DB is now hardcoded, so any caller that passes a non-default micGain to init() will always get 12 dB, silently. For example, audio.init(CODEC2_MODE_1600, 3) (9 dB) or any diagnostic path that tries to sweep gain levels will have the value discarded with no warning. The init() signature and its @param micGain doc in lxst_audio.h still advertise the parameter as functional (0-14, default 7 = 21dB), making this a silent API contract break. Either remove/default-away the parameter in the header, or apply the enum cast back: (es7210_gain_value_t)micGain with micGain's default changed to 4 (i.e., GAIN_12DB) in lxst_audio.h.

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/lxst_audio/lxst_audio.cpp
Line: 61

Comment:
**`micGain` parameter silently ignored**

`GAIN_12DB` is now hardcoded, so any caller that passes a non-default `micGain` to `init()` will always get 12 dB, silently. For example, `audio.init(CODEC2_MODE_1600, 3)` (9 dB) or any diagnostic path that tries to sweep gain levels will have the value discarded with no warning. The `init()` signature and its `@param micGain` doc in `lxst_audio.h` still advertise the parameter as functional (`0-14, default 7 = 21dB`), making this a silent API contract break. Either remove/default-away the parameter in the header, or apply the enum cast back: `(es7210_gain_value_t)micGain` with `micGain`'s default changed to `4` (i.e., `GAIN_12DB`) in `lxst_audio.h`.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant