...
 
Commits (3)
......@@ -242,6 +242,53 @@ fn compressor_bench(c: &mut Criterion) {
);
}
fn autowah_bench(c: &mut Criterion) {
let mut rng = SmallRng::seed_from_u64(345987);
let unity_interval = Uniform::new_inclusive(-1., 1.);
c.bench_function_over_inputs(
"autowah",
move |b: &mut Bencher, n: &usize| {
let mut autowah = Autowah::new(0.9);
let mut input = vec![DspEdge::new(1, 1, *n, 44100); 1];
//let size = input[0].buffer().len();
input[0].buffer_mut().copy_from_slice(
&rng.sample_iter(&unity_interval)
.take(*n)
.collect::<Vec<f32>>(),
);
b.iter(|| {
let mut output = vec![DspEdge::new(1, 1, *n, 44100); 1];
autowah.process(&input, &mut output)
})
},
vec![64, 128, 256, 512, 1024, 2048, 4096],
);
}
fn cubicnl_bench(c: &mut Criterion) {
let mut rng = SmallRng::seed_from_u64(345987);
let unity_interval = Uniform::new_inclusive(-1., 1.);
c.bench_function_over_inputs(
"cubicnl",
move |b: &mut Bencher, n: &usize| {
let mut cubicnl = Cubicnl::new(0.9, 2.1);
let mut input = vec![DspEdge::new(1, 1, *n, 44100); 1];
//let size = input[0].buffer().len();
input[0].buffer_mut().copy_from_slice(
&rng.sample_iter(&unity_interval)
.take(*n)
.collect::<Vec<f32>>(),
);
b.iter(|| {
let mut output = vec![DspEdge::new(1, 1, *n, 44100); 1];
cubicnl.process(&input, &mut output)
})
},
vec![64, 128, 256, 512, 1024, 2048, 4096],
);
}
criterion_group!(
benches,
osc_bench,
......@@ -252,6 +299,8 @@ criterion_group!(
transpose_bench,
zita_reverb_bench,
freeverb_bench,
compressor_bench
compressor_bench,
autowah_bench,
cubicnl_bench
);
criterion_main!(benches);
import("stdfaust.lib");
// We don't care about the values here. Just need it for the generation
level = hslider("level", 0.9, 0, 1, 0.01);
process = ve.autowah(level) ;
import("stdfaust.lib");
// We don't care about the values here. Just need it for the generation
drive = hslider("drive", 0.9, 0, 1, 0.01);
offset = hslider("offset", 0.9, 0, 100, 0.01);
process = ef.cubicnl(drive,offset) ;
......@@ -101,11 +101,15 @@ impl DspNode {
nb_channels,
node_infos.nb_outlets as usize,
)),
//TODO: Stack overflow if there
// Need to use ulimit -s 32768 to increase the size of the stack
"guitar" => Box::new(faust_effect::Guitar::from_node_infos(&node_infos)),
"transpose" => Box::new(faust_effect::Transposer::from_node_infos(&node_infos)),
"zita_reverb" => Box::new(faust_effect::ZitaReverb::from_node_infos(&node_infos)),
"freeverb" => Box::new(faust_effect::MonoFreeverb::from_node_infos(&node_infos)),
"compressor" => Box::new(faust_effect::Compressor::from_node_infos(&node_infos)),
"autowah" => Box::new(faust_effect::Autowah::from_node_infos(&node_infos)),
"cubicnl" => Box::new(faust_effect::Cubicnl::from_node_infos(&node_infos)),
"sink" => Box::new(InputsOutputsAdaptor::new(
node_infos.nb_inlets as usize,
nb_channels,
......@@ -127,6 +131,7 @@ impl DspNode {
}
}
};
DspNode {
node_infos,
node_processor,
......
......@@ -2049,3 +2049,264 @@ impl AudioEffect for Compressor {
}
}
}
/****************************************
** Autowah
****************************************/
pub struct Autowah {
fDummy: f32,
fHslider0: f32,
fSampleRate: i32,
fConst0: f32,
fConst1: f32,
fConst2: f32,
fRec2: [f32; 2],
fRec1: [f32; 2],
fConst3: f32,
fConst4: f32,
fRec3: [f32; 2],
fRec4: [f32; 2],
fRec0: [f32; 3],
}
impl Autowah {
pub fn init() -> Autowah {
Autowah {
fDummy: 0 as f32,
fHslider0: 0.0,
fSampleRate: 0,
fConst0: 0.0,
fConst1: 0.0,
fConst2: 0.0,
fRec2: [0.0; 2],
fRec1: [0.0; 2],
fConst3: 0.0,
fConst4: 0.0,
fRec3: [0.0; 2],
fRec4: [0.0; 2],
fRec0: [0.0; 3],
}
}
pub fn instanceResetUserInterface(&mut self) {
self.fHslider0 = 0.899999976;
}
pub fn instanceClear(&mut self) {
for l0 in 0..2 {
self.fRec2[l0 as usize] = 0.0;
}
for l1 in 0..2 {
self.fRec1[l1 as usize] = 0.0;
}
for l2 in 0..2 {
self.fRec3[l2 as usize] = 0.0;
}
for l3 in 0..2 {
self.fRec4[l3 as usize] = 0.0;
}
for l4 in 0..3 {
self.fRec0[l4 as usize] = 0.0;
}
}
pub fn instanceConstants(&mut self, sample_rate: i32) {
self.fSampleRate = sample_rate;
self.fConst0 = f32::min(192000.0, f32::max(1.0, self.fSampleRate as f32));
self.fConst1 = f32::exp(0.0 - (10.0 / self.fConst0));
self.fConst2 = 1.0 - self.fConst1;
self.fConst3 = 1413.71667 / self.fConst0;
self.fConst4 = 2827.43335 / self.fConst0;
}
pub fn instanceInit(&mut self, sample_rate: i32) {
self.instanceConstants(sample_rate);
self.instanceResetUserInterface();
self.instanceClear();
}
pub fn new(level: f32) -> Autowah {
let mut autowah = Autowah::init();
autowah.instanceInit(44_100);
autowah.setControlVariables(level);
autowah
}
pub fn from_node_infos(node_infos: &audiograph_parser::Node) -> Autowah {
let level = node_infos.more["level"]
.parse()
.expect("level is a float in [0,1]");
let autowah = Autowah::new(level);
autowah.check_io_node_infos(node_infos);
autowah
}
pub fn setControlVariables(&mut self, level: f32) {
self.fHslider0 = level;
}
}
impl fmt::Display for Autowah {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "autowah({})", self.fHslider0)
}
}
impl AudioEffect for Autowah {
fn nb_inputs(&self) -> usize {
return 1;
}
fn nb_outputs(&self) -> usize {
return 1;
}
fn process(&mut self, inputs: &[DspEdge], outputs: &mut [DspEdge]) {
debug_assert_eq!(inputs.len(), self.nb_inputs());
debug_assert_eq!(outputs.len(), self.nb_outputs());
let actual_samplerate = outputs[0].samplerate as i32;
let input = inputs[0].buffer();
let output = outputs[0].buffer_mut();
let count = output.len();
//Constants have to be changed if we change the samplerate...
// We should smooth it actually...
if self.fSampleRate != actual_samplerate {
self.instanceInit(actual_samplerate);
}
let fSlow0: f32 = self.fHslider0 as f32;
let fSlow1: f32 = 1.0 - fSlow0;
for i in 0..count {
let mut fTemp0: f32 = input[i as usize] as f32;
let mut fTemp1: f32 = f32::abs(fTemp0);
self.fRec2[0] = f32::max(
fTemp1,
(self.fConst1 * self.fRec2[1]) + (self.fConst2 * fTemp1),
);
self.fRec1[0] =
(0.999000013 * self.fRec1[1]) + (9.99999975e-05 * f32::powf(4.0, self.fRec2[0]));
let mut fTemp2: f32 = f32::powf(2.0, 2.29999995 * self.fRec2[0]);
let mut fTemp3: f32 = 1.0
- (self.fConst3 * (fTemp2 / f32::powf(2.0, (2.0 * (1.0 - self.fRec2[0])) + 1.0)));
self.fRec3[0] = (0.999000013 * self.fRec3[1])
- (0.00200000009 * (fTemp3 * f32::cos(self.fConst4 * fTemp2)));
self.fRec4[0] = (0.999000013 * self.fRec4[1]) + (0.00100000005 * faustpower2_f(fTemp3));
self.fRec0[0] = (fTemp0 * self.fRec1[0])
- ((self.fRec3[0] * self.fRec0[1]) + (self.fRec4[0] * self.fRec0[2]));
output[i as usize] =
((fSlow1 * fTemp0) + (fSlow0 * (self.fRec0[0] - self.fRec0[1]))) as f32;
self.fRec2[1] = self.fRec2[0];
self.fRec1[1] = self.fRec1[0];
self.fRec3[1] = self.fRec3[0];
self.fRec4[1] = self.fRec4[0];
self.fRec0[2] = self.fRec0[1];
self.fRec0[1] = self.fRec0[0];
}
}
}
/****************************************
** Cubic non linear distorsion
****************************************/
pub struct Cubicnl {
fDummy: f32,
fHslider0: f32,
fHslider1: f32,
fSampleRate: i32,
}
impl Cubicnl {
pub fn init() -> Cubicnl {
Cubicnl {
fDummy: 0 as f32,
fHslider0: 0.0,
fHslider1: 0.0,
fSampleRate: 0,
}
}
pub fn instanceResetUserInterface(&mut self) {
self.fHslider0 = 0.899999976;
self.fHslider1 = 0.899999976;
}
pub fn instanceClear(&mut self) {}
pub fn instanceConstants(&mut self, sample_rate: i32) {
self.fSampleRate = sample_rate;
}
pub fn instanceInit(&mut self, sample_rate: i32) {
self.instanceConstants(sample_rate);
self.instanceResetUserInterface();
self.instanceClear();
}
pub fn new(drive: f32, offset: f32) -> Cubicnl {
let mut cubicnl = Cubicnl::init();
cubicnl.setControlVariables(drive, offset);
cubicnl.instanceInit(44_100);
cubicnl
}
pub fn from_node_infos(node_infos: &audiograph_parser::Node) -> Cubicnl {
let drive = node_infos.more["drive"]
.parse()
.expect("drive is a float in [0,1]");
let offset = node_infos.more["offset"]
.parse()
.expect("offset is a float");
let cubicnl = Cubicnl::new(drive, offset);
cubicnl.check_io_node_infos(node_infos);
cubicnl
}
pub fn setControlVariables(&mut self, drive: f32, offset: f32) {
self.fHslider0 = offset;
self.fHslider1 = drive;
}
}
impl fmt::Display for Cubicnl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "cubicnl({}, {})", self.fHslider1, self.fHslider0)
}
}
impl AudioEffect for Cubicnl {
fn nb_inputs(&self) -> usize {
return 1;
}
fn nb_outputs(&self) -> usize {
return 1;
}
fn process(&mut self, inputs: &[DspEdge], outputs: &mut [DspEdge]) {
debug_assert_eq!(inputs.len(), self.nb_inputs());
debug_assert_eq!(outputs.len(), self.nb_outputs());
let actual_samplerate = outputs[0].samplerate as i32;
let input = inputs[0].buffer();
let output = outputs[0].buffer_mut();
let count = output.len();
//Constants have to be changed if we change the samplerate...
// We should smooth it actually...
if self.fSampleRate != actual_samplerate {
self.instanceInit(actual_samplerate);
}
let fSlow0: f32 = self.fHslider0 as f32;
let fSlow1: f32 = f32::powf(10.0, 2.0 * (self.fHslider1 as f32));
for i in 0..count {
let mut fTemp0: f32 = f32::max(
-1.0,
f32::min(1.0, fSlow0 + (fSlow1 * (input[i as usize] as f32))),
);
output[i as usize] = (fTemp0 * (1.0 - (0.333333343 * faustpower2_f(fTemp0)))) as f32;
}
}
}