feat(audio): forward capture-event sink to recording://level/device (T7.3)

start_recording now creates the EventSink alongside the existing frame
channel and forwards Level/DeviceChanged onto a small fire-and-forget
thread that emits "recording://level" and "recording://device".
This commit is contained in:
iamdoubz
2026-07-01 21:09:34 -05:00
parent 098331d6f5
commit fc9c1d9fc2
+37 -1
View File
@@ -222,8 +222,44 @@ pub async fn start_recording(
// Bounded so a slow/stalled transcription worker can never back up the capture thread.
let (frame_tx, frame_rx) = std::sync::mpsc::sync_channel::<Vec<f32>>(8);
// Level updates + device-change notices (FR-CAP-5/6); low-volume, forwarded to events below.
let (event_tx, event_rx) = std::sync::mpsc::sync_channel::<crate::audio::CaptureEvent>(8);
let capture = WasapiCapture
.start(&wav_path, frame_tx)
.start(&wav_path, frame_tx, event_tx)
.map_err(|e| WaError::new("audio", e.to_string()))?;
// Fire-and-forget: exits on its own once `event_tx` drops at capture stop;
// nothing downstream needs to join it.
let app_for_capture_events = app.clone();
let meeting_id_for_capture_events = meeting_id.clone();
std::thread::Builder::new()
.name("wa-capture-events".into())
.spawn(move || {
for event in event_rx {
match event {
crate::audio::CaptureEvent::Level(level) => {
let _ = app_for_capture_events.emit(
"recording://level",
serde_json::json!({
"meetingId": meeting_id_for_capture_events,
"rms": level.rms,
"peak": level.peak,
}),
);
}
crate::audio::CaptureEvent::DeviceChanged { recovered, message } => {
let _ = app_for_capture_events.emit(
"recording://device",
serde_json::json!({
"meetingId": meeting_id_for_capture_events,
"recovered": recovered,
"message": message,
}),
);
}
}
}
})
.map_err(|e| WaError::new("audio", e.to_string()))?;
let segments: Arc<StdMutex<Vec<TranscriptSegment>>> = Arc::new(StdMutex::new(Vec::new()));