This commit is contained in:
2026-10-30 10:37:29 +07:00
parent af2a276b1b
commit 6ce20927ee
9 changed files with 205 additions and 32 deletions
+1
View File
@@ -11,6 +11,7 @@ gpui.workspace = true
gpui-kit = { workspace = true, features = ["speech"] }
flume.workspace = true
instant.workspace = true
tts.workspace = true
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
common = { path = "../common" }
+1
View File
@@ -2,6 +2,7 @@
pub mod model;
#[cfg(not(target_arch = "wasm32"))]
mod parakeet;
pub mod speaker;
#[cfg(target_arch = "wasm32")]
mod web;
+47
View File
@@ -0,0 +1,47 @@
use tts::Tts;
/// Reads text aloud through the platform's speech backend, created on first use.
pub struct Speaker {
tts: Option<Tts>,
}
impl Default for Speaker {
fn default() -> Self {
Self::new()
}
}
impl Speaker {
pub fn new() -> Self {
Self { tts: None }
}
/// Speak the text, interrupting what this speaker is already saying.
pub fn speak(&mut self, text: &str) -> Result<(), tts::Error> {
let tts = match self.tts.as_ref() {
Some(tts) => tts,
None => self.tts.insert(Tts::default()?),
};
tts.speak(text, true)?;
Ok(())
}
/// Stop speaking; a speaker that never spoke is already silent.
pub fn stop(&mut self) -> Result<(), tts::Error> {
match self.tts.as_ref() {
Some(tts) => tts.stop()?,
None => return Ok(()),
}
Ok(())
}
/// Best-effort speaking state; a speaker that never spoke is silent.
pub fn speaking(&self) -> bool {
self.tts
.as_ref()
.and_then(|tts| tts.is_speaking().ok())
.unwrap_or(false)
}
}