Skip to content

Commit

Permalink
Merge pull request #9899 from relic-se/mixervoice_level_blockinput
Browse files Browse the repository at this point in the history
Implement `audiomixer.MixerVoice.level` as `synthio.BlockInput`
  • Loading branch information
tannewt authored Jan 2, 2025
2 parents fabd4a6 + a5956ea commit d4fb4e8
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 13 deletions.
14 changes: 9 additions & 5 deletions shared-bindings/audiomixer/MixerVoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions shared-bindings/audiomixer/MixerVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
11 changes: 10 additions & 1 deletion shared-module/audiomixer/Mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
18 changes: 13 additions & 5 deletions shared-module/audiomixer/MixerVoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
7 changes: 7 additions & 0 deletions shared-module/audiomixer/MixerVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

0 comments on commit d4fb4e8

Please sign in to comment.