Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions src/vocoder/coefficients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<f64>,
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<T: CoefficientsT> Deref for CoefficientsSession<'_, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
self.current
}
}

impl<T: CoefficientsT> Drop for CoefficientsSession<'_, T> {
fn drop(&mut self) {
self.current.copy_from_slice(&self.target);
}
}
39 changes: 13 additions & 26 deletions src/vocoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod stage;

use self::{
cepstrum::{CepstrumT, MelCepstrum},
coefficients::CoefficientsT,
excitation::Excitation,
generalized::Generalized,
lsp::LineSpectralPairs,
Expand Down Expand Up @@ -116,28 +117,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,
Expand All @@ -153,26 +147,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;
}
}
}
Expand Down
Loading