ported bw_rand and bw_noise_gen to new API

This commit is contained in:
Stefano D'Angelo 2022-11-28 11:50:22 +01:00
parent fa68b793f9
commit 11e71be62a
6 changed files with 92 additions and 110 deletions

1
TODO
View File

@ -4,7 +4,6 @@ code:
* audio rate optional pulse width/slope inputs?
* one pole process const input? (return also if const out)
* optimize triangle generation for constant pulse width
* naming type suffixes math.h vs random.h
* API for buffer fill, scale, offset, zero, copy...?
* web examples construction/destruction
* web effect multichannel in?

View File

@ -26,6 +26,7 @@
#endif
#include <bw_math.h>
#include <bw_noise_gen.h>
#include <bw_phase_gen.h>
#include <bw_osc_sin.h>
#include <bw_vol.h>
@ -60,6 +61,7 @@ struct _bw_example_synth {
// Sub-components
bw_phase_gen_coeffs phase_gen_coeffs;
bw_phase_gen_state phase_gen_state;
bw_noise_gen_coeffs noise_gen_coeffs;
bw_phase_gen_coeffs a440_phase_gen_coeffs;
bw_phase_gen_state a440_phase_gen_state;
bw_vol_coeffs vol_coeffs;
@ -76,6 +78,7 @@ struct _bw_example_synth {
float params[p_n];
// States
uint64_t rand_state;
int note;
float level;
@ -89,10 +92,14 @@ bw_example_synth bw_example_synth_new() {
return NULL;
bw_phase_gen_init(&instance->phase_gen_coeffs);
bw_noise_gen_init(&instance->noise_gen_coeffs, &instance->rand_state);
bw_phase_gen_init(&instance->a440_phase_gen_coeffs);
bw_vol_init(&instance->vol_coeffs);
bw_phase_gen_set_frequency(&instance->a440_phase_gen_coeffs, 440.f);
bw_noise_gen_set_sample_rate_scaling(&instance->noise_gen_coeffs, 1);
instance->rand_state = 0xbaddecaf600dfeed;
/*
bw_osc_pulse_init(&instance->osc_pulse);
bw_osc_filt_init(&instance->osc_filt);
@ -114,6 +121,7 @@ void bw_example_synth_free(bw_example_synth instance) {
void bw_example_synth_set_sample_rate(bw_example_synth instance, float sample_rate) {
bw_phase_gen_set_sample_rate(&instance->phase_gen_coeffs, sample_rate);
bw_noise_gen_set_sample_rate(&instance->noise_gen_coeffs, sample_rate);
bw_phase_gen_set_sample_rate(&instance->a440_phase_gen_coeffs, sample_rate);
bw_vol_set_sample_rate(&instance->vol_coeffs, sample_rate);
/*
@ -155,6 +163,10 @@ void bw_example_synth_process(bw_example_synth instance, const float** x, float*
//bw_phase_gen_process(&instance->phase_gen_coeffs, &instance->phase_gen_state, NULL, y[0], instance->buf, n_samples);
for (int i = 0; i < n_samples; i++)
y[0][i] = 0.f;
if (instance->note != -1)
bw_noise_gen_process(&instance->noise_gen_coeffs, y[0], n_samples);
/*
for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
float *out = y[0] + i;

View File

@ -28,7 +28,7 @@
* <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* <li>Refactored API.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>:
@ -50,40 +50,33 @@ extern "C" {
#endif
/*! api {{{
* #### bw_noise_gen
* #### bw_noise_gen_coeffs
* ```>>> */
typedef struct _bw_noise_gen bw_noise_gen;
typedef struct _bw_noise_gen_coeffs bw_noise_gen_coeffs;
/*! <<<```
* Instance object.
* >>> */
/*! ...
* Coefficients.
*
* #### bw_noise_gen_init()
* ```>>> */
void bw_noise_gen_init(bw_noise_gen *instance, uint64_t *state);
static inline void bw_noise_gen_init(bw_noise_gen_coeffs *BW_RESTRICT coeffs, uint64_t *BW_RESTRICT state);
/*! <<<```
* Initializes the `instance` object and lets it use the given `state`
* pointer to obtain pseudo-random numbers.
* >>> */
/*! ...
* Initializes `coeffs` and lets it use the given `state` pointer to obtain
* pseudo-random numbers.
*
* #### bw_noise_gen_set_sample_rate()
* ```>>> */
void bw_noise_gen_set_sample_rate(bw_noise_gen *instance, float sample_rate);
static inline void bw_noise_gen_set_sample_rate(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float sample_rate);
/*! <<<```
* Sets the `sample_rate` value for the given `instance`.
* Sets the `sample_rate` (Hz) value for the given `coeffs`.
* >>> */
/*! ...
* #### bw_noise_gen_reset()
*
* There is none (not needed).
* >>> */
static inline float bw_noise_gen_process1(const bw_noise_gen_coeffs *BW_RESTRICT coeffs);
static inline float bw_noise_gen_process1_scaling(const bw_noise_gen_coeffs *BW_RESTRICT coeffs);
/*! ...
* #### bw_noise_gen_process()
* ```>>> */
void bw_noise_gen_process(bw_noise_gen *instance, float* y, int n_samples);
static inline void bw_noise_gen_process(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float *BW_RESTRICT y, int n_samples);
/*! <<<```
* Lets the given `instance` generate `n_samples` samples and puts them in
* the output buffer `y`.
@ -92,7 +85,7 @@ void bw_noise_gen_process(bw_noise_gen *instance, float* y, int n_samples);
/*! ...
* #### bw_noise_gen_set_sample_rate_scaling()
* ```>>> */
void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen *instance, char value);
static inline void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen_coeffs *BW_RESTRICT coeffs, char value);
/*! <<<```
* Sets whether the output should be scaled (`value` non-`0`) or not (`0`)
* according to the sample rate by the given `instance`.
@ -105,20 +98,53 @@ void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen *instance, char value);
* Default value: `0`.
* }}} */
/* WARNING: the internal definition of this struct is not part of the public
* API. Its content may change at any time in future versions. Please, do not
* access its members directly. */
struct _bw_noise_gen {
/*** 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_math.h>
#include <bw_rand.h>
struct _bw_noise_gen_coeffs {
// Coefficients
float scaling_k;
// Parameters
char sample_rate_scaling;
// State
uint64_t *state;
char sample_rate_scaling;
};
static inline void bw_noise_gen_init(bw_noise_gen_coeffs *BW_RESTRICT coeffs, uint64_t *BW_RESTRICT state) {
coeffs->state = state;
coeffs->sample_rate_scaling = 0;
}
static inline void bw_noise_gen_set_sample_rate(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float sample_rate) {
coeffs->scaling_k = 0.004761904761904762f * bw_sqrtf_2(sample_rate);
}
static inline float bw_noise_gen_process1(const bw_noise_gen_coeffs *BW_RESTRICT coeffs) {
return bw_randf(coeffs->state);
}
static inline float bw_noise_gen_process1_scaling(const bw_noise_gen_coeffs *BW_RESTRICT coeffs) {
return coeffs->scaling_k * bw_randf(coeffs->state);
}
static inline void bw_noise_gen_process(bw_noise_gen_coeffs *BW_RESTRICT coeffs, float *BW_RESTRICT y, int n_samples) {
if (coeffs->sample_rate_scaling)
for (int i = 0; i < n_samples; i++)
y[i] = bw_noise_gen_process1(coeffs);
else
for (int i = 0; i < n_samples; i++)
y[i] = bw_noise_gen_process1_scaling(coeffs);
}
static inline void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen_coeffs *BW_RESTRICT coeffs, char value) {
coeffs->sample_rate_scaling = value;
}
#ifdef __cplusplus
}
#endif

View File

@ -33,6 +33,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>:
* <ul>
* <li>First release.</li>
@ -52,9 +57,9 @@ extern "C" {
#endif
/*! api {{{
* #### bw_rand_u32()
* #### bw_randu32()
* ```>>> */
uint32_t bw_rand_u32(uint64_t *state);
static inline uint32_t bw_randu32(uint64_t *BW_RESTRICT state);
/*! <<<```
* Returns a pseudo-random unsigned 32-bit integer in the range
* [`0`, `UINT32_MAX`].
@ -64,9 +69,9 @@ uint32_t bw_rand_u32(uint64_t *state);
* >>> */
/*! ...
* #### bw_rand_f()
* #### bw_randf()
* ```>>> */
float bw_rand_f(uint64_t *state);
static inline float bw_randf(uint64_t *BW_RESTRICT state);
/*! <<<```
* Returns a pseudo-random unsigned 32-bit floating point number in the range
* [`-1.f`, `1.f`].
@ -75,6 +80,22 @@ float bw_rand_f(uint64_t *state);
* between calls, and which gets updated by calls to this function.
* }}} */
/*** 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 uint32_t bw_randu32(uint64_t *BW_RESTRICT state) {
// Permuted Congruential Generator,
// taken from https://nullprogram.com/blog/2017/09/21/
*state = *state * 0x9b60933458e17d7d + 0xd737232eeccdf7ed;
return *state >> (29 - (*state >> 61));
}
static inline float bw_randf(uint64_t *BW_RESTRICT state) {
return (2.f / (float)UINT32_MAX) * (float)bw_randu32(state) - 1.f;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,45 +0,0 @@
/*
* Brickworks
*
* Copyright (C) 2022 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
*
* File author: Stefano D'Angelo
*/
#include <bw_noise_gen.h>
#include <bw_rand.h>
#include <bw_math.h>
void bw_noise_gen_init(bw_noise_gen *instance, uint64_t *state) {
instance->state = state;
instance->sample_rate_scaling = 0;
}
void bw_noise_gen_set_sample_rate(bw_noise_gen *instance, float sample_rate) {
instance->scaling_k = 0.004761904761904762f * bw_sqrtf_2(sample_rate);
}
void bw_noise_gen_process(bw_noise_gen *instance, float* y, int n_samples) {
for (int i = 0; i < n_samples; i++)
y[i] = bw_rand_f(instance->state);
if (instance->sample_rate_scaling)
for (int i = 0; i < n_samples; i++)
y[i] *= instance->scaling_k;
}
void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen *instance, char value) {
instance->sample_rate_scaling = value;
}

View File

@ -1,31 +0,0 @@
/*
* Brickworks
*
* Copyright (C) 2022 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
*
* File author: Stefano D'Angelo
*/
#include <bw_rand.h>
uint32_t bw_rand_u32(uint64_t *state) {
// Permuted Congruential Generator,
// taken from https://nullprogram.com/blog/2017/09/21/
*state = *state * 0x9b60933458e17d7d + 0xd737232eeccdf7ed;
return *state >> (29 - (*state >> 61));
}
float bw_rand_f(uint64_t *state) {
return (2.f / (float)UINT32_MAX) * (float)bw_random_u32(state) - 1.f;
}