@@ -88,6 +88,39 @@ STATIC bool mp3file_update_inbuf(audiomp3_mp3file_obj_t* self) {
88
88
#define BYTES_LEFT (self ) (self->inbuf_length - self->inbuf_offset)
89
89
#define CONSUME (self , n ) (self->inbuf_offset += n)
90
90
91
+ // http://id3.org/d3v2.3.0
92
+ // http://id3.org/id3v2.3.0
93
+ STATIC void mp3file_skip_id3v2 (audiomp3_mp3file_obj_t * self ) {
94
+ mp3file_update_inbuf (self );
95
+ if (BYTES_LEFT (self ) < 10 ) {
96
+ return ;
97
+ }
98
+ uint8_t * data = READ_PTR (self );
99
+ if (!(
100
+ data [0 ] == 'I' &&
101
+ data [1 ] == 'D' &&
102
+ data [2 ] == '3' &&
103
+ data [3 ] != 0xff &&
104
+ data [4 ] != 0xff &&
105
+ (data [5 ] & 0x1f ) == 0 &&
106
+ (data [6 ] & 0x80 ) == 0 &&
107
+ (data [7 ] & 0x80 ) == 0 &&
108
+ (data [8 ] & 0x80 ) == 0 &&
109
+ (data [9 ] & 0x80 ) == 0 )) {
110
+ return ;
111
+ }
112
+ uint32_t size = (data [6 ] << 21 ) | (data [7 ] << 14 ) | (data [8 ] << 7 ) | (data [9 ]);
113
+ size += 10 ; // size excludes the "header" (but not the "extended header")
114
+ // First, deduct from size whatever is left in buffer
115
+ uint32_t to_consume = MIN (size , BYTES_LEFT (self ));
116
+ CONSUME (self , to_consume );
117
+ size -= to_consume ;
118
+
119
+ // Next, seek in the file after the header
120
+ f_lseek (& self -> file -> fp , f_tell (& self -> file -> fp ) + size );
121
+ return ;
122
+ }
123
+
91
124
/* If a sync word can be found, advance to it and return true. Otherwise,
92
125
* return false.
93
126
*/
@@ -106,7 +139,15 @@ STATIC bool mp3file_find_sync_word(audiomp3_mp3file_obj_t* self) {
106
139
}
107
140
108
141
STATIC bool mp3file_get_next_frame_info (audiomp3_mp3file_obj_t * self , MP3FrameInfo * fi ) {
109
- int err = MP3GetNextFrameInfo (self -> decoder , fi , READ_PTR (self ));
142
+ int err ;
143
+ do {
144
+ err = MP3GetNextFrameInfo (self -> decoder , fi , READ_PTR (self ));
145
+ if (err == ERR_MP3_NONE ) {
146
+ break ;
147
+ }
148
+ CONSUME (self , 1 );
149
+ mp3file_find_sync_word (self );
150
+ } while (!self -> eof );
110
151
return err == ERR_MP3_NONE ;
111
152
}
112
153
@@ -223,6 +264,7 @@ void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t* self,
223
264
self -> eof = 0 ;
224
265
self -> other_channel = -1 ;
225
266
mp3file_update_inbuf (self );
267
+ mp3file_skip_id3v2 (self );
226
268
mp3file_find_sync_word (self );
227
269
}
228
270
@@ -253,6 +295,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t*
253
295
self -> buffer_index = !self -> buffer_index ;
254
296
int16_t * buffer = (int16_t * )(void * )self -> buffers [self -> buffer_index ];
255
297
298
+ mp3file_skip_id3v2 (self );
256
299
if (!mp3file_find_sync_word (self )) {
257
300
return self -> eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR ;
258
301
}
0 commit comments