Add "Direct USB TX" toggle to bypass the mixer on transmit - #722
Open
patrickrb wants to merge 1 commit into
Open
Add "Direct USB TX" toggle to bypass the mixer on transmit#722patrickrb wants to merge 1 commit into
patrickrb wants to merge 1 commit into
Conversation
The direct-libusb TX path (FT8TransmitSignal, selected when audioOutputDeviceId == -1 && usbAudioOutputVendorId != 0) sends the FT8 waveform straight to the USB radio, bypassing Android's shared mixer — so notification and other-app sounds can't be mixed into the transmission and go out on air (the mixer-bleed class of problem behind #597). It was only reachable by picking the "… (USB direct)" row in the Audio Output device picker, indistinguishable at a glance from the AudioManager "USB Audio" entry for the same card. Add a dedicated on/off toggle in Settings → Radio & Audio → Audio that drives the same three persisted config keys the device picker writes, so the two controls stay in sync and it round-trips across restarts. Enabling with no USB sound card present refuses and explains why; enabling requests USB permission like the picker does. Off falls back to the system-default AudioTrack sink. Decision logic is extracted to DirectUsbTx.kt (isDirectUsbTxEnabled / directUsbTxSelection / systemDefaultTxSelection) with DirectUsbTxTest covering both directions and the round-trip; the predicate deliberately mirrors the engine's TX-path branch so they can't drift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #722 +/- ##
============================================
- Coverage 35.98% 35.94% -0.05%
Complexity 289 289
============================================
Files 247 248 +1
Lines 30276 30330 +54
Branches 3989 3994 +5
============================================
+ Hits 10895 10902 +7
- Misses 19032 19079 +47
Partials 349 349
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Direct USB TX on/off toggle in Settings → Radio & Audio → Audio (right under Audio Output).
Why
The direct-libusb TX path already existed in
FT8TransmitSignal(chosen whenaudioOutputDeviceId == -1 && usbAudioOutputVendorId != 0), but the only way to select it was to find the… (USB direct)row in the Audio Output device picker — sitting right next to the AudioManagerUSB Audioentry for the same card, hard to tell apart. The direct path is the robust fix for the mixer-bleed class of problem (other apps' sounds transmitted on air) that the advisory audio-focus work in #597 can only partially mitigate, since notification sounds ignore audio focus.This exposes it as a clear, reversible toggle instead of touching the (working, timing-sensitive) TX pipeline.
How
audioOutputDevice,usbAudioOutputVid,usbAudioOutputPid) the device picker uses, so the two controls stay in sync and the setting round-trips across restarts.DirectUsbTx.kt(isDirectUsbTxEnabled/directUsbTxSelection/systemDefaultTxSelection) — pure functions, unit-tested. The enable predicate deliberately mirrors the engine's TX-path branch condition so the two can't drift.Testing
DirectUsbTxTestcovers the on/off predicate (including the deviceId-is-−1-but-no-VID edge) and the round-trip of each selection back through the predicate. Passes../gradlew assembleDebugclean.🤖 Generated with Claude Code