feat: add more synthesize options

This commit is contained in:
kimpure 2026-07-19 09:02:02 +00:00
parent 872d807a72
commit cad1970fe4
No known key found for this signature in database
3 changed files with 47 additions and 14 deletions

View file

@ -27,16 +27,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
.ok() .ok()
.and_then(|v| v.parse().ok()) .and_then(|v| v.parse().ok())
.unwrap_or(1.05); .unwrap_or(1.05);
let silence_duration: f32 = std::env::var("SUPERTONIC_SILENCE_DUR") let silence_before_duration: f32 = std::env::var("SUPERTONIC_SILENCE_BEFORE_DUR")
.ok() .ok()
.and_then(|v| v.parse().ok()) .and_then(|v| v.parse().ok())
.unwrap_or(0.3); .unwrap_or(0.0);
let silence_in_content_duration: f32 = std::env::var("SUPERTONIC_SILENCE_IN_CONTENT_DUR")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(0.26);
let silence_after_duration: f32 = std::env::var("SUPERTONIC_SILENCE_AFTER_DUR")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(0.4);
let workers: usize = std::env::var("SUPERTONIC_WORKERS") let workers: usize = std::env::var("SUPERTONIC_WORKERS")
.ok() .ok()
.and_then(|v| v.parse().ok()) .and_then(|v| v.parse().ok())
.unwrap_or(2); .unwrap_or(2);
let hf_repo = std::env::var("SUPERTONIC_HF_REPO") let hf_repo = std::env::var("SUPERTONIC_HF_REPO")
.unwrap_or_else(|_| "https://huggingface.co/Supertone/supertonic-3".to_string()); .unwrap_or_else(|_| "https://huggingface.co/Supertone/supertonic-3".to_string());
let sound_size_mul: f32 = std::env::var("SUPERTONIC_SIZE_MUL")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(1.5);
let model_path = PathBuf::from(&model_dir); let model_path = PathBuf::from(&model_dir);
tts::assets::ensure_assets(&model_path, &hf_repo)?; tts::assets::ensure_assets(&model_path, &hf_repo)?;
@ -66,7 +78,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
TtsOpts { TtsOpts {
total_step, total_step,
speed, speed,
silence_duration, silence_in_content_duration,
silence_before_duration,
silence_after_duration,
sound_size_mul,
}, },
)?); )?);

View file

@ -189,7 +189,10 @@ impl TextToSpeech {
style: &Style, style: &Style,
total_step: usize, total_step: usize,
speed: f32, speed: f32,
silence_duration: f32, silence_in_content_duration: f32,
silence_before_duration: f32,
silence_after_duration: f32,
sound_size_mul: f32,
) -> Result<(Vec<f32>, f32)> { ) -> Result<(Vec<f32>, f32)> {
let max_len = if lang == "ko" || lang == "ja" { let max_len = if lang == "ko" || lang == "ja" {
120 120
@ -198,8 +201,13 @@ impl TextToSpeech {
}; };
let chunks = chunk_text(text, Some(max_len)); let chunks = chunk_text(text, Some(max_len));
let mut wav_cat: Vec<f32> = Vec::new(); let before_slience_len = (silence_before_duration * self.sample_rate as f32) as usize;
let mut dur_cat: f32 = 0.0; let after_slience_len = (silence_after_duration * self.sample_rate as f32) as usize;
let content_silence_len = (silence_in_content_duration * self.sample_rate as f32) as usize;
let content_silence = vec![0.0f32; content_silence_len];
let after_slience = vec![0.0f32; after_slience_len];
let mut wav_cat: Vec<f32> = vec![0.0f32; before_slience_len];
let mut dur_cat: f32 = silence_before_duration + silence_after_duration;
for (i, chunk) in chunks.iter().enumerate() { for (i, chunk) in chunks.iter().enumerate() {
let (wav, duration) = self.infer( let (wav, duration) = self.infer(
@ -216,14 +224,18 @@ impl TextToSpeech {
if i == 0 { if i == 0 {
wav_cat.extend_from_slice(wav_chunk); wav_cat.extend_from_slice(wav_chunk);
dur_cat = dur; dur_cat += dur;
} else { } else {
let silence_len = (silence_duration * self.sample_rate as f32) as usize; wav_cat.extend_from_slice(&content_silence);
let silence = vec![0.0f32; silence_len];
wav_cat.extend_from_slice(&silence);
wav_cat.extend_from_slice(wav_chunk); wav_cat.extend_from_slice(wav_chunk);
dur_cat += silence_duration + dur; dur_cat += silence_in_content_duration + dur;
}
}
wav_cat.extend_from_slice(&after_slience);
if sound_size_mul != 1.0f32 {
for inner in wav_cat.iter_mut() {
*inner *= sound_size_mul;
} }
} }

View file

@ -13,7 +13,10 @@ use super::wav::wav_bytes;
pub struct TtsOpts { pub struct TtsOpts {
pub total_step: usize, pub total_step: usize,
pub speed: f32, pub speed: f32,
pub silence_duration: f32, pub silence_in_content_duration: f32,
pub silence_before_duration: f32,
pub silence_after_duration: f32,
pub sound_size_mul: f32,
} }
pub struct TtsJob { pub struct TtsJob {
@ -72,7 +75,10 @@ impl TtsPool {
&style, &style,
opts.total_step, opts.total_step,
opts.speed, opts.speed,
opts.silence_duration, opts.silence_in_content_duration,
opts.silence_before_duration,
opts.silence_after_duration,
opts.sound_size_mul,
) )
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
wav_bytes(&wav, tts.sample_rate).map_err(|e| e.to_string()) wav_bytes(&wav, tts.sample_rate).map_err(|e| e.to_string())