const arg for bw_note_queue_is_valid() + bw_one_pole_process{_multi} use BW_SIZE_T + beginning of debugging code in bw_one_pole

This commit is contained in:
Stefano D'Angelo 2023-07-25 15:03:29 +02:00
parent 8299cb7eae
commit d9272453fd
3 changed files with 378 additions and 73 deletions

5
TODO
View File

@ -3,12 +3,12 @@
code: code:
* android, ios * android, ios
* debugging (design by contract?, trace calls?)
1.0.0 1.0.0
----- -----
code: code:
* debugging
* check all examples again * check all examples again
* osc post filter (and one pole init, slew rate, etc.) val from input? set state instead? * osc post filter (and one pole init, slew rate, etc.) val from input? set state instead?
* audio rate optional pulse width/slope inputs? * audio rate optional pulse width/slope inputs?
@ -59,9 +59,10 @@ code:
* should remove bw_config? * should remove bw_config?
* use custom NDEBUG? * use custom NDEBUG?
* NULL (C) vs BW_SIZE_T (non-C)...? * NULL (C) vs BW_SIZE_T (non-C)...?
* clearly specify that state is tied to a particular set of coeffs (1:N)
build system: build system:
* single header generation * single header generation (vs modules in bwp... to think about)
post 1.0.0 post 1.0.0
---------- ----------

View File

@ -125,7 +125,7 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
* *
* #### bw_note_queue_add() * #### bw_note_queue_add()
* ```>>> */ * ```>>> */
static inline char bw_note_queue_is_valid(bw_note_queue *BW_RESTRICT queue); static inline char bw_note_queue_is_valid(const bw_note_queue *BW_RESTRICT queue);
/*! <<<``` /*! <<<```
* WRITEME * WRITEME
* }}} */ * }}} */
@ -179,7 +179,7 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue)); BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
} }
static inline char bw_note_queue_is_valid(bw_note_queue *BW_RESTRICT queue) { static inline char bw_note_queue_is_valid(const bw_note_queue *BW_RESTRICT queue) {
BW_ASSERT(queue != NULL); BW_ASSERT(queue != NULL);
if (queue->n_events >= 128 || queue->n_pressed >= 128) if (queue->n_events >= 128 || queue->n_pressed >= 128)

View File

@ -32,6 +32,10 @@
* <ul> * <ul>
* <li>Version <strong>0.6.0</strong>: * <li>Version <strong>0.6.0</strong>:
* <ul> * <ul>
* <li><code>bw_one_pole_process()</code> and
* <code>bw_one_pole_process_multi()</code> now use
* <code>BW_SIZE_T</code> to count samples and channels.</li>
* <li>Added debugging code.</li>
* <li>Removed dependency on bw_config.</li> * <li>Removed dependency on bw_config.</li>
* <li>Fixed bug when setting very high cutoff values.</li> * <li>Fixed bug when setting very high cutoff values.</li>
* </ul> * </ul>
@ -168,7 +172,7 @@ static inline float bw_one_pole_process1_asym_sticky_rel(const bw_one_pole_coeff
* *
* #### bw_one_pole_process() * #### bw_one_pole_process()
* ```>>> */ * ```>>> */
static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, const float *x, float *y, int n_samples); static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, const float *x, float *y, BW_SIZE_T n_samples);
/*! <<<``` /*! <<<```
* Processes the first `n_samples` of the input buffer `x` and fills the * 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 * first `n_samples` of the output buffer `y`, while using and updating both
@ -178,7 +182,7 @@ static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, b
* *
* #### bw_one_pole_process_multi() * #### bw_one_pole_process_multi()
* ```>>> */ * ```>>> */
static inline void bw_one_pole_process_multi(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples); static inline void bw_one_pole_process_multi(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state **BW_RESTRICT state, const float **x, float **y, BW_SIZE_T n_channels, BW_SIZE_T n_samples);
/*! <<<``` /*! <<<```
* Processes the first `n_samples` of the `n_channels` input buffers `x` and * 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 * fills the first `n_samples` of the `n_channels` output buffers `y`, while
@ -290,6 +294,18 @@ static inline void bw_one_pole_set_sticky_mode(bw_one_pole_coeffs *BW_RESTRICT c
static inline float bw_one_pole_get_y_z1(const bw_one_pole_state *BW_RESTRICT state); static inline float bw_one_pole_get_y_z1(const bw_one_pole_state *BW_RESTRICT state);
/*! <<<``` /*! <<<```
* Returns the last output sample as stored in `state`. * Returns the last output sample as stored in `state`.
*
* #### bw_one_pole_coeffs_is_valid()
* ```>>> */
static inline char bw_one_pole_coeffs_is_valid(const bw_one_pole_coeffs *BW_RESTRICT coeffs);
/*! <<<```
* WRITEME
*
* #### bw_one_pole_state_is_valid()
* ```>>> */
static inline char bw_one_pole_state_is_valid(const bw_one_pole_state *BW_RESTRICT state);
/*! <<<```
* WRITEME
* }}} */ * }}} */
/*** Implementation ***/ /*** Implementation ***/
@ -299,24 +315,44 @@ static inline float bw_one_pole_get_y_z1(const bw_one_pole_state *BW_RESTRICT st
#include <bw_math.h> #include <bw_math.h>
struct _bw_one_pole_coeffs { #ifdef BW_DEBUG_DEEP
// Coefficients enum _bw_one_pole_coeffs_state {
float Ttm2pi; _bw_one_pole_coeffs_state_invalid,
_bw_one_pole_coeffs_state_init,
_bw_one_pole_coeffs_state_set_sample_rate,
_bw_one_pole_coeffs_state_reset_coeffs,
};
#endif
float mA1u; struct _bw_one_pole_coeffs {
float mA1d; #ifdef BW_DEBUG_DEEP
float st2; uint32_t hash;
enum _bw_one_pole_coeffs_state state;
uint32_t reset_id;
#endif
// Coefficients
float Ttm2pi;
float mA1u;
float mA1d;
float st2;
// Parameters // Parameters
float cutoff_up; float cutoff_up;
float cutoff_down; float cutoff_down;
float sticky_thresh; float sticky_thresh;
bw_one_pole_sticky_mode sticky_mode; bw_one_pole_sticky_mode sticky_mode;
int param_changed; int param_changed;
}; };
struct _bw_one_pole_state { struct _bw_one_pole_state {
float y_z1; #ifdef BW_DEBUG_DEEP
uint32_t hash;
uint32_t coeffs_reset_id;
#endif
float y_z1;
}; };
#define _BW_ONE_POLE_PARAM_CUTOFF_UP 1 #define _BW_ONE_POLE_PARAM_CUTOFF_UP 1
@ -324,27 +360,36 @@ struct _bw_one_pole_state {
#define _BW_ONE_POLE_PARAM_STICKY_THRESH (1<<2) #define _BW_ONE_POLE_PARAM_STICKY_THRESH (1<<2)
static inline void bw_one_pole_init(bw_one_pole_coeffs *BW_RESTRICT coeffs) { static inline void bw_one_pole_init(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
BW_ASSERT(coeffs != NULL);
coeffs->cutoff_up = INFINITY; coeffs->cutoff_up = INFINITY;
coeffs->cutoff_down = INFINITY; coeffs->cutoff_down = INFINITY;
coeffs->sticky_thresh = 0.f; coeffs->sticky_thresh = 0.f;
coeffs->sticky_mode = bw_one_pole_sticky_mode_abs; coeffs->sticky_mode = bw_one_pole_sticky_mode_abs;
#ifdef BW_DEBUG_DEEP
coeffs->hash = bw_hash_sdbm("bw_one_pole_coeffs");
coeffs->state = _bw_one_pole_coeffs_state_init;
coeffs->reset_id = coeffs->hash + 1;
#endif
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
} }
static inline void bw_one_pole_set_sample_rate(bw_one_pole_coeffs *BW_RESTRICT coeffs, float sample_rate) { static inline void bw_one_pole_set_sample_rate(bw_one_pole_coeffs *BW_RESTRICT coeffs, float sample_rate) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
coeffs->Ttm2pi = -6.283185307179586f / sample_rate; coeffs->Ttm2pi = -6.283185307179586f / sample_rate;
#ifdef BW_DEBUG_DEEP
coeffs->state = _bw_one_pole_coeffs_state_set_sample_rate;
#endif
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state == _bw_one_pole_coeffs_state_set_sample_rate);
} }
static inline void bw_one_pole_reset_coeffs(bw_one_pole_coeffs *BW_RESTRICT coeffs) { static inline void _bw_one_pole_do_update_coeffs_ctrl(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
coeffs->param_changed = ~0;
bw_one_pole_update_coeffs_ctrl(coeffs);
}
static inline void bw_one_pole_reset_state(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float y_z1) {
(void)coeffs;
state->y_z1 = y_z1;
}
static inline void bw_one_pole_update_coeffs_ctrl(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
if (coeffs->param_changed) { if (coeffs->param_changed) {
if (coeffs->param_changed & _BW_ONE_POLE_PARAM_CUTOFF_UP) if (coeffs->param_changed & _BW_ONE_POLE_PARAM_CUTOFF_UP)
coeffs->mA1u = coeffs->cutoff_up > 1.591549430918953e8f ? 0.f : bw_expf_3(coeffs->Ttm2pi * coeffs->cutoff_up); coeffs->mA1u = coeffs->cutoff_up > 1.591549430918953e8f ? 0.f : bw_expf_3(coeffs->Ttm2pi * coeffs->cutoff_up);
@ -358,86 +403,236 @@ static inline void bw_one_pole_update_coeffs_ctrl(bw_one_pole_coeffs *BW_RESTRIC
} }
} }
static inline void bw_one_pole_reset_coeffs(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_set_sample_rate);
coeffs->param_changed = ~0;
_bw_one_pole_do_update_coeffs_ctrl(coeffs);
#ifdef BW_DEBUG_DEEP
coeffs->state = _bw_one_pole_coeffs_state_reset_coeffs;
coeffs->reset_id++;
#endif
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state == _bw_one_pole_coeffs_state_reset_coeffs);
}
static inline void bw_one_pole_reset_state(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float y_z1) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT(bw_is_finite(y_z1));
(void)coeffs;
state->y_z1 = y_z1;
#ifdef BW_DEBUG_DEEP
state->hash = bw_hash_sdbm("bw_one_pole_state");
state->coeffs_reset_id = coeffs->reset_id;
#endif
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
}
static inline void bw_one_pole_update_coeffs_ctrl(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
_bw_one_pole_do_update_coeffs_ctrl(coeffs);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
}
static inline void bw_one_pole_update_coeffs_audio(bw_one_pole_coeffs *BW_RESTRICT coeffs) { static inline void bw_one_pole_update_coeffs_audio(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
(void)coeffs; (void)coeffs;
} }
static inline float bw_one_pole_process1(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
const float y = x + coeffs->mA1u * (state->y_z1 - x); const float y = x + coeffs->mA1u * (state->y_z1 - x);
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline float bw_one_pole_process1_sticky_abs(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1_sticky_abs(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
float y = x + coeffs->mA1u * (state->y_z1 - x); float y = x + coeffs->mA1u * (state->y_z1 - x);
const float d = y - x; const float d = y - x;
if (d * d <= coeffs->st2) if (d * d <= coeffs->st2)
y = x; y = x;
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline float bw_one_pole_process1_sticky_rel(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1_sticky_rel(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
float y = x + coeffs->mA1u * (state->y_z1 - x); float y = x + coeffs->mA1u * (state->y_z1 - x);
const float d = y - x; const float d = y - x;
if (d * d <= coeffs->st2 * x * x) if (d * d <= coeffs->st2 * x * x)
y = x; y = x;
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline float bw_one_pole_process1_asym(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1_asym(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
const float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x); const float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x);
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline float bw_one_pole_process1_asym_sticky_abs(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1_asym_sticky_abs(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x); float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x);
const float d = y - x; const float d = y - x;
if (d * d <= coeffs->st2) if (d * d <= coeffs->st2)
y = x; y = x;
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline float bw_one_pole_process1_asym_sticky_rel(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) { static inline float bw_one_pole_process1_asym_sticky_rel(const bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, float x) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(x));
float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x); float y = x + (x >= state->y_z1 ? coeffs->mA1u : coeffs->mA1d) * (state->y_z1 - x);
const float d = y - x; const float d = y - x;
if (d * d <= coeffs->st2 * x * x) if (d * d <= coeffs->st2 * x * x)
y = x; y = x;
state->y_z1 = y; state->y_z1 = y;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, const float *x, float *y, int n_samples) { static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state *BW_RESTRICT state, const float *x, float *y, BW_SIZE_T n_samples) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT(n_samples == 0 || x != NULL);
BW_ASSERT_DEEP(!bw_has_nan(x, n_samples));
bw_one_pole_update_coeffs_ctrl(coeffs); bw_one_pole_update_coeffs_ctrl(coeffs);
if (y != NULL) { if (y != NULL) {
if (coeffs->mA1u != coeffs->mA1d) { if (coeffs->mA1u != coeffs->mA1d) {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1_asym_sticky_abs(coeffs, state, x[i]); y[i] = bw_one_pole_process1_asym_sticky_abs(coeffs, state, x[i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1_asym_sticky_rel(coeffs, state, x[i]); y[i] = bw_one_pole_process1_asym_sticky_rel(coeffs, state, x[i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1_asym(coeffs, state, x[i]); y[i] = bw_one_pole_process1_asym(coeffs, state, x[i]);
} }
} }
else { else {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1_sticky_abs(coeffs, state, x[i]); y[i] = bw_one_pole_process1_sticky_abs(coeffs, state, x[i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1_sticky_rel(coeffs, state, x[i]); y[i] = bw_one_pole_process1_sticky_rel(coeffs, state, x[i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[i] = bw_one_pole_process1(coeffs, state, x[i]); y[i] = bw_one_pole_process1(coeffs, state, x[i]);
} }
} }
@ -445,93 +640,104 @@ static inline void bw_one_pole_process(bw_one_pole_coeffs *BW_RESTRICT coeffs, b
if (coeffs->mA1u != coeffs->mA1d) { if (coeffs->mA1u != coeffs->mA1d) {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym_sticky_abs(coeffs, state, x[i]); bw_one_pole_process1_asym_sticky_abs(coeffs, state, x[i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym_sticky_rel(coeffs, state, x[i]); bw_one_pole_process1_asym_sticky_rel(coeffs, state, x[i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym(coeffs, state, x[i]); bw_one_pole_process1_asym(coeffs, state, x[i]);
} }
} }
else { else {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_sticky_abs(coeffs, state, x[i]); bw_one_pole_process1_sticky_abs(coeffs, state, x[i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_sticky_rel(coeffs, state, x[i]); bw_one_pole_process1_sticky_rel(coeffs, state, x[i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1(coeffs, state, x[i]); bw_one_pole_process1(coeffs, state, x[i]);
} }
} }
} }
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
BW_ASSERT_DEEP(coeffs->reset_id == state->coeffs_reset_id);
BW_ASSERT_DEEP(!bw_has_nan(y, n_samples));
} }
static inline void bw_one_pole_process_multi(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) { static inline void bw_one_pole_process_multi(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_state **BW_RESTRICT state, const float **x, float **y, BW_SIZE_T n_channels, BW_SIZE_T n_samples) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_reset_coeffs);
//...
bw_one_pole_update_coeffs_ctrl(coeffs); bw_one_pole_update_coeffs_ctrl(coeffs);
if (y != NULL) { if (y != NULL) {
if (coeffs->mA1u != coeffs->mA1d) { if (coeffs->mA1u != coeffs->mA1d) {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]);
} }
else { else {
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1_asym(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1_asym(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_asym(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym(coeffs, state[j], x[j][i]);
} }
} }
else { else {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]); bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]); bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]);
} }
else { else {
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
if (y[j] != NULL) if (y[j] != NULL)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
y[j][i] = bw_one_pole_process1(coeffs, state[j], x[j][i]); y[j][i] = bw_one_pole_process1(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
bw_one_pole_process1(coeffs, state[j], x[j][i]); bw_one_pole_process1(coeffs, state[j], x[j][i]);
} }
} }
@ -539,89 +745,187 @@ static inline void bw_one_pole_process_multi(bw_one_pole_coeffs *BW_RESTRICT coe
if (coeffs->mA1u != coeffs->mA1d) { if (coeffs->mA1u != coeffs->mA1d) {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym_sticky_rel(coeffs, state[j], x[j][i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1_asym(coeffs, state[j], x[j][i]); bw_one_pole_process1_asym(coeffs, state[j], x[j][i]);
} }
} }
else { else {
if (coeffs->st2 != 0.f) { if (coeffs->st2 != 0.f) {
if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs) if (coeffs->sticky_mode == bw_one_pole_sticky_mode_abs)
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]); bw_one_pole_process1_sticky_abs(coeffs, state[j], x[j][i]);
else else
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]); bw_one_pole_process1_sticky_rel(coeffs, state[j], x[j][i]);
} }
else { else {
for (int i = 0; i < n_samples; i++) for (BW_SIZE_T i = 0; i < n_samples; i++)
for (int j = 0; j < n_channels; j++) for (BW_SIZE_T j = 0; j < n_channels; j++)
bw_one_pole_process1(coeffs, state[j], x[j][i]); bw_one_pole_process1(coeffs, state[j], x[j][i]);
} }
} }
} }
//...
} }
static inline void bw_one_pole_set_cutoff(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_cutoff(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
bw_one_pole_set_cutoff_up(coeffs, value); bw_one_pole_set_cutoff_up(coeffs, value);
bw_one_pole_set_cutoff_down(coeffs, value); bw_one_pole_set_cutoff_down(coeffs, value);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_cutoff_up(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_cutoff_up(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
if (coeffs->cutoff_up != value) { if (coeffs->cutoff_up != value) {
coeffs->cutoff_up = value; coeffs->cutoff_up = value;
coeffs->param_changed |= _BW_ONE_POLE_PARAM_CUTOFF_UP; coeffs->param_changed |= _BW_ONE_POLE_PARAM_CUTOFF_UP;
} }
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_cutoff_down(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_cutoff_down(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
if (coeffs->cutoff_down != value) { if (coeffs->cutoff_down != value) {
coeffs->cutoff_down = value; coeffs->cutoff_down = value;
coeffs->param_changed |= _BW_ONE_POLE_PARAM_CUTOFF_DOWN; coeffs->param_changed |= _BW_ONE_POLE_PARAM_CUTOFF_DOWN;
} }
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_tau(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_tau(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
bw_one_pole_set_tau_up(coeffs, value); bw_one_pole_set_tau_up(coeffs, value);
bw_one_pole_set_tau_down(coeffs, value); bw_one_pole_set_tau_down(coeffs, value);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_tau_up(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_tau_up(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
bw_one_pole_set_cutoff_up(coeffs, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value)); bw_one_pole_set_cutoff_up(coeffs, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value));
// tau < 1 ns is instantaneous for any practical purpose // tau < 1 ns is instantaneous for any practical purpose
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_tau_down(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_tau_down(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
BW_ASSERT(!bw_is_nan(value));
BW_ASSERT(value >= 0.f);
bw_one_pole_set_cutoff_down(coeffs, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value)); bw_one_pole_set_cutoff_down(coeffs, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value));
// as before // as before
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_sticky_thresh(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) { static inline void bw_one_pole_set_sticky_thresh(bw_one_pole_coeffs *BW_RESTRICT coeffs, float value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
//...
if (coeffs->sticky_thresh != value) { if (coeffs->sticky_thresh != value) {
coeffs->sticky_thresh = value; coeffs->sticky_thresh = value;
coeffs->param_changed |= _BW_ONE_POLE_PARAM_STICKY_THRESH; coeffs->param_changed |= _BW_ONE_POLE_PARAM_STICKY_THRESH;
} }
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline void bw_one_pole_set_sticky_mode(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_sticky_mode value) { static inline void bw_one_pole_set_sticky_mode(bw_one_pole_coeffs *BW_RESTRICT coeffs, bw_one_pole_sticky_mode value) {
BW_ASSERT(coeffs != NULL);
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
//...
coeffs->sticky_mode = value; coeffs->sticky_mode = value;
BW_ASSERT_DEEP(bw_one_pole_coeffs_is_valid(coeffs));
BW_ASSERT_DEEP(coeffs->state >= _bw_one_pole_coeffs_state_init);
} }
static inline float bw_one_pole_get_y_z1(const bw_one_pole_state *BW_RESTRICT state) { static inline float bw_one_pole_get_y_z1(const bw_one_pole_state *BW_RESTRICT state) {
BW_ASSERT(state != NULL);
BW_ASSERT_DEEP(bw_one_pole_state_is_valid(state));
return state->y_z1; return state->y_z1;
} }
static inline char bw_one_pole_coeffs_is_valid(const bw_one_pole_coeffs *BW_RESTRICT coeffs) {
BW_ASSERT(coeffs != NULL);
#ifdef BW_DEBUG_DEEP
if (coeffs->hash != bw_hash_sdbm("bw_one_pole_coeffs"))
return 0;
#endif
//...
return 1;
}
static inline char bw_one_pole_state_is_valid(const bw_one_pole_state *BW_RESTRICT state) {
BW_ASSERT(state != NULL);
#ifdef BW_DEBUG_DEEP
if (state->hash != bw_hash_sdbm("bw_one_pole_state"))
return 0;
#endif
return bw_is_finite(state->y_z1);
}
#undef _BW_ONE_POLE_PARAM_CUTOFF_UP #undef _BW_ONE_POLE_PARAM_CUTOFF_UP
#undef _BW_ONE_POLE_PARAM_CUTOFF_DOWN #undef _BW_ONE_POLE_PARAM_CUTOFF_DOWN
#undef _BW_ONE_POLE_PARAM_STICKY_THRESH #undef _BW_ONE_POLE_PARAM_STICKY_THRESH