From ea465fe923c07876589a55f0cfcae8b78bd3ebe2 Mon Sep 17 00:00:00 2001 From: cm-ayf Date: Sat, 26 Jul 2025 12:23:57 +0900 Subject: [PATCH 1/2] introduce CoefficientsSession --- src/vocoder/coefficients.rs | 49 ++++++++++++++++++++++++++++++++++--- src/vocoder/mod.rs | 43 ++++++++++++-------------------- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/vocoder/coefficients.rs b/src/vocoder/coefficients.rs index 22c130cb..24627888 100644 --- a/src/vocoder/coefficients.rs +++ b/src/vocoder/coefficients.rs @@ -57,7 +57,13 @@ impl CoefficientsT for GeneralizedCoefficients { } } -pub trait CoefficientsT: Buffer { +impl Generalized for GeneralizedCoefficients { + fn gamma(&self) -> f64 { + self.gamma + } +} + +pub trait CoefficientsT: Buffer + Sized { type Cep: CepstrumT; fn to_cep(&self, alpha: f64) -> Self::Cep; @@ -76,10 +82,45 @@ pub trait CoefficientsT: Buffer { let ir = self.b2mc(alpha).freqt(576 - 1, -alpha).c2ir(576); ir.iter().map(|x| x * x).sum() } + + fn start(&mut self, target: Self, fperiod: usize) -> CoefficientsSession<'_, Self> { + let increment = self + .iter() + .zip(&target[..self.len()]) + .map(|(current, target)| (target - current) / fperiod as f64) + .collect(); + CoefficientsSession { + current: self, + increment, + target, + } + } } -impl Generalized for GeneralizedCoefficients { - fn gamma(&self) -> f64 { - self.gamma +pub struct CoefficientsSession<'a, T: CoefficientsT> { + current: &'a mut T, + increment: Vec, + target: T, +} + +impl<'a, T: CoefficientsT> CoefficientsSession<'a, T> { + pub fn advance(&mut self) { + for (current, inc) in self.current.iter_mut().zip(&self.increment) { + *current += inc; + } + } +} + +impl Deref for CoefficientsSession<'_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.current + } +} + +impl Drop for CoefficientsSession<'_, T> { + fn drop(&mut self) { + self.current.copy_from_slice(&self.target); } } diff --git a/src/vocoder/mod.rs b/src/vocoder/mod.rs index 83c00d03..26859090 100644 --- a/src/vocoder/mod.rs +++ b/src/vocoder/mod.rs @@ -2,7 +2,10 @@ #![allow(missing_docs)] -use crate::constants::{MAX_LF0, MIN_LF0, NODATA}; +use crate::{ + constants::{MAX_LF0, MIN_LF0, NODATA}, + vocoder::coefficients::CoefficientsT, +}; #[macro_use] mod buffer; @@ -116,28 +119,21 @@ impl Vocoder { let mut cepstrum = MelCepstrum::new(spectrum, self.alpha); cepstrum.postfilter_mcp(self.beta); let cc = cepstrum.mc2b(); - let cinc: Vec<_> = cc - .iter() - .zip(coefficients.iter()) - .map(|(cc, c)| (cc - c) / self.fperiod as f64) - .collect(); + let mut coefficients = coefficients.start(cc, self.fperiod); self.excitation.start(p, self.fperiod); - (0..self.fperiod).for_each(|i| { + for r in &mut rawdata[..self.fperiod] { let mut x = self.excitation.get(lpf); if x != 0.0 { x *= coefficients[0].exp(); } - filter.df(&mut x, self.alpha, coefficients); - for i in 0..coefficients.len() { - coefficients[i] += cinc[i]; - } - rawdata[i] = x * self.volume; - }); + filter.df(&mut x, self.alpha, &coefficients); + coefficients.advance(); + *r = x * self.volume; + } self.excitation.end(p); - *coefficients = cc; } Stage::NonZero { stage, @@ -153,26 +149,19 @@ impl Vocoder { for i in 1..cc.len() { cc[i] *= gamma; } - let cinc: Vec<_> = cc - .iter() - .zip(coefficients.iter()) - .map(|(cc, c)| (cc - c) / self.fperiod as f64) - .collect(); + let mut coefficients = coefficients.start(cc, self.fperiod); self.excitation.start(p, self.fperiod); - (0..self.fperiod).for_each(|i| { + for r in &mut rawdata[..self.fperiod] { let mut x = self.excitation.get(lpf); x *= coefficients[0]; - filter.df(&mut x, self.alpha, coefficients); - for i in 0..coefficients.len() { - coefficients[i] += cinc[i]; - } - rawdata[i] = x * self.volume; - }); + filter.df(&mut x, self.alpha, &coefficients); + coefficients.advance(); + *r = x * self.volume; + } self.excitation.end(p); - *coefficients = cc; } } } From 91c6418ee62ed5f3ee22aba71ec74c2e7dc28554 Mon Sep 17 00:00:00 2001 From: cm-ayf Date: Sat, 26 Jul 2025 12:28:03 +0900 Subject: [PATCH 2/2] fix import position --- src/vocoder/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vocoder/mod.rs b/src/vocoder/mod.rs index 26859090..8c801612 100644 --- a/src/vocoder/mod.rs +++ b/src/vocoder/mod.rs @@ -2,10 +2,7 @@ #![allow(missing_docs)] -use crate::{ - constants::{MAX_LF0, MIN_LF0, NODATA}, - vocoder::coefficients::CoefficientsT, -}; +use crate::constants::{MAX_LF0, MIN_LF0, NODATA}; #[macro_use] mod buffer; @@ -20,6 +17,7 @@ mod stage; use self::{ cepstrum::{CepstrumT, MelCepstrum}, + coefficients::CoefficientsT, excitation::Excitation, generalized::Generalized, lsp::LineSpectralPairs,