Skip to content

Commit

Permalink
Use rational
Browse files Browse the repository at this point in the history
  • Loading branch information
DrPeaboss committed Oct 15, 2024
1 parent dc20bdb commit 01070ce
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 17 deletions.
46 changes: 46 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ repository = "https://github.com/DrPeaboss/simple_src"
keywords = ["audio", "dsp", "sample-rate"]
exclude = ["*.py"]

[dependencies]
num-rational = "0.4"

[dev-dependencies]
divan = "0.1.14"
hound = "3.5.1"
Expand Down
32 changes: 23 additions & 9 deletions src/linear.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Linear converter
use num_rational::Rational64;

use super::{Convert, Error, Result};

enum State {
Expand All @@ -9,18 +11,29 @@ enum State {
}

pub struct Converter {
step: f64,
pos: f64,
numer: usize,
denom: usize,
pos: usize,
coefs: Vec<f64>,
last_in: [f64; 2],
state: State,
}

impl Converter {
#[inline]
fn new(step: f64) -> Self {
let rstep = Rational64::approximate_float(step).unwrap();
let numer = *rstep.numer() as usize;
let denom = *rstep.denom() as usize;
let mut coefs = Vec::with_capacity(denom);
for i in 0..denom {
coefs.push(i as f64 / denom as f64);
}
Self {
step,
pos: 0.0,
numer,
denom,
pos: 0,
coefs,
last_in: [0.0; 2],
state: State::First,
}
Expand All @@ -38,15 +51,15 @@ impl Convert for Converter {
State::First => {
if let Some(s) = iter.next() {
self.last_in[1] = s;
self.pos = 1.0;
self.pos = self.numer;
self.state = State::Normal;
} else {
return None;
}
}
State::Normal => {
while self.pos >= 1.0 {
self.pos -= 1.0;
while self.pos >= self.denom {
self.pos -= self.denom;
self.last_in[0] = self.last_in[1];
if let Some(s) = iter.next() {
self.last_in[1] = s;
Expand All @@ -55,8 +68,9 @@ impl Convert for Converter {
return None;
}
}
let interp = self.last_in[0] + (self.last_in[1] - self.last_in[0]) * self.pos;
self.pos += self.step;
let coef = self.coefs[self.pos];
let interp = self.last_in[0] + (self.last_in[1] - self.last_in[0]) * coef;
self.pos += self.numer;
return Some(interp);
}
State::Suspend => {
Expand Down
29 changes: 21 additions & 8 deletions src/sinc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::collections::VecDeque;
use std::f64::consts::PI;
use std::sync::Arc;

use num_rational::Rational64;

use super::{Convert, Error, Result};

#[inline]
Expand Down Expand Up @@ -82,8 +84,10 @@ enum State {
}

pub struct Converter {
step: f64,
pos: f64,
numer: usize,
denom: usize,
pos: usize,
coefs: Vec<f64>,
half_order: f64,
quan: f64,
filter: Arc<Vec<f64>>,
Expand All @@ -94,12 +98,21 @@ pub struct Converter {
impl Converter {
#[inline]
fn new(step: f64, order: u32, quan: u32, filter: Arc<Vec<f64>>) -> Self {
let rstep = Rational64::approximate_float(step).unwrap();
let numer = *rstep.numer() as usize;
let denom = *rstep.denom() as usize;
let mut coefs = Vec::with_capacity(denom);
for i in 0..denom {
coefs.push(i as f64 / denom as f64);
}
let taps = (order + 1) as usize;
let mut buf = VecDeque::with_capacity(taps);
buf.extend(std::iter::repeat(0.0).take(taps));
Self {
step,
pos: 0.0,
numer,
denom,
pos: 0,
coefs,
half_order: 0.5 * order as f64,
quan: quan as f64,
filter,
Expand All @@ -110,7 +123,7 @@ impl Converter {

#[inline]
fn interpolate(&self) -> f64 {
let coef = self.pos;
let coef = self.coefs[self.pos];
let mut interp = 0.0;
let pos_max = self.filter.len() - 1;
for (i, s) in self.buf.iter().enumerate() {
Expand All @@ -137,8 +150,8 @@ impl Convert for Converter {
loop {
match self.state {
State::Normal => {
while self.pos >= 1.0 {
self.pos -= 1.0;
while self.pos >= self.denom {
self.pos -= self.denom;
if let Some(s) = iter.next() {
self.buf.pop_front();
self.buf.push_back(s);
Expand All @@ -147,8 +160,8 @@ impl Convert for Converter {
return None;
}
}
self.pos += self.step;
let interp = self.interpolate();
self.pos += self.numer;
return Some(interp);
}
State::Suspend => {
Expand Down

0 comments on commit 01070ce

Please sign in to comment.