bw_delay tentative + bw_ceilf + bw_buf_fill + BW_SIZE_T + fix bw_wah doc

This commit is contained in:
Stefano D'Angelo 2023-03-04 08:17:31 +01:00
parent 1843233c96
commit ab417d4c61
6 changed files with 281 additions and 19 deletions

4
TODO
View File

@ -26,6 +26,10 @@ code:
* better common config.h (less stuff maybe, or more stuff - decide)
* separate tests an examples?
* define common midi CCs for examples
* get_y_z1, common strategy?
* sqrt(0) and corner cases, common strategy?
* MEM_REQ_ROUGH() macro?
* use BW_SIZE_T, check constant types
build system:
* make makefiles handle paths with spaces etc

View File

@ -29,7 +29,7 @@
* <ul>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Added `bw_buf_add()`.</li>
* <li>Added `bw_buf_fill()` and `bw_buf_add()`.</li>
* </ul>
* </li>
* <li>Version <strong>0.3.0</strong>:
@ -51,6 +51,12 @@ extern "C" {
#endif
/*! api {{{
* #### bw_buf_fill()
* ```>>> */
static inline voide bw_buf_fill(float *dest, float k, int n_elems);
/*! <<<```
* Sets the first `n_elems` in `dest` to `k`.
*
* #### bw_buf_add()
* ```>>> */
static inline void bw_buf_add(float *dest, const float *src, float k, int n_elems);
@ -85,6 +91,11 @@ static inline void bw_buf_mul(float *dest, const float *src1, const float *src2,
/* 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 voide bw_buf_fill(float *dest, float k, int n_elems) {
for (int i = 0; i < n_elems; i++)
dest[i] = k;
}
static inline void bw_buf_add(float *dest, const float *src, float k, int n_elems) {
for (int i = 0; i < n_elems; i++)
dest[i] = k + src[i];

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ foundation }}}
* version {{{ 0.2.0 }}}
* version {{{ 0.4.0 }}}
* requires {{{ bw_config }}}
* description {{{
* A common header to make sure that a bunch of basic definitions are
@ -28,10 +28,15 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Added `BW_SIZE_T`.</li>
* </ul>
* </li>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Removed <code>BW_MALLOC</code>, <code>BW_REALLOC</code>, and <code>BW_FREE</code>.</li>
* <li>Added <code>BW_RESTRICT</code>.</li>
* <li>Removed `BW_MALLOC`, `BW_REALLOC`, and `BW_FREE`.</li>
* <li>Added `BW_RESTRICT`.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>:
@ -58,11 +63,16 @@
#include <bw_config.h>
/*! ...
*
* #### NULL
* If `NULL` is not defined, then `stddef.h` is `#include`d.
* #### NULL and BW_SIZE_T
* If `NULL` or `BW_SIZE_T` are not defined, then `stddef.h` is `#include`d.
*
* If `BW_SIZE_T` is not defined, the it is defined as `size_t`.
* >>> */
#ifndef NULL
#if !defined(NULL) || !defined(BW_SIZE_T)
# include <stddef.h>
# if !defined(BW_SIZE_T)
# define BW_SIZE_T size_t
# endif
#endif
/*! ...
*
@ -86,7 +96,8 @@
/*! ...
*
* #### BW_RESTRICT
* If `BW_RESTRICT` is not defined, then it is defined as `restrict` if C99 is supported.
* If `BW_RESTRICT` is not defined, then it is defined as `restrict` if C99
* is supported.
* >>> */
#ifndef BW_RESTRICT
# if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)

213
include/bw_delay.h Normal file
View File

@ -0,0 +1,213 @@
/*
* 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 {{{ dsp }}}
* version {{{ 0.4.0 }}}
* requires {{{ bw_buf bw_config bw_common bw_math }}}
* description {{{
* Interpolated delay line.
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>First release.</li>
* </ul>
* </li>
* </ul>
* }}}
*/
#ifndef _BW_DELAY_H
#define _BW_DELAY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bw_common.h>
/*! api {{{
* #### bw_delay_coeffs
* ```>>> */
typedef struct _bw_delay_coeffs bw_delay_coeffs;
/*! <<<```
* Coefficients and related.
*
* ### bw_delay_state
* ```>>> */
typedef struct _bw_delay_state bw_delay_state;
/*! <<<```
* Internal state and related.
*
* #### bw_delay_init()
* ```>>> */
static inline void bw_delay_init(bw_delay_coeffs *BW_RESTRICT coeffs);
/*! <<<```
* Initializes input parameter values in `coeffs`.
*
* #### bw_delay_set_sample_rate()
* ```>>> */
static inline void bw_delay_set_sample_rate(bw_delay_coeffs *BW_RESTRICT coeffs, float sample_rate);
/*! <<<```
* Sets the `sample_rate` (Hz) value in `coeffs`.
*
* ### bw_delay_mem_req()
* ```>>> */
static inline BW_SIZE_T bw_delay_mem_req(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, float max_delay);
/*! <<<```
* XXX
*
* ### bw_delay_mem_set()
* ```>>> */
static inline void bw_delay_mem_set(bw_delay_state *BW_RESTRICT state, void *mem);
/*! <<<```
* XXX
*
* #### bw_delay_reset_coeffs()
* ```>>> */
static inline void bw_delay_reset_coeffs(bw_delay_coeffs *BW_RESTRICT coeffs);
/*! <<<```
* Resets coefficients in `coeffs` to assume their target values.
*
* #### bw_delay_reset_state()
* ```>>> */
static inline void bw_delay_reset_state(const bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state);
/*! <<<```
* Resets the given `state` to its initial values using the given `coeffs`.
*
* #### bw_delay_update_coeffs_ctrl()
* ```>>> */
static inline void bw_delay_update_coeffs_ctrl(bw_delay_coeffs *BW_RESTRICT coeffs);
/*! <<<```
* Triggers control-rate update of coefficients in `coeffs`.
*
* #### bw_delay_update_coeffs_audio()
* ```>>> */
static inline void bw_delay_update_coeffs_audio(bw_delay_coeffs *BW_RESTRICT coeffs);
/*! <<<```
* Triggers audio-rate update of coefficients in `coeffs`.
*
* #### bw_delay_process1()
* ```>>> */
static inline float bw_delay_process1(const bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, float x);
/*! <<<```
* Processes one input sample `x` using `coeffs`, while using and updating
* `state`. Returns the corresponding output sample.
*
* #### bw_env_follow_process()
* ```>>> */
static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_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).
*
* #### bw_delay_set_delay()
* ```>>> */
static inline void bw_delay_set_delay(bw_delay_coeffs *BW_RESTRICT coeffs, float value);
/*! <<<```
* XXX
*
* Default value: `0.f`.
* }}} */
/*** 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. */
#include <bw_buf.h>
#include <bw_math.h>
struct _bw_delay_coeffs {
// Coefficients
float fs;
// Parameters
float delay;
};
struct _bw_delay_state {
float *buf;
BW_SIZE_T len;
BW_SIZE_T idx;
};
static inline void bw_delay_init(bw_delay_coeffs *BW_RESTRICT coeffs) {
coeffs->delay = 0.f;
}
static inline void bw_delay_set_sample_rate(bw_delay_coeffs *BW_RESTRICT coeffs, float sample_rate) {
coeffs->fs = sample_rate;
}
static inline BW_SIZE_T bw_delay_mem_req(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, float max_delay) {
return (BW_SIZE_T)bw_ceilf(coeffs->fs * max_delay) + 1;
}
static inline void bw_delay_mem_set(bw_delay_state *BW_RESTRICT state, void *mem) {
state->buf = (float *)mem;
}
static inline void bw_delay_reset_coeffs(bw_delay_coeffs *BW_RESTRICT coeffs) {
}
static inline void bw_delay_reset_state(const bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state) {
bw_buf_fill(state->buf, 0.f, size->len);
state->idx = 0;
}
static inline void bw_delay_update_coeffs_ctrl(bw_delay_coeffs *BW_RESTRICT coeffs) {
}
static inline void bw_delay_update_coeffs_audio(bw_delay_coeffs *BW_RESTRICT coeffs) {
}
static inline float bw_delay_process1(const bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, float x) {
// XXX optim, coeffs
const float s = coeffs->delay * coeffs->fs;
const float f = bw_floorf(s);
const float d = coeffs->delay - f;
const BW_SIZE_T j = (BW_SIZE_T)d;
const BW_SIZE_T l = (state->idx >= d ? state->idx : state->idx + state->len) - d;
const BW_SIZE_T h = l == state->len - 1 ? 0 : l + 1;
const BW_SIZE_T n = state->idx == state->len - 1 ? 0 : state->idx + 1;
state->buf[idx] = x;
const float y = state->buf[state->idx] + d * (state->buf[n] - state->buf[state->idx]);
state->idx = n;
return y;
}
static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, const float *x, float *y, int n_samples) {
for (int i = 0; i < n_samples; i++)
y[i] = bw_delay_process1(coeffs, state, x[i];
}
static inline void bw_delay_set_delay(bw_delay_coeffs *BW_RESTRICT coeffs, float value) {
coeffs->delay = value;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -70,19 +70,22 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Added `bw_ceilf()`.</li>
* </ul>
* </li>
* <li>Version <strong>0.3.0</strong>:
* <ul>
* <li>Added <code>bw_log10f_3()</code>, <code>bw_pow10f_3()</code>,
* <code>bw_dB2linf_3()</code>, and
* <code>bw_lin2dBf_3()</code>.</li>
* <li>Fixed computation bug in <code>bw_sqrtf_2()</code>.</li>
* <li>Added `bw_log10f_3()`, `bw_pow10f_3()`, `bw_dB2linf_3()`, and
* `bw_lin2dBf_3()`.</li>
* <li>Fixed computation bug in `bw_sqrtf_2()`.</li>
* </ul>
* </li>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Added <code>bw_sin2pif_3()</code>, <code>bw_cos2pif_3()</code>,
* <code>bw_tan2pif_3()</code>, <code>bw_omega_3lognr()</code>, and
* <code>bw_tanhf_3()</code>.</li>
* <li>Added `bw_sin2pif_3()`, `bw_cos2pif_3()`, `bw_tan2pif_3()`,
* `bw_omega_3lognr()`, and `bw_tanhf_3()`.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>:
@ -227,9 +230,16 @@ static inline float bw_roundf(float x);
* ```>>> */
static inline float bw_floorf(float x);
/*! <<<```
* Returns the biggest integer lower or equal than `x` (i.e., `x` is rounded
* Returns the biggest integer less or equal than `x` (i.e., `x` is rounded
* down).
*
* #### bw_ceilf()
* ```>>> */
static inline float bw_ceilf(float x);
/*! <<<```
* Returns the smallest integer greater or equal than `x` (i.e., `x` is
* rounded up).
*
* #### bw_rcpf_2()
* ```>>> */
static inline float bw_rcpf_2(float x);
@ -525,6 +535,14 @@ static inline float bw_floorf(float x) {
return t.f - s.f;
}
static inline float bw_ceilf(float x) {
_bw_floatint t = {.f = bw_truncf(x)}; // first bit set when t < 0
_bw_floatint y = {.f = x - t.f}; // first bit set when t > x
_bw_floatint s = {.f = 1.f};
s.i &= bw_signfilli32(~t.i & y.i);
return t.f + s.f;
}
static inline float bw_rcpf_2(float x) {
_bw_floatint v = {.f = x};
v.i = 0x7ef0e840 - v.i;

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.3.0 }}}
* version {{{ 0.4.0 }}}
* requires {{{ bw_config bw_common bw_one_pole bw_math bw_svf }}}
* description {{{
* Wah effect.
@ -29,6 +29,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>Fixed documentation for `bw_wah_state` and `bw_wah_reset_state()`.</li>
* </ul>
* </li>
* <li>Version <strong>0.3.0</strong>:
* <ul>
* <li>Use bandpass SVF output rather than lowpass.</li>
@ -59,7 +64,7 @@ typedef struct _bw_wah_coeffs bw_wah_coeffs;
/*! <<<```
* Coefficients and related.
*
* ### bw_svf_state
* ### bw_wah_state
* ```>>> */
typedef struct _bw_wah_state bw_wah_state;
/*! <<<```
@ -77,7 +82,7 @@ static inline void bw_wah_set_sample_rate(bw_wah_coeffs *BW_RESTRICT coeffs, flo
/*! <<<```
* Sets the `sample_rate` (Hz) value in `coeffs`.
*
* #### bw_wah_reset_state()
* #### bw_wah_reset_coeffs()
* ```>>> */
static inline void bw_wah_reset_coeffs(bw_wah_coeffs *BW_RESTRICT coeffs);
/*! <<<```