diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c index 0d91ee6982..f8b39c29e3 100644 --- a/shared-module/synthio/MidiTrack.c +++ b/shared-module/synthio/MidiTrack.c @@ -156,7 +156,7 @@ uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t * void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, bool single_channel_output, uint8_t channel) { - + synthio_synth_reset_buffer(&self->synth, single_channel_output, channel); self->synth.span.dur = 0; self->next_span = 0; } @@ -172,7 +172,7 @@ audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t self->synth.span = self->track[self->next_span++]; } - synthio_synth_synthesize(&self->synth, buffer, buffer_length); + synthio_synth_synthesize(&self->synth, buffer, buffer_length, single_channel_output ? 0 : channel); return (self->synth.span.dur == 0 && self->next_span >= self->total_spans) ? GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; diff --git a/shared-module/synthio/Synthesizer.c b/shared-module/synthio/Synthesizer.c index 8cfc73a980..25c91ecbe0 100644 --- a/shared-module/synthio/Synthesizer.c +++ b/shared-module/synthio/Synthesizer.c @@ -58,12 +58,13 @@ uint8_t common_hal_synthio_synthesizer_get_channel_count(synthio_synthesizer_obj void synthio_synthesizer_reset_buffer(synthio_synthesizer_obj_t *self, bool single_channel_output, uint8_t channel) { + synthio_synth_reset_buffer(&self->synth, single_channel_output, channel); } audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_obj_t *self, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { self->synth.span.dur = SYNTHIO_MAX_DUR; - synthio_synth_synthesize(&self->synth, buffer, buffer_length); + synthio_synth_synthesize(&self->synth, buffer, buffer_length, single_channel_output ? channel : 0); return GET_BUFFER_MORE_DATA; } diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index 0dee75deb7..7ac8e47746 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -44,16 +44,27 @@ int synthio_span_count_active_channels(synthio_midi_span_t *span) { } -void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t *buffer_length) { +void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t *buffer_length, uint8_t channel) { + + if (channel == synth->other_channel) { + *buffer_length = synth->last_buffer_length; + *bufptr = (uint8_t *)(synth->buffers[synth->other_buffer_index] + channel); + return; + } + + synth->buffer_index = !synth->buffer_index; + synth->other_channel = 1 - channel; + synth->other_buffer_index = synth->buffer_index; + int16_t *out_buffer = (int16_t *)(void *)synth->buffers[synth->buffer_index]; + uint16_t dur = MIN(SYNTHIO_MAX_DUR, synth->span.dur); synth->span.dur -= dur; - memset(synth->buffer, 0, synth->buffer_length); + memset(out_buffer, 0, synth->buffer_length); int32_t sample_rate = synth->sample_rate; int active_channels = synthio_span_count_active_channels(&synth->span); const int16_t *waveform = synth->waveform; uint32_t waveform_length = synth->waveform_length; - int16_t *out_buffer = synth->buffer; if (active_channels) { int16_t loudness = 0x3fff / (1 + active_channels); for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) { @@ -84,27 +95,38 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t } } - *buffer_length = dur * SYNTHIO_BYTES_PER_SAMPLE; - *buffer = (uint8_t *)synth->buffer; + *buffer_length = synth->last_buffer_length = dur * SYNTHIO_BYTES_PER_SAMPLE; + *bufptr = (uint8_t *)out_buffer; +} + +void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_output, uint8_t channel) { + if (single_channel_output && channel == 1) { + return; + } + synth->other_channel = -1; } bool synthio_synth_deinited(synthio_synth_t *synth) { - return synth->buffer == NULL; + return synth->buffers[0] == NULL; } void synthio_synth_deinit(synthio_synth_t *synth) { - m_del(uint8_t, synth->buffer, synth->buffer_length); - synth->buffer = NULL; + m_del(uint8_t, synth->buffers[0], synth->buffer_length); + m_del(uint8_t, synth->buffers[1], synth->buffer_length); + synth->buffers[0] = NULL; + synth->buffers[1] = NULL; } void synthio_synth_init(synthio_synth_t *synth, uint16_t max_dur) { synth->buffer_length = MIN(SYNTHIO_MAX_DUR, max_dur) * SYNTHIO_BYTES_PER_SAMPLE; - synth->buffer = m_malloc(synth->buffer_length, false); + synth->buffers[0] = m_malloc(synth->buffer_length, false); + synth->buffers[1] = m_malloc(synth->buffer_length, false); + synth->other_channel = -1; } void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { - *single_buffer = true; + *single_buffer = false; *samples_signed = true; *max_buffer_length = synth->buffer_length; *spacing = 1; diff --git a/shared-module/synthio/__init__.h b/shared-module/synthio/__init__.h index 9397495f98..e14e5ead10 100644 --- a/shared-module/synthio/__init__.h +++ b/shared-module/synthio/__init__.h @@ -28,7 +28,7 @@ #define SYNTHIO_BITS_PER_SAMPLE (16) #define SYNTHIO_BYTES_PER_SAMPLE (SYNTHIO_BITS_PER_SAMPLE / 8) -#define SYNTHIO_MAX_DUR (512) +#define SYNTHIO_MAX_DUR (256) #define SYNTHIO_SILENCE (0x80) #include "shared-module/audiocore/__init__.h" @@ -40,21 +40,25 @@ typedef struct { typedef struct { uint32_t sample_rate; - int16_t *buffer; + int16_t *buffers[2]; const int16_t *waveform; uint16_t buffer_length; + uint16_t last_buffer_length; + uint8_t other_channel, buffer_index, other_buffer_index; uint16_t waveform_length; synthio_midi_span_t span; uint32_t accum[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; } synthio_synth_t; void synthio_span_init(synthio_midi_span_t *span); -void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t *buffer_length); +void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t *buffer_length, uint8_t channel); void synthio_synth_deinit(synthio_synth_t *synth); bool synthio_synth_deinited(synthio_synth_t *synth); void synthio_synth_init(synthio_synth_t *synth, uint16_t max_dur); void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing); +void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_output, uint8_t channel); void synthio_synth_parse_waveform(mp_buffer_info_t *bufinfo_waveform, mp_obj_t waveform_obj); + bool synthio_span_change_note(synthio_midi_span_t *span, uint8_t old_note, uint8_t new_note); int synthio_span_count_active_channels(synthio_midi_span_t *span);