new bw_buf and using it in synth examples + small optimization to bw_peak

This commit is contained in:
Stefano D'Angelo 2023-01-16 18:08:39 +01:00
parent 3254074efc
commit a5cb9b9c06
4 changed files with 108 additions and 15 deletions

View File

@ -39,6 +39,7 @@
#include <bw_env_gen.h>
#include <bw_gain.h>
#include <bw_env_follow.h>
#include <bw_buf.h>
enum {
p_volume,
@ -299,8 +300,7 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
instance->buf[1][j] = instance->mod_wheel * (out[j] + instance->params[p_mod_mix] * (instance->buf[0][j] - out[j]));
const float vcf_mod = 0.3f * instance->params[p_vcf_mod] * instance->buf[1][0];
for (int j = 0; j < n; j++)
instance->buf[2][j] = instance->params[p_vco1_mod] * instance->buf[1][j];
bw_buf_scale(instance->buf[2], instance->buf[1], instance->params[p_vco1_mod], n);
bw_phase_gen_process(&instance->vco1_phase_gen_coeffs, &instance->vco1_phase_gen_state, instance->buf[2], instance->buf[2], instance->buf[3], n);
if (instance->params[p_vco1_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
bw_osc_tri_process(&instance->vco1_tri_coeffs, instance->buf[2], instance->buf[3], instance->buf[2], n);
@ -314,8 +314,7 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
bw_osc_tri_reset_coeffs(&instance->vco1_tri_coeffs);
}
for (int j = 0; j < n; j++)
instance->buf[1][j] = instance->params[p_vco2_mod] * instance->buf[1][j];
bw_buf_scale(instance->buf[1], instance->buf[1], instance->params[p_vco2_mod], n);
bw_phase_gen_process(&instance->vco2_phase_gen_coeffs, &instance->vco2_phase_gen_state, instance->buf[1], instance->buf[1], instance->buf[3], n);
if (instance->params[p_vco2_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
bw_osc_tri_process(&instance->vco2_tri_coeffs, instance->buf[1], instance->buf[3], instance->buf[1], n);
@ -333,16 +332,16 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
bw_gain_process(&instance->vco2_gain_coeffs, instance->buf[1], instance->buf[1], n);
bw_gain_process(&instance->vco3_gain_coeffs, out, out, n);
bw_gain_process(&instance->noise_gain_coeffs, instance->buf[0], instance->buf[0], n);
for (int j = 0; j < n; j++)
out[j] = out[j] + instance->buf[1][j] + instance->buf[2][j];
bw_buf_mix(out, out, instance->buf[1], n);
bw_buf_mix(out, out, instance->buf[2], n);
bw_osc_filt_process(&instance->osc_filt_state, out, out, n);
const float k = instance->params[p_noise_color] >= 0.5f
? 3.f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs) * bw_pink_filt_get_scaling_k(&instance->pink_filt_coeffs)
: 0.01f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs);
for (int j = 0; j < n; j++)
out[j] = out[j] + 3.f * instance->buf[0][j];
bw_buf_scale(instance->buf[0], instance->buf[0], k, n);
bw_buf_mix(out, out, instance->buf[0], n);
bw_env_gen_process(&instance->vcf_env_gen_coeffs, &instance->vcf_env_gen_state, NULL, n);
float v = instance->params[p_vcf_cutoff] + instance->params[p_vcf_contour] * bw_env_gen_get_y_z1(&instance->vcf_env_gen_state) + vcf_mod;
@ -358,14 +357,12 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
bw_svf_process(&instance->vcf_coeffs, &instance->vcf_state, out, out, NULL, NULL, n);
bw_env_gen_process(&instance->vca_env_gen_coeffs, &instance->vca_env_gen_state, instance->buf[0], n);
for (int j = 0; j < n; j++)
out[j] *= instance->buf[0][j];
bw_buf_mul(out, out, instance->buf[0], n);
bw_phase_gen_process(&instance->a440_phase_gen_coeffs, &instance->a440_phase_gen_state, NULL, instance->buf[0], NULL, n);
bw_osc_sin_process(instance->buf[0], instance->buf[0], n);
if (instance->params[p_a440] >= 0.5f)
for (int j = 0; j < n; j++)
out[j] += instance->buf[0][j];
bw_buf_mix(out, out, instance->buf[0], n);
bw_gain_process(&instance->gain_coeffs, out, out, n);
bw_env_follow_process(&instance->env_follow_coeffs, &instance->env_follow_state, out, NULL, n);

View File

@ -34,6 +34,7 @@
#include <bw_env_gen.h>
#include <bw_gain.h>
#include <bw_env_follow.h>
#include <bw_buf.h>
enum {
p_volume,
@ -140,8 +141,7 @@ void bw_example_synth_simple_process(bw_example_synth_simple instance, const flo
bw_osc_filt_process(&instance->osc_filt_state, out, out, n);
bw_svf_process(&instance->svf_coeffs, &instance->svf_state, out, out, NULL, NULL, n);
bw_env_gen_process(&instance->env_gen_coeffs, &instance->env_gen_state, instance->buf, n);
for (int j = 0; j < n; j++)
out[j] *= instance->buf[j];
bw_buf_mul(out, out, instance->buf, n);
bw_gain_process(&instance->gain_coeffs, out, out, n);
bw_env_follow_process(&instance->env_follow_coeffs, &instance->env_follow_state, out, NULL, n);
}

95
include/bw_buf.h Normal file
View File

@ -0,0 +1,95 @@
/*
* Brickworks
*
* Copyright (C) 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
* the Free Software Foundation, version 3 of the License.
*
* Brickworks 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 Brickworks. If not, see <http://www.gnu.org/licenses/>.
*
* File author: Stefano D'Angelo
*/
/*!
* module_type {{{ utility }}}
* version {{{ 0.3.0 }}}
* requires {{{ bw_config bw_common }}}
* description {{{
* Common operations on buffers.
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.3.0</strong>:
* <ul>
* <li>First release.</li>
* </ul>
* </li>
* </ul>
* }}}
*/
#ifndef _BW_BUF_H
#define _BW_BUF_H
#include <bw_common.h>
#ifdef __cplusplus
extern "C" {
#endif
/*! api {{{
* #### bw_buf_scale()
* ```>>> */
static inline void bw_buf_scale(float *dest, const float *src, float k, int n_elems);
/*! <<<```
* Multiplies the first `n_elems` in `src` by `k` and stores the results in
* the first `n_elems` of `dest`.
*
* #### bw_buf_mix()
* ```>>> */
static inline void bw_buf_mix(float *dest, const float *src1, const float *src2, int n_elems);
/*! <<<```
* Adds the first `n_elems` of `src1` and `src2` and stores the results in
* the first `n_elems` of `dest`.
*
* #### bw_buf_mul()
* ```>>> */
static inline void bw_buf_mul(float *dest, const float *src1, const float *src2, int n_elems);
/*! <<<```
* Multiplies the first `n_elems` of `src1` and `src2` and stores the results
* in the first `n_elems` of `dest`.
* }}} */
/*** Implementation ***/
/* WARNING: This part of the file is not part of the public API. Its content may
* change at any time in future versions. Please, do not use it directly. */
static inline void bw_buf_scale(float *dest, const float *src, float k, int n_elems) {
for (int i = 0; i < n_elems; i++)
dest[i] = k * src[i];
}
static inline void bw_buf_mix(float *dest, const float *src1, const float *src2, int n_elems) {
for (int i = 0; i < n_elems; i++)
dest[i] = src1[i] + src2[i];
}
static inline void bw_buf_mul(float *dest, const float *src1, const float *src2, int n_elems) {
for (int i = 0; i < n_elems; i++)
dest[i] = src1[i] * src2[i];
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -220,7 +220,8 @@ static inline void _bw_ls2_update_mm2_params(bw_ls1_coeffs *BW_RESTRICT coeffs)
if (coeffs->use_bandwidth) {
if (coeffs->param_changed & (_BW_PEAK_PARAM_PEAK_GAIN | _BW_PEAK_PARAM_BANDWIDTH)) {
if (coeffs->param_changed & _BW_PEAK_PARAM_BANDWIDTH) {
coeffs->bw_Q = (bw_pow2f_3(0.5f * coeffs->bandiwdth) * bw_sqrtf_2(coeffs->peak_gain)) * bw_rcpf_2(bw_pow2f_3(coeffs->bandiwdth) - 1.f);
const float k = bw_pow2f_3(coeffs->bandiwdth);
coeffs->bw_Q = bw_sqrtf_2(k * coeffs->peak_gain) * bw_rcpf_2(k - 1.f);
bw_mm2_set_Q(&coeffs->mm2_coeffs, coeffs->bw_Q);
}
bw_mm2_set_coeff_bp(&coeffs->mm2_coeffs, (coeffs->peak_gain - 1.f) * bw_rcpf_2(coeffs->bw_Q));