SHARE
TWEET

Untitled

a guest Apr 20th, 2019 88 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. fn main() {
  2.     let samples : Vec<f32> = Oscillator::sine().take(20).collect();
  3.     println!("sine:     {:?}", samples);
  4.     let lp_samples : Vec<f32> = butterworth_lowpass(Oscillator::sine(), 5000.0).take(20).collect();
  5.     println!("filtered: {:?}", lp_samples);
  6. }
  7.  
  8.  
  9. struct Oscillator<'a> {
  10.     func: Box<dyn Fn(f32) -> f32 + 'a>,
  11.     phase: f32,
  12.     inc: f32,
  13. }
  14.  
  15. impl<'a> Iterator for Oscillator<'a> {
  16.     type Item = f32;
  17.     fn next(&mut self) -> Option<Self::Item> {
  18.         let wave = (*self.func)(self.phase);
  19.         self.phase += self.inc;
  20.         if self.phase >= 1.0 { self.phase -= 1.0; }
  21.         Some(wave)
  22.     }
  23. }
  24.  
  25. impl<'a> Oscillator<'a> {
  26.     pub fn new< F>(func : F) -> Self where F: Fn(f32)->f32 + 'a {
  27.         Self {
  28.             phase : 0.0,
  29.             inc   : 0.05,
  30.             func  : Box::new(func),
  31.         }
  32.     }
  33.  
  34.     pub fn sine() -> Self {
  35.         use std::f32::consts::PI;
  36.         Self::new ( |phase| (2.0 * PI * phase).sin() )
  37.     }
  38. }
  39.  
  40. struct ButterWorthState {
  41.     b0: f32,
  42.     b1: f32,
  43.     b2: f32,
  44.     a1: f32,
  45.     a2: f32,
  46.     x : [f32; 2],
  47.     y : [f32; 2],
  48. }
  49.  
  50. /// pass the given iterator through a 2nd-order butterworth lowpass filter with the given cutoff frequency
  51. fn butterworth_lowpass<I: Iterator<Item = f32>>(i: I, cutoff: f32) -> impl Iterator<Item = f32> {
  52.     let ita = 1.0 / (std::f32::consts::PI * cutoff / 48000.0).tan();
  53.     let q = 2.0f32.sqrt();
  54.     let b0 = 1.0 / (1.0 + q * ita + ita * ita);
  55.     let b1 = 2.0 * b0;
  56.     let b2 = b0;
  57.     let a1 = 2.0 * (ita * ita - 1.0) * b0;
  58.     let a2 = -(1.0 - q * ita + ita * ita) * b0;
  59.  
  60.     i.scan(ButterWorthState { b0, b1, b2, a1, a2, x: [0.0, 0.0], y: [0.0, 0.0]}, |s, new_sample| {
  61.         let output = s.b0 * new_sample + s.b1 * s.x[0] + s.b2 * s.x[1] + s.a1 * s.y[0] + s.a2 * s.y[1];
  62.         s.x[1] = s.x[0];
  63.         s.x[0] = new_sample;
  64.         s.y[1] = s.y[0];
  65.         s.y[0] = output;
  66.         Some(output)
  67.     })
  68. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top