From 542c7c9c199bd14ee01a086fb101e6229c631149 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Thu, 19 Dec 2024 20:33:42 -0600 Subject: [PATCH 1/3] Implement level as BlockInput. --- shared-bindings/audiomixer/MixerVoice.c | 8 ++++---- shared-bindings/audiomixer/MixerVoice.h | 4 ++-- shared-module/audiomixer/Mixer.c | 7 +++++-- shared-module/audiomixer/MixerVoice.c | 10 +++++----- shared-module/audiomixer/MixerVoice.h | 3 ++- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index 321a192a9d23..706d8f488d4f 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -13,6 +13,7 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" //| class MixerVoice: //| """Voice objects used with Mixer @@ -75,17 +76,16 @@ static mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *po } MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); -//| level: float +//| level: synthio.BlockInput //| """The volume level of a voice, as a floating point number between 0 and 1.""" static mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { - return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); + return common_hal_audiomixer_mixervoice_get_level(self_in); } MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_level_obj, audiomixer_mixervoice_obj_get_level); static mp_obj_t audiomixer_mixervoice_obj_set_level(mp_obj_t self_in, mp_obj_t level_in) { audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_float_t level = mp_arg_validate_obj_float_range(level_in, 0, 1, MP_QSTR_level); - common_hal_audiomixer_mixervoice_set_level(self, level); + common_hal_audiomixer_mixervoice_set_level(self, level_in); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(audiomixer_mixervoice_set_level_obj, audiomixer_mixervoice_obj_set_level); diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h index 9007911b78cb..cf6643d995c0 100644 --- a/shared-bindings/audiomixer/MixerVoice.h +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -15,8 +15,8 @@ void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *sel void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent); void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample, bool loop); void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t *self); -mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t gain); +mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t gain); bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *self); diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index f086e78323be..a0ea89f24bb3 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -188,9 +188,12 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, } } - uint32_t n = MIN(voice->buffer_length, length); + uint32_t n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->channel_count); uint32_t *src = voice->remaining_buffer; - uint16_t level = voice->level; + + // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. + shared_bindings_synthio_lfo_tick(self->sample_rate); //, n / self->channel_count); // Requires #9776 + uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); // First active voice gets copied over verbatim. if (!voices_active) { diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index 66a47c269b48..91e2024ee8cc 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -15,19 +15,19 @@ void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self) { self->sample = NULL; - self->level = 1 << 15; + common_hal_audiomixer_mixervoice_set_level(self, mp_obj_new_float(1.0)); } void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent) { self->parent = parent; } -mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { - return (mp_float_t)self->level / (1 << 15); +mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { + return self->level.obj; } -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t level) { - self->level = (uint16_t)(level * (1 << 15)); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->level, MP_QSTR_level); } bool common_hal_audiomixer_mixervoice_get_loop(audiomixer_mixervoice_obj_t *self) { diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h index ad70f64b6e16..ac9f802632a7 100644 --- a/shared-module/audiomixer/MixerVoice.h +++ b/shared-module/audiomixer/MixerVoice.h @@ -9,6 +9,7 @@ #include "shared-module/audiomixer/__init__.h" #include "shared-module/audiomixer/Mixer.h" +#include "shared-module/synthio/block.h" typedef struct { mp_obj_base_t base; @@ -18,5 +19,5 @@ typedef struct { bool more_data; uint32_t *remaining_buffer; uint32_t buffer_length; - uint16_t level; + synthio_block_slot_t level; } audiomixer_mixervoice_obj_t; From e37502c2a07f2bc1b91d3624d0ec99dbb56f6bfc Mon Sep 17 00:00:00 2001 From: dcooperdalrymple Date: Fri, 20 Dec 2024 11:07:42 -0600 Subject: [PATCH 2/3] Fix pre-commit formatting error. --- shared-module/audiomixer/Mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index a0ea89f24bb3..1b63242d9b74 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -192,7 +192,7 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, uint32_t *src = voice->remaining_buffer; // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. - shared_bindings_synthio_lfo_tick(self->sample_rate); //, n / self->channel_count); // Requires #9776 + shared_bindings_synthio_lfo_tick(self->sample_rate); uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); // First active voice gets copied over verbatim. From a5956eab82d98acd95af0e1ef7b344ddb1116c7b Mon Sep 17 00:00:00 2001 From: dcooperdalrymple Date: Fri, 20 Dec 2024 11:24:06 -0600 Subject: [PATCH 3/3] Revert to original functionality when synthio is not supported. --- shared-bindings/audiomixer/MixerVoice.c | 6 +++++- shared-module/audiomixer/Mixer.c | 8 +++++++- shared-module/audiomixer/MixerVoice.c | 8 ++++++++ shared-module/audiomixer/MixerVoice.h | 6 ++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index 706d8f488d4f..f06f079414ce 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -13,7 +13,9 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/util.h" +#if CIRCUITPY_SYNTHIO #include "shared-module/synthio/block.h" +#endif //| class MixerVoice: //| """Voice objects used with Mixer @@ -77,7 +79,9 @@ static mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *po MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); //| level: synthio.BlockInput -//| """The volume level of a voice, as a floating point number between 0 and 1.""" +//| """The volume level of a voice, as a floating point number between 0 and 1. If your board +//| does not support synthio, this property will only accept a float value. +//| """ static mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { return common_hal_audiomixer_mixervoice_get_level(self_in); } diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 1b63242d9b74..ce3f1d79f2fb 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -188,12 +188,18 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, } } - uint32_t n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->channel_count); uint32_t *src = voice->remaining_buffer; + #if CIRCUITPY_SYNTHIO + uint32_t n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->channel_count); + // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. shared_bindings_synthio_lfo_tick(self->sample_rate); uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); + #else + uint32_t n = MIN(voice->buffer_length, length); + uint16_t level = voice->level; + #endif // First active voice gets copied over verbatim. if (!voices_active) { diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index 91e2024ee8cc..49a88639d395 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -23,11 +23,19 @@ void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *se } mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { + #if CIRCUITPY_SYNTHIO return self->level.obj; + #else + return mp_obj_new_float((mp_float_t)self->level / (1 << 15)); + #endif } void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t arg) { + #if CIRCUITPY_SYNTHIO synthio_block_assign_slot(arg, &self->level, MP_QSTR_level); + #else + self->level = (uint16_t)(mp_arg_validate_obj_float_range(arg, 0, 1, MP_QSTR_level) * (1 << 15)); + #endif } bool common_hal_audiomixer_mixervoice_get_loop(audiomixer_mixervoice_obj_t *self) { diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h index ac9f802632a7..dd9095515459 100644 --- a/shared-module/audiomixer/MixerVoice.h +++ b/shared-module/audiomixer/MixerVoice.h @@ -9,7 +9,9 @@ #include "shared-module/audiomixer/__init__.h" #include "shared-module/audiomixer/Mixer.h" +#if CIRCUITPY_SYNTHIO #include "shared-module/synthio/block.h" +#endif typedef struct { mp_obj_base_t base; @@ -19,5 +21,9 @@ typedef struct { bool more_data; uint32_t *remaining_buffer; uint32_t buffer_length; + #if CIRCUITPY_SYNTHIO synthio_block_slot_t level; + #else + uint16_t level; + #endif } audiomixer_mixervoice_obj_t;