-
Notifications
You must be signed in to change notification settings - Fork 332
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add -double support for faust2jackrust and faust2portaudiorust.
- Loading branch information
Showing
6 changed files
with
421 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
/************************************************************************ | ||
FAUST Architecture File | ||
Copyright (C) 2003-2024 GRAME, Centre National de Creation Musicale | ||
--------------------------------------------------------------------- | ||
This Architecture section is free software; you can redistribute it | ||
and/or modify it under the terms of the GNU General Public License | ||
as published by the Free Software Foundation; either version 3 of | ||
the License, or (at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program; If not, see <http://www.gnu.org/licenses/>. | ||
EXCEPTION : As a special exception, you may create a larger work | ||
that contains this FAUST architecture section and distribute | ||
that work under terms of your choice, so long as this FAUST | ||
architecture section is not modified. | ||
************************************************************************ | ||
************************************************************************/ | ||
|
||
#![allow(unused_parens)] | ||
#![allow(non_snake_case)] | ||
#![allow(non_camel_case_types)] | ||
#![allow(dead_code)] | ||
#![allow(unused_variables)] | ||
#![allow(unused_mut)] | ||
#![allow(non_upper_case_globals)] | ||
|
||
//! Faust JACK architecture file | ||
extern crate jack; | ||
use jack::prelude as j; | ||
use std::io; | ||
extern crate libm; | ||
|
||
type F32 = f32; | ||
type F64 = f64; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct ParamIndex(pub i32); | ||
|
||
pub struct Soundfile<'a,T> { | ||
fBuffers: &'a&'a T, | ||
fLength: &'a i32, | ||
fSR: &'a i32, | ||
fOffset: &'a i32, | ||
fChannels: i32 | ||
} | ||
|
||
pub trait FaustDsp { | ||
type T; | ||
|
||
fn new() -> Self where Self: Sized; | ||
fn metadata(&self, m: &mut dyn Meta); | ||
fn get_sample_rate(&self) -> i32; | ||
fn get_num_inputs(&self) -> i32; | ||
fn get_num_outputs(&self) -> i32; | ||
fn class_init(sample_rate: i32) where Self: Sized; | ||
fn instance_reset_params(&mut self); | ||
fn instance_clear(&mut self); | ||
fn instance_constants(&mut self, sample_rate: i32); | ||
fn instance_init(&mut self, sample_rate: i32); | ||
fn init(&mut self, sample_rate: i32); | ||
fn build_user_interface(&self, ui_interface: &mut dyn UI<Self::T>); | ||
fn build_user_interface_static(ui_interface: &mut dyn UI<Self::T>) where Self: Sized; | ||
fn get_param(&self, param: ParamIndex) -> Option<Self::T>; | ||
fn set_param(&mut self, param: ParamIndex, value: Self::T); | ||
fn compute(&mut self, count: i32, inputs: &[&[Self::T]], outputs: &mut[&mut[Self::T]]); | ||
} | ||
|
||
pub trait Meta { | ||
// -- metadata declarations | ||
fn declare(&mut self, key: &str, value: &str); | ||
} | ||
|
||
pub trait UI<T> { | ||
// -- widget's layouts | ||
fn open_tab_box(&mut self, label: &str); | ||
fn open_horizontal_box(&mut self, label: &str); | ||
fn open_vertical_box(&mut self, label: &str); | ||
fn close_box(&mut self); | ||
|
||
// -- active widgets | ||
fn add_button(&mut self, label: &str, param: ParamIndex); | ||
fn add_check_button(&mut self, label: &str, param: ParamIndex); | ||
fn add_vertical_slider(&mut self, label: &str, param: ParamIndex, init: T, min: T, max: T, step: T); | ||
fn add_horizontal_slider(&mut self, label: &str, param: ParamIndex, init: T, min: T, max: T, step: T); | ||
fn add_num_entry(&mut self, label: &str, param: ParamIndex, init: T, min: T, max: T, step: T); | ||
|
||
// -- passive widgets | ||
fn add_horizontal_bargraph(&mut self, label: &str, param: ParamIndex, min: T, max: T); | ||
fn add_vertical_bargraph(&mut self, label: &str, param: ParamIndex, min: T, max: T); | ||
|
||
// -- metadata declarations | ||
fn declare(&mut self, param: Option<ParamIndex>, key: &str, value: &str); | ||
} | ||
|
||
<<includeIntrinsic>> | ||
<<includeclass>> | ||
|
||
fn main() { | ||
|
||
// Create JACK client | ||
let (client, _status) = j::Client::new("faust_rust", j::client_options::NO_START_SERVER).unwrap(); | ||
|
||
// Allocation DSP on the heap | ||
let mut dsp; | ||
#[cfg(feature = "default-boxed")] | ||
{ | ||
use default_boxed::DefaultBoxed; | ||
dsp = mydsp::default_boxed(); | ||
} | ||
|
||
#[cfg(not(feature = "default-boxed"))] | ||
{ | ||
dsp = Box::new(mydsp::new()); | ||
} | ||
|
||
println!("Faust Rust code running with JACK: sample-rate = {} buffer-size = {}", client.sample_rate(), client.buffer_size()); | ||
|
||
println!("get_num_inputs: {}", dsp.get_num_inputs()); | ||
println!("get_num_outputs: {}", dsp.get_num_outputs()); | ||
|
||
// Init DSP with a given SR | ||
dsp.init(client.sample_rate() as i32); | ||
|
||
// Register ports. They will be used in a callback that will be | ||
// called when new data is available. | ||
|
||
let in_a = client.register_port("in1", j::AudioInSpec::default()).unwrap(); | ||
let in_b = client.register_port("in2", j::AudioInSpec::default()).unwrap(); | ||
|
||
let mut out_a = client.register_port("out1", j::AudioOutSpec::default()).unwrap(); | ||
let mut out_b = client.register_port("out2", j::AudioOutSpec::default()).unwrap(); | ||
|
||
let process_callback = move |_: &j::Client, ps: &j::ProcessScope| -> j::JackControl { | ||
let mut out_a_p = j::AudioOutPort::new(&mut out_a, ps); | ||
let mut out_b_p = j::AudioOutPort::new(&mut out_b, ps); | ||
|
||
let in_a_p = j::AudioInPort::new(&in_a, ps); | ||
let in_b_p = j::AudioInPort::new(&in_b, ps); | ||
|
||
// Adapt f32 inputs in f64 inputs | ||
let input0: &[f32] = &in_a_p; | ||
let input1: &[f32] = &in_b_p; | ||
|
||
let input0_f64: Vec<f64> = input0.iter().map(|&sample| sample as f64).collect(); | ||
let input1_f64: Vec<f64> = input1.iter().map(|&sample| sample as f64).collect(); | ||
|
||
let inputs_f64: [&[f64]; 2] = [&input0_f64[..], &input1_f64[..]]; | ||
let inputs_ref: &[&[f64]] = &inputs_f64; | ||
|
||
// Prepare f64 outputs | ||
let mut output0_f64: Vec<f64> = vec![0.0; out_a_p.len()]; | ||
let mut output1_f64: Vec<f64> = vec![0.0; out_b_p.len()]; | ||
|
||
let mut outputs_f64: [&mut [f64]; 2] = [&mut output0_f64[..], &mut output1_f64[..]]; | ||
let outputs_ref: &mut [&mut [f64]] = &mut outputs_f64; | ||
|
||
// Compute using f64 inputs and outputs | ||
dsp.compute(in_a_p.len() as i32, inputs_ref, outputs_ref); | ||
|
||
// Convert f64 outputs to f32 outputs | ||
let output0: &mut[f32] = &mut out_a_p; | ||
let output1: &mut[f32] = &mut out_b_p; | ||
|
||
// Copy and convert outputs_ref[0] (f64) to output0 (f32) | ||
for (dest, &src) in output0.iter_mut().zip(outputs_ref[0].iter()) { | ||
*dest = src as f32; | ||
} | ||
for (dest, &src) in output1.iter_mut().zip(outputs_ref[1].iter()) { | ||
*dest = src as f32; | ||
} | ||
|
||
j::JackControl::Continue | ||
}; | ||
let process = j::ClosureProcessHandler::new(process_callback); | ||
|
||
// Activate the client, which starts the processing. | ||
let active_client = j::AsyncClient::new(client, (), process).unwrap(); | ||
|
||
// Wait for user input to quit | ||
println!("Press enter/return to quit..."); | ||
let mut user_input = String::new(); | ||
io::stdin().read_line(&mut user_input).ok(); | ||
|
||
active_client.deactivate().unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.