1
Fork 0
cruisecontrol/interface/src/main.rs

75 lines
2.5 KiB
Rust

#![feature(iter_collect_into)]
use std::{sync::mpsc, thread::sleep, time::Duration};
use anyhow::{Context, Ok, Result};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use pitch_detection::{detector::{mcleod::McLeodDetector, PitchDetector}, utils};
use rust_music_theory::note::{Note, NoteLetter, Pitch, Tuning};
fn main() -> Result<()> {
// assumes pulseaudio system with f32 samples and 2204 sample packets
dbg!(cpal::available_hosts());
let host = cpal::default_host();
let device = host.devices().unwrap().find(|d|d.name().unwrap() == "pulse").context("no pulse")?;
let config = device.default_input_config()?;
dbg!(config.sample_format());
let rate = config.sample_rate();
let (sender, notes) = mpsc::channel();
const POWER_THRESHOLD: f32 = 5.0;
const CLARITY_THRESHOLD: f32 = 0.7;
const PACKET_LEN: usize = 2204;
let stream = device.build_input_stream(&config.into(),
move | data: &[f32], _: &_| {
assert!(data.len() >= PACKET_LEN);
let data = &data[..PACKET_LEN];
// reinitialized every packet as it is not thread safe
let mut detctor = McLeodDetector::new(PACKET_LEN, PACKET_LEN/2);
let vol = utils::buffer::square_sum(data);
sender.send((detctor.get_pitch(data, rate.0 as usize, POWER_THRESHOLD, CLARITY_THRESHOLD),vol)).unwrap();
},
move |err| {eprintln!("{err}")} ,
Some(Duration::from_secs(1)))?;
stream.play()?;
for (note,vol) in notes {
if let Some(note) = note {
//dbg!(note.frequency);
dbg!(note.clarity);
dbg!(vol);
let note = Note::from_freq(note.frequency, Tuning::EqualTemperament);
match note.pitch {
Pitch { letter: NoteLetter::A, accidental: 0} => {
println!("forward");
}
Pitch { letter: NoteLetter::A, accidental: 1} => {
println!("backward");
}
Pitch { letter: NoteLetter::C, accidental: 0} => {
println!("right");
}
Pitch { letter: NoteLetter::C, accidental: 1} => {
println!("left");
}
Pitch { letter: NoteLetter::G, accidental: 0} => {
println!("fire");
}
pitch => {
dbg!(pitch);
}
}
}
}
drop(stream);
Ok(())
}