fix(audio,ios): correct ios_voice_unit imports + iOS stop() field access (rc.8+61)
iOS build of chanora_audio (target aarch64-apple-ios) failed with
four compilation errors after commit 2 landed. Root causes were
all simple symbol-path / cfg-gating mistakes from the skeleton
commit; the underlying design is unchanged.
1. ios_voice_unit.rs: wrong import path for OutPacket. The
chanora_protocol crate re-exports it at the crate root
(`pub use ...::OutPacket` in lib.rs line 52), not from a
`voice` submodule (which doesn't exist).
- use chanora_protocol::voice::OutPacket;
+ use chanora_protocol::OutPacket;
2. ios_voice_unit.rs: LinearPcmFlags lives in
`coreaudio::audio_unit::audio_format`, not in
`stream_format` (the doc page lists it under StreamFormat but
the actual module path is the upstream Apple naming).
- use coreaudio::audio_unit::stream_format::LinearPcmFlags;
+ use coreaudio::audio_unit::audio_format::LinearPcmFlags;
3. ios_voice_unit.rs: `Ordering` import unused (commit 1
skeleton callbacks don't load atomics yet — that comes in
commits 3 + 4). Remove from the std::sync::atomic import to
silence the unused_imports warning.
4. engine.rs::AudioEngine::stop(): the existing body unconditionally
touched self._input_stream and self._output_stream, but commit
2 cfg-gated those fields away on iOS (and added an iOS-only
_ios_voice_unit field in their place). Split the field drop
logic with the same target_os = "ios" cfg so each platform
only touches the fields it actually has.
Also clean up two pre-existing warnings exposed by the iOS cfg
gating:
5. engine.rs: `tracing::{error, warn}` were imported
unconditionally but are only used inside cpal log lines.
Cfg-gate the import to not(target_os = "ios").
6. engine.rs: `AudioData`, `CodecType`, `OutAudio` from
chanora_protocol are only referenced in the Opus encoder feed
inside CaptureState — cpal-side only. Cfg-gate to
not(target_os = "ios"); keep `InboundVoice` + `OutPacket`
on the unconditional path because the inbound forwarder + (in
commit 3) the iOS capture pipeline both reference them.
Also fix a stray duplicate `#[cfg(not(target_os = "ios"))]`
attribute that landed on line 18 in commit 2.
Build verify (Linux host): cargo check -p chanora_audio clean
in 0.53s. iOS-side check pending on Mac.
Build counter bumped 60 -> 61 — the About dialog will display
v1.0.0-rc.8+61 so the user can confirm the build under test
matches this commit.
This commit is contained in:
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.0-rc.8+60
|
||||
version: 1.0.0-rc.8+61
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.5
|
||||
|
||||
@@ -13,9 +13,14 @@ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
use cpal::{SampleFormat, SizedSample};
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
use tracing::{debug, info};
|
||||
// `error!` and `warn!` are used only inside the cpal capture /
|
||||
// playback paths (`build_input_stream`, `build_output_stream`,
|
||||
// `try_open_capture` log lines). Cfg-gate the imports too so iOS
|
||||
// builds don't carry an unused-imports warning.
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
use tracing::{error, warn};
|
||||
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
use audiopus::coder::Encoder as OpusEncoder;
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
@@ -26,9 +31,16 @@ use audiopus::{
|
||||
|
||||
use tsclientlib::audio::AudioHandler;
|
||||
|
||||
use chanora_protocol::{
|
||||
AudioData, CodecType, InboundVoice, OutAudio, OutPacket,
|
||||
};
|
||||
// `AudioData`, `CodecType`, `OutAudio` are referenced only by the
|
||||
// cpal capture pipeline's Opus encode path (`CaptureState::encode_and_send`).
|
||||
// `InboundVoice` + `OutPacket` are used by every platform — the
|
||||
// inbound forwarder task pumps `InboundVoice` into AudioHandler on
|
||||
// iOS too, and `OutPacket` flows out of the capture pipeline once
|
||||
// commit 3 lands. Cfg-gate the cpal-only ones to keep iOS warnings
|
||||
// clean.
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
use chanora_protocol::{AudioData, CodecType, OutAudio};
|
||||
use chanora_protocol::{InboundVoice, OutPacket};
|
||||
|
||||
use crate::AudioError;
|
||||
|
||||
@@ -641,12 +653,24 @@ impl AudioEngine {
|
||||
// The platform PTT backend is no longer owned by the
|
||||
// engine (SDD-088); its lifecycle is managed by
|
||||
// `chanora_core::ptt::PttController`. The engine only
|
||||
// needs to abort its watchdog and drop the cpal streams.
|
||||
// needs to abort its watchdog and drop the audio streams.
|
||||
// Aborting the watchdog cancels its tokio task.
|
||||
self.ptt_watchdog.take();
|
||||
// Drop the streams, which stops their callback threads.
|
||||
// Each platform has a slightly different backend; the
|
||||
// common contract is that dropping the wrapper stops
|
||||
// audio. iOS collapses input + output into one
|
||||
// `IosVoiceUnit` (see `ios_voice_unit.rs`); every other
|
||||
// platform has separate cpal input + cpal/SDL output.
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
let _ = self._input_stream.lock().unwrap().take();
|
||||
let _ = self._output_stream.lock().unwrap().take();
|
||||
}
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
let _ = self._ios_voice_unit.lock().unwrap().take();
|
||||
}
|
||||
info!(target: "chanora_audio", "audio engine stopped");
|
||||
}
|
||||
|
||||
|
||||
@@ -75,14 +75,12 @@
|
||||
//! * AVAudioSession category / mode configuration — Swift owns the
|
||||
//! session (it must be set up before Flutter loads).
|
||||
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use coreaudio::audio_unit::audio_format::LinearPcmFlags;
|
||||
use coreaudio::audio_unit::render_callback::{self, data};
|
||||
use coreaudio::audio_unit::{
|
||||
AudioUnit, Element, SampleFormat, Scope, StreamFormat,
|
||||
};
|
||||
use coreaudio::audio_unit::stream_format::LinearPcmFlags;
|
||||
use coreaudio::audio_unit::{AudioUnit, Element, SampleFormat, Scope, StreamFormat};
|
||||
use coreaudio::audio_unit::IOType;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{info, warn};
|
||||
@@ -90,7 +88,7 @@ use tsclientlib::audio::AudioHandler;
|
||||
|
||||
use crate::engine::SessionAudioId;
|
||||
use crate::AudioError;
|
||||
use chanora_protocol::voice::OutPacket;
|
||||
use chanora_protocol::OutPacket;
|
||||
|
||||
/// 20 ms at 48 kHz mono — one Opus frame's worth of samples.
|
||||
/// Aligning the AudioUnit IO buffer to this frame size keeps the
|
||||
|
||||
Reference in New Issue
Block a user