Skip to content
Snippets Groups Projects
Commit b8758686 authored by moon2's avatar moon2 :speech_balloon:
Browse files

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.
parent 32361d12
No related branches found
No related tags found
1 merge request!684bl00mbox channel system upgrade
Showing
with 609 additions and 323 deletions
......@@ -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
)
......@@ -5,5 +5,5 @@
void bl00mbox_init(){
bl00mbox_plugin_registry_init();
bl00mbox_channels_init();
bl00mbox_audio_init();
}
//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;
}
#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
This diff is collapsed.
#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
//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);
#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;
}
#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
......@@ -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);
......@@ -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
......@@ -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
......@@ -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);
......
......@@ -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;
......
#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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment