-
Notifications
You must be signed in to change notification settings - Fork 62
Description
Hey hey,
i'm currently experimenting with using fundsp as a testing utility for my open source DJing Software (https://codeberg.org/OpenDJLab/LibreDJ). I want to test if the sampler part is properly working, so jumping around, looping, pitching etc.
My idea is to have a test signal that is a frequency sweep of a simple sine from 440hz to xyz and using an fft to get back the "location" of what the sampler really played back. As my sampler is not a fundsp graph node, i'm rendering the test signal into a Vec<Vec> and try to shove the output of the sampler back into a Wave.
a) What I didn't figure out yet though is how to do the .display() that fundsp offers for rendering a little fft graph
b) How one could get a fft table at all from Wave
This is my code so far, appreciate any tips:
use std::path::Path;
use fundsp::prelude64::*;
use test_log::test;
use crate::{Player, PlayerCommand};
static TEST_SIGNAL_SAMPLE_RATE: f64 = 44100.;
fn generate_test_chirp() -> [Vec<f32>; 2] {
let mut graph =
(440.0 * 4.0 * (envelope(|t| pow(t / 60., 2.0))) + 440.0 >> sine()) >> split::<U2>();
//let c = c >> (pass() | envelope(|t| (xerp11(500.0, 5000.0, sin_hz(0.05, t)), 0.9))) >> !bandrez() >> bandrez();
let wave = Wave::render(TEST_SIGNAL_SAMPLE_RATE, 60.0, &mut graph);
let left: Vec<f32> = wave.channel(0).to_vec();
let right: Vec<f32> = wave.channel(1).to_vec();
[left, right]
}
#[test]
fn test_player() {
let test_signal_samples = generate_test_chirp();
let mut player = Player::from_mono_wave(
TEST_SIGNAL_SAMPLE_RATE as usize,
TEST_SIGNAL_SAMPLE_RATE as usize,
1024,
test_signal_samples[0].clone(),
);
// player.command(0, PlayerCommand::Play(Some(false)));
let mut output_left = Vec::new();
let mut output_right = Vec::new();
let mut tmp_left = vec![0.0; 1024];
let mut tmp_right = vec![0.0; 1024];
for i in 0..=((10.0 * TEST_SIGNAL_SAMPLE_RATE) / 1024.) as usize {
println!("x={i}");
player
.proceed_and_fill_buffer(
&mut tmp_left[0..1024],
&mut tmp_right[0..1024],
TEST_SIGNAL_SAMPLE_RATE as usize,
1024,
)
.unwrap();
output_left.extend_from_slice(&tmp_left);
output_right.extend_from_slice(&tmp_right);
}
player.command(0, PlayerCommand::Play(Some(true)));
for i in 0..=((10.0 * TEST_SIGNAL_SAMPLE_RATE) / 1024.) as usize {
player
.proceed_and_fill_buffer(
&mut tmp_left[0..1024],
&mut tmp_right[0..1024],
TEST_SIGNAL_SAMPLE_RATE as usize,
1024,
)
.unwrap();
output_left.extend_from_slice(&tmp_left);
output_right.extend_from_slice(&tmp_right);
}
let wave = Wave::from_samples(TEST_SIGNAL_SAMPLE_RATE, &output_left);
// wave.display();
let path = Path::new("/tmp/test.wav");
wave.save_wav32(path).unwrap();
}