Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement audiomixer.MixerVoice.level as synthio.BlockInput #9899

Merged
merged 3 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;