main.rs (3012B)
1 use aerothesis::Aerothesis; 2 use nih_plug::prelude::util; 3 use rustfft::{num_complex::Complex, FftPlanner}; 4 use textplots::{Chart, Plot, Shape}; 5 6 fn main() -> Result<(), Box<dyn std::error::Error>> { 7 let mut plugin = Aerothesis::default(); 8 let sample_rate = 44100.0; 9 let seconds = 1.0; 10 let num_samples = (sample_rate * seconds) as usize; 11 12 plugin.sample_rate = sample_rate; 13 plugin.note_frequency = util::midi_note_to_freq(60); // C4 (u8) 14 // plugin.note_frequency = util::midi_note_to_freq(54); // F#3 (u8) 15 16 // For simulation in main.rs, we use the default parameters from AerothesisParams::default() 17 // because nih-plug parameters are designed to be managed by a host and don't have 18 // simple setter methods for plain values without a ParamSetter context. 19 // Default resonance: OpenPipe, Decay: 0.9 20 21 let mut displacements = Vec::with_capacity(num_samples); 22 let mut osc = Vec::with_capacity(num_samples); 23 24 for i in 0..num_samples { 25 // let x_current = self.resonance() - self.avg_x_history(); 26 27 // for sample in channel_samples { 28 // *sample = (x_current * gain).clamp(-1.0, 1.0); 29 // } 30 31 // Simple attack envelope for breath pressure 32 plugin.v_breath = if i < 2000 { 33 (i as f32 / 2000.0) * 100.0 34 } else { 35 100.0 36 }; 37 38 let sample = plugin.displacement() - plugin.avg_x_history(); 39 osc.push(plugin.osc_x()); 40 displacements.push(sample); 41 } 42 43 let len = (sample_rate * 0.05) as usize; 44 45 let data: Vec<(f32, f32)> = (0..len) 46 .map(|i| (i as f32, displacements[i + (sample_rate * 0.1) as usize])) 47 .collect(); 48 49 println!("--- Waveform ---"); 50 Chart::new(360, 60, 0.0, len as f32) 51 .lineplot(&Shape::Lines(&data)) 52 .display(); 53 54 let fft_len = displacements.len().next_power_of_two(); 55 let mut planner = FftPlanner::new(); 56 let fft = planner.plan_fft_forward(fft_len); 57 58 let mut buffer: Vec<Complex<f32>> = displacements 59 .iter() 60 .map(|&s| Complex { re: s, im: 0.0 }) 61 .collect(); 62 buffer.resize(fft_len, Complex { re: 0.0, im: 0.0 }); 63 64 fft.process(&mut buffer); 65 66 let mut spectrum_data = Vec::with_capacity(fft_len / 2); 67 for (i, complex) in buffer.iter().enumerate().take(fft_len / 2) { 68 let freq = (i as f32 * sample_rate) / fft_len as f32; 69 if freq > 2000.0 { 70 break; 71 } 72 spectrum_data.push((freq, complex.norm())); 73 } 74 if let Some(max) = spectrum_data 75 .iter() 76 .enumerate() 77 .max_by(|(_, a), (_, b)| a.1.partial_cmp(&b.1).unwrap()) 78 { 79 println!("max freq is {} Hz", max.0); 80 } 81 82 println!("\n--- Spectrum (0 - 2000Hz) ---"); 83 Chart::new(180, 60, 0.0, 2000.0) 84 .lineplot(&Shape::Lines(&spectrum_data)) 85 .display(); 86 87 Ok(()) 88 }