diff --git a/shared-module/audiomp3/MP3File.c b/shared-module/audiomp3/MP3File.c index f0c4adc263..f4861da360 100644 --- a/shared-module/audiomp3/MP3File.c +++ b/shared-module/audiomp3/MP3File.c @@ -151,10 +151,13 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t* self, self->channel_count = fi.nChans; self->frame_buffer_size = fi.outputSamps*sizeof(int16_t); + if ((intptr_t)buffer & 1) { + buffer += 1; buffer_size -= 1; + } if (buffer_size >= 2 * self->frame_buffer_size) { self->len = buffer_size / 2 / self->frame_buffer_size * self->frame_buffer_size; - self->buffers[0] = buffer; - self->buffers[1] = buffer + self->len; + self->buffers[0] = (int16_t*)(void*)buffer; + self->buffers[1] = (int16_t*)(void*)buffer + self->len; } else { self->len = 2 * self->frame_buffer_size; self->buffers[0] = m_malloc(self->len, false); @@ -218,6 +221,7 @@ void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t* self, f_lseek(&self->file->fp, 0); self->inbuf_offset = self->inbuf_length; self->eof = 0; + self->other_channel = -1; mp3file_update_inbuf(self); mp3file_find_sync_word(self); } @@ -234,26 +238,30 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t* channel = 0; } - uint16_t channel_read_count = self->channel_read_count[channel]++; - bool need_more_data = self->read_count++ == channel_read_count; - - *bufptr = self->buffers[self->buffer_index] + channel; + *bufptr = (uint8_t*)(self->buffers[self->buffer_index] + channel); *buffer_length = self->frame_buffer_size; - if (need_more_data) { - self->buffer_index = !self->buffer_index; - int16_t *buffer = (int16_t *)(void *)self->buffers[self->buffer_index]; + if (channel == self->other_channel) { + *bufptr = (uint8_t*)(self->buffers[self->other_buffer_index] + channel); + self->other_channel = -1; + return GET_BUFFER_MORE_DATA; + } - if (!mp3file_find_sync_word(self)) { - return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR; - } - int bytes_left = BYTES_LEFT(self); - uint8_t *inbuf = READ_PTR(self); - int err = MP3Decode(self->decoder, &inbuf, &bytes_left, buffer, 0); - CONSUME(self, BYTES_LEFT(self) - bytes_left); - if (err) { - return GET_BUFFER_DONE; - } + self->other_channel = 1-channel; + self->other_buffer_index = self->buffer_index; + + self->buffer_index = !self->buffer_index; + int16_t *buffer = (int16_t *)(void *)self->buffers[self->buffer_index]; + + if (!mp3file_find_sync_word(self)) { + return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR; + } + int bytes_left = BYTES_LEFT(self); + uint8_t *inbuf = READ_PTR(self); + int err = MP3Decode(self->decoder, &inbuf, &bytes_left, buffer, 0); + CONSUME(self, BYTES_LEFT(self) - bytes_left); + if (err) { + return GET_BUFFER_DONE; } return GET_BUFFER_MORE_DATA; diff --git a/shared-module/audiomp3/MP3File.h b/shared-module/audiomp3/MP3File.h index 12649ac1ad..9d99e8d1f0 100644 --- a/shared-module/audiomp3/MP3File.h +++ b/shared-module/audiomp3/MP3File.h @@ -39,7 +39,7 @@ typedef struct { uint8_t* inbuf; uint32_t inbuf_length; uint32_t inbuf_offset; - uint8_t* buffers[2]; + int16_t* buffers[2]; uint32_t len; uint32_t frame_buffer_size; @@ -50,8 +50,8 @@ typedef struct { uint8_t channel_count; bool eof; - uint16_t read_count; - uint16_t channel_read_count[2]; + int8_t other_channel; + int8_t other_buffer_index; } audiomp3_mp3file_obj_t; // These are not available from Python because it may be called in an interrupt.