feat(ios,p0): iOS P0 platform, audio fixes, channel UX
This commit is contained in:
@@ -216,12 +216,7 @@ impl AudioEngine {
|
||||
// other platform stays on the cpal / SDL flow below.
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
return Self::start_with_gate_ios(
|
||||
cfg,
|
||||
voice_out_tx,
|
||||
voice_in_rx,
|
||||
transmit_gate,
|
||||
);
|
||||
return Self::start_with_gate_ios(cfg, voice_out_tx, voice_in_rx, transmit_gate);
|
||||
}
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
@@ -684,6 +679,55 @@ impl AudioEngine {
|
||||
info!(target: "chanora_audio", "audio engine stopped");
|
||||
}
|
||||
|
||||
/// iOS-only: restart the underlying VoiceProcessingIO unit after
|
||||
/// route changes.
|
||||
pub fn ios_restart_voice_unit(&self) -> Result<(), AudioError> {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
let mut guard = self._ios_voice_unit.lock().unwrap();
|
||||
let unit = guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| AudioError::Backend("ios voice unit not running".to_string()))?;
|
||||
return unit.restart();
|
||||
}
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// iOS-only: pause the underlying VoiceProcessingIO unit.
|
||||
pub fn ios_pause_voice_unit(&self) -> Result<(), AudioError> {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
let mut guard = self._ios_voice_unit.lock().unwrap();
|
||||
let unit = guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| AudioError::Backend("ios voice unit not running".to_string()))?;
|
||||
return unit.pause();
|
||||
}
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// iOS-only: resume the underlying VoiceProcessingIO unit.
|
||||
pub fn ios_resume_voice_unit(&self) -> Result<(), AudioError> {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
let mut guard = self._ios_voice_unit.lock().unwrap();
|
||||
let unit = guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| AudioError::Backend("ios voice unit not running".to_string()))?;
|
||||
return unit.resume();
|
||||
}
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the **transmission gate** (SRS-201). When true the
|
||||
/// encoder feed is allowed to emit Opus frames; when false the
|
||||
/// captured audio is discarded before encoding. This is the
|
||||
@@ -768,8 +812,7 @@ impl AudioEngine {
|
||||
/// sensible range internally.
|
||||
pub fn set_output_gain(&self, gain: f32) {
|
||||
let clamped = gain.clamp(0.0, 4.0);
|
||||
self.output_gain
|
||||
.store(clamped.to_bits(), Ordering::Relaxed);
|
||||
self.output_gain.store(clamped.to_bits(), Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Current master output gain.
|
||||
@@ -818,12 +861,8 @@ fn try_open_capture(
|
||||
in_stream_cfg.buffer_size = cpal::BufferSize::Default;
|
||||
}
|
||||
|
||||
let mut opus_enc = OpusEncoder::new(
|
||||
OpusSampleRate::Hz48000,
|
||||
OpusChannels::Mono,
|
||||
OpusApp::Voip,
|
||||
)
|
||||
.map_err(|e| AudioError::Opus(format!("encoder new: {e}")))?;
|
||||
let mut opus_enc = OpusEncoder::new(OpusSampleRate::Hz48000, OpusChannels::Mono, OpusApp::Voip)
|
||||
.map_err(|e| AudioError::Opus(format!("encoder new: {e}")))?;
|
||||
|
||||
// Opus VOIP tuning. Defaults give us 'auto' bitrate (can drop
|
||||
// to ~6 kbps during silence \u2014 which sounds garbled when
|
||||
@@ -1147,13 +1186,12 @@ where
|
||||
// `same_rate` is the common case where the device is already at
|
||||
// 48 kHz — bypass the resampler entirely.
|
||||
let same_rate = dev_sample_rate == SAMPLE_RATE;
|
||||
let resample_state: Arc<Mutex<PlaybackResampleState>> = Arc::new(Mutex::new(
|
||||
PlaybackResampleState {
|
||||
let resample_state: Arc<Mutex<PlaybackResampleState>> =
|
||||
Arc::new(Mutex::new(PlaybackResampleState {
|
||||
pos: 0.0,
|
||||
last_l: 0.0,
|
||||
last_r: 0.0,
|
||||
},
|
||||
));
|
||||
}));
|
||||
// Reusable scratch buffer for 48 kHz stereo samples coming out
|
||||
// of AudioHandler. Allocating a fresh `Vec` per cpal callback on
|
||||
// glibc malloc was costing measurable time on the realtime audio
|
||||
|
||||
Reference in New Issue
Block a user