multichannel api for bw(pp)_{noise_gen,osc_filt,osc_saw,osc_sin,pink_filt,sr_reduce}

This commit is contained in:
Stefano D'Angelo 2023-07-04 09:34:37 +02:00
parent 61e57084e4
commit c4074927ce
14 changed files with 202 additions and 62 deletions

54
TODO
View File

@ -1,9 +1,11 @@
1.0.0
-----
code:
* blep etc in a module?
* osc post filter (and one pole init, slew rate, etc.) val from input? set state instead?
* audio rate optional pulse width/slope inputs?
* should rather use backward Euler in bw_onepole?
* one pole process const input? (return also if const out)
* optimize triangle generation for constant pulse width
* web examples construction/destruction
* web effect mono->stereo and stereo->mono inputs? or display "input needs to be n channels"?
* check const restrict etc.
@ -13,27 +15,17 @@ code:
* should clip slope in triangle?
* fix vst3 mapped values (visible in Ableton Live) and short names
* polish examples (ranges, etc.)
* compute bit depth reduction only when input changes? (state, option?)
* common smoothing policy (as control rate as possible?) - smoothing control?
* avoid "force" in coeffs update by using inline functions?
* should rather use backward Euler in bw_onepole?
* csch for bw_peak bandwidth -> Q, inv sqrt ls2 hs2
* sample rate-constant coeffs? (pan case)
* pan process with no out: should just reset coeffs?
* trace calls (debug)
* svf bandpass out polarity too confusing (inverted in mm2)?
* better common config.h (less stuff maybe, or more stuff - decide)
* separate tests an examples?
* define common midi CCs for examples
* pan process with no out: should just reset coeffs?
* get_y_z1, common strategy?
* sqrt(0) and corner cases, common strategy?
* MEM_REQ_ROUGH() macro?
* use BW_SIZE_T, check constant types
* web examples: need to export memset?
* bw_satur gain compensation to divide by actual gain (derivative) rather than gain parameter?
* cite papers, thank authors
* add initial state (x0) to reset state of lp1, ap1, mm1, hs1, ls1, others? all?
* check unused param warning visual studio
* bw_comb: should also modulate feedback?
* bw_comb: integer target delay values?
* bw_svf/lp1 automatically limited (max) prewarp frequency to avoid instability?
@ -41,13 +33,10 @@ code:
* bw_math: review types
* src inside distortions? w/ control from outside?
* bw_fuzz gain compensation?
* remove union value = {.f = v};? (std c++ latest)
* remove union value = {.f = v};? (std c++ latest) - C++ compound literals...
* make gain of distortions homogeneous?
* max_delay -> set sample rate? see reverb
* revise typedef style (see https://stackoverflow.com/questions/54752861/using-an-anonymous-struct-vs-a-named-struct-with-typedef)
* sr-dependent vs cr-dependent coeffs? see synth poly example
* bw_buf_copy (to be used in bw_slew_lim)?
* C++ compound literals...
* multichannel api even where not needed?
* x_y vs xy var names
* don't use reserved identifiers (https://devblogs.microsoft.com/oldnewthing/20230109-00/?p=107685)
@ -55,16 +44,37 @@ code:
* mem req -> return value of set sample rate?
* peak gain + Q ???
* bwpp -> bwxx
* float -> double, etc. ?
* sr_reduce reset_coeffs? update_coeffs? process_multi?
* src(_int) process_multi?
* fix definitions leading to X ** -> const X ** error https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion, fix fx_balance, fx_pan, synth_poly
* drywet -> dry_wet, ringmod -> ring_mod, etc?
* allow nullptr in C++ wrappers where process_multi arg can be NULL
* src post filt?
* better src filter
* bw_env_gen process_multi gate const?
* c++ get coeffs/state? or public? src nIn/OutSamples case (array vs single value), delay read/write, process1? process single?
* bw_buf invert src dest order?
* check unititialized warnings
build system:
* single header generation
post 1.0.0
----------
code:
* blep etc in a module?
* optimize triangle generation for constant pulse width
* compute bit depth reduction only when input changes? (state, option?)
* avoid "force" in coeffs update by using inline functions?
* csch for bw_peak bandwidth -> Q, inv sqrt ls2 hs2
* separate tests and examples?
* define common midi CCs for examples
* MEM_REQ_ROUGH() macro?
* web examples: need to export memset?
* check unused param warning visual studio
* float -> double, etc. ?
* bw_buf_copy (to be used in bw_slew_lim)?
* src post filt?
build system:
* make makefiles handle paths with spaces etc
@ -76,3 +86,9 @@ build system:
* VC, XCode, etc project files?
* single header(s)
* cross compile (rpi etc.)
--
code:
* sample rate-constant coeffs? (pan case)
* sr-dependent vs cr-dependent coeffs? see synth poly example

View File

@ -197,6 +197,8 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
float *b0[N_VOICES], *b1[N_VOICES], *b2[N_VOICES], *b3[N_VOICES], *b4[N_VOICES];
char gates[N_VOICES];
bw_osc_filt_state *osc_filt_states[N_VOICES];
bw_pink_filt_state *pink_filt_states[N_VOICES];
bw_env_gen_state *vcf_env_gen_states[N_VOICES], *vca_env_gen_states[N_VOICES];
for (int j = 0; j < N_VOICES; j++) {
b0[j] = instance->voices[j].buf[0];
@ -205,6 +207,8 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
b3[j] = instance->voices[j].buf[3];
b4[j] = instance->voices[j].buf[4];
gates[j] = instance->voices[j].gate;
osc_filt_states[j] = &instance->voices[j].osc_filt_state;
pink_filt_states[j] = &instance->voices[j].pink_filt_state;
vcf_env_gen_states[j] = &instance->voices[j].vcf_env_gen_state;
vca_env_gen_states[j] = &instance->voices[j].vca_env_gen_state;
}
@ -222,20 +226,17 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
bw_osc_pulse_process_multi(&instance->vco3_pulse_coeffs, (const float **)b0, (const float **)b1, b0, N_VOICES, n);
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
} else {
for (int j = 0; j < N_VOICES; j++)
bw_osc_saw_process(&instance->vco_saw_coeffs, b0[j], b1[j], b0[j], n);
bw_osc_saw_process_multi(&instance->vco_saw_coeffs, (const float **)b0, (const float **)b1, b0, N_VOICES, n);
bw_osc_pulse_reset_coeffs(&instance->vco3_pulse_coeffs);
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
}
for (int j = 0; j < N_VOICES; j++)
bw_noise_gen_process(&instance->noise_gen_coeffs, b1[j], n);
bw_noise_gen_process_multi(&instance->noise_gen_coeffs, b1, N_VOICES, n);
if (instance->params[p_noise_color] >= 0.5f)
for (int j = 0; j < N_VOICES; j++)
bw_pink_filt_process(&instance->pink_filt_coeffs, &instance->voices[j].pink_filt_state, b1[j], b1[j], n);
bw_pink_filt_process_multi(&instance->pink_filt_coeffs, pink_filt_states, (const float **)b1, b1, N_VOICES, n);
else
for (int j = 0; j < N_VOICES; j++)
bw_pink_filt_reset_state(&instance->pink_filt_coeffs, &instance->voices[j].pink_filt_state); // FIXME: calling this here is sloppy coding
bw_pink_filt_reset_state(&instance->pink_filt_coeffs, pink_filt_states[j]); // FIXME: calling this here is sloppy coding
for (int j = 0; j < N_VOICES; j++)
bw_buf_scale(b1[j], b1[j], 5.f, n);
@ -257,8 +258,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
bw_osc_pulse_process_multi(&instance->vco1_pulse_coeffs, (const float **)b3, (const float **)b4, b3, N_VOICES, n);
bw_osc_tri_reset_coeffs(&instance->vco1_tri_coeffs);
} else {
for (int j = 0; j < N_VOICES; j++)
bw_osc_saw_process(&instance->vco_saw_coeffs, b3[j], b4[j], b3[j], n);
bw_osc_saw_process_multi(&instance->vco_saw_coeffs, (const float **)b3, (const float **)b4, b3, N_VOICES, n);
bw_osc_pulse_reset_coeffs(&instance->vco1_pulse_coeffs);
bw_osc_tri_reset_coeffs(&instance->vco1_tri_coeffs);
}
@ -274,8 +274,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
bw_osc_pulse_process_multi(&instance->vco2_pulse_coeffs, (const float **)b2, (const float **)b4, b2, N_VOICES, n);
bw_osc_tri_reset_coeffs(&instance->vco2_tri_coeffs);
} else {
for (int j = 0; j < N_VOICES; j++)
bw_osc_saw_process(&instance->vco_saw_coeffs, b2[j], b4[j], b2[j], n);
bw_osc_saw_process_multi(&instance->vco_saw_coeffs, (const float **)b2, (const float **)b4, b2, N_VOICES, n);
bw_osc_pulse_reset_coeffs(&instance->vco2_pulse_coeffs);
bw_osc_tri_reset_coeffs(&instance->vco2_tri_coeffs);
}
@ -289,8 +288,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
bw_buf_mix(b0[j], b0[j], b3[j], n);
}
for (int j = 0; j < N_VOICES; j++)
bw_osc_filt_process(&instance->voices[j].osc_filt_state, b0[j], b0[j], n);
bw_osc_filt_process_multi(osc_filt_states, (const float **)b0, b0, N_VOICES, n);
const float k = instance->params[p_noise_color] >= 0.5f
? 6.f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs) * bw_pink_filt_get_scaling_k(&instance->pink_filt_coeffs)

View File

@ -1,7 +1,7 @@
/*
* Brickworks
*
* Copyright (C) 2022 Orastron Srl unipersonale
* Copyright (C) 2022, 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.2.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math bw_rand }}}
* description {{{
* Generator of white noise with uniform distribution.
@ -31,6 +31,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_noise_gen_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API.</li>
@ -91,6 +96,13 @@ static inline void bw_noise_gen_process(bw_noise_gen_coeffs *BW_RESTRICT coeffs,
* Generates and fills the first `n_samples` of the output buffer `y` using
* `coeffs`.
*
* #### bw_noise_gen_process_multi()
* ```>>> */
static inline void bw_noise_gen_process_multi(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float **y, int n_channels, int n_samples);
/*! <<<```
* Generates and fills the first `n_samples` of the `n_channels` output
* buffers `y` using `coeffs`.
*
* #### bw_noise_gen_set_sample_rate_scaling()
* ```>>> */
static inline void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen_coeffs *BW_RESTRICT coeffs, char value);
@ -156,6 +168,11 @@ static inline void bw_noise_gen_process(bw_noise_gen_coeffs *BW_RESTRICT coeffs,
y[i] = bw_noise_gen_process1_scaling(coeffs);
}
static inline void bw_noise_gen_process_multi(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float **y, int n_channels, int n_samples) {
for (int i = 0; i < n_channels; i++)
bw_noise_gen_process(coeffs, y[i], n_samples);
}
static inline void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen_coeffs *BW_RESTRICT coeffs, char value) {
coeffs->sample_rate_scaling = value;
}

View File

@ -1,7 +1,7 @@
/*
* Brickworks
*
* Copyright (C) 2022 Orastron Srl unipersonale
* Copyright (C) 2022, 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.2.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config }}}
* description {{{
* Post-filter to decolorate oscillator waveshapers when antialiasing is on.
@ -33,6 +33,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_osc_filt_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API.</li>
@ -83,6 +88,14 @@ static inline void bw_osc_filt_process(bw_osc_filt_state *BW_RESTRICT state, con
* Processes the first `n_samples` of the input buffer `x` and fills the
* first `n_samples` of the output buffer `y`, while using and updating
* `state`.
*
* #### bw_osc_filt_process_multi()
* ```>>> */
static inline void bw_osc_filt_process_multi(bw_osc_filt_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x` and
* fills the first `n_samples` of the `n_channels` output buffers `y`, while
* using and updating each of the `n_channels` `state`s.
* }}} */
/*** Implementation ***/
@ -112,6 +125,11 @@ static inline void bw_osc_filt_process(bw_osc_filt_state *BW_RESTRICT state, con
y[i] = bw_osc_filt_process1(state, x[i]);
}
static inline void bw_osc_filt_process_multi(bw_osc_filt_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) {
for (int i = 0; i < n_channels; i++)
bw_osc_filt_process(state[i], x[i], y[i], n_samples);
}
#ifdef __cplusplus
}
#endif

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.4.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math }}}
* description {{{
* Sawtooth oscillator waveshaper with PolyBLEP antialiasing.
@ -30,6 +30,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_osc_saw_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Fixed unused parameter warnings.</li>
@ -91,11 +96,23 @@ static inline void bw_osc_saw_process(bw_osc_saw_coeffs *BW_RESTRICT coeffs, con
/*! <<<```
* Processes the first `n_samples` of the input buffer `x`, containing the
* normalized phase signal, and fills the first `n_samples` of the output
* buffer `y`, while using and updating `coeffs`.
* buffer `y`, while using `coeffs`.
*
* If antialiasing is enabled, `x_phase_inc` must contain phase increment
* values, otherwise it is ignored and can be `NULL`.
*
* #### bw_osc_saw_process_multi()
* ```>>> */
static inline void bw_osc_saw_process_multi(bw_osc_saw_coeffs *BW_RESTRICT coeffs, const float **x, const float **x_phase_inc, float **y, int n_channels, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x`,
* containing the normalized phase signals, and fills the first `n_samples`
* of the `n_samples` output buffers `y`, while using `coeffs`.
*
* If antialiasing is enabled, each of the `n_channels` buffers pointed by
* `x_phase_inc` must contain phase increment values, otherwise `x_phase_inc`
* is ignored and can be `NULL`.
*
* #### bw_osc_saw_set_antialiasing()
* ```>>> */
static inline void bw_osc_saw_set_antialiasing(bw_osc_saw_coeffs *BW_RESTRICT coeffs, char value);
@ -158,6 +175,15 @@ static inline void bw_osc_saw_process(bw_osc_saw_coeffs *BW_RESTRICT coeffs, con
y[i] = bw_osc_saw_process1(coeffs, x[i]);
}
static inline void bw_osc_saw_process_multi(bw_osc_saw_coeffs *BW_RESTRICT coeffs, const float **x, const float **x_phase_inc, float **y, int n_channels, int n_samples) {
if (x_phase_inc != NULL)
for (int i = 0; i < n_channels; i++)
bw_osc_saw_process(coeffs, x[i], x_phase_inc[i], y[i], n_samples);
else
for (int i = 0; i < n_channels; i++)
bw_osc_saw_process(coeffs, x[i], NULL, y[i], n_samples);
}
static inline void bw_osc_saw_set_antialiasing(bw_osc_saw_coeffs *BW_RESTRICT coeffs, char value) {
coeffs->antialiasing = value;
}

View File

@ -1,7 +1,7 @@
/*
* Brickworks
*
* Copyright (C) 2022 Orastron Srl unipersonale
* Copyright (C) 2022, 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.2.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math }}}
* description {{{
* Sinusoidal oscillator waveshaper.
@ -30,6 +30,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_osc_sin_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API.</li>
@ -69,6 +74,14 @@ static inline void bw_osc_sin_process(const float *x, float* y, int n_samples);
* Processes the first `n_samples` of the input buffer `x`, containing the
* normalized phase signal, and fills the first `n_samples` of the output
* buffer `y`.
*
* #### bw_osc_sin_process_multi()
* ```>>> */
static inline void bw_osc_sin_process_multi(const float **x, float **y, int n_channels, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x`,
* containing the normalized phase signals, and fills the first `n_samples`
* of the `n_channels` output buffers `y`.
* }}} */
/*** Implementation ***/
@ -87,6 +100,11 @@ static inline void bw_osc_sin_process(const float *x, float* y, int n_samples) {
y[i] = bw_osc_sin_process1(x[i]);
}
static inline void bw_osc_sin_process_multi(const float **x, float **y, int n_channels, int n_samples) {
for (int i = 0; i < n_channels; i++)
bw_osc_sin_process(x[i], y[i], n_samples);
}
#ifdef __cplusplus
}
#endif

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.4.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config }}}
* description {{{
* Pinking filter.
@ -34,6 +34,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_pink_filt_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Fixed unused parameter warnings.</li>
@ -119,8 +124,17 @@ static inline float bw_pink_filt_process1_scaling(const bw_pink_filt_coeffs *BW_
static inline void bw_pink_filt_process(bw_pink_filt_coeffs *BW_RESTRICT coeffs, bw_pink_filt_state *BW_RESTRICT state, const float *x, float *y, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the input buffer `x` and fills the
* first `n_samples` of the output buffer `y`, while using and updating both
* `coeffs` and `state` (control and audio rate).
* first `n_samples` of the output buffer `y`, while using `coeffs` and
* both using and updating `state`.
*
* #### bw_pink_filt_process_multi()
* ```>>> */
static inline void bw_pink_filt_process_multi(bw_pink_filt_coeffs *BW_RESTRICT coeffs, bw_pink_filt_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x` and
* fills the first `n_samples` of the `n_channels` output buffers `y`, while
* using the common `coeffs` and both using and updating each of the
* `n_channels` `state`s.
*
* #### bw_pink_filt_set_sample_rate_scaling()
* ```>>> */
@ -207,6 +221,11 @@ static inline void bw_pink_filt_process(bw_pink_filt_coeffs *BW_RESTRICT coeffs,
y[i] = bw_pink_filt_process1(coeffs, state, x[i]);
}
static inline void bw_pink_filt_process_multi(bw_pink_filt_coeffs *BW_RESTRICT coeffs, bw_pink_filt_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) {
for (int i = 0; i < n_channels; i++)
bw_pink_filt_process(coeffs, state[i], x[i], y[i], n_samples);
}
static inline void bw_pink_filt_set_sample_rate_scaling(bw_pink_filt_coeffs *BW_RESTRICT coeffs, char value) {
coeffs->sample_rate_scaling = value;
}

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.4.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math }}}
* description {{{
* Sample rate reducer.
@ -31,6 +31,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_sr_reduce_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Fixed unused parameter warnings.</li>
@ -92,7 +97,16 @@ static inline void bw_sr_reduce_process(bw_sr_reduce_coeffs *BW_RESTRICT coeffs,
/*! <<<```
* Processes the first `n_samples` of the input buffer `x` and fills the
* first `n_samples` of the output buffer `y`, while using `coeffs` and
* using and updating `state` (control and audio rate).
* both using and updating `state` (control and audio rate).
*
* #### bw_sr_reduce_process_multi()
* ```>>> */
static inline void bw_sr_reduce_process_multi(bw_sr_reduce_coeffs *BW_RESTRICT coeffs, bw_sr_reduce_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples);
/*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x` and
* fills the first `n_samples` of the `n_channels` output buffers `y`, while
* using the common `coeffs` and both using and updating each of the
* `n_channels` `state`s.
*
* #### bw_sr_reduce_set_ratio()
* ```>>> */
@ -145,6 +159,11 @@ static inline void bw_sr_reduce_process(bw_sr_reduce_coeffs *BW_RESTRICT coeffs,
y[i] = bw_sr_reduce_process1(coeffs, state, x[i]);
}
static inline void bw_sr_reduce_process_multi(bw_sr_reduce_coeffs *BW_RESTRICT coeffs, bw_sr_reduce_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) {
for (int i = 0; i < n_channels; i++)
bw_sr_reduce_process(coeffs, state[i], x[i], y[i], n_samples);
}
static inline void bw_sr_reduce_set_ratio(bw_sr_reduce_coeffs *BW_RESTRICT coeffs, float value) {
coeffs->ratio = value;
}

View File

@ -57,8 +57,7 @@ namespace Brickworks {
inline void NoiseGen<N_CHANNELS>::process(
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_noise_gen_process(&coeffs, y.data()[i], nSamples);
bw_noise_gen_process_multi(&coeffs, y.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>

View File

@ -28,6 +28,8 @@ namespace Brickworks {
template<BW_SIZE_T N_CHANNELS>
class OscFilt {
public:
OscFilt();
void reset();
void process(
std::array<const float *, N_CHANNELS> x,
@ -36,8 +38,15 @@ namespace Brickworks {
private:
bw_osc_filt_state states[N_CHANNELS];
bw_osc_filt_state *statesP[N_CHANNELS];
};
template<BW_SIZE_T N_CHANNELS>
inline OscFilt<N_CHANNELS>::OscFilt() {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
statesP[i] = states + i;
}
template<BW_SIZE_T N_CHANNELS>
inline void OscFilt<N_CHANNELS>::reset() {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
@ -49,8 +58,7 @@ namespace Brickworks {
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_osc_filt_process(states + i, x.data()[i], y.data()[i], nSamples);
bw_osc_filt_process_multi(statesP, x.data(), y.data(), N_CHANNELS, nSamples);
}
}

View File

@ -53,8 +53,7 @@ namespace Brickworks {
std::array<const float *, N_CHANNELS> x_phase_inc,
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_osc_saw_process(&coeffs, x.data()[i], x_phase_inc.data()[i], y.data()[i], nSamples);
bw_osc_saw_process_multi(&coeffs, x.data(), x_phase_inc.data(), y.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>

View File

@ -36,8 +36,7 @@ namespace Brickworks {
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_osc_sin_process(x.data()[i], y.data()[i], nSamples);
bw_osc_sin_process_multi(x.data(), y.data(), N_CHANNELS, nSamples);
}
}

View File

@ -44,11 +44,14 @@ namespace Brickworks {
private:
bw_pink_filt_coeffs coeffs;
bw_pink_filt_state states[N_CHANNELS];
bw_pink_filt_state *statesP[N_CHANNELS];
};
template<BW_SIZE_T N_CHANNELS>
inline PinkFilt<N_CHANNELS>::PinkFilt() {
bw_pink_filt_init(&coeffs);
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
statesP[i] = states + i;
}
template<BW_SIZE_T N_CHANNELS>
@ -67,8 +70,7 @@ namespace Brickworks {
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_pink_filt_process(&coeffs, states + i, x.data()[i], y.data()[i], nSamples);
bw_pink_filt_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>

View File

@ -41,11 +41,14 @@ namespace Brickworks {
private:
bw_sr_reduce_coeffs coeffs;
bw_sr_reduce_state states[N_CHANNELS];
bw_sr_reduce_state *statesP[N_CHANNELS];
};
template<BW_SIZE_T N_CHANNELS>
inline SRReduce<N_CHANNELS>::SRReduce() {
bw_sr_reduce_init(&coeffs);
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
statesP[i] = states + i;
}
template<BW_SIZE_T N_CHANNELS>
@ -59,8 +62,7 @@ namespace Brickworks {
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_sr_reduce_process(&coeffs, states + i, x.data()[i], y.data()[i], nSamples);
bw_sr_reduce_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>