diff --git a/shared-bindings/audiodelays/PitchShift.c b/shared-bindings/audiodelays/PitchShift.c index ee3bf5afdd7..49950df6a34 100644 --- a/shared-bindings/audiodelays/PitchShift.c +++ b/shared-bindings/audiodelays/PitchShift.c @@ -186,6 +186,28 @@ MP_PROPERTY_GETSET(audiodelays_pitch_shift_mix_obj, (mp_obj_t)&audiodelays_pitch_shift_set_mix_obj); +//| freeze: bool +//| """If True, the window buffer won't accept new audio information and will be "frozen" in +//| it's current state, resulting in a sustaining tone. Normal operation is resumed when set to +//| False. If the audio buffer is reset, this value will also be reset to False.""" +static mp_obj_t audiodelays_pitch_shift_obj_get_freeze(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_audiodelays_pitch_shift_get_freeze(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_get_freeze_obj, audiodelays_pitch_shift_obj_get_freeze); + +static mp_obj_t audiodelays_pitch_shift_obj_set_freeze(mp_obj_t self_in, mp_obj_t freeze_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + bool freeze = mp_obj_is_true(freeze_in); + common_hal_audiodelays_pitch_shift_set_freeze(self, freeze); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_pitch_shift_set_freeze_obj, audiodelays_pitch_shift_obj_set_freeze); + +MP_PROPERTY_GETSET(audiodelays_pitch_shift_freeze_obj, + (mp_obj_t)&audiodelays_pitch_shift_get_freeze_obj, + (mp_obj_t)&audiodelays_pitch_shift_set_freeze_obj); + + //| playing: bool //| """True when the effect is playing a sample. (read-only)""" //| @@ -255,6 +277,7 @@ static const mp_rom_map_elem_t audiodelays_pitch_shift_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_pitch_shift_playing_obj) }, { MP_ROM_QSTR(MP_QSTR_semitones), MP_ROM_PTR(&audiodelays_pitch_shift_semitones_obj) }, { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_pitch_shift_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_freeze), MP_ROM_PTR(&audiodelays_pitch_shift_freeze_obj) }, AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(audiodelays_pitch_shift_locals_dict, audiodelays_pitch_shift_locals_dict_table); diff --git a/shared-bindings/audiodelays/PitchShift.h b/shared-bindings/audiodelays/PitchShift.h index 78c78b5ea82..5544d1a0aff 100644 --- a/shared-bindings/audiodelays/PitchShift.h +++ b/shared-bindings/audiodelays/PitchShift.h @@ -23,6 +23,9 @@ void common_hal_audiodelays_pitch_shift_set_semitones(audiodelays_pitch_shift_ob mp_obj_t common_hal_audiodelays_pitch_shift_get_mix(audiodelays_pitch_shift_obj_t *self); void common_hal_audiodelays_pitch_shift_set_mix(audiodelays_pitch_shift_obj_t *self, mp_obj_t arg); +bool common_hal_audiodelays_pitch_shift_get_freeze(audiodelays_pitch_shift_obj_t *self); +void common_hal_audiodelays_pitch_shift_set_freeze(audiodelays_pitch_shift_obj_t *self, bool freeze); + bool common_hal_audiodelays_pitch_shift_get_playing(audiodelays_pitch_shift_obj_t *self); void common_hal_audiodelays_pitch_shift_play(audiodelays_pitch_shift_obj_t *self, mp_obj_t sample, bool loop); void common_hal_audiodelays_pitch_shift_stop(audiodelays_pitch_shift_obj_t *self); diff --git a/shared-module/audiodelays/PitchShift.c b/shared-module/audiodelays/PitchShift.c index 2c5d646aafb..42925fbf6ae 100644 --- a/shared-module/audiodelays/PitchShift.c +++ b/shared-module/audiodelays/PitchShift.c @@ -58,6 +58,7 @@ void common_hal_audiodelays_pitch_shift_construct(audiodelays_pitch_shift_obj_t synthio_block_assign_slot(semitones, &self->semitones, MP_QSTR_semitones); synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + self->freeze = false; // Allocate the window buffer self->window_len = window; // bytes @@ -126,9 +127,18 @@ void common_hal_audiodelays_pitch_shift_set_mix(audiodelays_pitch_shift_obj_t *s synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); } +bool common_hal_audiodelays_pitch_shift_get_freeze(audiodelays_pitch_shift_obj_t *self) { + return self->freeze; +} + +void common_hal_audiodelays_pitch_shift_set_freeze(audiodelays_pitch_shift_obj_t *self, bool freeze) { + self->freeze = freeze; +} + void audiodelays_pitch_shift_reset_buffer(audiodelays_pitch_shift_obj_t *self, bool single_channel_output, uint8_t channel) { + self->freeze = false; memset(self->buffer[0], 0, self->buffer_len); memset(self->buffer[1], 0, self->buffer_len); @@ -268,15 +278,17 @@ audioio_get_buffer_result_t audiodelays_pitch_shift_get_buffer(audiodelays_pitch } } - if (overlap_size) { - // Copy last sample from overlap and store in buffer - window_buffer[self->window_index + window_size * buf_offset] = overlap_buffer[self->overlap_index + overlap_size * buf_offset]; + if (!self->freeze) { + if (overlap_size) { + // Copy last sample from overlap and store in buffer + window_buffer[self->window_index + window_size * buf_offset] = overlap_buffer[self->overlap_index + overlap_size * buf_offset]; - // Save current sample in overlap - overlap_buffer[self->overlap_index + overlap_size * buf_offset] = (int16_t)sample_word; - } else { - // Write sample to buffer - window_buffer[self->window_index + window_size * buf_offset] = (int16_t)sample_word; + // Save current sample in overlap + overlap_buffer[self->overlap_index + overlap_size * buf_offset] = (int16_t)sample_word; + } else { + // Write sample to buffer + window_buffer[self->window_index + window_size * buf_offset] = (int16_t)sample_word; + } } // Determine how far we are into the overlap @@ -316,17 +328,19 @@ audioio_get_buffer_result_t audiodelays_pitch_shift_get_buffer(audiodelays_pitch } if (self->base.channel_count == 1 || buf_offset) { - // Increment window buffer write pointer - self->window_index++; - if (self->window_index >= window_size) { - self->window_index = 0; - } + if (!self->freeze) { + // Increment window buffer write pointer + self->window_index++; + if (self->window_index >= window_size) { + self->window_index = 0; + } - // Increment overlap buffer pointer - if (overlap_size) { - self->overlap_index++; - if (self->overlap_index >= overlap_size) { - self->overlap_index = 0; + // Increment overlap buffer pointer + if (overlap_size) { + self->overlap_index++; + if (self->overlap_index >= overlap_size) { + self->overlap_index = 0; + } } } diff --git a/shared-module/audiodelays/PitchShift.h b/shared-module/audiodelays/PitchShift.h index dddcfa4efc0..f156186b7f6 100644 --- a/shared-module/audiodelays/PitchShift.h +++ b/shared-module/audiodelays/PitchShift.h @@ -20,6 +20,7 @@ typedef struct { synthio_block_slot_t semitones; mp_float_t current_semitones; synthio_block_slot_t mix; + bool freeze; uint32_t window_len; uint32_t overlap_len;