use NDEBUG in examples + fix velocity in synth(pp)_poly + really remove bw_omega* + fix bw_math + fix high cutoff in bw_one_pole + debugging in bw_{note_queue,rand,voice_alloc}
This commit is contained in:
parent
681008abdb
commit
8299cb7eae
1
TODO
1
TODO
@ -84,6 +84,7 @@ code:
|
|||||||
* web effect mono->stereo and stereo->mono inputs? or display "input needs to be n channels"?
|
* web effect mono->stereo and stereo->mono inputs? or display "input needs to be n channels"?
|
||||||
* fix vst3 mapped values (visible in Ableton Live) and short names
|
* fix vst3 mapped values (visible in Ableton Live) and short names
|
||||||
* polish examples (ranges, etc.)
|
* polish examples (ranges, etc.)
|
||||||
|
* dump data structures (see note queue) and indicate error precisely
|
||||||
|
|
||||||
build system:
|
build system:
|
||||||
* make makefiles handle paths with spaces etc
|
* make makefiles handle paths with spaces etc
|
||||||
|
@ -12,11 +12,13 @@ SYSTEM_FILES_DIR = ${LIBDAISY_DIR}/core
|
|||||||
include ${SYSTEM_FILES_DIR}/Makefile
|
include ${SYSTEM_FILES_DIR}/Makefile
|
||||||
|
|
||||||
CPPFLAGS += \
|
CPPFLAGS += \
|
||||||
|
-DNDEBUG \
|
||||||
-I${ROOT_DIR} \
|
-I${ROOT_DIR} \
|
||||||
-I${ROOT_DIR}/../src \
|
-I${ROOT_DIR}/../src \
|
||||||
-I${ROOT_DIR}/../../../include
|
-I${ROOT_DIR}/../../../include
|
||||||
|
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
|
-DNDEBUG \
|
||||||
-I${ROOT_DIR} \
|
-I${ROOT_DIR} \
|
||||||
-I${ROOT_DIR}/../src \
|
-I${ROOT_DIR}/../src \
|
||||||
-I${ROOT_DIR}/../../../include \
|
-I${ROOT_DIR}/../../../include \
|
||||||
|
@ -7,6 +7,7 @@ BUILD_PLUGIN_DIR := build/${NAME}.vst3
|
|||||||
|
|
||||||
CXXFLAGS := \
|
CXXFLAGS := \
|
||||||
-DRELEASE=1 \
|
-DRELEASE=1 \
|
||||||
|
-DNDEBUG \
|
||||||
-I${ROOT_DIR} \
|
-I${ROOT_DIR} \
|
||||||
-I${ROOT_DIR}/../src \
|
-I${ROOT_DIR}/../src \
|
||||||
-I${COMMON_DIR} \
|
-I${COMMON_DIR} \
|
||||||
|
@ -404,7 +404,7 @@ float bw_example_synth_poly_get_parameter(bw_example_synth_poly *instance, int i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synth_poly_note_on(bw_example_synth_poly *instance, char note, char velocity) {
|
void bw_example_synth_poly_note_on(bw_example_synth_poly *instance, char note, char velocity) {
|
||||||
bw_note_queue_add(&instance->note_queue, note, velocity != 0, velocity, 0);
|
bw_note_queue_add(&instance->note_queue, note, velocity != 0, (1.f / 127.f) * velocity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synth_poly_note_off(bw_example_synth_poly *instance, char note) {
|
void bw_example_synth_poly_note_off(bw_example_synth_poly *instance, char note) {
|
||||||
|
@ -375,7 +375,7 @@ float bw_example_synthpp_poly_get_parameter(bw_example_synthpp_poly *instance, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synthpp_poly_note_on(bw_example_synthpp_poly *instance, char note, char velocity) {
|
void bw_example_synthpp_poly_note_on(bw_example_synthpp_poly *instance, char note, char velocity) {
|
||||||
instance->noteQueue.add(note, velocity != 0, velocity, false);
|
instance->noteQueue.add(note, velocity != 0, (1.f / 127.f) * velocity, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synthpp_poly_note_off(bw_example_synthpp_poly *instance, char note) {
|
void bw_example_synthpp_poly_note_off(bw_example_synthpp_poly *instance, char note) {
|
||||||
|
@ -371,28 +371,6 @@ static inline float bw_lin2dBf_3(float x);
|
|||||||
*
|
*
|
||||||
* Absolute error < 0.032, relative error < 1.5%.
|
* Absolute error < 0.032, relative error < 1.5%.
|
||||||
*
|
*
|
||||||
* #### bw_omega_3log()
|
|
||||||
* ```>>> */
|
|
||||||
static inline float bw_omega_3log(float x);
|
|
||||||
/*! <<<```
|
|
||||||
* Returns an approximation of `omega(x)`, where `omega` is the <a
|
|
||||||
* href="https://en.wikipedia.org/wiki/Wright_omega_function"
|
|
||||||
* target="_blank">Wright omega function</a>.
|
|
||||||
*
|
|
||||||
* Absolute error < 0.27, relative error < 14.6% for non-negative input and
|
|
||||||
* decreasing with increasing input, goes rapidly to 100% for progressively
|
|
||||||
* more negative input.
|
|
||||||
*
|
|
||||||
* #### bw_omega_3lognr()
|
|
||||||
* ```>>> */
|
|
||||||
static inline float bw_omega_3lognr(float x);
|
|
||||||
/*! <<<```
|
|
||||||
* Returns an approximation of `omega(x)`, where `omega` is the <a
|
|
||||||
* href="https://en.wikipedia.org/wiki/Wright_omega_function"
|
|
||||||
* target="_blank">Wright omega function</a>.
|
|
||||||
*
|
|
||||||
* Absolute error < 0.045, relative error < 3.7%.
|
|
||||||
*
|
|
||||||
* #### bw_sqrtf_2()
|
* #### bw_sqrtf_2()
|
||||||
* ```>>> */
|
* ```>>> */
|
||||||
static inline float bw_sqrtf_2(float x);
|
static inline float bw_sqrtf_2(float x);
|
||||||
@ -508,57 +486,57 @@ static inline float bw_absf(float x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_min0xf(float x) {
|
static inline float bw_min0xf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
const float y = 0.5f * (x - bw_absf(x));
|
const float y = 0.5f * (x - bw_absf(x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_max0xf(float x) {
|
static inline float bw_max0xf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
const float y = 0.5f * (x + bw_absf(x));
|
const float y = 0.5f * (x + bw_absf(x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_minf(float a, float b) {
|
static inline float bw_minf(float a, float b) {
|
||||||
BW_ASSERT(bw_isfinite(a));
|
BW_ASSERT(bw_is_finite(a));
|
||||||
BW_ASSERT(bw_isfinite(b));
|
BW_ASSERT(bw_is_finite(b));
|
||||||
const float y = a + bw_min0xf(b - a);
|
const float y = a + bw_min0xf(b - a);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_maxf(float a, float b) {
|
static inline float bw_maxf(float a, float b) {
|
||||||
BW_ASSERT(bw_isfinite(a));
|
BW_ASSERT(bw_is_finite(a));
|
||||||
BW_ASSERT(bw_isfinite(b));
|
BW_ASSERT(bw_is_finite(b));
|
||||||
const float y = a + bw_max0xf(b - a);
|
const float y = a + bw_max0xf(b - a);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_clipf(float x, float m, float M) {
|
static inline float bw_clipf(float x, float m, float M) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(bw_isfinite(m));
|
BW_ASSERT(bw_is_finite(m));
|
||||||
BW_ASSERT(bw_isfinite(M));
|
BW_ASSERT(bw_is_finite(M));
|
||||||
const float y = bw_minf(bw_maxf(x, m), M);
|
const float y = bw_minf(bw_maxf(x, m), M);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_truncf(float x) {
|
static inline float bw_truncf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
_bw_floatint v = {.f = x};
|
_bw_floatint v = {.f = x};
|
||||||
int32_t ex = (v.i & 0x7f800000) >> 23;
|
int32_t ex = (v.i & 0x7f800000) >> 23;
|
||||||
int32_t m = (~0u) << bw_clipi32(150 - ex, 0, 23);
|
int32_t m = (~0u) << bw_clipi32(150 - ex, 0, 23);
|
||||||
m &= bw_signfilli32(126 - ex) | 0x80000000;
|
m &= bw_signfilli32(126 - ex) | 0x80000000;
|
||||||
v.i &= m;
|
v.i &= m;
|
||||||
BW_ASSERT(bw_isfinite(v.f));
|
BW_ASSERT(bw_is_finite(v.f));
|
||||||
return v.f;
|
return v.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_roundf(float x) {
|
static inline float bw_roundf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
_bw_floatint v = {.f = x};
|
_bw_floatint v = {.f = x};
|
||||||
int32_t ex = (v.i & 0x7f800000) >> 23;
|
int32_t ex = (v.i & 0x7f800000) >> 23;
|
||||||
int32_t sh = bw_clipi32(150 - ex, 0, 23);
|
int32_t sh = bw_clipi32(150 - ex, 0, 23);
|
||||||
@ -571,38 +549,38 @@ static inline float bw_roundf(float x) {
|
|||||||
v.i &= mt;
|
v.i &= mt;
|
||||||
s.i &= ms;
|
s.i &= ms;
|
||||||
const float y = v.f + s.f;
|
const float y = v.f + s.f;
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_floorf(float x) {
|
static inline float bw_floorf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
_bw_floatint t = {.f = bw_truncf(x)}; // first bit set when t < 0
|
_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 y = {.f = x - t.f}; // first bit set when t > x
|
||||||
_bw_floatint s = {.f = 1.f};
|
_bw_floatint s = {.f = 1.f};
|
||||||
s.i &= bw_signfilli32(t.i & y.i);
|
s.i &= bw_signfilli32(t.i & y.i);
|
||||||
const float y = t.f - s.f;
|
const float r = t.f - s.f;
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(r));
|
||||||
return y;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_ceilf(float x) {
|
static inline float bw_ceilf(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
_bw_floatint t = {.f = bw_truncf(x)}; // first bit set when t < 0
|
_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 y = {.f = x - t.f}; // first bit set when t > x
|
||||||
_bw_floatint s = {.f = 1.f};
|
_bw_floatint s = {.f = 1.f};
|
||||||
s.i &= bw_signfilli32(~t.i & y.i);
|
s.i &= bw_signfilli32(~t.i & y.i);
|
||||||
const float y = t.f + s.f;
|
const float r = t.f + s.f;
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(r));
|
||||||
return y;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bw_intfracf(float x, float *i, float *f) {
|
static inline void bw_intfracf(float x, float *i, float *f) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
*i = bw_floorf(x);
|
*i = bw_floorf(x);
|
||||||
*f = x - *i;
|
*f = x - *i;
|
||||||
BW_ASSERT(bw_isfinite(*i));
|
BW_ASSERT(bw_is_finite(*i));
|
||||||
BW_ASSERT(bw_isfinite(*f));
|
BW_ASSERT(bw_is_finite(*f));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_rcpf_2(float x) {
|
static inline float bw_rcpf_2(float x) {
|
||||||
@ -614,85 +592,85 @@ static inline float bw_rcpf_2(float x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_sin2pif_3(float x) {
|
static inline float bw_sin2pif_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
x = x - bw_floorf(x);
|
x = x - bw_floorf(x);
|
||||||
float xp1 = x + x - 1.f;
|
float xp1 = x + x - 1.f;
|
||||||
float xp2 = bw_absf(xp1);
|
float xp2 = bw_absf(xp1);
|
||||||
float xp = 1.570796326794897f - 1.570796326794897f * bw_absf(xp2 + xp2 - 1.f);
|
float xp = 1.570796326794897f - 1.570796326794897f * bw_absf(xp2 + xp2 - 1.f);
|
||||||
const float y = -bw_copysignf(1.f, xp1) * (xp + xp * xp * (-0.05738534102710938f - 0.1107398163618408f * xp));
|
const float y = -bw_copysignf(1.f, xp1) * (xp + xp * xp * (-0.05738534102710938f - 0.1107398163618408f * xp));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_sinf_3(float x) {
|
static inline float bw_sinf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
const float y = bw_sin2pif_3(0.1591549430918953f * x);
|
const float y = bw_sin2pif_3(0.1591549430918953f * x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_cos2pif_3(float x) {
|
static inline float bw_cos2pif_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
return bw_sin2pif_3(x + 0.25f);
|
const float y = bw_sin2pif_3(x + 0.25f);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_cosf_3(float x) {
|
static inline float bw_cosf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
return bw_cos2pif_3(0.1591549430918953f * x);
|
const float y = bw_cos2pif_3(0.1591549430918953f * x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_tan2pif_3(float x) {
|
static inline float bw_tan2pif_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT((x - 0.5f * bw_floorf(x + x) <= 0.249840845056908f)
|
BW_ASSERT((x - 0.5f * bw_floorf(x + x) <= 0.249840845056908f)
|
||||||
|| (x - 0.5f * bw_floorf(x + x) >= 0.250159154943092f));
|
|| (x - 0.5f * bw_floorf(x + x) >= 0.250159154943092f));
|
||||||
return bw_sin2pif_3(x) * bw_rcpf_2(bw_cos2pif_3(x));
|
const float y = bw_sin2pif_3(x) * bw_rcpf_2(bw_cos2pif_3(x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_tanf_3(float x) {
|
static inline float bw_tanf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT((x - 3.141592653589793f * bw_floorf(0.318309886183791f * x) <= 1.569796326794897f)
|
BW_ASSERT((x - 3.141592653589793f * bw_floorf(0.318309886183791f * x) <= 1.569796326794897f)
|
||||||
|| (x - 3.141592653589793f * bw_floorf(0.318309886183791f * x) >= 1.571796326794896f));
|
|| (x - 3.141592653589793f * bw_floorf(0.318309886183791f * x) >= 1.571796326794896f));
|
||||||
x = 0.1591549430918953f * x;
|
x = 0.1591549430918953f * x;
|
||||||
const float y = bw_sin2pif_3(x) * bw_rcpf_2(bw_cos2pif_3(x));
|
const float y = bw_sin2pif_3(x) * bw_rcpf_2(bw_cos2pif_3(x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_log2f_3(float x) {
|
static inline float bw_log2f_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 1.175494350822287e-38f);
|
BW_ASSERT(x >= 1.175494350822287e-38f);
|
||||||
_bw_floatint v = {.f = x};
|
_bw_floatint v = {.f = x};
|
||||||
int e = v.i >> 23;
|
int e = v.i >> 23;
|
||||||
v.i = (v.i & 0x007fffff) | 0x3f800000;
|
v.i = (v.i & 0x007fffff) | 0x3f800000;
|
||||||
const float y = (float)e - 129.213475204444817f + v.f * (3.148297929334117f + v.f * (-1.098865286222744f + v.f * 0.1640425613334452f));
|
const float y = (float)e - 129.213475204444817f + v.f * (3.148297929334117f + v.f * (-1.098865286222744f + v.f * 0.1640425613334452f));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_logf_3(float x) {
|
static inline float bw_logf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 1.175494350822287e-38f);
|
BW_ASSERT(x >= 1.175494350822287e-38f);
|
||||||
const float y = 0.693147180559945f * bw_log2f_3(x);
|
const float y = 0.693147180559945f * bw_log2f_3(x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_log10f_3(float x) {
|
static inline float bw_log10f_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 1.175494350822287e-38f);
|
BW_ASSERT(x >= 1.175494350822287e-38f);
|
||||||
const float y = 0.3010299956639811f * bw_log2f_3(x);
|
const float y = 0.3010299956639811f * bw_log2f_3(x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_pow2f_3(float x) {
|
static inline float bw_pow2f_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x <= 127.999f);
|
BW_ASSERT(x <= 127.999f);
|
||||||
if (x < -126.f)
|
if (x < -126.f)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
@ -702,48 +680,48 @@ static inline float bw_pow2f_3(float x) {
|
|||||||
float f = x - (float)l;
|
float f = x - (float)l;
|
||||||
v.i = (l + 127) << 23;
|
v.i = (l + 127) << 23;
|
||||||
const float y = v.f + v.f * f * (0.6931471805599453f + f * (0.2274112777602189f + f * 0.07944154167983575f));
|
const float y = v.f + v.f * f * (0.6931471805599453f + f * (0.2274112777602189f + f * 0.07944154167983575f));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_expf_3(float x) {
|
static inline float bw_expf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x <= 88.722f);
|
BW_ASSERT(x <= 88.722f);
|
||||||
const float y = bw_pow2f_3(1.442695040888963f * x);
|
const float y = bw_pow2f_3(1.442695040888963f * x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_pow10f_3(float x) {
|
static inline float bw_pow10f_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x <= 38.531f);
|
BW_ASSERT(x <= 38.531f);
|
||||||
const float y = bw_pow2f_3(3.321928094887363f * x);
|
const float y = bw_pow2f_3(3.321928094887363f * x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_dB2linf_3(float x) {
|
static inline float bw_dB2linf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x <= 770.630f);
|
BW_ASSERT(x <= 770.630f);
|
||||||
const float y = bw_pow2f_3(0.1660964047443682f * x);
|
const float y = bw_pow2f_3(0.1660964047443682f * x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_lin2dBf_3(float x) {
|
static inline float bw_lin2dBf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 1.175494350822287e-38f);
|
BW_ASSERT(x >= 1.175494350822287e-38f);
|
||||||
const float y = 20.f * bw_log10f_3(x);
|
const float y = 20.f * bw_log10f_3(x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_sqrtf_2(float x) {
|
static inline float bw_sqrtf_2(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 0.f);
|
BW_ASSERT(x >= 0.f);
|
||||||
if (x < 8.077935669463161e-28f) {
|
if (x < 8.077935669463161e-28f) {
|
||||||
const float y = 3.518437208883201e13f * x;
|
const float y = 3.518437208883201e13f * x;
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
_bw_floatint v = {.f = x};
|
_bw_floatint v = {.f = x};
|
||||||
@ -751,49 +729,49 @@ static inline float bw_sqrtf_2(float x) {
|
|||||||
float r = bw_rcpf_2(x);
|
float r = bw_rcpf_2(x);
|
||||||
v.f = v.f + v.f * (0.5f - 0.5f * r * v.f * v.f);
|
v.f = v.f + v.f * (0.5f - 0.5f * r * v.f * v.f);
|
||||||
v.f = v.f + v.f * (0.5f - 0.5f * r * v.f * v.f);
|
v.f = v.f + v.f * (0.5f - 0.5f * r * v.f * v.f);
|
||||||
BW_ASSERT(bw_isfinite(v.f));
|
BW_ASSERT(bw_is_finite(v.f));
|
||||||
return v.f;
|
return v.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_tanhf_3(float x) {
|
static inline float bw_tanhf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
const float xm = bw_clipf(x, -2.115287308554551f, 2.115287308554551f);
|
const float xm = bw_clipf(x, -2.115287308554551f, 2.115287308554551f);
|
||||||
const float axm = bw_absf(xm);
|
const float axm = bw_absf(xm);
|
||||||
const float y = xm * axm * (0.01218073260037716f * axm - 0.2750231331124371f) + xm;
|
const float y = xm * axm * (0.01218073260037716f * axm - 0.2750231331124371f) + xm;
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_sinhf_3(float x) {
|
static inline float bw_sinhf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= -88.722f && x <= 88.722f);
|
BW_ASSERT(x >= -88.722f && x <= 88.722f);
|
||||||
const float y = 0.5f * (bw_expf_3(x) - bw_expf_3(-x));
|
const float y = 0.5f * (bw_expf_3(x) - bw_expf_3(-x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_coshf_3(float x) {
|
static inline float bw_coshf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= -88.722f && x <= 88.722f);
|
BW_ASSERT(x >= -88.722f && x <= 88.722f);
|
||||||
const float y = 0.5f * (bw_expf_3(x) + bw_expf_3(-x));
|
const float y = 0.5f * (bw_expf_3(x) + bw_expf_3(-x));
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_asinhf_3(float x) {
|
static inline float bw_asinhf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= -1.7e38f && x <= 1.7e38f);
|
BW_ASSERT(x >= -1.7e38f && x <= 1.7e38f);
|
||||||
float a = bw_absf(x);
|
float a = bw_absf(x);
|
||||||
const float y = bw_copysignf(bw_logf_3((a >= 4096.f ? a : bw_sqrtf_2(a * a + 1.f)) + a), x);
|
const float y = bw_copysignf(bw_logf_3((a >= 4096.f ? a : bw_sqrtf_2(a * a + 1.f)) + a), x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_acoshf_3(float x) {
|
static inline float bw_acoshf_3(float x) {
|
||||||
BW_ASSERT(bw_isfinite(x));
|
BW_ASSERT(bw_is_finite(x));
|
||||||
BW_ASSERT(x >= 1.f);
|
BW_ASSERT(x >= 1.f);
|
||||||
const float y = bw_logf_3((x >= 8192.f ? x : bw_sqrtf_2(x * x - 1.f)) + x);
|
const float y = bw_logf_3((x >= 8192.f ? x : bw_sqrtf_2(x * x - 1.f)) + x);
|
||||||
BW_ASSERT(bw_isfinite(y));
|
BW_ASSERT(bw_is_finite(y));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
* <ul>
|
* <ul>
|
||||||
* <li>Version <strong>0.6.0</strong>:
|
* <li>Version <strong>0.6.0</strong>:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>Added debugging code.</li>
|
||||||
* <li>Removed dependency on bw_config.</li>
|
* <li>Removed dependency on bw_config.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
@ -121,6 +122,12 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
|
|||||||
*
|
*
|
||||||
* If `force_went_off` is set to non-`0`, `went_off` is always set to
|
* If `force_went_off` is set to non-`0`, `went_off` is always set to
|
||||||
* non-`0`.
|
* non-`0`.
|
||||||
|
*
|
||||||
|
* #### bw_note_queue_add()
|
||||||
|
* ```>>> */
|
||||||
|
static inline char bw_note_queue_is_valid(bw_note_queue *BW_RESTRICT queue);
|
||||||
|
/*! <<<```
|
||||||
|
* WRITEME
|
||||||
* }}} */
|
* }}} */
|
||||||
|
|
||||||
/*** Implementation ***/
|
/*** Implementation ***/
|
||||||
@ -129,17 +136,26 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
|
|||||||
* change at any time in future versions. Please, do not use it directly. */
|
* change at any time in future versions. Please, do not use it directly. */
|
||||||
|
|
||||||
static inline void bw_note_queue_reset(bw_note_queue *BW_RESTRICT queue) {
|
static inline void bw_note_queue_reset(bw_note_queue *BW_RESTRICT queue) {
|
||||||
|
BW_ASSERT(queue != NULL);
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
queue->status[i] = (bw_note_queue_status){ .pressed = 0, .velocity = 0.f };
|
queue->status[i] = (bw_note_queue_status){ .pressed = 0, .velocity = 0.f };
|
||||||
queue->n_pressed = 0;
|
queue->n_pressed = 0;
|
||||||
queue->n_events = 0;
|
queue->n_events = 0;
|
||||||
|
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bw_note_queue_clear(bw_note_queue *BW_RESTRICT queue) {
|
static inline void bw_note_queue_clear(bw_note_queue *BW_RESTRICT queue) {
|
||||||
|
BW_ASSERT(queue != NULL);
|
||||||
|
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
|
||||||
queue->n_events = 0;
|
queue->n_events = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned char note, char pressed, float velocity, char force_went_off) {
|
static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned char note, char pressed, float velocity, char force_went_off) {
|
||||||
|
BW_ASSERT(queue != NULL);
|
||||||
|
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
|
||||||
|
BW_ASSERT(note < 128);
|
||||||
|
BW_ASSERT(bw_is_finite(velocity) && velocity <= 1.f);
|
||||||
|
|
||||||
if (!pressed && !queue->status[note].pressed)
|
if (!pressed && !queue->status[note].pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -159,6 +175,37 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
|
|||||||
else if (!pressed && queue->status[note].pressed)
|
else if (!pressed && queue->status[note].pressed)
|
||||||
queue->n_pressed--;
|
queue->n_pressed--;
|
||||||
queue->status[note] = (bw_note_queue_status){ .pressed = pressed, .velocity = velocity };
|
queue->status[note] = (bw_note_queue_status){ .pressed = pressed, .velocity = velocity };
|
||||||
|
|
||||||
|
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char bw_note_queue_is_valid(bw_note_queue *BW_RESTRICT queue) {
|
||||||
|
BW_ASSERT(queue != NULL);
|
||||||
|
|
||||||
|
if (queue->n_events >= 128 || queue->n_pressed >= 128)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)queue->n_events; i++) {
|
||||||
|
bw_note_queue_event *ev = queue->events + i;
|
||||||
|
if (ev->note >= 128 || !bw_is_finite(ev->status.velocity) || ev->status.velocity > 1.f)
|
||||||
|
return 0;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
bw_note_queue_event *ev2 = queue->events + j;
|
||||||
|
if (ev2->note == ev->note)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
for (int i = 0; i < 128; i++) {
|
||||||
|
bw_note_queue_status *st = queue->status + i;
|
||||||
|
if (st->pressed)
|
||||||
|
cnt++;
|
||||||
|
if (!bw_is_finite(st->velocity) || st->velocity > 1.f)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt == queue->n_pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
* <li>Version <strong>0.6.0</strong>:
|
* <li>Version <strong>0.6.0</strong>:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Removed dependency on bw_config.</li>
|
* <li>Removed dependency on bw_config.</li>
|
||||||
|
* <li>Fixed bug when setting very high cutoff values.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
* <li>Version <strong>0.5.0</strong>:
|
* <li>Version <strong>0.5.0</strong>:
|
||||||
@ -346,9 +347,11 @@ static inline void bw_one_pole_reset_state(const bw_one_pole_coeffs *BW_RESTRICT
|
|||||||
static inline void bw_one_pole_update_coeffs_ctrl(bw_one_pole_coeffs *BW_RESTRICT coeffs) {
|
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 = 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);
|
||||||
|
// tau < 1 ns is instantaneous for any practical purpose
|
||||||
if (coeffs->param_changed & _BW_ONE_POLE_PARAM_CUTOFF_DOWN)
|
if (coeffs->param_changed & _BW_ONE_POLE_PARAM_CUTOFF_DOWN)
|
||||||
coeffs->mA1d = bw_expf_3(coeffs->Ttm2pi * coeffs->cutoff_down);
|
coeffs->mA1d = coeffs->cutoff_down > 1.591549430918953e8f ? 0.f : bw_expf_3(coeffs->Ttm2pi * coeffs->cutoff_down);
|
||||||
|
// as before
|
||||||
if (coeffs->param_changed & _BW_ONE_POLE_PARAM_STICKY_THRESH)
|
if (coeffs->param_changed & _BW_ONE_POLE_PARAM_STICKY_THRESH)
|
||||||
coeffs->st2 = coeffs->sticky_thresh * coeffs->sticky_thresh;
|
coeffs->st2 = coeffs->sticky_thresh * coeffs->sticky_thresh;
|
||||||
coeffs->param_changed = 0;
|
coeffs->param_changed = 0;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
* <ul>
|
* <ul>
|
||||||
* <li>Version <strong>0.6.0</strong>:
|
* <li>Version <strong>0.6.0</strong>:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>Added debugging code.</li>
|
||||||
* <li>Removed dependency on bw_config.</li>
|
* <li>Removed dependency on bw_config.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
@ -90,6 +91,7 @@ static inline float bw_randf(uint64_t *BW_RESTRICT state);
|
|||||||
* change at any time in future versions. Please, do not use it directly. */
|
* change at any time in future versions. Please, do not use it directly. */
|
||||||
|
|
||||||
static inline uint32_t bw_randu32(uint64_t *BW_RESTRICT state) {
|
static inline uint32_t bw_randu32(uint64_t *BW_RESTRICT state) {
|
||||||
|
BW_ASSERT(state != NULL);
|
||||||
// Permuted Congruential Generator,
|
// Permuted Congruential Generator,
|
||||||
// taken from https://nullprogram.com/blog/2017/09/21/
|
// taken from https://nullprogram.com/blog/2017/09/21/
|
||||||
*state = *state * 0x9b60933458e17d7d + 0xd737232eeccdf7ed;
|
*state = *state * 0x9b60933458e17d7d + 0xd737232eeccdf7ed;
|
||||||
@ -97,6 +99,7 @@ static inline uint32_t bw_randu32(uint64_t *BW_RESTRICT state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline float bw_randf(uint64_t *BW_RESTRICT state) {
|
static inline float bw_randf(uint64_t *BW_RESTRICT state) {
|
||||||
|
BW_ASSERT(state != NULL);
|
||||||
return (2.f / (float)UINT32_MAX) * (float)bw_randu32(state) - 1.f;
|
return (2.f / (float)UINT32_MAX) * (float)bw_randu32(state) - 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
* <ul>
|
* <ul>
|
||||||
* <li>Version <strong>0.6.0</strong>:
|
* <li>Version <strong>0.6.0</strong>:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>Added debugging code.</li>
|
||||||
* <li>Removed dependency on bw_config.</li>
|
* <li>Removed dependency on bw_config.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
@ -88,7 +89,7 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* #### bw_voice_alloc()
|
* #### bw_voice_alloc()
|
||||||
* ```>>> */
|
* ```>>> */
|
||||||
void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *BW_RESTRICT queue, void **BW_RESTRICT voices, int n_voices);
|
void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *BW_RESTRICT queue, void **BW_RESTRICT voices, BW_SIZE_T n_voices);
|
||||||
/*! <<<```
|
/*! <<<```
|
||||||
* It performs voice allocation according to `opts` and using the events in
|
* It performs voice allocation according to `opts` and using the events in
|
||||||
* `queue`.
|
* `queue`.
|
||||||
@ -102,7 +103,17 @@ void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *
|
|||||||
/* WARNING: This part of the file is not part of the public API. Its content may
|
/* 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. */
|
* change at any time in future versions. Please, do not use it directly. */
|
||||||
|
|
||||||
void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *BW_RESTRICT queue, void **BW_RESTRICT voices, int n_voices) {
|
void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *BW_RESTRICT queue, void **BW_RESTRICT voices, BW_SIZE_T n_voices) {
|
||||||
|
BW_ASSERT(opts != NULL);
|
||||||
|
BW_ASSERT(opts->priority == bw_voice_alloc_priority_low || opts->priority == bw_voice_alloc_priority_high);
|
||||||
|
BW_ASSERT(n_voices == 0 || opts->note_on != NULL);
|
||||||
|
BW_ASSERT(n_voices == 0 || opts->note_off != NULL);
|
||||||
|
BW_ASSERT(n_voices == 0 || opts->get_note != NULL);
|
||||||
|
BW_ASSERT(n_voices == 0 || opts->is_free != NULL);
|
||||||
|
BW_ASSERT(queue != NULL);
|
||||||
|
BW_ASSERT_DEEP(bw_note_queue_is_valid(queue));
|
||||||
|
BW_ASSERT(n_voices == 0 || voices != NULL);
|
||||||
|
|
||||||
for (unsigned char i = 0; i < queue->n_events; i++) {
|
for (unsigned char i = 0; i < queue->n_events; i++) {
|
||||||
bw_note_queue_event *ev = queue->events + i;
|
bw_note_queue_event *ev = queue->events + i;
|
||||||
for (int j = 0; j < n_voices; j++)
|
for (int j = 0; j < n_voices; j++)
|
||||||
|
Loading…
Reference in New Issue
Block a user