Skip to content

Commit

Permalink
Merge pull request adafruit#2384 from jepler/mp3-fixes
Browse files Browse the repository at this point in the history
MP3: skip id3v2 tags, make "bartlebeats" tracks playable
  • Loading branch information
tannewt authored Dec 16, 2019
2 parents 6c3d555 + 91a1706 commit 8384e46
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
2 changes: 1 addition & 1 deletion shared-module/audiocore/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ uint8_t audiosample_channel_count(mp_obj_t sample_obj) {

void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj));
proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel, audio_channel);
}

audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
Expand Down
3 changes: 2 additions & 1 deletion shared-module/audiocore/__init__.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ typedef enum {
typedef uint32_t (*audiosample_sample_rate_fun)(mp_obj_t);
typedef uint8_t (*audiosample_bits_per_sample_fun)(mp_obj_t);
typedef uint8_t (*audiosample_channel_count_fun)(mp_obj_t);
typedef void (*audiosample_reset_buffer_fun)(mp_obj_t);
typedef void (*audiosample_reset_buffer_fun)(mp_obj_t,
bool single_channel, uint8_t audio_channel);
typedef audioio_get_buffer_result_t (*audiosample_get_buffer_fun)(mp_obj_t,
bool single_channel, uint8_t channel, uint8_t** buffer,
uint32_t* buffer_length);
Expand Down
45 changes: 44 additions & 1 deletion shared-module/audiomp3/MP3File.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,39 @@ STATIC bool mp3file_update_inbuf(audiomp3_mp3file_obj_t* self) {
#define BYTES_LEFT(self) (self->inbuf_length - self->inbuf_offset)
#define CONSUME(self, n) (self->inbuf_offset += n)

// http://id3.org/d3v2.3.0
// http://id3.org/id3v2.3.0
STATIC void mp3file_skip_id3v2(audiomp3_mp3file_obj_t* self) {
mp3file_update_inbuf(self);
if (BYTES_LEFT(self) < 10) {
return;
}
uint8_t *data = READ_PTR(self);
if (!(
data[0] == 'I' &&
data[1] == 'D' &&
data[2] == '3' &&
data[3] != 0xff &&
data[4] != 0xff &&
(data[5] & 0x1f) == 0 &&
(data[6] & 0x80) == 0 &&
(data[7] & 0x80) == 0 &&
(data[8] & 0x80) == 0 &&
(data[9] & 0x80) == 0)) {
return;
}
uint32_t size = (data[6] << 21) | (data[7] << 14) | (data[8] << 7) | (data[9]);
size += 10; // size excludes the "header" (but not the "extended header")
// First, deduct from size whatever is left in buffer
uint32_t to_consume = MIN(size, BYTES_LEFT(self));
CONSUME(self, to_consume);
size -= to_consume;

// Next, seek in the file after the header
f_lseek(&self->file->fp, f_tell(&self->file->fp) + size);
return;
}

/* If a sync word can be found, advance to it and return true. Otherwise,
* return false.
*/
Expand All @@ -106,7 +139,15 @@ STATIC bool mp3file_find_sync_word(audiomp3_mp3file_obj_t* self) {
}

STATIC bool mp3file_get_next_frame_info(audiomp3_mp3file_obj_t* self, MP3FrameInfo* fi) {
int err = MP3GetNextFrameInfo(self->decoder, fi, READ_PTR(self));
int err;
do {
err = MP3GetNextFrameInfo(self->decoder, fi, READ_PTR(self));
if (err == ERR_MP3_NONE) {
break;
}
CONSUME(self, 1);
mp3file_find_sync_word(self);
} while (!self->eof);
return err == ERR_MP3_NONE;
}

Expand Down Expand Up @@ -223,6 +264,7 @@ void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t* self,
self->eof = 0;
self->other_channel = -1;
mp3file_update_inbuf(self);
mp3file_skip_id3v2(self);
mp3file_find_sync_word(self);
}

Expand Down Expand Up @@ -253,6 +295,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t*
self->buffer_index = !self->buffer_index;
int16_t *buffer = (int16_t *)(void *)self->buffers[self->buffer_index];

mp3file_skip_id3v2(self);
if (!mp3file_find_sync_word(self)) {
return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR;
}
Expand Down

0 comments on commit 8384e46

Please sign in to comment.