tts: add an audio output port, and feed TTS utterances into it

This commit is contained in:
2026-06-08 15:59:25 +02:00
parent 34d58e5d66
commit 16c6cc7001
3 changed files with 62 additions and 10 deletions
+34 -2
View File
@@ -1,4 +1,4 @@
use jack::{AudioIn, ClientOptions};
use jack::{AudioIn, AudioOut, ClientOptions};
use oximedia_metering::vu_meter::VuMeter;
use tokio::sync::*;
@@ -32,15 +32,23 @@ pub struct MicStream {
pub sample_rate: u32
}
pub async fn start_audio_input(messages: &mpsc::Sender<String>) -> (AudioInputControl, MicStream) {
#[derive(Debug)]
pub struct TtsOutStream {
pub sink: mpsc::Sender<Vec<f32>>,
pub sample_rate: u32
}
pub async fn start_audio_input(messages: &mpsc::Sender<String>) -> (AudioInputControl, MicStream, TtsOutStream) {
let (exit_tx, exit_rx) = oneshot::channel();
let (mic_audio_sink, mic_audio_src) = mpsc::channel(32);
let (tts_audio_sink, mut tts_audio_src) = mpsc::channel(32);
let (volume_sink, volume_src) = watch::channel(0.);
let (client, _status) = jack::Client::new("Eva-Cohost", ClientOptions::default() | ClientOptions::SESSION_ID).unwrap();
let mic_port = client.register_port("microphone-in", AudioIn::default()).unwrap();
let mut tts_port = client.register_port("tts-out", AudioOut::default()).unwrap();
let rate = client.sample_rate();
if let Ok(_) = client.connect_ports_by_name("mixxx-mic-1:capture_MONO", mic_port.name().unwrap().as_str()) {
@@ -50,6 +58,8 @@ pub async fn start_audio_input(messages: &mpsc::Sender<String>) -> (AudioInputCo
}
let mut meter = VuMeter::new(rate.into(), 1, None);
let mut tts_output_buf = vec![];
tts_output_buf.reserve(1024);
let handler = jack::contrib::ClosureProcessHandler::new(move |_client, scope| {
if mic_port.connected_count().unwrap() > 0 {
@@ -67,6 +77,25 @@ pub async fn start_audio_input(messages: &mpsc::Sender<String>) -> (AudioInputCo
}
});
}
if let Ok(mut next_outbuf) = tts_audio_src.try_recv() {
tts_output_buf.append(&mut next_outbuf);
}
if tts_port.connected_count().unwrap() > 0 && !tts_output_buf.is_empty() {
let outbuf = tts_port.as_mut_slice(scope);
let mut next_segment: Vec<f32> = tts_output_buf.drain(0..(outbuf.len()).min(tts_output_buf.len())).collect();
let underrun = outbuf.len() - next_segment.len();
if underrun > 0 {
for _ in 0..underrun {
next_segment.push(0.);
}
}
outbuf.copy_from_slice(&next_segment);
}
jack::Control::Continue
});
@@ -84,5 +113,8 @@ pub async fn start_audio_input(messages: &mpsc::Sender<String>) -> (AudioInputCo
}, MicStream {
sample_rate: rate,
src: mic_audio_src
}, TtsOutStream {
sample_rate: rate,
sink: tts_audio_sink
})
}