mod notes; mod proc; mod outputers; mod buf; mod rfft; mod args; use crate::notes::{Notes, note_range, ProcerNotes}; use crate::proc::{Procer, ProcerData}; use crate::rfft::RFftProcer; use crate::buf::{StaticBuffer, Procers}; use crate::outputers::{Outputers, SimpleOutputer, LineLayout}; use crate::args::SimpleArgs; use clap::{Parser, CommandFactory, FromArgMatches}; //use std::collections::VecDeque; fn main() { const CHANNELS: u32 = 2; const PERIOD_SIZE: usize = 240; // 1024 frames const PROC_SIZE: usize = 1 << 14; // 16k frames (so about .3413_ of a second) //let disp_threshold = 0.00372314453125; //let disp_threshold = 0.00526532149076897; //let disp_threshold = 50. / (i16::MAX as f32); //const PERIOD_SIZE: usize = 480; //const PROC_SIZE: usize = 1 << 13; // 8k //let period_size = 1024; let sample_rate = 48000; //let proc_size = 1 << 14; // 16k (so about .3413_ of a second) // we update every period_size so it updates every 21.3_ms but we keep a running average of the // last 341.3_ms so low frequencies can be interpreted with the fft (using fir or iir filters // or wavelets or inner product spaces and frames is something to do in the future, but for now i'm just // porting older python code over for performance that used ffts, and maybe messing with dct // but it'll have the same limitations of ffts mostly probably) let notes = note_range((Notes::C, 2), (Notes::E, 7)); // US and prob BS here should be *2 when dealing with stereo, but going with mono rn let rfproc: RFftProcer = RFftProcer::new(sample_rate); let pnotes = rfproc.make_pnotes(¬es); //println!("{:#?}", pnotes); for pnote in &pnotes { println!("{}", pnote); } println!("{}", rfproc); let args = SimpleArgs::parse(); println!("Args: {:?}", args); // TODO: having an app-specific default threshold might be a good idea for smolguitar, // not sure how to do that yet, maybe there's an API for changing the default of an arg in clap let disp_threshold = args.threshold; //let outputer = Outputers::Simple(SimpleOutputer); //let outputer = Outputers::LineLayout(LineLayout::new(0.2, true, (0., 255., 220.), ¬es)); let outputer = args.get_outputer(¬es); let rfpdata = ProcerData::new(&rfproc, ProcerNotes(pnotes, disp_threshold)); let mut buf: StaticBuffer = StaticBuffer::new(48000, CHANNELS, vec![(Procers::Rfft(rfproc), rfpdata)], "Microphone_c".to_string(), args.get_outdev(), outputer); println!("{}", buf); let mut aout = alsa::Output::buffer_open().unwrap(); buf.adev.dump(&mut aout); match &buf.outdev { Some(outdev) => { outdev.dump(&mut aout); }, None => {}, } println!("{}", aout); buf.capture_loop(); //println!("{:#?}", pdata); }