add overloaded C++ API w/ C-style arrays in bw_buf + update examples

This commit is contained in:
Stefano D'Angelo 2023-08-12 08:04:51 +02:00
parent 3a948b1c99
commit 225ef9108c
4 changed files with 130 additions and 31 deletions

1
TODO
View File

@ -35,7 +35,6 @@ code:
* peak gain + Q ??? * peak gain + Q ???
* merge c++ code into c headers * merge c++ code into c headers
* sr_reduce reset_coeffs? update_coeffs? process_multi? * sr_reduce reset_coeffs? update_coeffs? 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? * drywet -> dry_wet, ringmod -> ring_mod, etc?
* allow nullptr in C++ wrappers where process_multi arg can be NULL * allow nullptr in C++ wrappers where process_multi arg can be NULL
* better src filter * better src filter

View File

@ -237,7 +237,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
else else
for (int j = 0; j < N_VOICES; j++) for (int j = 0; j < N_VOICES; j++)
bw_pink_filt_reset_state(&instance->pink_filt_coeffs, pink_filt_states[j]); // 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
bw_buf_scale_multi((const float **)b1, 5.f, b1, N_VOICES, n); bw_buf_scale_multi((const float * const *)b1, 5.f, b1, N_VOICES, n);
float vcf_mod[N_VOICES]; float vcf_mod[N_VOICES];
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
@ -282,16 +282,16 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
bw_gain_process_multi(&instance->vco2_gain_coeffs, (const float **)b2, b2, N_VOICES, n); bw_gain_process_multi(&instance->vco2_gain_coeffs, (const float **)b2, b2, N_VOICES, n);
bw_gain_process_multi(&instance->vco3_gain_coeffs, (const float **)b0, b0, N_VOICES, n); bw_gain_process_multi(&instance->vco3_gain_coeffs, (const float **)b0, b0, N_VOICES, n);
bw_gain_process_multi(&instance->noise_gain_coeffs, (const float **)b1, b1, N_VOICES, n); bw_gain_process_multi(&instance->noise_gain_coeffs, (const float **)b1, b1, N_VOICES, n);
bw_buf_mix_multi((const float **)b0, (const float **)b2, b0, N_VOICES, n); bw_buf_mix_multi((const float * const *)b0, (const float * const *)b2, b0, N_VOICES, n);
bw_buf_mix_multi((const float **)b0, (const float **)b3, b0, N_VOICES, n); bw_buf_mix_multi((const float * const *)b0, (const float * const *)b3, b0, N_VOICES, n);
bw_osc_filt_process_multi(osc_filt_states, (const float **)b0, b0, N_VOICES, 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 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) ? 6.f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs) * bw_pink_filt_get_scaling_k(&instance->pink_filt_coeffs)
: 0.1f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs); : 0.1f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs);
bw_buf_scale_multi((const float **)b1, k, b1, N_VOICES, n); bw_buf_scale_multi((const float * const *)b1, k, b1, N_VOICES, n);
bw_buf_mix_multi((const float **)b0, (const float **)b1, b0, N_VOICES, n); bw_buf_mix_multi((const float * const *)b0, (const float * const *)b1, b0, N_VOICES, n);
bw_env_gen_process_multi(&instance->vcf_env_gen_coeffs, vcf_env_gen_states, gates, NULL, N_VOICES, n); bw_env_gen_process_multi(&instance->vcf_env_gen_coeffs, vcf_env_gen_states, gates, NULL, N_VOICES, n);
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
@ -309,7 +309,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
} }
bw_env_gen_process_multi(&instance->vca_env_gen_coeffs, vca_env_gen_states, gates, b1, N_VOICES, n); bw_env_gen_process_multi(&instance->vca_env_gen_coeffs, vca_env_gen_states, gates, b1, N_VOICES, n);
bw_buf_mul_multi((const float **)b0, (const float **)b1, b0, N_VOICES, n); bw_buf_mul_multi((const float * const *)b0, (const float * const *)b1, b0, N_VOICES, n);
bw_buf_fill(0.f, out, n); bw_buf_fill(0.f, out, n);
for (int j = 0; j < N_VOICES; j++) for (int j = 0; j < N_VOICES; j++)

View File

@ -167,10 +167,16 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
const float vcf_mod_k = 0.3f * instance->params[p_vcf_mod]; const float vcf_mod_k = 0.3f * instance->params[p_vcf_mod];
float *xb0[N_VOICES], *xb1[N_VOICES], *xb2[N_VOICES], *xb3[N_VOICES], *xb4[N_VOICES];
std::array<float *, N_VOICES> b0, b1, b2, b3, b4, na; std::array<float *, N_VOICES> b0, b1, b2, b3, b4, na;
std::array<const float *, N_VOICES> cb0, cb1, cb2, cb3, cb4; std::array<const float *, N_VOICES> cb0, cb1, cb2, cb3, cb4;
std::array<char, N_VOICES> gates; std::array<char, N_VOICES> gates;
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
xb0[j] = instance->voices[j].buf[0];
xb1[j] = instance->voices[j].buf[1];
xb2[j] = instance->voices[j].buf[2];
xb3[j] = instance->voices[j].buf[3];
xb4[j] = instance->voices[j].buf[4];
b0.data()[j] = instance->voices[j].buf[0]; b0.data()[j] = instance->voices[j].buf[0];
b1.data()[j] = instance->voices[j].buf[1]; b1.data()[j] = instance->voices[j].buf[1];
b2.data()[j] = instance->voices[j].buf[2]; b2.data()[j] = instance->voices[j].buf[2];
@ -208,7 +214,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
instance->pinkFilt.process(cb1, b1, n); instance->pinkFilt.process(cb1, b1, n);
else else
instance->pinkFilt.reset(); // FIXME: calling this here is sloppy coding instance->pinkFilt.reset(); // FIXME: calling this here is sloppy coding
bufScale<N_VOICES>(b1, cb1, 5.f, n); bufScale<N_VOICES>(xb1, 5.f, xb1, n);
float vcf_mod[N_VOICES]; float vcf_mod[N_VOICES];
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
@ -218,8 +224,8 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
} }
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
bufScale<1>({b3.data()[j]}, {b2.data()[j]}, instance->params[p_vco1_mod], n); bufScale<1>({xb2[j]}, instance->params[p_vco1_mod], {xb3[j]}, n);
instance->voices[j].vco1PhaseGen.process({b3.data()[j]}, {b3.data()[j]}, {b4.data()[j]}, n); instance->voices[j].vco1PhaseGen.process({b3.data()[j]}, {b4.data()[j]}, {b3.data()[j]}, n);
} }
if (instance->params[p_vco1_waveform] >= (1.f / 4.f + 1.f / 2.f)) { if (instance->params[p_vco1_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
instance->vco1OscTri.process(cb3, cb4, b3, n); instance->vco1OscTri.process(cb3, cb4, b3, n);
@ -234,7 +240,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
} }
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
bufScale<1>({b2.data()[j]}, {b2.data()[j]}, instance->params[p_vco2_mod], n); bufScale<1>({xb2[j]}, instance->params[p_vco2_mod], {xb2[j]}, n);
instance->voices[j].vco2PhaseGen.process({b2.data()[j]}, {b2.data()[j]}, {b4.data()[j]}, n); instance->voices[j].vco2PhaseGen.process({b2.data()[j]}, {b2.data()[j]}, {b4.data()[j]}, n);
} }
if (instance->params[p_vco2_waveform] >= (1.f / 4.f + 1.f / 2.f)) { if (instance->params[p_vco2_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
@ -253,16 +259,16 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
instance->vco2Gain.process(cb2, b2, n); instance->vco2Gain.process(cb2, b2, n);
instance->vco3Gain.process(cb0, b0, n); instance->vco3Gain.process(cb0, b0, n);
instance->noiseGain.process(cb1, b1, n); instance->noiseGain.process(cb1, b1, n);
bufMix<N_VOICES>(b0, cb0, cb2, n); bufMix<N_VOICES>(xb0, xb2, xb0, n);
bufMix<N_VOICES>(b0, cb0, cb3, n); bufMix<N_VOICES>(xb0, xb3, xb0, n);
instance->oscFilt.process(cb0, b0, n); instance->oscFilt.process(cb0, b0, n);
const float k = instance->params[p_noise_color] >= 0.5f const float k = instance->params[p_noise_color] >= 0.5f
? 6.f * instance->noiseGen.getScalingK() * instance->pinkFilt.getScalingK() ? 6.f * instance->noiseGen.getScalingK() * instance->pinkFilt.getScalingK()
: 0.1f * instance->noiseGen.getScalingK(); : 0.1f * instance->noiseGen.getScalingK();
bufScale<N_VOICES>(b1, cb1, k, n); bufScale<N_VOICES>(xb1, k, xb1, n);
bufMix<N_VOICES>(b0, cb0, cb1, n); bufMix<N_VOICES>(xb0, xb1, xb0, n);
instance->vcfEnvGen.process(gates, na, n); instance->vcfEnvGen.process(gates, na, n);
for (int j = 0; j < N_VOICES; j++) { for (int j = 0; j < N_VOICES; j++) {
@ -280,16 +286,16 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
} }
instance->vcaEnvGen.process(gates, b1, n); instance->vcaEnvGen.process(gates, b1, n);
bufMul<N_VOICES>(b0, cb0, cb1, n); bufMul<N_VOICES>(xb0, xb1, xb0, n);
bufFill<1>({out}, 0.f, n); bufFill<1>(0.f, {out}, n);
for (int j = 0; j < N_VOICES; j++) for (int j = 0; j < N_VOICES; j++)
bufMix<1>({out}, {out}, {b0.data()[j]}, n); bufMix<1>({out}, {xb0[j]}, {out}, n);
instance->a440PhaseGen.process({nullptr}, {instance->buf}, {nullptr}, n); instance->a440PhaseGen.process({nullptr}, {instance->buf}, {nullptr}, n);
oscSinProcess<1>({instance->buf}, {instance->buf}, n); oscSinProcess<1>({instance->buf}, {instance->buf}, n);
if (instance->params[p_a440] >= 0.5f) if (instance->params[p_a440] >= 0.5f)
bufMix<1>({out}, {out}, {instance->buf}, n); bufMix<1>({out}, {instance->buf}, {out}, n);
instance->gain.process({out}, {out}, n); instance->gain.process({out}, {out}, n);
instance->ppm.process({out}, {nullptr}, n); instance->ppm.process({out}, {nullptr}, n);

View File

@ -35,6 +35,8 @@
* <li>Added more <code>const</code> specifiers to input * <li>Added more <code>const</code> specifiers to input
* arguments.</li> * arguments.</li>
* <li>Moved C++ code to C header.</li> * <li>Moved C++ code to C header.</li>
* <li>Added overladed C++ functions taking C-style arrays as
* arguments.</li>
* <li>Removed usage of reserved identifiers.</li> * <li>Removed usage of reserved identifiers.</li>
* </ul> * </ul>
* </li> * </li>
@ -176,7 +178,13 @@ namespace Brickworks {
* ##### Brickworks::bufFill * ##### Brickworks::bufFill
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufFill( inline void bufFill(
float k,
float ** dest,
int nSamples);
template<size_t N_CHANNELS>
inline void bufFill(
float k, float k,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples); int nSamples);
@ -185,7 +193,13 @@ void bufFill(
* ##### Brickworks::bufNeg * ##### Brickworks::bufNeg
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufNeg( inline void bufNeg(
const float * const *src,
float **dest,
int nSamples);
template<size_t N_CHANNELS>
inline void bufNeg(
std::array<const float *, N_CHANNELS> src, std::array<const float *, N_CHANNELS> src,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples); int nSamples);
@ -194,7 +208,14 @@ void bufNeg(
* ##### Brickworks::bufAdd * ##### Brickworks::bufAdd
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufAdd( inline void bufAdd(
const float * const *src,
float **dest,
float k,
int nSamples);
template<size_t N_CHANNELS>
inline void bufAdd(
std::array<const float *, N_CHANNELS> src, std::array<const float *, N_CHANNELS> src,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
float k, float k,
@ -204,7 +225,14 @@ void bufAdd(
* ##### Brickworks::bufScale * ##### Brickworks::bufScale
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufScale( inline void bufScale(
const float * const *src,
float k,
float **dest,
int nSamples);
template<size_t N_CHANNELS>
inline void bufScale(
std::array<const float *, N_CHANNELS> src, std::array<const float *, N_CHANNELS> src,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
float k, float k,
@ -214,7 +242,14 @@ void bufScale(
* ##### Brickworks::bufMix * ##### Brickworks::bufMix
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufMix( inline void bufMix(
const float * const *src1,
const float * const *src2,
float **dest,
int nSamples);
template<size_t N_CHANNELS>
inline void bufMix(
std::array<const float *, N_CHANNELS> src1, std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2, std::array<const float *, N_CHANNELS> src2,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
@ -224,7 +259,14 @@ void bufMix(
* ##### Brickworks::bufMul * ##### Brickworks::bufMul
* ```>>> */ * ```>>> */
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
void bufMul( inline void bufMul(
const float * const *src1,
const float * const *src2,
float **dest,
int nSamples);
template<size_t N_CHANNELS>
inline void bufMul(
std::array<const float *, N_CHANNELS> src1, std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2, std::array<const float *, N_CHANNELS> src2,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
@ -355,12 +397,28 @@ static inline void bw_buf_mul_multi(const float * const *src1, const float * con
namespace Brickworks { namespace Brickworks {
template<size_t N_CHANNELS>
inline void bufFill(
float k,
float ** dest,
int nSamples) {
bw_buf_fill_multi(k, dest, N_CHANNELS, nSamples);
}
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
inline void bufFill( inline void bufFill(
float k, float k,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_fill_multi(k, dest.data(), N_CHANNELS, nSamples); bufFill<N_CHANNELS>(k, dest.data(), nSamples);
}
template<size_t N_CHANNELS>
inline void bufNeg(
const float * const *src,
float **dest,
int nSamples) {
bw_buf_neg_multi(src, dest, N_CHANNELS, nSamples);
} }
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
@ -368,7 +426,16 @@ inline void bufNeg(
std::array<const float *, N_CHANNELS> src, std::array<const float *, N_CHANNELS> src,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_neg_multi(src.data(), dest.data(), N_CHANNELS, nSamples); bufNeg<N_CHANNELS>(src, dest, nSamples);
}
template<size_t N_CHANNELS>
inline void bufAdd(
const float * const *src,
float **dest,
float k,
int nSamples) {
bw_buf_add_multi(src, k, dest, N_CHANNELS, nSamples);
} }
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
@ -377,7 +444,16 @@ inline void bufAdd(
float k, float k,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_add_multi(src.data(), k, dest.data(), N_CHANNELS, nSamples); bufAdd<N_CHANNELS>(src, k, dest, nSamples);
}
template<size_t N_CHANNELS>
inline void bufScale(
const float * const *src,
float k,
float **dest,
int nSamples) {
bw_buf_scale_multi(src, k, dest, N_CHANNELS, nSamples);
} }
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
@ -386,7 +462,16 @@ inline void bufScale(
float k, float k,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_scale_multi(src.data(), k, dest.data(), N_CHANNELS, nSamples); bufScale<N_CHANNELS>(src, k, dest, nSamples);
}
template<size_t N_CHANNELS>
inline void bufMix(
const float * const *src1,
const float * const *src2,
float **dest,
int nSamples) {
bw_buf_mix_multi(src1, src2, dest, N_CHANNELS, nSamples);
} }
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
@ -395,7 +480,16 @@ inline void bufMix(
std::array<const float *, N_CHANNELS> src2, std::array<const float *, N_CHANNELS> src2,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_mix_multi(src1.data(), src2.data(), dest.data(), N_CHANNELS, nSamples); bufMix<N_CHANNELS>(src1, src2, dest, nSamples);
}
template<size_t N_CHANNELS>
inline void bufMul(
const float * const *src1,
const float * const *src2,
float **dest,
int nSamples) {
bw_buf_mul_multi(src1, src2, dest, N_CHANNELS, nSamples);
} }
template<size_t N_CHANNELS> template<size_t N_CHANNELS>
@ -404,7 +498,7 @@ inline void bufMul(
std::array<const float *, N_CHANNELS> src2, std::array<const float *, N_CHANNELS> src2,
std::array<float *, N_CHANNELS> dest, std::array<float *, N_CHANNELS> dest,
int nSamples) { int nSamples) {
bw_buf_mul_multi(src1.data(), src2.data(), dest.data(), N_CHANNELS, nSamples); bufMul<N_CHANNELS>(src1, src2, dest, nSamples);
} }
} }