diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index 321a192a9d23..f06f079414ce 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -13,6 +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 @@ -75,17 +78,18 @@ 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 -//| """The volume level of a voice, as a floating point number between 0 and 1.""" +//| level: synthio.BlockInput +//| """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 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..ce3f1d79f2fb 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -188,9 +188,18 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, } } - uint32_t n = MIN(voice->buffer_length, length); 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 66a47c269b48..49a88639d395 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -15,19 +15,27 @@ 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) { + #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_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) { + #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 ad70f64b6e16..dd9095515459 100644 --- a/shared-module/audiomixer/MixerVoice.h +++ b/shared-module/audiomixer/MixerVoice.h @@ -9,6 +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; @@ -18,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;