Skip to main content

dracon_tts_runtime/
lib.rs

1#![warn(missing_docs)]
2
3//! Dracon TTS Runtime — text-to-speech with Kitten and Kokoro backends.
4//!
5//! ## Engines
6//!
7//! - [`KittenTTS`] — espeak-ng-based TTS (lightweight, no GPU required)
8//! - [`KokoroTts`] — ONNX-based neural TTS (higher quality, GPU preferred)
9//! - [`TtsEngine`] — enum dispatching to either engine
10//!
11//! ## Feature Flags
12//!
13//! - `kitten` — enable Kitten TTS (default)
14//! - `kokoro` — enable Kokoro TTS (requires ort ONNX runtime)
15//!
16//! ## Example
17//!
18//! ```ignore
19//! use dracon_tts_runtime::{TtsEngine, KokoroTts};
20//! let tts = KokoroTts::new(model_path, voices_dir). await?;
21//! tts.speak("Hello world").await;
22//! ```
23
24pub mod contracts;
25pub mod kitten;
26pub mod kokoro;
27
28use anyhow::Result;
29
30pub use contracts::{
31    DynTtsEngine, Gender, SynthesisRequest, SynthesisResult, TextToSpeech, TtsConfig,
32    TtsEngineBase, TtsResult, VoiceInfo, VoiceProvider,
33};
34
35pub use kitten::KittenTTS;
36pub use kokoro::KokoroTts;
37
38#[derive(Clone)]
39pub enum TtsEngine {
40    Kitten(std::sync::Arc<KittenTTS>),
41    Kokoro(std::sync::Arc<KokoroTts>),
42}
43
44impl TtsEngine {
45    pub fn speak(&self, text: &str) -> Result<()> {
46        match self {
47            TtsEngine::Kitten(k) => TextToSpeech::speak(&**k, text),
48            TtsEngine::Kokoro(k) => TextToSpeech::speak(&**k, text),
49        }
50    }
51
52    pub fn stop(&self) -> Result<()> {
53        match self {
54            TtsEngine::Kitten(k) => TextToSpeech::stop(&**k),
55            TtsEngine::Kokoro(k) => TextToSpeech::stop(&**k),
56        }
57    }
58
59    pub fn is_speaking(&self) -> bool {
60        match self {
61            TtsEngine::Kitten(k) => TextToSpeech::is_speaking(&**k),
62            TtsEngine::Kokoro(k) => TextToSpeech::is_speaking(&**k),
63        }
64    }
65
66    pub fn name(&self) -> &'static str {
67        match self {
68            TtsEngine::Kitten(k) => TextToSpeech::name(&**k),
69            TtsEngine::Kokoro(k) => TextToSpeech::name(&**k),
70        }
71    }
72
73    pub async fn speak_nowait(&self, text: &str) {
74        match self {
75            TtsEngine::Kitten(k) => k.speak_nowait(text).await,
76            TtsEngine::Kokoro(k) => k.speak_nowait(text).await,
77        }
78    }
79
80    pub async fn wait_until_done(&self) {
81        match self {
82            TtsEngine::Kitten(k) => k.wait_until_done().await,
83            TtsEngine::Kokoro(k) => k.wait_until_done().await,
84        }
85    }
86}