Skip to content

feat(#4023): add adjustable local audio bridge gain controls - #4024

Open
AI7BQ wants to merge 2 commits into
rigplane:mainfrom
AI7BQ:codex/4023-audio-bridge-gain
Open

AI7BQ wants to merge 2 commits into
rigplane:mainfrom
AI7BQ:codex/4023-audio-bridge-gain

Conversation

@AI7BQ

@AI7BQ AI7BQ commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Scope

Add independent bridge-local gain in dB:

  • Device-to-radio input gain and radio-to-device output gain.
  • Omitted options default to 0 dB; the PCM helper returns the original bytes at 0 dB.
  • Signed 16-bit PCM saturation, including extreme finite positive gains.
  • rigplane audio bridge --input-gain-db / --output-gain-db.
  • rigplane web --bridge-input-gain-db / --bridge-output-gain-db.
  • Effective gains in GET /api/v1/bridge and partial updates through PATCH /api/v1/bridge.
  • Invalid CLI values are rejected by argparse; invalid API values receive 400, and PATCH requires a running bridge (409 otherwise).

This is one semantic unit despite exceeding the six-file soft threshold: the ten files wire the same bridge gain contract through PCM processing, both CLI entry points, the HTTP contract/routing/server, and their existing test files. No unrelated scope-demand or LAN recovery commits are included.

The implementation is ported from the contributor's local commit 408e45308570921eb471b8d4958c3eb623cfc150, onto upstream base d786ffd9f. The port adds tests and corrections for finite-gain overflow and invalid numeric input handling. After independent review, the new gains were made keyword-only on the web startup methods to preserve existing positional arguments.

Verification

  • Relevant local tests or checks run
  • Public/open-core boundary checked
  • Release or migration impact documented if applicable

Executed in the isolated contribution worktree, using uv's Python 3.11.16:

uv run pytest tests/test_audio_bridge.py -q --tb=short -k 'pcm_gain or bridge_gain or applies_output_gain or applies_input_gain or output_gain_does_not'
Result on upstream implementation with feature tests: 9 failed, 72 deselected, for missing gain functionality (expected RED).

uv run pytest tests/test_audio_bridge.py::test_pcm_gain_extreme_finite_values tests/test_cli.py::TestBridgeGainArguments::test_bridge_gain_rejects_non_finite_arguments tests/test_web_server_coverage.py::test_bridge_patch_rejects_invalid_gain_payloads -q --tb=short
Result before edge-case corrections: 14 failed, 7 passed (expected RED).

uv run pytest tests/test_audio_bridge.py tests/test_cli.py tests/test_cli_coverage.py tests/test_web_api_contract.py tests/test_web_server_coverage.py -q --tb=short
Result on initial candidate 40fcec228c1e47d3955cfd8d41fda84f535c3ceb: 585 passed.

uv run pytest tests/test_web_server_coverage.py::test_bridge_methods_preserve_legacy_positional_arguments tests/test_web_server_coverage.py::test_deferred_bridge_preserves_legacy_positional_configuration -q --tb=short
Result before positional-compatibility correction: 3 failed (expected RED).

uv run pytest tests/test_web_server_coverage.py tests/test_cli.py tests/test_cli_coverage.py -q --tb=short
Result after positional-compatibility correction: 473 passed. Audio processing and API-contract files were unchanged by this correction.

uv run ruff check src/rigplane/audio/bridge.py src/rigplane/cli/__init__.py src/rigplane/web/api_contract.py src/rigplane/web/server.py src/rigplane/web/web_routing.py tests/test_audio_bridge.py tests/test_cli.py tests/test_cli_coverage.py tests/test_web_api_contract.py tests/test_web_server_coverage.py
Result: all checks passed.

uv run ruff format --check src/rigplane/audio/bridge.py src/rigplane/cli/__init__.py src/rigplane/web/api_contract.py src/rigplane/web/server.py src/rigplane/web/web_routing.py tests/test_audio_bridge.py tests/test_cli.py tests/test_cli_coverage.py tests/test_web_api_contract.py tests/test_web_server_coverage.py
Result: 10 files already formatted.

uv run mypy --strict src/rigplane/web
Result: success, no issues in 29 source files.

uv run ruff check src/rigplane/web/server.py tests/test_web_server_coverage.py
uv run ruff format --check src/rigplane/web/server.py tests/test_web_server_coverage.py
Result after positional-compatibility correction: lint passed; 2 files already formatted. The web mypy command above also passed again after the correction.

git diff HEAD --check
git diff --cached --check
Result: both passed before commit.

Evidence comes from the commands above, not the historical test counts in the issue. Bridge playback/capture tests use the existing fake audio backend. The tests exercise PCM gain/clipping, bridge-copy isolation, CLI defaults/forwarding, partial HTTP updates, and invalid values.

No dependencies or migration are required. CLI help, bridge parameter docstrings, and the stable HTTP endpoint contract describe the additions.

Required CI is not confirmed green. At head c285856, the commit status API reported quick-v2-observe failed with "Unknown: fork execution is outside this metadata observation." The review observation reported a missing trusted standalone exact-head PASS. The relayed independent PASS comment has author association CONTRIBUTOR, not OWNER/MEMBER/COLLABORATOR; maintainers must resolve trusted review and required CI execution before merge. Metadata publisher success is not evidence that product tests ran. These statuses were established with the GitHub commit status and check-runs APIs.

Frontend/full suites and physical-radio tests were not run locally. No live services were restarted. IC-9700 / ALSA loopback / Dire Wolf validation remains separate: start with output gain -10 dB, measure receive levels, and check decode performance and TX behavior.

Agent Review

  • Independent agent review comment posted before merge
  • Reviewer: gain-verifier (initial review) and gain-delta-verifier (corrected-head delta review). The initial positional-compatibility defect is fixed in c285856.
  • Result: Agent Review: PASS c285856e5ebce7f83b8074d0f830447f086de5ff, relayed independent verdict. Gate eligibility remains a maintainer action because this comment is from a CONTRIBUTOR.
  • If BLOCKED: include concrete problems, file/line references, risks, required
    fixes, and checks to rerun.

Notes

  • Out of scope / follow-ups: frontend gain controls, deployment/service configuration, unrelated scope-demand and LAN recovery work, and hardware acceptance.
  • Please retain maintainer edits on the fork branch. This PR is ready for required CI and independent review, not a request to bypass merge gates.

Port the bridge-local gain implementation from 408e45308570921eb471b8d4958c3eb623cfc150 onto upstream main. Validate finite CLI and API inputs and saturate extreme positive PCM gain without overflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AI7BQ

AI7BQ commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Agent Review: BLOCKED 40fcec2

Relayed verdict from independent verifier gain-verifier: the new gain parameters precede existing positional label/max_retries/retry_base_delay arguments in WebServer.start_audio_bridge and WebServer.defer_audio_bridge_start (src/rigplane/web/server.py, lines 3388 and 3456). Legacy positional calls bind the label as input gain and can raise TypeError. Required fix: preserve the old positional order and add regression tests for both methods; run affected focused tests, scoped Ruff/format, web mypy, and obtain review/CI for the corrected head. Other reviewed gain, isolation, validation, and TX-gate behavior passed focused mutation checks. Correction is in progress; this is not a merge approval.

Keep the existing web bridge startup argument order and make the new gain options keyword-only. Add regression tests for both method signatures and deferred configuration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AI7BQ

AI7BQ commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Agent Review: PASS c285856

Relayed verdict from independent gain-delta-verifier, who did not author the implementation. The previous positional-compatibility finding is fixed: both web bridge startup methods preserve legacy arguments and make gain options keyword-only. In isolated scratch at this exact head, reinstating the old defective parameter order caused all three regression cases to fail; restored signatures passed, as did a nearby default change. The correction log reports 473 server/CLI tests passed. Earlier independent review confirmed the unchanged gain math, saturation, zero bypass, bridge-local isolation, HTTP validation, and TX-gate ordering through focused mutations. Reviewed worktree is clean.

CI is separate and is not confirmed green: quick-v2-observe reports fork execution outside metadata observation; the review observer previously reported a missing trusted exact-head PASS. This code verdict is not a merge authorization. A maintainer must resolve required execution evidence and publish/accept a trusted verdict if this contributor comment is ineligible for the gate. PR body is being updated to reflect the failed/inconclusive CI snapshot.

This branch has not been deployed

No deployments
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.

feat: Add adjustable gain controls to the local audio bridge.

1 participant