Skip to content

iOS: DigiRig Data-VOX operation + FT-891 (audio-only, no CAT) - #751

Merged
patrickrb merged 3 commits into
devfrom
feat/ios-digirig-vox
Aug 22, 2026
Merged

iOS: DigiRig Data-VOX operation + FT-891 (audio-only, no CAT)#751
patrickrb merged 3 commits into
devfrom
feat/ios-digirig-vox

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

What

iOS/iPadOS can't access USB-serial CAT, so the FT-891 runs audio-only through a DigiRig with the radio's Data-VOX keying on the transmit audio. This makes that path actually work and adds the FT-891.

  1. Adaptive audio routing (the functional fix). The session was .playAndRecord with .defaultToSpeaker, which pins output to the built-in speaker — so TX audio never reached the DigiRig's USB output and Data-VOX never keyed. New pure AudioSessionPolicy.playAndRecordOptions(usbAudioConnected:) drops .defaultToSpeaker when a USB audio device is present (output follows to the DigiRig, feeding the radio) and keeps it when none is (bare iPhone/iPad RX stays audible — no regression). AudioCaptureService applies it at start() and re-applies on route change so a DigiRig attach/detach flips the behavior; loop-guarded (ignores category/override reasons, only re-sets when options differ), and clears a stuck builtInSpeaker override only while USB is active.
  2. Honest PTT UI. Only VOX is selectable now — CAT/RTS/DTR PTT need a wired CAT link iOS won't allow over USB. The enum cases are kept (a future Wi-Fi/rigctld bridge could use them); a persisted non-VOX value coerces to VOX; a footer explains it.
  3. FT-891 added to the rig picker.
  4. Data-VOX setup hint in Radio & Audio settings (connect DigiRig over USB-C, select as Input + Output, enable Data-VOX + VOX gain on the radio, PTT = VOX).

Tests

597 FT8AFKit tests pass (2 new AudioSessionPolicyTests) + 7 new app tests in a new FT8AFTests target (RigModelTests FT-891 present/round-trip, PttModeTests selectable == [.vox], AudioCaptureSessionOptionsTests neutral→AVAudioSession.CategoryOptions). App builds. xcodegen regenerated for the new file + test target/scheme.

On-device verification pending

USB output routing is device behavior — with a DigiRig + FT-891 attached, confirm TX audio leaves via USB (not the speaker), the FT-891's Data-VOX keys on the FT8 tones, and the transmission is decodable/spotted; and that attach/detach flips output between speaker and USB.

🤖 Generated with Claude Code

iOS can't do USB-serial CAT, so the FT-891 runs audio-only via a DigiRig
with the radio's Data-VOX keying on TX audio. Makes that path actually work:

- Adaptive audio routing (the functional fix): the session forced output to
  the built-in speaker (.defaultToSpeaker), so TX audio never reached the
  DigiRig and Data-VOX never keyed. New pure AudioSessionPolicy drops
  .defaultToSpeaker when a USB audio device is present (output follows to the
  DigiRig, feeding the radio) and keeps it when none is (bare device RX stays
  audible). AudioCaptureService applies it at start and re-applies on route
  change (attach/detach flips it), loop-guarded, clearing a stuck speaker
  override only when USB is active.
- Honest PTT UI: only VOX is offered (CAT/RTS/DTR need a wired CAT link iOS
  won't allow over USB); enum cases kept for a future Wi-Fi/rigctld bridge; a
  persisted non-VOX value coerces to VOX. Footer explains why.
- FT-891 added to the rig picker.
- Data-VOX setup hint in Radio & Audio settings.

597 FT8AFKit tests + 7 new app tests (FT8AFTests target) pass; app builds.
xcodegen regenerated (new AudioSessionPolicy + app test target/scheme).

On-device verification pending: with a DigiRig + FT-891 attached, confirm TX
audio leaves via USB (not speaker), Data-VOX keys, and TX is decodable.

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

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 41.77%. Comparing base (d24b408) to head (cb6f53c).
⚠️ Report is 6 commits behind head on dev.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                dev     #751      +/-   ##
============================================
+ Coverage     41.69%   41.77%   +0.08%     
  Complexity      284      284              
============================================
  Files           278      280       +2     
  Lines         32960    33006      +46     
  Branches       3940     3940              
============================================
+ Hits          13742    13788      +46     
  Misses        18868    18868              
  Partials        350      350              
Flag Coverage Δ
ios 97.70% <100.00%> (+0.01%) ⬆️
native 9.93% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...FT8AFKit/Sources/FT8Audio/AudioSessionPolicy.swift 100.00% <100.00%> (ø)
.../Tests/FT8AudioTests/AudioSessionPolicyTests.swift 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Cold-start USB detection precedes session activation, while legacy non-VOX settings are masked rather than normalized.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Enables iOS DigiRig Data-VOX operation by adapting audio routing and adding FT-891 support.

Changes:

  • Routes TX audio to connected USB interfaces.
  • Restricts iOS PTT selection to VOX and adds setup guidance.
  • Adds FT-891 and app-level tests.
File summaries
File Description
AudioSessionPolicyTests.swift Tests USB routing policy.
AudioSessionPolicy.swift Defines platform-neutral session options.
project.yml Adds the app test target and scheme.
RigModelTests.swift Tests FT-891 persistence.
PttModeTests.swift Tests selectable PTT modes.
AudioCaptureSessionOptionsTests.swift Tests AVFoundation option mapping.
TransmissionSettings.swift Restricts the PTT picker to VOX.
RadioAudioSettings.swift Adds DigiRig setup guidance.
AudioCaptureService.swift Applies routing policy on startup and route changes.
AppState.swift Adds FT-891 and selectable PTT metadata.
FT8AF.xscheme Registers app tests with the scheme.
project.pbxproj Adds generated test-target configuration.
Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ios/FT8AF/FT8AF/Engine/AudioCaptureService.swift Outdated
Comment thread ios/FT8AF/FT8AF/Screens/Settings/TransmissionSettings.swift
Comment thread ios/FT8AF/FT8AF/Engine/AudioCaptureService.swift Outdated
Comment thread ios/FT8AF/FT8AFTests/PttModeTests.swift
patrickrb and others added 2 commits August 22, 2026 11:49
- Bootstrap the session into .playAndRecord (neutral options) and activate
  it BEFORE evaluating USB presence: under the default playback category
  availableInputs/currentRoute list no inputs, so an already-attached
  DigiRig read as absent and .defaultToSpeaker was pinned. Observers are
  now registered before activation so its route change is never missed.
- Move the USB-presence predicate into AudioSessionPolicy over
  AudioPortKind lists (host-tested, one test per detection path) and add
  bootstrapOptions with tests.
- Migrate a persisted CAT/RTS/DTR pttMode to VOX in SettingsPersistence.load
  via PttMode.coercedForIOS, not just in the picker binding; regression
  tests cover the helper and the load path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AudioRouteController is @mainactor, so sharing kind(of:) with the
nonisolated AudioCaptureService.usbAudioPresent failed to compile. The
mapper is pure; mark it nonisolated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@patrickrb
patrickrb merged commit cc40de7 into dev Aug 22, 2026
17 checks passed
@patrickrb
patrickrb deleted the feat/ios-digirig-vox branch August 22, 2026 17:05
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.

2 participants