feat(audio,ios): AVAudioSession PlayAndRecord+voiceChat in AppDelegate
iOS AVAudioSession must be configured BEFORE Flutter starts its
audio pipeline; the canonical place is application(_:didFinishLaunching\
WithOptions:) in AppDelegate.swift. This commit:
apps/chanora_flutter/ios/Runner/AppDelegate.swift:
* import AVFoundation
* In application(_:didFinishLaunchingWithOptions:), call
AVAudioSession.sharedInstance().setCategory(.playAndRecord,
mode: .voiceChat,
options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
followed by setActive(true). Failures are NSLogged but do not
block app launch — cpal's CoreAudio backend will still come up
against the default iOS routing.
This shape:
* routes the receiver/speaker like a phone call (.playAndRecord +
.voiceChat),
* engages on-device AEC / NS where supported,
* defaults to speaker so users don't have to hold the phone to
their ear,
* permits Bluetooth headsets (AirPods et al. just work).
crates/chanora_audio/src/engine.rs:
* Replace the iOS engine-start placeholder log line ('binding
pending — Chanora iOS audio is documented-only for Beta') with
an honest acknowledgment that the AVAudioSession configuration
lives Swift-side. The Rust engine acknowledges the request, then
cpal opens its CoreAudio streams against the session.
iOS-only Rust code is #[cfg(target_os = "ios")]-gated so this commit
is no-op on every other platform.
SRS-197: iOS/macOS audio routing contract. DEC-025: iOS officially
in scope for P0 (Focused PTT only — Apple's sandbox model has no
global PTT analogue).
This commit is contained in:
@@ -261,9 +261,25 @@ impl AudioEngine {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
if cfg.mobile_voice_preset {
|
||||
// iOS AVAudioSession configuration is performed
|
||||
// Swift-side in `apps/chanora_flutter/ios/Runner/
|
||||
// AppDelegate.swift::application(_:didFinishLaunching\
|
||||
// WithOptions:)` BEFORE Flutter starts its audio
|
||||
// pipeline. The category/mode set there
|
||||
// (`.playAndRecord` + `.voiceChat`,
|
||||
// `defaultToSpeaker | allowBluetooth |
|
||||
// allowBluetoothA2DP`) is the recommended iOS shape
|
||||
// for voice clients and engages on-device AEC / NS
|
||||
// routing where supported. cpal's CoreAudio
|
||||
// backend then opens its streams against that
|
||||
// session and inherits the routing. Logging here
|
||||
// just records that the engine-start path
|
||||
// acknowledges the request; the actual session
|
||||
// mutation lives in Swift because it must happen
|
||||
// before Dart loads.
|
||||
info!(
|
||||
target: "chanora_audio",
|
||||
"ios: voice-chat session mode requested (binding pending — Chanora iOS audio is documented-only for Beta)"
|
||||
"ios: voice-chat session mode requested — AVAudioSession configured in AppDelegate"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user