bw_voice_alloc_mode -> bw_voice_alloc_priority + finished C doc
This commit is contained in:
parent
73185217e7
commit
bd3a6367e0
1
TODO
1
TODO
@ -63,6 +63,7 @@ code:
|
||||
* c++ get coeffs/state? or public? src nIn/OutSamples case (array vs single value), delay read/write, process1? process single?
|
||||
* bw_buf invert src dest order?
|
||||
* check unititialized warnings
|
||||
* voice alloc mode -> voice alloc priority
|
||||
|
||||
build system:
|
||||
* single header generation
|
||||
|
@ -167,7 +167,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
|
||||
|
||||
(void)x;
|
||||
|
||||
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_mode_low, note_on, note_off, get_note, is_free };
|
||||
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_priority_low, note_on, note_off, get_note, is_free };
|
||||
void *voices[N_VOICES];
|
||||
for (int i = 0; i < N_VOICES; i++)
|
||||
voices[i] = (void *)(instance->voices + i);
|
||||
|
@ -132,7 +132,6 @@ static char is_free(void *BW_RESTRICT voice) {
|
||||
return !v->gate && phase == bw_env_gen_phase_off;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const float** x, float** y, int n_samples) {
|
||||
// FIXME: control-rate modulations are asynchronous here...
|
||||
// it's all good as long as hosts gives us buffers whose length is a multiple of 32,
|
||||
@ -140,7 +139,7 @@ void bw_example_synthpp_poly_process(bw_example_synthpp_poly *instance, const fl
|
||||
|
||||
(void)x;
|
||||
|
||||
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_mode_low, note_on, note_off, get_note, is_free };
|
||||
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_priority_low, note_on, note_off, get_note, is_free };
|
||||
void *voices[N_VOICES];
|
||||
for (int i = 0; i < N_VOICES; i++)
|
||||
voices[i] = (void *)(instance->voices + i);
|
||||
|
@ -23,9 +23,10 @@
|
||||
* version {{{ 0.5.0 }}}
|
||||
* requires {{{ bw_common bw_config }}}
|
||||
* description {{{
|
||||
* Note queue.
|
||||
* Simple data structure that helps keeping track of note on/off events and
|
||||
* pressed key status.
|
||||
*
|
||||
* ...
|
||||
* It is not concerned with timing.
|
||||
* }}}
|
||||
* changelog {{{
|
||||
* <ul>
|
||||
@ -55,6 +56,10 @@ typedef struct {
|
||||
float velocity; // negative = unknown / not available
|
||||
} bw_note_queue_status;
|
||||
/*! <<<```
|
||||
* Note status:
|
||||
* * `pressed`: whether the note is pressed (non-`0`) or not (`0`);
|
||||
* * `velocity`: velocity in [`0.f`, `1.f`].
|
||||
*
|
||||
* #### bw_note_queue_event
|
||||
* ```>>> */
|
||||
typedef struct {
|
||||
@ -63,6 +68,12 @@ typedef struct {
|
||||
char went_off;
|
||||
} bw_note_queue_event;
|
||||
/*! <<<```
|
||||
* Note on/off event:
|
||||
* * `note`: note number in [`0`, `127`];
|
||||
* * `status`: note status;
|
||||
* * `went_off`: whether a note off event fired on the same note (non-`0`)
|
||||
* or not (`0`) -- see `bw_note_queue`.
|
||||
*
|
||||
* #### bw_note_queue
|
||||
* ```>>> */
|
||||
typedef struct {
|
||||
@ -72,18 +83,39 @@ typedef struct {
|
||||
unsigned char n_pressed;
|
||||
} bw_note_queue;
|
||||
/*! <<<```
|
||||
* Note on/off event queue and pressed key status:
|
||||
* * `events`: events since the reset/clear -- the order is not meaningful
|
||||
* and it contains maximum one event per note number, so that the last
|
||||
* event added for a given note overwrites the previous if it exists;
|
||||
* `went_off` is set to non-`0` in case of a note off event or when
|
||||
* overwriting an event whose `went_off` was already non-`0`;
|
||||
* * `n_events`: number of elements in `events`;
|
||||
* * `status`: current status of all notes;
|
||||
* * `n_pressed`: number of currently pressed keys.
|
||||
*
|
||||
* #### bw_note_queue_reset()
|
||||
* ```>>> */
|
||||
static inline void bw_note_queue_reset(bw_note_queue *BW_RESTRICT queue);
|
||||
/*! <<<```
|
||||
* Clear both the event queue (no events) and the note statuses (all notes
|
||||
* off, all velocities `0.f`) in `queue`.
|
||||
*
|
||||
* #### bw_note_queue_clear()
|
||||
* ```>>> */
|
||||
static inline void bw_note_queue_clear(bw_note_queue *BW_RESTRICT queue);
|
||||
/*! <<<```
|
||||
* Clears the event queue (no events) in `queue` without affecting the note
|
||||
* statuses.
|
||||
*
|
||||
* #### bw_note_queue_add()
|
||||
* ```>>> */
|
||||
static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned char note, char pressed, float velocity, char force_went_off);
|
||||
/*! <<<```
|
||||
* Adds a new event to `queue` with the specified `note` number, `pressed`
|
||||
* value, and `velocity`.
|
||||
*
|
||||
* If `force_went_off` is set to non-`0`, `went_off` is always set to
|
||||
* non-`0`.
|
||||
* }}} */
|
||||
|
||||
/*** Implementation ***/
|
||||
|
@ -86,7 +86,7 @@ typedef enum {
|
||||
* Distance metrics for sticky behavior:
|
||||
* * `bw_one_pole_sticky_mode_abs`: absolute difference (|`out` - `in`|);
|
||||
* * `bw_one_pole_sticky_mode_rel`: relative difference with respect to
|
||||
* input (|`out` - `in`| / |`in`|);
|
||||
* input (|`out` - `in`| / |`in`|).
|
||||
*
|
||||
* #### bw_one_pole_init()
|
||||
* ```>>> */
|
||||
|
@ -23,9 +23,7 @@
|
||||
* version {{{ 0.5.0 }}}
|
||||
* requires {{{ bw_common bw_config bw_note_queue }}}
|
||||
* description {{{
|
||||
* Basic voice allocator.
|
||||
*
|
||||
* ...
|
||||
* Basic voice allocator with low/high note priority.
|
||||
* }}}
|
||||
* changelog {{{
|
||||
* <ul>
|
||||
@ -49,17 +47,21 @@ extern "C" {
|
||||
#include <bw_note_queue.h>
|
||||
|
||||
/*! api {{{
|
||||
* #### bw_voice_alloc_mode
|
||||
* #### bw_voice_alloc_priority
|
||||
* ```>>> */
|
||||
typedef enum {
|
||||
bw_voice_alloc_mode_low,
|
||||
bw_voice_alloc_mode_high
|
||||
} bw_voice_alloc_mode;
|
||||
bw_voice_alloc_priority_low,
|
||||
bw_voice_alloc_priority_high
|
||||
} bw_voice_alloc_priority;
|
||||
/*! <<<```
|
||||
* Note priority:
|
||||
* * `bw_voice_alloc_priority_low`: low note priority;
|
||||
* * `bw_voice_alloc_priority_high`: high note priority.
|
||||
*
|
||||
* #### bw_voice_alloc_opts
|
||||
* ```>>> */
|
||||
typedef struct {
|
||||
bw_voice_alloc_mode mode;
|
||||
bw_voice_alloc_priority priority;
|
||||
|
||||
void (*note_on)(void *BW_RESTRICT voice, unsigned char note, float velocity);
|
||||
void (*note_off)(void *BW_RESTRICT voice, float velocity);
|
||||
@ -67,10 +69,27 @@ typedef struct {
|
||||
char (*is_free)(void *BW_RESTRICT voice);
|
||||
} bw_voice_alloc_opts;
|
||||
/*! <<<```
|
||||
* Voice allocation options:
|
||||
* * `priority`: note priority;
|
||||
* * `note_on`: note on callback, where `voice` is an opaque pointer to the
|
||||
* chosen voice, `note` is the note number, and `velocity` is the note
|
||||
* velocity in [`0.f`, `1.f`];
|
||||
* * `note_off`: note off callback, where `voice` is an opaque pointer to
|
||||
* the chosen voice and `velocity` is the note velocity in [`0.f`, `1.f`];
|
||||
* * `get_note`: callback that returns the note number associated to the
|
||||
* given `voice`;
|
||||
* * `is_free`: callback that returns whether the given `voice` is free
|
||||
* (non-`0`) or not (`0`);
|
||||
*
|
||||
* #### 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);
|
||||
/*! <<<```
|
||||
* It performs voice allocation according to `opts` and using the events in
|
||||
* `queue`.
|
||||
*
|
||||
* `voices` is the array of opaque voice pointers and `n_voices` indicates
|
||||
* the number of elements in `voices`.
|
||||
* }}} */
|
||||
|
||||
/*** Implementation ***/
|
||||
@ -101,7 +120,7 @@ void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *
|
||||
int v = ev->note;
|
||||
for (int j = 0; j < n_voices; j++) {
|
||||
int n = opts->get_note(voices[j]);
|
||||
if (!queue->status[n].pressed && (k < 0 || (opts->mode == bw_voice_alloc_mode_low ? n > v : n < v))) {
|
||||
if (!queue->status[n].pressed && (k < 0 || (opts->priority == bw_voice_alloc_priority_low ? n > v : n < v))) {
|
||||
v = n;
|
||||
k = j;
|
||||
}
|
||||
@ -113,7 +132,7 @@ void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *
|
||||
|
||||
for (int j = 0; j < n_voices; j++) {
|
||||
int n = opts->get_note(voices[j]);
|
||||
if (opts->mode == bw_voice_alloc_mode_low ? n > v : n < v) {
|
||||
if (opts->priority == bw_voice_alloc_priority_low ? n > v : n < v) {
|
||||
v = n;
|
||||
k = j;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user