diff --git a/crates/chanora_audio/src/engine.rs b/crates/chanora_audio/src/engine.rs index aca1ad7..60de397 100644 --- a/crates/chanora_audio/src/engine.rs +++ b/crates/chanora_audio/src/engine.rs @@ -43,6 +43,25 @@ pub struct AudioEngineConfig { /// Initial PTT state. When false the encoder is bypassed and no /// outbound packets are produced. pub ptt_initial: bool, + /// Audio-effect toggles. The struct is honoured by *naming* but + /// the filters themselves are still no-op in Beta — see the + /// crate-level docs and DEC-007/008/009/010. + pub effects: crate::AudioEffects, + /// A.5 mobile: prefer the OS-provided "voice communication" + /// audio source on mobile platforms (Android + /// `MediaRecorder.AudioSource.VOICE_COMMUNICATION`, iOS + /// `AVAudioSession.Mode.voiceChat`). On Linux desktop this is + /// ignored — the DSP chain stays a no-op and we use the + /// default ALSA/PipeWire source. + /// + /// Beta status: the *config flag* is plumbed through every + /// layer; the *Android-side preset switch* is documented but + /// not yet wired through cpal, which currently uses the + /// AAudio default input. RISK-AUDIO-MOBILE-001 tracks this gap. + /// Setting `true` is a forward-compatible no-op for Beta and + /// will become active once cpal exposes input-preset hooks (or + /// when Chanora ships an Oboe-based fork). + pub mobile_voice_preset: bool, } impl Default for AudioEngineConfig { @@ -50,6 +69,8 @@ impl Default for AudioEngineConfig { Self { mic_gain: 1.0, ptt_initial: false, + effects: crate::AudioEffects::default(), + mobile_voice_preset: true, } } } @@ -114,6 +135,36 @@ impl AudioEngine { "starting audio engine" ); + // A.5 mobile-only preset acknowledgement. On Linux desktop + // the flag is ignored; on Android we log it so a future cpal + // / Oboe wiring can be observed in the diagnostic export. + #[cfg(target_os = "android")] + { + if cfg.mobile_voice_preset { + info!( + target: "chanora_audio", + "android: mobile_voice_preset requested (RISK-AUDIO-MOBILE-001 — flag plumbed, switch pending cpal upstream)" + ); + } + if cfg.effects.aec || cfg.effects.noise_suppression { + info!( + target: "chanora_audio", + aec = cfg.effects.aec, + ns = cfg.effects.noise_suppression, + "android: effects requested; awaiting OS-source switch to engage hardware AEC/NS" + ); + } + } + #[cfg(target_os = "ios")] + { + if cfg.mobile_voice_preset { + info!( + target: "chanora_audio", + "ios: voice-chat session mode requested (binding pending — Chanora iOS audio is documented-only for Beta)" + ); + } + } + let ptt = Arc::new(AtomicBool::new(cfg.ptt_initial)); let frames_sent = Arc::new(AtomicU32::new(0)); let frames_received = Arc::new(AtomicU32::new(0));