use crate::{
audio::{
load::{LoadedAudioModel, base_load_model},
tts::model::TtsModel,
},
error::Result,
};
pub const MODEL_REMAPPING: &[(&str, &str)] = &[
("qwen3_tts", "qwen3_tts"),
("outetts", "outetts"),
("spark", "spark"),
("marvis", "sesame"),
("csm", "sesame"),
("voxcpm", "voxcpm"),
("voxcpm1.5", "voxcpm"),
("voxcpm2", "voxcpm2"),
("vibevoice_streaming", "vibevoice"),
("chatterbox_turbo", "chatterbox_turbo"),
("soprano", "soprano"),
("bailingmm", "bailingmm"),
("kitten", "kitten_tts"),
("echo_tts", "echo_tts"),
("fish_qwen3_omni", "fish_qwen3_omni"),
("irodori_tts", "irodori_tts"),
("voxtral_tts", "voxtral_tts"),
("kugelaudio", "kugelaudio"),
("audiodit", "longcat_audiodit"),
("longcat", "longcat_audiodit"),
("omnivoice", "omnivoice"),
("melotts", "melotts"),
("moss_tts_nano", "moss_tts_nano"),
("moss_tts_delay", "moss_tts"),
("moss_tts_local", "moss_tts"),
];
pub fn load_model<F>(path: &str, constructor: F) -> Result<Box<dyn TtsModel>>
where
F: FnOnce(LoadedAudioModel) -> Result<Box<dyn TtsModel>>,
{
let bundle = base_load_model(path)?;
constructor(bundle)
}
pub fn load<F>(path: &str, constructor: F) -> Result<Box<dyn TtsModel>>
where
F: FnOnce(LoadedAudioModel) -> Result<Box<dyn TtsModel>>,
{
load_model(path, constructor)
}
#[cfg(test)]
mod tests {
use super::*;
use std::{fs, path::PathBuf};
struct FakeTts;
impl TtsModel for FakeTts {
fn sample_rate(&self) -> u32 {
24_000
}
}
fn temp_dir(name: &str) -> PathBuf {
let dir = std::env::temp_dir().join(format!(
"mlxrs_audio_tts_load_{}_{}",
std::process::id(),
name
));
let _ = fs::remove_dir_all(&dir);
fs::create_dir_all(&dir).unwrap();
dir
}
#[test]
fn load_tts_constructs_via_factory() {
let dir = temp_dir("constructs_via_factory");
let body = r#"{ "model_type": "kokoro" }"#;
fs::write(dir.join("config.json"), body).unwrap();
let captured: std::cell::RefCell<Option<PathBuf>> = std::cell::RefCell::new(None);
let model = load(&dir.to_string_lossy(), |bundle| {
*captured.borrow_mut() = Some(bundle.model_path().to_path_buf());
Ok(Box::new(FakeTts))
})
.expect("load constructs via the supplied factory");
assert_eq!(captured.into_inner().unwrap(), dir);
assert_eq!(model.sample_rate(), 24_000);
}
}