multichannel api in bw_buf + bwpp_buf + adjusted synth(pp)_poly

This commit is contained in:
Stefano D'Angelo 2023-07-04 11:06:34 +02:00
parent c4074927ce
commit 6e1212d8f5
4 changed files with 217 additions and 30 deletions

View File

@ -237,8 +237,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
else
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
for (int j = 0; j < N_VOICES; j++)
bw_buf_scale(b1[j], b1[j], 5.f, n);
bw_buf_scale_multi(b1, (const float **)b1, 5.f, N_VOICES, n);
float vcf_mod[N_VOICES];
for (int j = 0; j < N_VOICES; j++) {
@ -283,20 +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->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);
for (int j = 0; j < N_VOICES; j++) {
bw_buf_mix(b0[j], b0[j], b2[j], n);
bw_buf_mix(b0[j], b0[j], b3[j], n);
}
bw_buf_mix_multi(b0, (const float **)b0, (const float **)b2, N_VOICES, n);
bw_buf_mix_multi(b0, (const float **)b0, (const float **)b3, 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
? 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);
for (int j = 0; j < N_VOICES; j++) {
bw_buf_scale(b1[j], b1[j], k, n);
bw_buf_mix(b0[j], b0[j], b1[j], n);
}
bw_buf_scale_multi(b1, (const float **)b1, k, N_VOICES, n);
bw_buf_mix_multi(b0, (const float **)b0, (const float **)b1, 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++) {
@ -314,8 +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);
for (int j = 0; j < N_VOICES; j++)
bw_buf_mul(b0[j], b0[j], b1[j], n);
bw_buf_mul_multi(b0, (const float **)b0, (const float **)b1, N_VOICES, n);
bw_buf_fill(out, 0.f, n);
for (int j = 0; j < N_VOICES; j++)

View File

@ -21,7 +21,7 @@
#include "bw_example_synthpp_poly.h"
#include <bw_math.h>
#include <bw_buf.h>
#include <bwpp_buf.h>
#include <bw_voice_alloc.h>
void bw_example_synthpp_poly_init(bw_example_synthpp_poly *instance) {
@ -209,8 +209,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
instance->pinkFilt.process(cb1, b1, n);
else
instance->pinkFilt.reset(); // FIXME: calling this here is sloppy coding
for (int j = 0; j < N_VOICES; j++)
bw_buf_scale(b1.data()[j], b1.data()[j], 5.f, n);
bufScale<N_VOICES>(b1, cb1, 5.f, n);
float vcf_mod[N_VOICES];
for (int j = 0; j < N_VOICES; j++) {
@ -220,7 +219,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
}
for (int j = 0; j < N_VOICES; j++) {
bw_buf_scale(b3.data()[j], b2.data()[j], instance->params[p_vco1_mod], n);
bufScale<1>({b3.data()[j]}, {b2.data()[j]}, instance->params[p_vco1_mod], n);
instance->voices[j].vco1PhaseGen.process({b3.data()[j]}, {b3.data()[j]}, {b4.data()[j]}, n);
}
if (instance->params[p_vco1_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
@ -236,7 +235,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
}
for (int j = 0; j < N_VOICES; j++) {
bw_buf_scale(b2.data()[j], b2.data()[j], instance->params[p_vco2_mod], n);
bufScale<1>({b2.data()[j]}, {b2.data()[j]}, instance->params[p_vco2_mod], 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)) {
@ -255,20 +254,16 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
instance->vco2Gain.process(cb2, b2, n);
instance->vco3Gain.process(cb0, b0, n);
instance->noiseGain.process(cb1, b1, n);
for (int j = 0; j < N_VOICES; j++) {
bw_buf_mix(b0.data()[j], b0.data()[j], b2.data()[j], n);
bw_buf_mix(b0.data()[j], b0.data()[j], b3.data()[j], n);
}
bufMix<N_VOICES>(b0, cb0, cb2, n);
bufMix<N_VOICES>(b0, cb0, cb3, n);
instance->oscFilt.process(cb0, b0, n);
const float k = instance->params[p_noise_color] >= 0.5f
? 6.f * instance->noiseGen.getScalingK() * instance->pinkFilt.getScalingK()
: 0.1f * instance->noiseGen.getScalingK();
for (int j = 0; j < N_VOICES; j++) {
bw_buf_scale(b1.data()[j], b1.data()[j], k, n);
bw_buf_mix(b0.data()[j], b0.data()[j], b1.data()[j], n);
}
bufScale<N_VOICES>(b1, cb1, k, n);
bufMix<N_VOICES>(b0, cb0, cb1, n);
instance->vcfEnvGen.process(gates, na, n);
for (int j = 0; j < N_VOICES; j++) {
@ -286,17 +281,16 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
}
instance->vcaEnvGen.process(gates, b1, n);
for (int j = 0; j < N_VOICES; j++)
bw_buf_mul(b0.data()[j], b0.data()[j], b1.data()[j], n);
bufMul<N_VOICES>(b0, cb0, cb1, n);
bw_buf_fill(out, 0.f, n);
bufFill<1>({out}, 0.f, n);
for (int j = 0; j < N_VOICES; j++)
bw_buf_mix(out, out, b0.data()[j], n);
bufMix<1>({out}, {out}, {b0.data()[j]}, n);
instance->a440PhaseGen.process({nullptr}, {instance->buf}, {nullptr}, n);
oscSinProcess<1>({instance->buf}, {instance->buf}, n);
if (instance->params[p_a440] >= 0.5f)
bw_buf_mix(out, out, instance->buf, n);
bufMix<1>({out}, {out}, {instance->buf}, n);
instance->gain.process({out}, {out}, n);
instance->ppm.process({out}, {nullptr}, n);

View File

@ -29,6 +29,7 @@
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_buf_*_multi()</code>.</li>
* <li>Added <code>bw_buf_neg()</code>.</li>
* </ul>
* </li>
@ -97,6 +98,53 @@ static inline void bw_buf_mul(float *dest, const float *src1, const float *src2,
/*! <<<```
* Multiplies the first `n_elems` of `src1` and `src2` and stores the results
* in the first `n_elems` of `dest`.
*
* #### bw_buf_fill_multi()
* ```>>> */
static inline void bw_buf_fill_multi(float **dest, float k, int n_channels, int n_elems);
/*! <<<```
* Sets the first `n_elems` in each of the `n_channels` buffers `dest` to
* `k`.
*
* #### bw_buf_neg_multi()
* ```>>> */
static inline void bw_buf_neg_multi(float **dest, const float **src, int n_channels, int n_elems);
/*! <<<```
* Inverts the sign of the first `n_elems` in each of the `n_channels`
* buffers `src` and stores the results in the first `n_elems` in each of the
* `n_channels` buffers `dest`.
*
* #### bw_buf_add_multi()
* ```>>> */
static inline void bw_buf_add_multi(float **dest, const float **src, float k, int n_channels, int n_elems);
/*! <<<```
* Adds `k` to the first `n_elems` in each of the `n_channels` buffers `src`
* and stores the results in the first `n_elems` in each of the `n_channels`
* buffers `dest`.
*
* #### bw_buf_scale_multi()
* ```>>> */
static inline void bw_buf_scale_multi(float **dest, const float **src, float k, int n_channels, int n_elems);
/*! <<<```
* Multiplies the first `n_elems` in each of the `n_channels` buffers `src`
* by `k` and stores the results in the first `n_elems` in each of the
* `n_channels` buffers `dest`.
*
* #### bw_buf_mix_multi()
* ```>>> */
static inline void bw_buf_mix_multi(float **dest, const float **src1, const float **src2, int n_channels, int n_elems);
/*! <<<```
* Adds the first `n_elems` in each of the `n_channels` buffers `src1` and
* `src2` and stores the results in the first `n_elems` in each of the
* `n_channels` buffers `dest`.
*
* #### bw_buf_mul_multi()
* ```>>> */
static inline void bw_buf_mul_multi(float **dest, const float **src1, const float **src2, int n_channels, int n_elems);
/*! <<<```
* Multiplies the first `n_elems` in each of the `n_channels` buffers `src1`
* and `src2` and stores the results in the first `n_elems` in each of the
* `n_channels` buffers `dest`.
* }}} */
/*** Implementation ***/
@ -134,6 +182,36 @@ static inline void bw_buf_mul(float *dest, const float *src1, const float *src2,
dest[i] = src1[i] * src2[i];
}
static inline void bw_buf_fill_multi(float **dest, float k, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_fill(dest[i], k, n_elems);
}
static inline void bw_buf_neg_multi(float **dest, const float **src, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_neg(dest[i], src[i], n_elems);
}
static inline void bw_buf_add_multi(float **dest, const float **src, float k, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_add(dest[i], src[i], k, n_elems);
}
static inline void bw_buf_scale_multi(float **dest, const float **src, float k, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_scale(dest[i], src[i], k, n_elems);
}
static inline void bw_buf_mix_multi(float **dest, const float **src1, const float **src2, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_mix(dest[i], src1[i], src2[i], n_elems);
}
static inline void bw_buf_mul_multi(float **dest, const float **src1, const float **src2, int n_channels, int n_elems) {
for (int i = 0; i < n_channels; i++)
bw_buf_mul(dest[i], src1[i], src2[i], n_elems);
}
#ifdef __cplusplus
}
#endif

121
include/bwpp_buf.h Normal file
View File

@ -0,0 +1,121 @@
/*
* Brickworks
*
* Copyright (C) 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can reosc_sinribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Brickworks is osc_sinributed 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 Brickworks. If not, see <http://www.gnu.org/licenses/>.
*
* File author: Stefano D'Angelo
*/
#ifndef BWPP_BUF_H
#define BWPP_BUF_H
#include <bw_buf.h>
#include <array>
namespace Brickworks {
template<BW_SIZE_T N_CHANNELS>
void bufFill(
std::array<float *, N_CHANNELS> dest,
float k,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
void bufNeg(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
void bufAdd(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
float k,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
void bufScale(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
float k,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
void bufMix(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
void bufMul(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2,
int nSamples);
template<BW_SIZE_T N_CHANNELS>
inline void bufFill(
std::array<float *, N_CHANNELS> dest,
float k,
int nSamples) {
bw_buf_fill_multi(dest.data(), k, N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>
inline void bufNeg(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
int nSamples) {
bw_buf_neg_multi(dest.data(), src.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>
inline void bufAdd(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
float k,
int nSamples) {
bw_buf_add_multi(dest.data(), src.data(), k, N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>
inline void bufScale(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src,
float k,
int nSamples) {
bw_buf_scale_multi(dest.data(), src.data(), k, N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>
inline void bufMix(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2,
int nSamples) {
bw_buf_mix_multi(dest.data(), src1.data(), src2.data(), N_CHANNELS, nSamples);
}
template<BW_SIZE_T N_CHANNELS>
inline void bufMul(
std::array<float *, N_CHANNELS> dest,
std::array<const float *, N_CHANNELS> src1,
std::array<const float *, N_CHANNELS> src2,
int nSamples) {
bw_buf_mul_multi(dest.data(), src1.data(), src2.data(), N_CHANNELS, nSamples);
}
}
#endif