From b8758686b8285dd368a90222baccb2e864c5c08f Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Thu, 9 May 2024 05:48:40 +0200 Subject: [PATCH] bl00mbox channel system upgrade channels are now dynamically allocated and can be garbage collected. note that channels do NOT live on the mp heap so their memory footprint won't trigger a gc, we rely on pyst3m just doing that on its own every now and then. --- components/bl00mbox/CMakeLists.txt | 2 + components/bl00mbox/bl00mbox.c | 2 +- components/bl00mbox/bl00mbox_audio.c | 329 ++++++++++-------- components/bl00mbox/bl00mbox_os.c | 36 ++ components/bl00mbox/bl00mbox_user.c | 143 ++++---- components/bl00mbox/config/bl00mbox_config.h | 13 + components/bl00mbox/include/bl00mbox_audio.h | 77 ++-- components/bl00mbox/include/bl00mbox_ll.h | 54 +++ components/bl00mbox/include/bl00mbox_os.h | 22 ++ components/bl00mbox/include/bl00mbox_user.h | 84 ++--- .../bl00mbox/micropython/bl00mbox/_plugins.py | 3 +- .../bl00mbox/micropython/bl00mbox/_user.py | 85 +++-- .../bl00mbox/micropython/mp_sys_bl00mbox.c | 78 ++++- .../standard_plugin_lib/range_shifter.c | 2 +- .../standard_plugin_lib/slew_rate_limiter.c | 2 - 15 files changed, 609 insertions(+), 323 deletions(-) create mode 100644 components/bl00mbox/bl00mbox_os.c create mode 100644 components/bl00mbox/config/bl00mbox_config.h create mode 100644 components/bl00mbox/include/bl00mbox_ll.h create mode 100644 components/bl00mbox/include/bl00mbox_os.h diff --git a/components/bl00mbox/CMakeLists.txt b/components/bl00mbox/CMakeLists.txt index ecdabe8423..851a55b400 100644 --- a/components/bl00mbox/CMakeLists.txt +++ b/components/bl00mbox/CMakeLists.txt @@ -5,6 +5,7 @@ idf_component_register( bl00mbox.c bl00mbox_audio.c bl00mbox_user.c + bl00mbox_os.c bl00mbox_plugin_registry.c bl00mbox_radspa_requirements.c radspa/standard_plugin_lib/osc.c @@ -36,4 +37,5 @@ idf_component_register( radspa radspa/standard_plugin_lib extern + config ) diff --git a/components/bl00mbox/bl00mbox.c b/components/bl00mbox/bl00mbox.c index ad55b04417..cd601f717e 100644 --- a/components/bl00mbox/bl00mbox.c +++ b/components/bl00mbox/bl00mbox.c @@ -5,5 +5,5 @@ void bl00mbox_init(){ bl00mbox_plugin_registry_init(); - bl00mbox_channels_init(); + bl00mbox_audio_init(); } diff --git a/components/bl00mbox/bl00mbox_audio.c b/components/bl00mbox/bl00mbox_audio.c index 763110736a..ae8a3e2cf8 100644 --- a/components/bl00mbox/bl00mbox_audio.c +++ b/components/bl00mbox/bl00mbox_audio.c @@ -1,199 +1,241 @@ //SPDX-License-Identifier: CC0-1.0 #include "bl00mbox_audio.h" +#include "bl00mbox_ll.h" +#include "bl00mbox_user.h" +#include "bl00mbox_os.h" static bool is_initialized = false; -static bool bl00mbox_audio_run = true; -void bl00mbox_audio_enable(){ bl00mbox_audio_run = true; } -void bl00mbox_audio_disable(){ bl00mbox_audio_run = false; } static uint16_t full_buffer_len; static uint32_t render_pass_id; int16_t * bl00mbox_line_in_interlaced = NULL; -// fixed-length list of channels -static bl00mbox_channel_t channels[BL00MBOX_CHANNELS]; -static int8_t last_chan_event = 0; -// foregrounded channel is always rendered -// note: regardless of settings the system channel 0 is always rendered -static uint8_t bl00mbox_channel_foreground = 0; -// channels may request being active while not being in foreground -static bool bl00mbox_channel_background_mute_override[BL00MBOX_CHANNELS] = {false,}; - -bool bl00mbox_channel_set_background_mute_override(uint8_t channel_index, bool enable){ -#ifdef BL00MBOX_BACKGROUND_MUTE_OVERRIDE_ENABLE - if(channel_index >= BL00MBOX_CHANNELS) return false; - bl00mbox_channel_background_mute_override[channel_index] = enable; - return true; -#else - return false; -#endif +static int32_t free_chan_index = 0; // increments +static bl00mbox_ll_t * all_chans = NULL; +static bl00mbox_ll_t * background_mute_override_chans = NULL; +static bl00mbox_channel_t * foreground_chan = NULL; +static bl00mbox_lock_t render_lock = NULL; + +static bl00mbox_channel_t * cached_chan = NULL; + +bl00mbox_channel_t * bl00mbox_get_channel(int32_t channel_index){ + if(channel_index < 0) return NULL; + if(cached_chan && (cached_chan->index == channel_index)){ + return cached_chan; + } + bl00mbox_ll_t * chll = all_chans; + while(chll){ + bl00mbox_channel_t * chan = chll->content; + if(chan->index == channel_index){ + cached_chan = chan; + return chan; + } + chll = chll->next; + } + return NULL; } -bool bl00mbox_channel_get_background_mute_override(uint8_t channel_index){ - if(channel_index >= BL00MBOX_CHANNELS) return false; - return bl00mbox_channel_background_mute_override[channel_index]; +bool bl00mbox_get_channel_exists(int32_t channel_index){ + return (bool) bl00mbox_get_channel(channel_index); } -static void ** ptr_to_be_set_by_audio_task = NULL; -static void * ptr_to_be_set_by_audio_task_target = NULL; -// TODO: multicore thread safety on this boi -static volatile bool ptr_set_request_pending = false; -static uint64_t bl00mbox_audio_waitfor_timeout = 0ULL; +int32_t bl00mbox_get_channel_index_positional_all_chans(int32_t position){ + bl00mbox_ll_t * chll = all_chans; + if(!chll) return -1; + while(position){ + position--; + chll = chll->next; + if(!chll) return -1; + } + bl00mbox_channel_t * chan = chll->content; + return chan->index; +} -bool bl00mbox_audio_waitfor_pointer_change(void ** ptr, void * new_val){ - /// takes pointer to pointer that is to be set null - if(!is_initialized) return false; - ptr_to_be_set_by_audio_task = ptr; - ptr_to_be_set_by_audio_task_target = new_val; - ptr_set_request_pending = true; - - volatile uint64_t timeout = 0; // cute - while(ptr_set_request_pending){ - timeout++; - // TODO: nop - if(bl00mbox_audio_waitfor_timeout && (timeout = bl00mbox_audio_waitfor_timeout)){ - return false; - } +int32_t bl00mbox_get_channel_index_positional_background_mute_override_chans(int32_t position){ + bl00mbox_ll_t * chll = background_mute_override_chans; + if(!chll) return -1; + while(position){ + position--; + chll = chll->next; + if(!chll) return -1; + } + bl00mbox_channel_t * chan = chll->content; + return chan->index; +} + +bool bl00mbox_channel_set_background_mute_override(int32_t channel_index, bool enable){ + bl00mbox_channel_t * ch = bl00mbox_get_channel(channel_index); + if(!ch) return false; + if(enable){ + bl00mbox_ll_prepend(&background_mute_override_chans, ch, &render_lock); + } else { + bl00mbox_ll_pop(&background_mute_override_chans, ch, &render_lock); } return true; } -bool bl00mbox_audio_do_pointer_change(){ - if(ptr_set_request_pending){ - (* ptr_to_be_set_by_audio_task) = ptr_to_be_set_by_audio_task_target; - ptr_to_be_set_by_audio_task_target = NULL; - ptr_to_be_set_by_audio_task = NULL; - ptr_set_request_pending = false; - return true; +bool bl00mbox_channel_get_background_mute_override(int32_t channel_index){ + bl00mbox_channel_t * ch = bl00mbox_get_channel(channel_index); + if(!ch) return false; + return bl00mbox_ll_contains(&background_mute_override_chans, ch); +} + +int32_t bl00mbox_channel_get_foreground_index(){ + if(foreground_chan) return foreground_chan->index; + return -1; +} + +void bl00mbox_channel_set_foreground_index(int32_t channel_index){ + bl00mbox_channel_t * chan = bl00mbox_get_channel(channel_index); + if(!chan) return; + if(foreground_chan != chan){ + bl00mbox_take_lock(&render_lock); + foreground_chan = chan; + bl00mbox_give_lock(&render_lock); } - return false; } -void bl00mbox_channel_event(uint8_t chan){ +void bl00mbox_channel_event(int32_t index){ #ifdef BL00MBOX_AUTO_FOREGROUNDING - last_chan_event = chan; + bl00mbox_channel_set_foreground_index(index); #endif } -bl00mbox_channel_t * bl00mbox_get_channel(uint8_t channel_index){ - if(channel_index >= BL00MBOX_CHANNELS) return NULL; - return &(channels[channel_index]); +static bl00mbox_channel_t * _bl00mbox_channel_create(){ + if(free_chan_index < 0) return NULL; + bl00mbox_channel_t * chan = calloc(1, sizeof(bl00mbox_channel_t)); + if(!chan) return NULL; + if(!bl00mbox_ll_prepend(&all_chans, chan, NULL)){ + free(chan); + return NULL; + } + chan->volume = BL00MBOX_DEFAULT_CHANNEL_VOLUME; + chan->sys_gain = 4096; + chan->is_active = true; + chan->index = free_chan_index; + free_chan_index += 1; + + bl00mbox_create_lock(&chan->render_lock); + bl00mbox_take_lock(&render_lock); + foreground_chan = chan; + bl00mbox_give_lock(&render_lock); + return chan; } - -uint8_t bl00mbox_channel_get_foreground_index(){ - return bl00mbox_channel_foreground; +bl00mbox_channel_t * bl00mbox_channel_create(){ + bl00mbox_channel_t * chan = _bl00mbox_channel_create(); + if(!chan) bl00mbox_log_error("channel allocation failed"); + return chan; } -void bl00mbox_channel_set_foreground_index(uint8_t channel_index){ - if(channel_index >= BL00MBOX_CHANNELS) return; - last_chan_event = channel_index; +void bl00mbox_channel_delete(bl00mbox_channel_t * chan){ + if(!chan) return; + if(cached_chan == chan) cached_chan = NULL; + if(foreground_chan == chan){ + bl00mbox_take_lock(&render_lock); + foreground_chan = NULL; + bl00mbox_give_lock(&render_lock); + } + bl00mbox_ll_pop(&background_mute_override_chans, chan, &render_lock); + bl00mbox_ll_pop(&all_chans, chan, NULL); + bl00mbox_channel_clear(chan->index); + // be really sure that nobody else holds the lock. the renderer + // doesn't at this point, but if there's multiple tasks running + // clients there may be collisions. + // since the client api is generally not thread safe at this point + // it's okay, we can add the feature easily by just wrapping _all_ + // client api in a lock at some point in the future. + bl00mbox_delete_lock(&chan->render_lock); + free(chan->name); + free(chan); } -bool bl00mbox_channel_get_free(uint8_t channel_index){ - if(channel_index >= BL00MBOX_CHANNELS) return false; - return bl00mbox_get_channel(channel_index)->is_free; +bool bl00mbox_channel_get_free(int32_t channel_index){ + // TODO: deprecate + bl00mbox_channel_t * chan = bl00mbox_get_channel(channel_index); + return !chan; } -bool bl00mbox_channel_set_free(uint8_t channel_index, bool free){ - if(channel_index >= BL00MBOX_CHANNELS) return false; - bl00mbox_get_channel(channel_index)->is_free = free; +bool bl00mbox_channel_set_free(int32_t channel_index, bool set_free){ + // TODO: deprecate + bl00mbox_channel_t * chan = bl00mbox_get_channel(channel_index); + if(!chan) return false; + if(set_free) bl00mbox_channel_delete(chan); return true; } -uint8_t bl00mbox_channel_get_free_index(){ - uint8_t ret = 1; // never return system channel - for(; ret < BL00MBOX_CHANNELS; ret++){ - if(bl00mbox_get_channel(ret)->is_free){ - bl00mbox_get_channel(ret)->is_free = false; - break; - } - } - last_chan_event = ret; - return ret; +int32_t bl00mbox_channel_get_free_index(){ + bl00mbox_channel_t * chan = bl00mbox_channel_create(); + if(chan) return chan->index; + return -1; } -char * bl00mbox_channel_get_name(uint8_t channel_index){ - if(channel_index >= BL00MBOX_CHANNELS) return NULL; - return bl00mbox_get_channel(channel_index)->name; -} -void bl00mbox_channel_set_name(uint8_t channel_index, char * new_name){ - if(channel_index >= BL00MBOX_CHANNELS) return; - bl00mbox_channel_t * chan = bl00mbox_get_channel(channel_index); - if(chan->name != NULL) free(chan->name); - chan->name = strdup(new_name); +char * bl00mbox_channel_get_name(int32_t channel_index){ + bl00mbox_channel_t * chan = bl00mbox_get_channel(channel_index); + if(!chan) return NULL; + return chan->name; } -void bl00mbox_channels_init(){ - for(uint8_t i = 0; i < BL00MBOX_CHANNELS; i++){ - bl00mbox_channel_t * chan = bl00mbox_get_channel(i); - chan->volume = BL00MBOX_DEFAULT_CHANNEL_VOLUME; - chan->sys_gain = 4096; - chan->root_list = NULL; - chan->buds = NULL; - chan->connections = NULL; - chan->is_active = true; - chan->is_free = true; - chan->always_render = NULL; - chan->name = NULL; - chan->dc = 0; - } - is_initialized = true; +void bl00mbox_channel_set_name(int32_t channel_index, char * new_name){ + bl00mbox_channel_t * ch = bl00mbox_get_channel(channel_index); + if(!ch) return; + if(ch->name != NULL) free(ch->name); + ch->name = strdup(new_name); } -void bl00mbox_channel_enable(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return; +void bl00mbox_channel_enable(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return; ch->is_active = true; } -void bl00mbox_channel_disable(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return; +void bl00mbox_channel_disable(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return; ch->is_active = false; } -void bl00mbox_channel_set_compute_mean_square(uint8_t chan, bool compute){ - if(chan >= (BL00MBOX_CHANNELS)) return; +void bl00mbox_channel_set_compute_mean_square(int32_t chan, bool compute){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return; ch->compute_mean_square = compute; if(!compute) ch->mean_square = 0; } -bool bl00mbox_channel_get_compute_mean_square(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return 0; +bool bl00mbox_channel_get_compute_mean_square(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return 0; return ch->compute_mean_square; } -uint32_t bl00mbox_channel_get_mean_square(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return 0; +uint32_t bl00mbox_channel_get_mean_square(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return 0; return ch->mean_square; } -void bl00mbox_channel_set_sys_gain(uint8_t chan, int16_t volume){ - if(chan >= (BL00MBOX_CHANNELS)) return; +void bl00mbox_channel_set_sys_gain(int32_t chan, int16_t volume){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return; ch->sys_gain = volume; } -int16_t bl00mbox_channel_get_sys_gain(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return 0; +int16_t bl00mbox_channel_get_sys_gain(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return 0; return ch->sys_gain; } -void bl00mbox_channel_set_volume(uint8_t chan, uint16_t volume){ - if(chan >= (BL00MBOX_CHANNELS)) return; +void bl00mbox_channel_set_volume(int32_t chan, uint16_t volume){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return; ch->volume = volume < 32767 ? volume : 32767; } -int16_t bl00mbox_channel_get_volume(uint8_t chan){ - if(chan >= (BL00MBOX_CHANNELS)) return 0; +int16_t bl00mbox_channel_get_volume(int32_t chan){ bl00mbox_channel_t * ch = bl00mbox_get_channel(chan); + if(!ch) return 0; return ch->volume; } @@ -208,8 +250,7 @@ void bl00mbox_audio_bud_render(bl00mbox_bud_t * bud){ bud->is_being_rendered = false; } -static bool bl00mbox_audio_channel_render(bl00mbox_channel_t * chan, int16_t * out, bool adding){ - if(render_pass_id == chan->render_pass_id) return false; +static bool _bl00mbox_audio_channel_render(bl00mbox_channel_t * chan, int16_t * out, bool adding){ chan->render_pass_id = render_pass_id; bl00mbox_bud_list_t * always = chan->always_render; @@ -223,7 +264,7 @@ static bool bl00mbox_audio_channel_render(bl00mbox_channel_t * chan, int16_t * o int32_t vol = radspa_mult_shift(chan->volume, chan->sys_gain); // early exit when no sources or muted: - if((root == NULL) || (!chan->is_active) || (!vol)){ + if((root == NULL) || (!vol)){ return false; } @@ -291,33 +332,36 @@ static bool bl00mbox_audio_channel_render(bl00mbox_channel_t * chan, int16_t * o return true; } -bool _bl00mbox_audio_render(int16_t * rx, int16_t * tx, uint16_t len){ - if(!is_initialized) return false; - - bl00mbox_audio_do_pointer_change(); - bl00mbox_channel_foreground = last_chan_event; +static bool bl00mbox_audio_channel_render(bl00mbox_channel_t * chan, int16_t * out, bool adding){ + if(!chan) return false; + if(!chan->is_active) return false; + if(render_pass_id == chan->render_pass_id) return false; + bl00mbox_take_lock(&chan->render_lock); + bool ret = _bl00mbox_audio_channel_render(chan, out, adding); + bl00mbox_give_lock(&chan->render_lock); + return ret; +} - if(!bl00mbox_audio_run) return false; +static bool _bl00mbox_audio_render(int16_t * rx, int16_t * tx, uint16_t len){ + if(!is_initialized) return false; render_pass_id++; // fresh pass, all relevant sources must be recomputed full_buffer_len = len/2; bl00mbox_line_in_interlaced = rx; int16_t acc[full_buffer_len]; bool acc_init = false; - // system channel always runs non-adding - acc_init = bl00mbox_audio_channel_render(&(channels[0]), acc, acc_init) || acc_init; - // re-rendering channels is ok, if render_pass_id didn't change it will just exit - acc_init = bl00mbox_audio_channel_render(&(channels[bl00mbox_channel_foreground]), acc, acc_init) || acc_init; + bl00mbox_take_lock(&render_lock); - // TODO: scales poorly if there's many channels -#ifdef BL00MBOX_BACKGROUND_MUTE_OVERRIDE_ENABLE - for(uint8_t i = 1; i < (BL00MBOX_CHANNELS); i++){ - if(bl00mbox_channel_background_mute_override[i]){ - acc_init = bl00mbox_audio_channel_render(&(channels[i]), acc, acc_init) || acc_init; - } + // re-rendering channels is ok, if render_pass_id didn't change it will just exit + acc_init = bl00mbox_audio_channel_render(foreground_chan, acc, acc_init) || acc_init; + bl00mbox_ll_t * chll = background_mute_override_chans; + while(chll){ + acc_init = bl00mbox_audio_channel_render(chll->content, acc, acc_init) || acc_init; + chll = chll->next; } -#endif + + bl00mbox_give_lock(&render_lock); if(!acc_init) return false; @@ -331,3 +375,10 @@ bool _bl00mbox_audio_render(int16_t * rx, int16_t * tx, uint16_t len){ void bl00mbox_audio_render(int16_t * rx, int16_t * tx, uint16_t len){ if(!_bl00mbox_audio_render(rx, tx, len)) memset(tx, 0, len*sizeof(int16_t)); } + +void bl00mbox_audio_init(){ + if(render_lock) abort(); + bl00mbox_create_lock(&render_lock); + if(!render_lock) abort(); + is_initialized = true; +} diff --git a/components/bl00mbox/bl00mbox_os.c b/components/bl00mbox/bl00mbox_os.c new file mode 100644 index 0000000000..9f7807012f --- /dev/null +++ b/components/bl00mbox/bl00mbox_os.c @@ -0,0 +1,36 @@ +#include "bl00mbox_os.h" + +#ifdef BL00MBOX_FREERTOS +void bl00mbox_create_lock(bl00mbox_lock_t * lock){ * lock = xSemaphoreCreateMutex(); } +void bl00mbox_delete_lock(bl00mbox_lock_t * lock){ if(lock) vSemaphoreDelete(* lock); } +void bl00mbox_take_lock(bl00mbox_lock_t * lock){ if(lock) xSemaphoreTake(* lock, portMAX_DELAY); } +void bl00mbox_give_lock(bl00mbox_lock_t * lock){ if(lock) xSemaphoreGive(* lock); } +#endif + +#if defined(BL00MBOX_ESPIDF) +// macros in header +#elif defined(BL00MBOX_PRINTF) +#include <stdarg.h> +#include <string.h> +static void _bl00mbox_log(char * pre, char * txt, va_list args){ + int len = strlen(pre) + strlen(txt) + 2; + char msg[len]; + snprintf(msg, len, "%s%s\n", pre, txt); + vprintf(msg, args); +} +void bl00mbox_log_error(char * txt, ...){ + va_list args; + va_start(args, txt); + _bl00mbox_log("bl00mbox error: ", txt, args); + va_end(args); +}; +void bl00mbox_log_info(char * txt, ...){ + va_list args; + va_start(args, txt); + _bl00mbox_log("bl00mbox info: ", txt, args); + va_end(args); +}; +#else +void bl00mbox_log_error(char * txt, ...){}; +void bl00mbox_log_info(char * txt, ...){}; +#endif diff --git a/components/bl00mbox/bl00mbox_user.c b/components/bl00mbox/bl00mbox_user.c index e828b4f4a9..3d81973a09 100644 --- a/components/bl00mbox/bl00mbox_user.c +++ b/components/bl00mbox/bl00mbox_user.c @@ -7,9 +7,9 @@ radspa_signal_t * bl00mbox_signal_get_by_index(radspa_t * plugin, uint16_t signa } static uint64_t bl00mbox_bud_index = 1; -bl00mbox_bud_t * bl00mbox_channel_get_bud_by_index(uint8_t channel, uint32_t index); +bl00mbox_bud_t * bl00mbox_channel_get_bud_by_index(int32_t channel, uint32_t index); -uint16_t bl00mbox_channel_buds_num(uint8_t channel){ +uint16_t bl00mbox_channel_buds_num(int32_t channel){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->buds != NULL){ @@ -23,7 +23,7 @@ uint16_t bl00mbox_channel_buds_num(uint8_t channel){ return ret; } -uint64_t bl00mbox_channel_get_bud_by_list_pos(uint8_t channel, uint32_t pos){ +uint64_t bl00mbox_channel_get_bud_by_list_pos(int32_t channel, uint32_t pos){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->buds != NULL){ @@ -39,7 +39,7 @@ uint64_t bl00mbox_channel_get_bud_by_list_pos(uint8_t channel, uint32_t pos){ return 0; } -uint16_t bl00mbox_channel_conns_num(uint8_t channel){ +uint16_t bl00mbox_channel_conns_num(int32_t channel){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->connections != NULL){ @@ -53,7 +53,7 @@ uint16_t bl00mbox_channel_conns_num(uint8_t channel){ return ret; } -uint16_t bl00mbox_channel_mixer_num(uint8_t channel){ +uint16_t bl00mbox_channel_mixer_num(int32_t channel){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->root_list != NULL){ @@ -67,7 +67,7 @@ uint16_t bl00mbox_channel_mixer_num(uint8_t channel){ return ret; } -uint64_t bl00mbox_channel_get_bud_by_mixer_list_pos(uint8_t channel, uint32_t pos){ +uint64_t bl00mbox_channel_get_bud_by_mixer_list_pos(int32_t channel, uint32_t pos){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->buds != NULL){ @@ -83,7 +83,7 @@ uint64_t bl00mbox_channel_get_bud_by_mixer_list_pos(uint8_t channel, uint32_t po return 0; } -uint32_t bl00mbox_channel_get_signal_by_mixer_list_pos(uint8_t channel, uint32_t pos){ +uint32_t bl00mbox_channel_get_signal_by_mixer_list_pos(int32_t channel, uint32_t pos){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); uint16_t ret = 0; if(chan->buds != NULL){ @@ -99,7 +99,7 @@ uint32_t bl00mbox_channel_get_signal_by_mixer_list_pos(uint8_t channel, uint32_t return 0; } -uint16_t bl00mbox_channel_subscriber_num(uint8_t channel, uint64_t bud_index, uint16_t signal_index){ +uint16_t bl00mbox_channel_subscriber_num(int32_t channel, uint64_t bud_index, uint16_t signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -121,7 +121,7 @@ uint16_t bl00mbox_channel_subscriber_num(uint8_t channel, uint64_t bud_index, ui return ret; } -uint64_t bl00mbox_channel_get_bud_by_subscriber_list_pos(uint8_t channel, uint64_t bud_index, +uint64_t bl00mbox_channel_get_bud_by_subscriber_list_pos(int32_t channel, uint64_t bud_index, uint16_t signal_index, uint8_t pos){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; @@ -146,7 +146,7 @@ uint64_t bl00mbox_channel_get_bud_by_subscriber_list_pos(uint8_t channel, uint64 return 0; } -int32_t bl00mbox_channel_get_signal_by_subscriber_list_pos(uint8_t channel, uint64_t bud_index, +int32_t bl00mbox_channel_get_signal_by_subscriber_list_pos(int32_t channel, uint64_t bud_index, uint16_t signal_index, uint8_t pos){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; @@ -171,7 +171,7 @@ int32_t bl00mbox_channel_get_signal_by_subscriber_list_pos(uint8_t channel, uint return 0; } -uint64_t bl00mbox_channel_get_source_bud(uint8_t channel, uint64_t bud_index, uint16_t signal_index){ +uint64_t bl00mbox_channel_get_source_bud(int32_t channel, uint64_t bud_index, uint16_t signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -183,7 +183,7 @@ uint64_t bl00mbox_channel_get_source_bud(uint8_t channel, uint64_t bud_index, ui return conn->source_bud->index; } -uint16_t bl00mbox_channel_get_source_signal(uint8_t channel, uint64_t bud_index, uint16_t signal_index){ +uint16_t bl00mbox_channel_get_source_signal(int32_t channel, uint64_t bud_index, uint16_t signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -195,7 +195,7 @@ uint16_t bl00mbox_channel_get_source_signal(uint8_t channel, uint64_t bud_index, return conn->signal_index; } -static bl00mbox_connection_t * create_connection(uint8_t channel){ +static bl00mbox_connection_t * create_connection(int32_t channel){ bl00mbox_connection_t * ret = malloc(sizeof(bl00mbox_connection_t)); if(ret == NULL) return NULL; bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); @@ -217,18 +217,20 @@ static bl00mbox_connection_t * create_connection(uint8_t channel){ static bool weak_delete_connection(bl00mbox_connection_t * conn){ if(conn->subs != NULL) return false; + bl00mbox_channel_t * chan = bl00mbox_get_channel(conn->channel); // nullify source bud connection; bl00mbox_bud_t * bud = conn->source_bud; if(bud != NULL){ radspa_signal_t * tx = bl00mbox_signal_get_by_index(bud->plugin, conn->signal_index); if(tx != NULL){ - bl00mbox_audio_waitfor_pointer_change(&(tx->buffer), NULL); + bl00mbox_take_lock(&chan->render_lock); + tx->buffer = NULL; + bl00mbox_give_lock(&chan->render_lock); } } // pop from channel list - bl00mbox_channel_t * chan = bl00mbox_get_channel(conn->channel); if(chan->connections != NULL){ if(chan->connections != conn){ bl00mbox_connection_t * prev = chan->connections; @@ -238,9 +240,15 @@ static bool weak_delete_connection(bl00mbox_connection_t * conn){ break; } } - if(prev->chan_next != NULL) bl00mbox_audio_waitfor_pointer_change(&(prev->chan_next), conn->chan_next); + if(prev->chan_next != NULL){ + bl00mbox_take_lock(&chan->render_lock); + prev->chan_next = conn->chan_next; + bl00mbox_give_lock(&chan->render_lock); + } } else { - bl00mbox_audio_waitfor_pointer_change(&(chan->connections), conn->chan_next); + bl00mbox_take_lock(&chan->render_lock); + chan->connections = conn->chan_next; + bl00mbox_give_lock(&chan->render_lock); } } @@ -248,7 +256,7 @@ static bool weak_delete_connection(bl00mbox_connection_t * conn){ return true; } -bl00mbox_bud_t * bl00mbox_channel_get_bud_by_index(uint8_t channel, uint32_t index){ +bl00mbox_bud_t * bl00mbox_channel_get_bud_by_index(int32_t channel, uint32_t index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return NULL; if(chan->buds == NULL) return NULL; @@ -261,7 +269,7 @@ bl00mbox_bud_t * bl00mbox_channel_get_bud_by_index(uint8_t channel, uint32_t ind return bud; } -bl00mbox_bud_t * bl00mbox_channel_new_bud(uint8_t channel, uint32_t id, uint32_t init_var){ +bl00mbox_bud_t * bl00mbox_channel_new_bud(int32_t channel, uint32_t id, uint32_t init_var){ /// creates a new bud instance of the plugin with descriptor id "id" and the initialization variable /// "init_var" and appends it to the plugin list of the corresponding channel. returns pointer to /// the bud if successfull, else NULL. @@ -296,7 +304,7 @@ bl00mbox_bud_t * bl00mbox_channel_new_bud(uint8_t channel, uint32_t id, uint32_t return bud; } -bool bl00mbox_channel_delete_bud(uint8_t channel, uint32_t bud_index){ +bool bl00mbox_channel_delete_bud(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -324,11 +332,13 @@ bool bl00mbox_channel_delete_bud(uint8_t channel, uint32_t bud_index){ seek = seek->chan_next; } if(seek != NULL){ + bl00mbox_take_lock(&chan->render_lock); if(prev != NULL){ - bl00mbox_audio_waitfor_pointer_change(&(prev->chan_next), seek->chan_next); + prev->chan_next = seek->chan_next; } else { - bl00mbox_audio_waitfor_pointer_change(&(chan->buds), seek->chan_next); + chan->buds = seek->chan_next; } + bl00mbox_give_lock(&chan->render_lock); free_later = true; } } @@ -338,7 +348,7 @@ bool bl00mbox_channel_delete_bud(uint8_t channel, uint32_t bud_index){ return true; } -bool bl00mbox_channel_clear(uint8_t channel){ +bool bl00mbox_channel_clear(int32_t channel){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = chan->buds; @@ -350,7 +360,7 @@ bool bl00mbox_channel_clear(uint8_t channel){ return true; } -bool bl00mbox_channel_connect_signal_to_output_mixer(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +bool bl00mbox_channel_connect_signal_to_output_mixer(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -418,7 +428,7 @@ bool bl00mbox_channel_connect_signal_to_output_mixer(uint8_t channel, uint32_t b return true; } -bool bl00mbox_channel_disconnect_signal_from_output_mixer(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +bool bl00mbox_channel_disconnect_signal_from_output_mixer(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ //TODO bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; @@ -442,11 +452,13 @@ bool bl00mbox_channel_disconnect_signal_from_output_mixer(uint8_t channel, uint3 } if(rt == NULL) return false; // root doesn't exist + bl00mbox_take_lock(&chan->render_lock); if(rt_prev == NULL){ - bl00mbox_audio_waitfor_pointer_change(&(chan->root_list), rt->next); + chan->root_list = rt->next; } else { - bl00mbox_audio_waitfor_pointer_change(&(rt_prev->next), rt->next); + rt_prev->next = rt->next; } + bl00mbox_give_lock(&chan->render_lock); free(rt); if(conn->subs != NULL){ @@ -460,11 +472,13 @@ bool bl00mbox_channel_disconnect_signal_from_output_mixer(uint8_t channel, uint3 seek = seek->next; } if(seek != NULL){ + bl00mbox_take_lock(&chan->render_lock); if(prev != NULL){ - bl00mbox_audio_waitfor_pointer_change(&(prev->next), seek->next); + prev->next = seek->next; } else { - bl00mbox_audio_waitfor_pointer_change(&(conn->subs), seek->next); + conn->subs = seek->next; } + bl00mbox_give_lock(&chan->render_lock); free(seek); } } @@ -474,7 +488,8 @@ bool bl00mbox_channel_disconnect_signal_from_output_mixer(uint8_t channel, uint3 return true; } -bool bl00mbox_channel_disconnect_signal_rx(uint8_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index){ +bool bl00mbox_channel_disconnect_signal_rx(int32_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index){ + bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); bl00mbox_bud_t * bud_rx = bl00mbox_channel_get_bud_by_index(channel, bud_rx_index); if(bud_rx == NULL) return false; // bud index doesn't exist @@ -491,7 +506,9 @@ bool bl00mbox_channel_disconnect_signal_rx(uint8_t channel, uint32_t bud_rx_inde radspa_signal_t * tx = bl00mbox_signal_get_by_index(bud_tx->plugin, conn->signal_index); if(tx == NULL) return false; // signal index doesn't exist - bl00mbox_audio_waitfor_pointer_change(&(rx->buffer), NULL); + bl00mbox_take_lock(&chan->render_lock); + rx->buffer = NULL; + bl00mbox_give_lock(&chan->render_lock); if(conn->subs != NULL){ bl00mbox_connection_subscriber_t * seek = conn->subs; @@ -506,11 +523,13 @@ bool bl00mbox_channel_disconnect_signal_rx(uint8_t channel, uint32_t bud_rx_inde seek = seek->next; } if(seek != NULL){ + bl00mbox_take_lock(&chan->render_lock); if(prev != NULL){ - bl00mbox_audio_waitfor_pointer_change(&(prev->next), seek->next); + prev->next = seek->next; } else { - bl00mbox_audio_waitfor_pointer_change(&(conn->subs), seek->next); + conn->subs = seek->next; } + bl00mbox_give_lock(&chan->render_lock); free(seek); } } @@ -520,7 +539,7 @@ bool bl00mbox_channel_disconnect_signal_rx(uint8_t channel, uint32_t bud_rx_inde return true; } -bool bl00mbox_channel_disconnect_signal_tx(uint8_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index){ +bool bl00mbox_channel_disconnect_signal_tx(int32_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index){ bl00mbox_bud_t * bud_tx = bl00mbox_channel_get_bud_by_index(channel, bud_tx_index); if(bud_tx == NULL) return false; // bud index doesn't exist @@ -546,7 +565,7 @@ bool bl00mbox_channel_disconnect_signal_tx(uint8_t channel, uint32_t bud_tx_inde return true; } -bool bl00mbox_channel_disconnect_signal(uint8_t channel, uint32_t bud_index, uint32_t signal_index){ +bool bl00mbox_channel_disconnect_signal(int32_t channel, uint32_t bud_index, uint32_t signal_index){ bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); if(bud == NULL) return false; // bud index doesn't exist radspa_signal_t * sig = bl00mbox_signal_get_by_index(bud->plugin, signal_index); @@ -560,7 +579,7 @@ bool bl00mbox_channel_disconnect_signal(uint8_t channel, uint32_t bud_index, uin return false; } -bool bl00mbox_channel_connect_signal(uint8_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index, +bool bl00mbox_channel_connect_signal(int32_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index, uint32_t bud_tx_index, uint32_t bud_tx_signal_index){ bl00mbox_bud_t * bud_rx = bl00mbox_channel_get_bud_by_index(channel, bud_rx_index); bl00mbox_bud_t * bud_tx = bl00mbox_channel_get_bud_by_index(channel, bud_tx_index); @@ -612,7 +631,7 @@ bool bl00mbox_channel_connect_signal(uint8_t channel, uint32_t bud_rx_index, uin return true; } -bool bl00mbox_channel_bud_exists(uint8_t channel, uint32_t bud_index){ +bool bl00mbox_channel_bud_exists(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -623,7 +642,7 @@ bool bl00mbox_channel_bud_exists(uint8_t channel, uint32_t bud_index){ } } -char * bl00mbox_channel_bud_get_name(uint8_t channel, uint32_t bud_index){ +char * bl00mbox_channel_bud_get_name(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -631,7 +650,7 @@ char * bl00mbox_channel_bud_get_name(uint8_t channel, uint32_t bud_index){ return bud->plugin->descriptor->name; } -char * bl00mbox_channel_bud_get_description(uint8_t channel, uint32_t bud_index){ +char * bl00mbox_channel_bud_get_description(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -639,7 +658,7 @@ char * bl00mbox_channel_bud_get_description(uint8_t channel, uint32_t bud_index) return bud->plugin->descriptor->description; } -uint32_t bl00mbox_channel_bud_get_plugin_id(uint8_t channel, uint32_t bud_index){ +uint32_t bl00mbox_channel_bud_get_plugin_id(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -647,7 +666,7 @@ uint32_t bl00mbox_channel_bud_get_plugin_id(uint8_t channel, uint32_t bud_index) return bud->plugin->descriptor->id; } -uint32_t bl00mbox_channel_bud_get_init_var(uint8_t channel, uint32_t bud_index){ +uint32_t bl00mbox_channel_bud_get_init_var(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -655,7 +674,7 @@ uint32_t bl00mbox_channel_bud_get_init_var(uint8_t channel, uint32_t bud_index){ return bud->init_var; } -uint16_t bl00mbox_channel_bud_get_num_signals(uint8_t channel, uint32_t bud_index){ +uint16_t bl00mbox_channel_bud_get_num_signals(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -663,7 +682,7 @@ uint16_t bl00mbox_channel_bud_get_num_signals(uint8_t channel, uint32_t bud_inde return bud->plugin->len_signals; } -char * bl00mbox_channel_bud_get_signal_name(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +char * bl00mbox_channel_bud_get_signal_name(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -673,7 +692,7 @@ char * bl00mbox_channel_bud_get_signal_name(uint8_t channel, uint32_t bud_index, return sig->name; } -int8_t bl00mbox_channel_bud_get_signal_name_multiplex(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +int8_t bl00mbox_channel_bud_get_signal_name_multiplex(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -683,7 +702,7 @@ int8_t bl00mbox_channel_bud_get_signal_name_multiplex(uint8_t channel, uint32_t return sig->name_multiplex; } -char * bl00mbox_channel_bud_get_signal_description(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +char * bl00mbox_channel_bud_get_signal_description(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -693,7 +712,7 @@ char * bl00mbox_channel_bud_get_signal_description(uint8_t channel, uint32_t bud return sig->description; } -char * bl00mbox_channel_bud_get_signal_unit(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +char * bl00mbox_channel_bud_get_signal_unit(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -703,7 +722,7 @@ char * bl00mbox_channel_bud_get_signal_unit(uint8_t channel, uint32_t bud_index, return sig->unit; } -bool bl00mbox_channel_bud_get_always_render(uint8_t channel, uint32_t bud_index){ +bool bl00mbox_channel_bud_get_always_render(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -711,7 +730,7 @@ bool bl00mbox_channel_bud_get_always_render(uint8_t channel, uint32_t bud_index) return bud->always_render; } -bool bl00mbox_channel_bud_set_always_render(uint8_t channel, uint32_t bud_index, bool value){ +bool bl00mbox_channel_bud_set_always_render(int32_t channel, uint32_t bud_index, bool value){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -723,13 +742,17 @@ bool bl00mbox_channel_bud_set_always_render(uint8_t channel, uint32_t bud_index, new->bud = bud; new->next = NULL; if(chan->always_render == NULL){ - bl00mbox_audio_waitfor_pointer_change(&(chan->always_render), new); + bl00mbox_take_lock(&chan->render_lock); + chan->always_render = new; + bl00mbox_give_lock(&chan->render_lock); } else{ bl00mbox_bud_list_t * end = chan->always_render; while(end->next != NULL){ end = end->next; } - bl00mbox_audio_waitfor_pointer_change(&(end->next), new); + bl00mbox_take_lock(&chan->render_lock); + end->next = new; + bl00mbox_give_lock(&chan->render_lock); } } else { if(chan->always_render != NULL){ @@ -743,11 +766,13 @@ bool bl00mbox_channel_bud_set_always_render(uint8_t channel, uint32_t bud_index, seek = seek->next; } if(seek != NULL){ + bl00mbox_take_lock(&chan->render_lock); if(prev != NULL){ - bl00mbox_audio_waitfor_pointer_change(&(prev->next), seek->next); + prev->next = seek->next; } else { - bl00mbox_audio_waitfor_pointer_change(&(chan->always_render), seek->next); + chan->always_render = seek->next; } + bl00mbox_give_lock(&chan->render_lock); free(seek); } } @@ -758,7 +783,7 @@ bool bl00mbox_channel_bud_set_always_render(uint8_t channel, uint32_t bud_index, return true; } -bool bl00mbox_channel_bud_set_signal_value(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index, int16_t value){ +bool bl00mbox_channel_bud_set_signal_value(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index, int16_t value){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -776,7 +801,7 @@ bool bl00mbox_channel_bud_set_signal_value(uint8_t channel, uint32_t bud_index, return true; } -int16_t bl00mbox_channel_bud_get_signal_value(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +int16_t bl00mbox_channel_bud_get_signal_value(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return -32768; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -792,7 +817,7 @@ int16_t bl00mbox_channel_bud_get_signal_value(uint8_t channel, uint32_t bud_inde } } -uint32_t bl00mbox_channel_bud_get_signal_hints(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){ +uint32_t bl00mbox_channel_bud_get_signal_hints(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -803,7 +828,7 @@ uint32_t bl00mbox_channel_bud_get_signal_hints(uint8_t channel, uint32_t bud_ind return sig->hints; } -bool bl00mbox_channel_bud_set_table_value(uint8_t channel, uint32_t bud_index, uint32_t table_index, int16_t value){ +bool bl00mbox_channel_bud_set_table_value(int32_t channel, uint32_t bud_index, uint32_t table_index, int16_t value){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -816,7 +841,7 @@ bool bl00mbox_channel_bud_set_table_value(uint8_t channel, uint32_t bud_index, u return true; } -int16_t bl00mbox_channel_bud_get_table_value(uint8_t channel, uint32_t bud_index, uint32_t table_index){ +int16_t bl00mbox_channel_bud_get_table_value(int32_t channel, uint32_t bud_index, uint32_t table_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -827,7 +852,7 @@ int16_t bl00mbox_channel_bud_get_table_value(uint8_t channel, uint32_t bud_index return bud->plugin->plugin_table[table_index]; } -int16_t * bl00mbox_channel_bud_get_table_pointer(uint8_t channel, uint32_t bud_index){ +int16_t * bl00mbox_channel_bud_get_table_pointer(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return false; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); @@ -836,7 +861,7 @@ int16_t * bl00mbox_channel_bud_get_table_pointer(uint8_t channel, uint32_t bud_i return bud->plugin->plugin_table; } -uint32_t bl00mbox_channel_bud_get_table_len(uint8_t channel, uint32_t bud_index){ +uint32_t bl00mbox_channel_bud_get_table_len(int32_t channel, uint32_t bud_index){ bl00mbox_channel_t * chan = bl00mbox_get_channel(channel); if(chan == NULL) return 0; bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index); diff --git a/components/bl00mbox/config/bl00mbox_config.h b/components/bl00mbox/config/bl00mbox_config.h new file mode 100644 index 0000000000..38171d8dc5 --- /dev/null +++ b/components/bl00mbox/config/bl00mbox_config.h @@ -0,0 +1,13 @@ +#pragma once +#define BL00MBOX_FLOW3R + +#ifdef BL00MBOX_FLOW3R +//#include "flow3r_bsp.h" +//#define BL00MBOX_MAX_BUFFER_LEN FLOW3R_BSP_AUDIO_DMA_BUFFER_SIZE +#define BL00MBOX_MAX_BUFFER_LEN 64 +#define BL00MBOX_DEFAULT_CHANNEL_VOLUME 8192 +#define BL00MBOX_AUTO_FOREGROUNDING +#define BL00MBOX_LOOPS_ENABLE +#define BL00MBOX_FREERTOS +#define BL00MBOX_ESPIDF +#endif diff --git a/components/bl00mbox/include/bl00mbox_audio.h b/components/bl00mbox/include/bl00mbox_audio.h index 18cd250e1f..0a4490c54c 100644 --- a/components/bl00mbox/include/bl00mbox_audio.h +++ b/components/bl00mbox/include/bl00mbox_audio.h @@ -1,13 +1,7 @@ //SPDX-License-Identifier: CC0-1.0 #pragma once - -//TODO: move this to kconfig someday? -#define BL00MBOX_MAX_BUFFER_LEN 128 -#define BL00MBOX_DEFAULT_CHANNEL_VOLUME 8000 -#define BL00MBOX_CHANNELS 32 -#define BL00MBOX_BACKGROUND_MUTE_OVERRIDE_ENABLE -#define BL00MBOX_AUTO_FOREGROUNDING -#define BL00MBOX_LOOPS_ENABLE +#include "bl00mbox_config.h" +#include "bl00mbox_os.h" #include <stdio.h> #include <math.h> @@ -28,7 +22,7 @@ typedef struct _bl00mbox_bud_t{ uint64_t index; // unique index number for bud uint32_t render_pass_id; // may be used by host to determine whether recomputation is necessary uint32_t init_var; // init var that was used for plugin creation - uint8_t channel; // index of channel that owns the plugin + int32_t channel; // index of channel that owns the plugin volatile bool is_being_rendered; // true if rendering the plugin is in progress, else false. bool always_render; struct _bl00mbox_bud_t * chan_next; //for linked list in bl00mbox_channel_t @@ -41,7 +35,7 @@ typedef struct _bl00mbox_bud_list_t{ typedef struct _bl00mbox_connection_subscriber_t{ uint8_t type; // 0: standard signal input, 1: output mixer - uint8_t channel; + int32_t channel; uint64_t bud_index; uint32_t signal_index; struct _bl00mbox_connection_subscriber_t * next; @@ -52,7 +46,7 @@ typedef struct _bl00mbox_connection_t{ //child of bl00mbox_ll_t struct _bl00mbox_bud_t * source_bud; uint32_t signal_index; // signal of source_bud that renders to buffer struct _bl00mbox_connection_subscriber_t * subs; - uint8_t channel; + int32_t channel; struct _bl00mbox_connection_t * chan_next; //for linked list in bl00mbox_channel_t; } bl00mbox_connection_t; @@ -62,8 +56,9 @@ typedef struct _bl00mbox_channel_root_t{ } bl00mbox_channel_root_t; typedef struct{ + int32_t index; + bl00mbox_lock_t render_lock; bool is_active; // rendering can be skipped if false - bool is_free; bool compute_mean_square; uint32_t mean_square; char * name; @@ -77,31 +72,35 @@ typedef struct{ struct _bl00mbox_connection_t * connections; // linked list with all channel connections } bl00mbox_channel_t; -bl00mbox_channel_t * bl00mbox_get_channel(uint8_t chan); -void bl00mbox_channel_enable(uint8_t chan); - -void bl00mbox_channel_enable(uint8_t chan); -void bl00mbox_channel_disable(uint8_t chan); -void bl00mbox_channel_set_volume(uint8_t chan, uint16_t volume); -int16_t bl00mbox_channel_get_volume(uint8_t chan); -void bl00mbox_channel_set_sys_gain(uint8_t chan, int16_t volume); -int16_t bl00mbox_channel_get_sys_gain(uint8_t chan); -void bl00mbox_channel_set_compute_mean_square(uint8_t chan, bool compute); -bool bl00mbox_channel_get_compute_mean_square(uint8_t chan); -uint32_t bl00mbox_channel_get_mean_square(uint8_t chan); -void bl00mbox_channel_event(uint8_t chan); -uint8_t bl00mbox_channel_get_free_index(); -void bl00mbox_channels_init(); -uint8_t bl00mbox_channel_get_foreground_index(); -void bl00mbox_channel_set_foreground_index(uint8_t channel_index); -bool bl00mbox_channel_get_free(uint8_t channel_index); -bool bl00mbox_channel_set_free(uint8_t channel_index, bool free); - -bool bl00mbox_channel_get_background_mute_override(uint8_t channel_index); -bool bl00mbox_channel_set_background_mute_override(uint8_t channel_index, bool enable); - -char * bl00mbox_channel_get_name(uint8_t channel_index); -void bl00mbox_channel_set_name(uint8_t channel_index, char * new_name); - -bool bl00mbox_audio_waitfor_pointer_change(void ** ptr, void * new_val); +void bl00mbox_audio_init(); + +bl00mbox_channel_t * bl00mbox_get_channel(int32_t chan); +void bl00mbox_channel_enable(int32_t chan); + +void bl00mbox_channel_enable(int32_t chan); +void bl00mbox_channel_disable(int32_t chan); +void bl00mbox_channel_set_volume(int32_t chan, uint16_t volume); +int16_t bl00mbox_channel_get_volume(int32_t chan); +void bl00mbox_channel_set_sys_gain(int32_t chan, int16_t volume); +int16_t bl00mbox_channel_get_sys_gain(int32_t chan); +void bl00mbox_channel_set_compute_mean_square(int32_t chan, bool compute); +bool bl00mbox_channel_get_compute_mean_square(int32_t chan); +uint32_t bl00mbox_channel_get_mean_square(int32_t chan); +void bl00mbox_channel_event(int32_t chan); +bool bl00mbox_channel_get_free(int32_t channel_index); +bool bl00mbox_channel_set_free(int32_t channel_index, bool free); + +bool bl00mbox_channel_get_background_mute_override(int32_t channel_index); +bool bl00mbox_channel_set_background_mute_override(int32_t channel_index, bool enable); + +char * bl00mbox_channel_get_name(int32_t channel_index); +void bl00mbox_channel_set_name(int32_t channel_index, char * new_name); + void bl00mbox_audio_bud_render(bl00mbox_bud_t * bud); + +bool bl00mbox_get_channel_exists(int32_t channel_index); +int32_t bl00mbox_channel_get_free_index(); +int32_t bl00mbox_get_channel_index_positional_all_chans(int32_t position); +int32_t bl00mbox_get_channel_index_positional_background_mute_override_chans(int32_t position); +int32_t bl00mbox_channel_get_foreground_index(); +void bl00mbox_channel_set_foreground_index(int32_t channel_index); diff --git a/components/bl00mbox/include/bl00mbox_ll.h b/components/bl00mbox/include/bl00mbox_ll.h new file mode 100644 index 0000000000..0d3a315805 --- /dev/null +++ b/components/bl00mbox/include/bl00mbox_ll.h @@ -0,0 +1,54 @@ +#pragma once +#include "bl00mbox_os.h" + +typedef struct _bl00mbox_ll_t { + struct _bl00mbox_ll_t * next; + void * content; +} bl00mbox_ll_t; + +bool bl00mbox_ll_contains(bl00mbox_ll_t ** startref, void * content){ + if(!startref) return false; // list doesn't exist + bl00mbox_ll_t * seek = * startref; + if(!seek) return false; // list is empty + while(seek){ + if(seek->content == content) break; + seek = seek->next; + } + return seek; +} + +bool bl00mbox_ll_prepend(bl00mbox_ll_t ** startref, void * content, bl00mbox_lock_t * write_lock){ + if(!startref) return false; + if(bl00mbox_ll_contains(startref, content)) return false; + bl00mbox_ll_t * ll = malloc(sizeof(bl00mbox_ll_t)); + if(!ll) return false; + ll->content = content; + ll->next = *startref; + bl00mbox_take_lock(write_lock); + *startref = ll; + bl00mbox_give_lock(write_lock); + return true; +} + +bool bl00mbox_ll_pop(bl00mbox_ll_t ** startref, void * content, bl00mbox_lock_t * write_lock){ + if(!startref) return false; // list doesn't exist + bl00mbox_ll_t * seek = * startref; + if(!seek) return false; // list is empty + bl00mbox_ll_t * prev = NULL; + while(seek){ + if(seek->content == content) break; + prev = seek; + seek = seek->next; + } + if(!seek) return false; // not found + bl00mbox_take_lock(write_lock); + if(prev){ // normal + prev->next = seek->next; + } else { // first element + * startref = seek->next; + } + bl00mbox_give_lock(write_lock); + free(seek); + return true; +} + diff --git a/components/bl00mbox/include/bl00mbox_os.h b/components/bl00mbox/include/bl00mbox_os.h new file mode 100644 index 0000000000..fbb422fa42 --- /dev/null +++ b/components/bl00mbox/include/bl00mbox_os.h @@ -0,0 +1,22 @@ +#pragma once +#include "bl00mbox_config.h" + +#ifdef BL00MBOX_FREERTOS +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +typedef SemaphoreHandle_t bl00mbox_lock_t; +#endif + +void bl00mbox_create_lock(bl00mbox_lock_t * lock); +void bl00mbox_delete_lock(bl00mbox_lock_t * lock); +void bl00mbox_take_lock(bl00mbox_lock_t * lock); +void bl00mbox_give_lock(bl00mbox_lock_t * lock); + +#ifdef BL00MBOX_ESPIDF +#include "esp_log.h" +#define bl00mbox_log_error(txt, ...) ESP_LOGE("bl00mbox", txt, ##__VA_ARGS__); +#define bl00mbox_log_info(txt, ...) ESP_LOGI("bl00mbox", txt, ##__VA_ARGS__); +#else +void bl00mbox_log_error(char * txt, ...); +void bl00mbox_log_info(char * txt, ...); +#endif diff --git a/components/bl00mbox/include/bl00mbox_user.h b/components/bl00mbox/include/bl00mbox_user.h index e4f2cb8bc0..58bdd59f9b 100644 --- a/components/bl00mbox/include/bl00mbox_user.h +++ b/components/bl00mbox/include/bl00mbox_user.h @@ -7,53 +7,55 @@ #include "bl00mbox_plugin_registry.h" #include "bl00mbox_audio.h" +#include "bl00mbox_os.h" + #include <stdint.h> #include "bl00mbox_audio.h" #include "radspa_helpers.h" -uint16_t bl00mbox_channel_buds_num(uint8_t channel); -uint64_t bl00mbox_channel_get_bud_by_list_pos(uint8_t channel, uint32_t pos); -uint16_t bl00mbox_channel_conns_num(uint8_t channel); -uint16_t bl00mbox_channel_mixer_num(uint8_t channel); -uint64_t bl00mbox_channel_get_bud_by_mixer_list_pos(uint8_t channel, uint32_t pos); -uint32_t bl00mbox_channel_get_signal_by_mixer_list_pos(uint8_t channel, uint32_t pos); -bool bl00mbox_channel_clear(uint8_t channel); +uint16_t bl00mbox_channel_buds_num(int32_t channel); +uint64_t bl00mbox_channel_get_bud_by_list_pos(int32_t channel, uint32_t pos); +uint16_t bl00mbox_channel_conns_num(int32_t channel); +uint16_t bl00mbox_channel_mixer_num(int32_t channel); +uint64_t bl00mbox_channel_get_bud_by_mixer_list_pos(int32_t channel, uint32_t pos); +uint32_t bl00mbox_channel_get_signal_by_mixer_list_pos(int32_t channel, uint32_t pos); +bool bl00mbox_channel_clear(int32_t channel); -bool bl00mbox_channel_connect_signal_to_output_mixer(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -bool bl00mbox_channel_connect_signal(uint8_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index, +bool bl00mbox_channel_connect_signal_to_output_mixer(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +bool bl00mbox_channel_connect_signal(int32_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index, uint32_t bud_tx_index, uint32_t bud_tx_signal_index); -bool bl00mbox_channel_disconnect_signal_rx(uint8_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index); -bool bl00mbox_channel_disconnect_signal_tx(uint8_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index); -bool bl00mbox_channel_disconnect_signal(uint8_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index); -bool bl00mbox_channel_disconnect_signal_from_output_mixer(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); - -bl00mbox_bud_t * bl00mbox_channel_new_bud(uint8_t channel, uint32_t id, uint32_t init_var); -bool bl00mbox_channel_delete_bud(uint8_t channel, uint32_t bud_index); -bool bl00mbox_channel_bud_exists(uint8_t channel, uint32_t bud_index); -char * bl00mbox_channel_bud_get_name(uint8_t channel, uint32_t bud_index); -char * bl00mbox_channel_bud_get_description(uint8_t channel, uint32_t bud_index); -uint32_t bl00mbox_channel_bud_get_plugin_id(uint8_t channel, uint32_t bud_index); -uint32_t bl00mbox_channel_bud_get_init_var(uint8_t channel, uint32_t bud_index); -uint16_t bl00mbox_channel_bud_get_num_signals(uint8_t channel, uint32_t bud_index); - -char * bl00mbox_channel_bud_get_signal_name(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -int8_t bl00mbox_channel_bud_get_signal_name_multiplex(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -char * bl00mbox_channel_bud_get_signal_description(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -char * bl00mbox_channel_bud_get_signal_unit(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -bool bl00mbox_channel_bud_get_always_render(uint8_t channel, uint32_t bud_index); -bool bl00mbox_channel_bud_set_always_render(uint8_t channel, uint32_t bud_index, bool value); -bool bl00mbox_channel_bud_set_signal_value(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index, int16_t value); -int16_t bl00mbox_channel_bud_get_signal_value(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -uint32_t bl00mbox_channel_bud_get_signal_hints(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index); -uint16_t bl00mbox_channel_subscriber_num(uint8_t channel, uint64_t bud_index, uint16_t signal_index); -uint64_t bl00mbox_channel_get_bud_by_subscriber_list_pos(uint8_t channel, uint64_t bud_index, +bool bl00mbox_channel_disconnect_signal_rx(int32_t channel, uint32_t bud_rx_index, uint32_t bud_rx_signal_index); +bool bl00mbox_channel_disconnect_signal_tx(int32_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index); +bool bl00mbox_channel_disconnect_signal(int32_t channel, uint32_t bud_tx_index, uint32_t bud_tx_signal_index); +bool bl00mbox_channel_disconnect_signal_from_output_mixer(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); + +bl00mbox_bud_t * bl00mbox_channel_new_bud(int32_t channel, uint32_t id, uint32_t init_var); +bool bl00mbox_channel_delete_bud(int32_t channel, uint32_t bud_index); +bool bl00mbox_channel_bud_exists(int32_t channel, uint32_t bud_index); +char * bl00mbox_channel_bud_get_name(int32_t channel, uint32_t bud_index); +char * bl00mbox_channel_bud_get_description(int32_t channel, uint32_t bud_index); +uint32_t bl00mbox_channel_bud_get_plugin_id(int32_t channel, uint32_t bud_index); +uint32_t bl00mbox_channel_bud_get_init_var(int32_t channel, uint32_t bud_index); +uint16_t bl00mbox_channel_bud_get_num_signals(int32_t channel, uint32_t bud_index); + +char * bl00mbox_channel_bud_get_signal_name(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +int8_t bl00mbox_channel_bud_get_signal_name_multiplex(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +char * bl00mbox_channel_bud_get_signal_description(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +char * bl00mbox_channel_bud_get_signal_unit(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +bool bl00mbox_channel_bud_get_always_render(int32_t channel, uint32_t bud_index); +bool bl00mbox_channel_bud_set_always_render(int32_t channel, uint32_t bud_index, bool value); +bool bl00mbox_channel_bud_set_signal_value(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index, int16_t value); +int16_t bl00mbox_channel_bud_get_signal_value(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +uint32_t bl00mbox_channel_bud_get_signal_hints(int32_t channel, uint32_t bud_index, uint32_t bud_signal_index); +uint16_t bl00mbox_channel_subscriber_num(int32_t channel, uint64_t bud_index, uint16_t signal_index); +uint64_t bl00mbox_channel_get_bud_by_subscriber_list_pos(int32_t channel, uint64_t bud_index, uint16_t signal_index, uint8_t pos); -int32_t bl00mbox_channel_get_signal_by_subscriber_list_pos(uint8_t channel, uint64_t bud_index, +int32_t bl00mbox_channel_get_signal_by_subscriber_list_pos(int32_t channel, uint64_t bud_index, uint16_t signal_index, uint8_t pos); -uint64_t bl00mbox_channel_get_source_bud(uint8_t channel, uint64_t bud_index, uint16_t signal_index); -uint16_t bl00mbox_channel_get_source_signal(uint8_t channel, uint64_t bud_index, uint16_t signal_index); +uint64_t bl00mbox_channel_get_source_bud(int32_t channel, uint64_t bud_index, uint16_t signal_index); +uint16_t bl00mbox_channel_get_source_signal(int32_t channel, uint64_t bud_index, uint16_t signal_index); -bool bl00mbox_channel_bud_set_table_value(uint8_t channel, uint32_t bud_index, uint32_t table_index, int16_t value); -int16_t bl00mbox_channel_bud_get_table_value(uint8_t channel, uint32_t bud_index, uint32_t table_index); -uint32_t bl00mbox_channel_bud_get_table_len(uint8_t channel, uint32_t bud_index); -int16_t * bl00mbox_channel_bud_get_table_pointer(uint8_t channel, uint32_t bud_index); +bool bl00mbox_channel_bud_set_table_value(int32_t channel, uint32_t bud_index, uint32_t table_index, int16_t value); +int16_t bl00mbox_channel_bud_get_table_value(int32_t channel, uint32_t bud_index, uint32_t table_index); +uint32_t bl00mbox_channel_bud_get_table_len(int32_t channel, uint32_t bud_index); +int16_t * bl00mbox_channel_bud_get_table_pointer(int32_t channel, uint32_t bud_index); diff --git a/components/bl00mbox/micropython/bl00mbox/_plugins.py b/components/bl00mbox/micropython/bl00mbox/_plugins.py index 2d3bbffb4b..0c0d6f3cd4 100644 --- a/components/bl00mbox/micropython/bl00mbox/_plugins.py +++ b/components/bl00mbox/micropython/bl00mbox/_plugins.py @@ -688,14 +688,15 @@ class _Sequencer(_Plugin): num_tracks = min(len(beat["tracks"]), self.num_tracks) [self.load_track_pattern(beat["tracks"][i], i) for i in range(num_tracks)] + @_plugin_set_subclass(38) class _TriggerMerge(_Plugin): @property def block_stop(self): table = self.table_int16_array return bool(table[0]) + @block_stop.setter def block_stop(self, val): table = self.table_int16_array table[0] = 1 if val else 0 - diff --git a/components/bl00mbox/micropython/bl00mbox/_user.py b/components/bl00mbox/micropython/bl00mbox/_user.py index 698be81259..56ca658ebd 100644 --- a/components/bl00mbox/micropython/bl00mbox/_user.py +++ b/components/bl00mbox/micropython/bl00mbox/_user.py @@ -307,11 +307,11 @@ class SignalOutput(Signal): if (s >= 0) and (b > 0): cons += [ _makeSignal( - bl00mbox._plugins._make_new_plugin(Channel(chan), 0, b), s + bl00mbox._plugins._make_new_plugin(SysChannel(chan), 0, b), s ) ] elif s == -1: - cons += [ChannelMixer(Channel(chan))] + cons += [ChannelMixer(SysChannel(chan))] return cons @@ -358,7 +358,9 @@ class SignalInput(Signal): s = sys_bl00mbox.channel_get_source_signal(chan, bud, sig) if (s >= 0) and (b > 0): cons += [ - _makeSignal(bl00mbox._plugins._make_new_plugin(Channel(chan), 0, b), s) + _makeSignal( + bl00mbox._plugins._make_new_plugin(SysChannel(chan), 0, b), s + ) ] return cons @@ -572,17 +574,14 @@ class Channel: elif type(name) == str: self._channel_num = sys_bl00mbox.channel_get_free_index() self.name = name - elif type(name) == int: - num = int(name) - if num < sys_bl00mbox.NUM_CHANNELS and num >= 0: - self._channel_num = num - else: - self._channel_num = sys_bl00mbox.NUM_CHANNELS - 1 # garbage channel else: - self._channel_num = sys_bl00mbox.NUM_CHANNELS - 1 # garbage channel + raise TypeError("must be None or str") + if self._channel_num < 0: + raise Bl00mboxError("Channel could not be initialized") global _channel_init_callback if _channel_init_callback is not None: _channel_init_callback(self) + self._tripwire = sys_bl00mbox.channel_wire(self._channel_num) def __repr__(self): ret = "[channel " + str(self.channel_num) @@ -596,8 +595,9 @@ class Channel: ret += "\n gain: " + str(self.gain_dB) + "dB" b = self.num_plugins ret += "\n plugins: " + str(b) - if len(self.plugins) != b: - ret += " (desync" + str(len(self.plugins)) + ")" + # actual_len = len(list(self.plugins)) + # if actual_len != b: + # ret += " (desync" + actual_len + ")" ret += "\n " + "\n ".join(repr(self.mixer).split("\n")) return ret @@ -610,10 +610,6 @@ class Channel: @property def name(self): - if self._channel_num == 0: - return "system" - if self._channel_num == 31: - return "garbage" name = sys_bl00mbox.channel_get_name(self.channel_num) if name is None: return "" @@ -641,19 +637,6 @@ class Channel: else: raise TypeError("not a plugin") - @staticmethod - def print_overview(): - ret = [] - for i in range(sys_bl00mbox.NUM_CHANNELS): - c = Channel(i) - if c.free: - continue - ret += [repr(c)] - if len(ret) != 0: - print("\n".join(ret)) - else: - print("no active channels") - def print_plugins(self): for plugin in self.plugins: print(repr(plugin)) @@ -670,11 +653,9 @@ class Channel: @property def plugins(self): - ret = [] for i in range(sys_bl00mbox.channel_buds_num(self.channel_num)): b = sys_bl00mbox.channel_get_bud_by_list_pos(self.channel_num, i) - ret += [bl00mbox._plugins._make_new_plugin(self, 0, b)] - return ret + yield [bl00mbox._plugins._make_new_plugin(self, 0, b)] @property def channel_num(self): @@ -763,15 +744,19 @@ class Channel: if val: sys_bl00mbox.channel_set_foreground(self.channel_num) elif sys_bl00mbox.channel_get_foreground() == self.channel_num: - sys_bl00mbox.channel_set_foreground(0) + sys_bl00mbox.channel_set_foreground(-1) class SysChannel(Channel): - def __init__(self, index=0): - if index < sys_bl00mbox.NUM_CHANNELS and index >= 0: - self._channel_num = index + def __init__(self, identifier): + if isinstance(identifier, int): + if not sys_bl00mbox.channel_get_exists(identifier): + raise Bl00mboxError(f"channel index {identifier} not found") + self._channel_num = identifier + elif isinstance(identifier, Channel): + self._channel_num = identifier.channel_num else: - raise Bl00mboxError(f"channel index {index} not found") + raise Bl00mboxError("improper identifier") @property def sys_gain_dB(self): @@ -808,3 +793,29 @@ class SysChannel(Channel): return 10 * math.log(ret, 10) + _rms_base else: return None + + +def all_channels(): + index = 0 + while True: + ret = sys_bl00mbox.channel_get_index_positional_all_chans(index) + if ret < 0: + break + yield SysChannel(ret) + index += 1 + + +def active_channels(): + index = 0 + fore = sys_bl00mbox.channel_get_foreground() + if fore >= 0: + yield SysChannel(fore) + while True: + ret = sys_bl00mbox.channel_get_index_positional_background_mute_override_chans( + index + ) + if ret < 0: + break + if ret != fore: + yield SysChannel(ret) + index += 1 diff --git a/components/bl00mbox/micropython/mp_sys_bl00mbox.c b/components/bl00mbox/micropython/mp_sys_bl00mbox.c index 7324036ef0..e5e85360ac 100644 --- a/components/bl00mbox/micropython/mp_sys_bl00mbox.c +++ b/components/bl00mbox/micropython/mp_sys_bl00mbox.c @@ -5,10 +5,15 @@ #include "py/runtime.h" #include "bl00mbox.h" +#include "bl00mbox_os.h" #include "bl00mbox_plugin_registry.h" #include "bl00mbox_user.h" #include "radspa.h" +#if !MICROPY_ENABLE_FINALISER +#error "bl00mbox needs finaliser" +#endif + // ======================== // PLUGIN OPERATIONS // ======================== @@ -55,6 +60,66 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_plugin_registry_num_plugins_obj, // CHANNEL OPERATIONS // ======================== +STATIC const mp_obj_type_t channel_wire_type; + +typedef struct _channel_wire_obj_t { + mp_obj_base_t base; + int32_t index; +} channel_wire_obj_t; + +STATIC mp_obj_t channel_wire_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + channel_wire_obj_t *self = m_new_obj_with_finaliser(channel_wire_obj_t); + self->base.type = &channel_wire_type; + self->index = mp_obj_get_int(args[0]); + bl00mbox_log_info("making channel %d", (int)self->index); + return MP_OBJ_FROM_PTR(self); +} + +mp_obj_t mp_channel_wire_trip(mp_obj_t self_in) { + channel_wire_obj_t *self = MP_OBJ_TO_PTR(self_in); + bl00mbox_log_info("freeing channel %d", (int)self->index); + bl00mbox_channel_clear(self->index); + bl00mbox_channel_set_free(self->index, true); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_channel_wire_trip_obj, mp_channel_wire_trip); + +STATIC const mp_rom_map_elem_t channel_wire_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_channel_wire_trip_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(channel_wire_locals_dict, + channel_wire_locals_dict_table); + +STATIC MP_DEFINE_CONST_OBJ_TYPE(channel_wire_type, MP_QSTR_channel_wire, + MP_TYPE_FLAG_NONE, make_new, + channel_wire_make_new, locals_dict, + &channel_wire_locals_dict); + +static mp_obj_t mp_channel_get_exists(mp_obj_t pos) { + return mp_obj_new_bool(bl00mbox_get_channel_exists(mp_obj_get_int(pos))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_channel_get_exists_obj, + mp_channel_get_exists); + +static mp_obj_t mp_channel_get_index_positional_all_chans(mp_obj_t pos) { + return mp_obj_new_int( + bl00mbox_get_channel_index_positional_all_chans(mp_obj_get_int(pos))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_channel_get_index_positional_all_chans_obj, + mp_channel_get_index_positional_all_chans); + +static mp_obj_t mp_channel_get_index_positional_background_mute_override_chans( + mp_obj_t pos) { + return mp_obj_new_int( + bl00mbox_get_channel_index_positional_background_mute_override_chans( + mp_obj_get_int(pos))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1( + mp_channel_get_index_positional_background_mute_override_chans_obj, + mp_channel_get_index_positional_background_mute_override_chans); + STATIC mp_obj_t mp_channel_clear(mp_obj_t index) { return mp_obj_new_bool(bl00mbox_channel_clear(mp_obj_get_int(index))); } @@ -533,7 +598,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3( mp_channel_disconnect_signal_from_output_mixer_obj, mp_channel_disconnect_signal_from_output_mixer); -STATIC const mp_map_elem_t bl00mbox_globals_table[] = { +STATIC const mp_rom_map_elem_t bl00mbox_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys_bl00mbox) }, @@ -548,6 +613,15 @@ STATIC const mp_map_elem_t bl00mbox_globals_table[] = { MP_ROM_PTR(&mp_plugin_index_get_description_obj) }, // CHANNEL OPERATIONS + { MP_OBJ_NEW_QSTR(MP_QSTR_channel_wire), (mp_obj_t)&channel_wire_type }, + { MP_ROM_QSTR(MP_QSTR_channel_get_exists), + MP_ROM_PTR(&mp_channel_get_exists_obj) }, + { MP_ROM_QSTR(MP_QSTR_channel_get_index_positional_all_chans), + MP_ROM_PTR(&mp_channel_get_index_positional_all_chans_obj) }, + { MP_ROM_QSTR( + MP_QSTR_channel_get_index_positional_background_mute_override_chans), + MP_ROM_PTR( + &mp_channel_get_index_positional_background_mute_override_chans_obj) }, { MP_ROM_QSTR(MP_QSTR_channel_get_free), MP_ROM_PTR(&mp_channel_get_free_obj) }, { MP_ROM_QSTR(MP_QSTR_channel_set_free), @@ -668,14 +742,12 @@ STATIC const mp_map_elem_t bl00mbox_globals_table[] = { MP_ROM_PTR(&mp_channel_disconnect_signal_from_output_mixer_obj) }, // CONSTANTS - { MP_ROM_QSTR(MP_QSTR_NUM_CHANNELS), MP_ROM_INT(BL00MBOX_CHANNELS) }, { MP_ROM_QSTR(MP_QSTR_RADSPA_SIGNAL_HINT_SCT), MP_ROM_INT(RADSPA_SIGNAL_HINT_SCT) }, { MP_ROM_QSTR(MP_QSTR_RADSPA_SIGNAL_HINT_GAIN), MP_ROM_INT(RADSPA_SIGNAL_HINT_GAIN) }, { MP_ROM_QSTR(MP_QSTR_RADSPA_SIGNAL_HINT_TRIGGER), MP_ROM_INT(RADSPA_SIGNAL_HINT_TRIGGER) }, - { MP_ROM_QSTR(MP_QSTR_BL00MBOX_CHANNELS), MP_ROM_INT(BL00MBOX_CHANNELS) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_bl00mbox_globals, bl00mbox_globals_table); diff --git a/components/bl00mbox/radspa/standard_plugin_lib/range_shifter.c b/components/bl00mbox/radspa/standard_plugin_lib/range_shifter.c index ad2c0202c7..a0dd0e6b57 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/range_shifter.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/range_shifter.c @@ -63,7 +63,7 @@ void range_shifter_run(radspa_t * range_shifter, uint16_t num_samples, uint32_t } bool input_const = true; if(speed > -10922){ - bool input_const = input != RADSPA_SIGNAL_NONCONST; + input_const = input != RADSPA_SIGNAL_NONCONST; } int32_t output_span; diff --git a/components/bl00mbox/radspa/standard_plugin_lib/slew_rate_limiter.c b/components/bl00mbox/radspa/standard_plugin_lib/slew_rate_limiter.c index 6341e42850..e2c8ec7a4b 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/slew_rate_limiter.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/slew_rate_limiter.c @@ -1,7 +1,5 @@ #include "slew_rate_limiter.h" -static inline int16_t waveshaper(int16_t saw, int16_t shape); - radspa_descriptor_t slew_rate_limiter_desc = { .name = "slew_rate_limiter", .id = 23, -- GitLab