feat: integrate chat voice and diagnostics client

This commit is contained in:
Edison Jwa
2026-05-23 06:51:55 +09:00
parent 7e28791ec2
commit 7d5d8c2c90
93 changed files with 10273 additions and 3347 deletions
@@ -17,13 +17,16 @@
// so the engine can hold a single `Box<dyn MobileVoiceAudioBackend>`
// across iOS and Android.
#![allow(dead_code)]
use std::fmt;
use std::sync::atomic::{AtomicBool, AtomicU32};
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc;
use tsclientlib::audio::AudioHandler;
use crate::engine::SessionAudioId;
use crate::AudioEffects;
use chanora_protocol::OutPacket;
/// Events the audio-callback thread or platform JNI listener can post
/// to the tokio side of the engine (SDD-115). Audio callbacks MUST
@@ -63,6 +66,36 @@ pub type BackendEventTx = mpsc::UnboundedSender<BackendEvent>;
/// against the active capture session.
pub type AudioSessionId = i32;
/// Engine-owned state shared with mobile voice audio callbacks.
#[derive(Clone)]
pub(crate) struct VoiceAudioParams {
/// Opus-encoded voice packets sent on this channel toward the
/// protocol layer.
pub voice_out_tx: mpsc::Sender<OutPacket>,
/// PTT transmission gate — true when the user holds the PTT key.
pub transmit_active: Arc<AtomicBool>,
/// Counter incremented per encoded frame sent.
pub frames_sent: Arc<AtomicU32>,
/// Pre-encode amplitude scale (1.0 = unity).
pub mic_gain: f32,
/// AudioHandler that inbound decode+mix feeds into; the output
/// callback pulls mixed stereo f32 from it.
pub handler: Arc<Mutex<AudioHandler<SessionAudioId>>>,
/// Master output gain (f32 bits stored in AtomicU32 for lock-free
/// cross-thread read from the realtime audio callback).
pub output_gain: Arc<AtomicU32>,
/// True = output silence regardless of incoming voice frames.
pub output_muted: Arc<AtomicBool>,
/// Optional TransmitModeSelector for VoiceActivity transmit mode.
/// The capture callback calls set_voice_activity_open on this when
/// VAD detects speech. None means VoiceActivity mode is disabled.
pub voice_activity_selector: Option<Arc<crate::TransmitModeSelector>>,
/// Shared audio-processing config (WebRTC APM flags, VAD backend).
pub audio_processing_config: Arc<Mutex<crate::AudioProcessingConfig>>,
/// Shared audio-processing statistics for diagnostics.
pub audio_processing_stats: Arc<crate::SharedAudioProcessingStats>,
}
/// Achieved performance-mode reported by the platform after stream
/// open (SDD-112 item 4).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -734,12 +767,18 @@ mod tests {
/// open()/start()/stop()/close()).
#[test]
fn swe4_uv_047_backend_error_display() {
assert!(format!("{}", BackendError::OpenFailed("x".into())).contains("open failed"));
assert!(
format!("{}", BackendError::LifecycleFailed("y".into())).contains("lifecycle failed")
);
assert!(format!("{}", BackendError::ErrorDisconnected).contains("disconnected"));
assert!(format!("{}", BackendError::Platform("z".into())).contains("platform"));
assert!(BackendError::OpenFailed("x".into())
.to_string()
.contains("open failed"));
assert!(BackendError::LifecycleFailed("y".into())
.to_string()
.contains("lifecycle failed"));
assert!(BackendError::ErrorDisconnected
.to_string()
.contains("disconnected"));
assert!(BackendError::Platform("z".into())
.to_string()
.contains("platform"));
}
/// SWE4-UV-047: achieved enums Display stably (used in
@@ -748,15 +787,15 @@ mod tests {
#[test]
fn swe4_uv_047_achieved_enum_display_is_stable() {
assert_eq!(
format!("{}", AchievedPerformanceMode::LowLatency),
AchievedPerformanceMode::LowLatency.to_string(),
"LowLatency"
);
assert_eq!(
format!("{}", AchievedPerformanceMode::PowerSaving),
AchievedPerformanceMode::PowerSaving.to_string(),
"PowerSaving"
);
assert_eq!(format!("{}", AchievedPerformanceMode::None), "None");
assert_eq!(format!("{}", AchievedSharingMode::Exclusive), "Exclusive");
assert_eq!(format!("{}", AchievedSharingMode::Shared), "Shared");
assert_eq!(AchievedPerformanceMode::None.to_string(), "None");
assert_eq!(AchievedSharingMode::Exclusive.to_string(), "Exclusive");
assert_eq!(AchievedSharingMode::Shared.to_string(), "Shared");
}
}