some basic fft code based on rustfft crate
This commit is contained in:
parent
5a3eb18f5c
commit
4e2cb0dca4
4 changed files with 72 additions and 1 deletions
|
@ -24,6 +24,7 @@ hound = "3.4.0"
|
||||||
microfft = "0.3.1"
|
microfft = "0.3.1"
|
||||||
num-complex = "0.2"
|
num-complex = "0.2"
|
||||||
jack = "0.6.6"
|
jack = "0.6.6"
|
||||||
|
rustfft = "6.0.0"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
|
@ -143,5 +143,7 @@ impl DspNode for SFilter {
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx_vals[0].set(out.read(ctx.nframes() - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,6 +422,18 @@ pub fn run_and_get_fft4096(
|
||||||
fft_thres_at_ms(&mut out_l[..], FFT::F4096, thres, offs_ms)
|
fft_thres_at_ms(&mut out_l[..], FFT::F4096, thres, offs_ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn run_and_get_fft4096_2(
|
||||||
|
node_exec: &mut hexodsp::nodes::NodeExecutor,
|
||||||
|
thres: u32) -> Vec<(u16, u32)>
|
||||||
|
{
|
||||||
|
let min_samples_for_fft = 4096.0;
|
||||||
|
let min_len_samples = 2.0 * min_samples_for_fft;
|
||||||
|
let run_len_s = min_len_samples / SAMPLE_RATE;
|
||||||
|
let (mut out_l, _out_r) = run_no_input(node_exec, run_len_s);
|
||||||
|
fft_16k(&mut out_l[..], 4096, thres)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn calc_exp_avg_buckets4096(fft: &[(u16, u32)]) -> Vec<(u16, u32)> {
|
pub fn calc_exp_avg_buckets4096(fft: &[(u16, u32)]) -> Vec<(u16, u32)> {
|
||||||
let mut avg = vec![];
|
let mut avg = vec![];
|
||||||
|
@ -592,3 +604,49 @@ pub fn fft_thres_at_ms(buf: &mut [f32], size: FFT, amp_thres: u32, ms_idx: f32)
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fft_16k(buf: &mut [f32], len: usize, amp_thres: u32) -> Vec<(u16, u32)> {
|
||||||
|
let mut res = vec![];
|
||||||
|
|
||||||
|
if len > buf.len() {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hann window:
|
||||||
|
for (i, s) in buf[0..len].iter_mut().enumerate() {
|
||||||
|
let w =
|
||||||
|
0.5
|
||||||
|
* (1.0
|
||||||
|
- ((2.0 * std::f32::consts::PI * i as f32)
|
||||||
|
/ (len as f32 - 1.0))
|
||||||
|
.cos());
|
||||||
|
*s *= w;
|
||||||
|
}
|
||||||
|
|
||||||
|
use rustfft::{FftPlanner, num_complex::Complex};
|
||||||
|
|
||||||
|
let mut complex_buf =
|
||||||
|
buf.iter()
|
||||||
|
.map(|s| Complex { re: *s, im: 0.0 })
|
||||||
|
.collect::<Vec<Complex<f32>>>();
|
||||||
|
|
||||||
|
let mut p = FftPlanner::<f32>::new();
|
||||||
|
let fft = p.plan_fft_forward(len);
|
||||||
|
|
||||||
|
fft.process(&mut complex_buf[0..len]);
|
||||||
|
|
||||||
|
let amplitudes: Vec<_> =
|
||||||
|
complex_buf[0..len].iter().map(|c| c.norm() as u32).collect();
|
||||||
|
println!("fft: {:?}", &complex_buf[0..len]);
|
||||||
|
|
||||||
|
for (i, amp) in amplitudes.iter().enumerate() {
|
||||||
|
if *amp >= amp_thres {
|
||||||
|
let freq = (i as f32 * SAMPLE_RATE) / len as f32;
|
||||||
|
println!("{:6.0} {}", freq, *amp);
|
||||||
|
res.push((freq.round() as u16, *amp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ mod common;
|
||||||
use common::*;
|
use common::*;
|
||||||
|
|
||||||
fn setup_sfilter_matrix() -> (Matrix, NodeExecutor) {
|
fn setup_sfilter_matrix() -> (Matrix, NodeExecutor) {
|
||||||
let (node_conf, mut node_exec) = new_node_engine();
|
let (node_conf, node_exec) = new_node_engine();
|
||||||
let mut matrix = Matrix::new(node_conf, 3, 3);
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
let noise = NodeId::Noise(0);
|
let noise = NodeId::Noise(0);
|
||||||
|
@ -50,6 +50,16 @@ fn check_node_sfilter_lowpass() {
|
||||||
(1500, 8), (2000, 4), (3000, 4), (4000, 0), (8000, 0), (12000, 0),
|
(1500, 8), (2000, 4), (3000, 4), (4000, 0), (8000, 0), (12000, 0),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// let v = run_and_get_fft4096_2(&mut node_exec, 1);
|
||||||
|
// assert_eq!(
|
||||||
|
// avg_fft_freqs(4.0, &[
|
||||||
|
// 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 8000, 12000, 16000,
|
||||||
|
// ], &v[..]), vec![
|
||||||
|
// (0, 16), (100, 24), (250, 16), (500, 12), (750, 12), (1000, 12),
|
||||||
|
// (1500, 8), (2000, 4), (3000, 4), (4000, 0), (8000, 0), (12000, 0),
|
||||||
|
// ]);
|
||||||
|
// assert!(false);
|
||||||
|
|
||||||
// Low Pass @ 4000Hz
|
// Low Pass @ 4000Hz
|
||||||
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 0, 4000.0, 0.0);
|
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 0, 4000.0, 0.0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in a new issue