Guest User

Untitled

a guest
Apr 20th, 2019
90
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