comparison data/fileio/MP3FileReader.cpp @ 1288:5ef9b4d4bbdb 3.0-integration

Filter out Xing/LAME info frames, rather than letting them go to the mp3 decoder as if they were audio frames. Fixes the 1152-sample zero pad at start of some decoded mp3 files (distinct from decoder delay). The logic here is based on the madplay code.
author Chris Cannam
date Thu, 24 Nov 2016 13:32:04 +0000
parents 97f21b03269b
children a45312bd9306
comparison
equal deleted inserted replaced
1287:97f21b03269b 1288:5ef9b4d4bbdb
58 m_fileRate = 0; 58 m_fileRate = 0;
59 m_fileSize = 0; 59 m_fileSize = 0;
60 m_bitrateNum = 0; 60 m_bitrateNum = 0;
61 m_bitrateDenom = 0; 61 m_bitrateDenom = 0;
62 m_cancelled = false; 62 m_cancelled = false;
63 m_mp3FrameCount = 0;
63 m_completion = 0; 64 m_completion = 0;
64 m_done = false; 65 m_done = false;
65 m_reporter = reporter; 66 m_reporter = reporter;
66 67
67 struct stat stat; 68 struct stat stat;
145 while ((m_channelCount == 0 || m_fileRate == 0 || m_sampleRate == 0) 146 while ((m_channelCount == 0 || m_fileRate == 0 || m_sampleRate == 0)
146 && !m_done) { 147 && !m_done) {
147 usleep(10); 148 usleep(10);
148 } 149 }
149 150
150 SVDEBUG << "MP3FileReader ctor: exiting with file rate = " << m_fileRate << endl; 151 SVDEBUG << "MP3FileReader: decoding startup complete, file rate = " << m_fileRate << endl;
151 } 152 }
152 153
153 if (m_error != "") { 154 if (m_error != "") {
154 SVDEBUG << "MP3FileReader::MP3FileReader(\"" << m_path << "\"): ERROR: " << m_error << endl; 155 SVDEBUG << "MP3FileReader::MP3FileReader(\"" << m_path << "\"): ERROR: " << m_error << endl;
155 } 156 }
294 { 295 {
295 DecoderData data; 296 DecoderData data;
296 struct mad_decoder decoder; 297 struct mad_decoder decoder;
297 298
298 data.start = (unsigned char const *)mm; 299 data.start = (unsigned char const *)mm;
299 data.length = (unsigned long)sz; 300 data.length = sz;
300 data.reader = this; 301 data.reader = this;
301 302
302 mad_decoder_init(&decoder, &data, input, 0, 0, output, error, 0); 303 mad_decoder_init(&decoder, // decoder to initialise
304 &data, // our own data block for callbacks
305 input_callback, // provides (entire) input to mad
306 0, // checks header
307 filter_callback, // filters frame before decoding
308 output_callback, // receives decoded output
309 error_callback, // handles decode errors
310 0); // "message_func"
311
303 mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); 312 mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
304 mad_decoder_finish(&decoder); 313 mad_decoder_finish(&decoder);
305 314
315 SVDEBUG << "MP3FileReader: Decoding complete, decoded " << m_mp3FrameCount
316 << " mp3 frames" << endl;
317
306 m_done = true; 318 m_done = true;
307 return true; 319 return true;
308 } 320 }
309 321
310 enum mad_flow 322 enum mad_flow
311 MP3FileReader::input(void *dp, struct mad_stream *stream) 323 MP3FileReader::input_callback(void *dp, struct mad_stream *stream)
312 { 324 {
313 DecoderData *data = (DecoderData *)dp; 325 DecoderData *data = (DecoderData *)dp;
314 326
315 if (!data->length) return MAD_FLOW_STOP; 327 if (!data->length) return MAD_FLOW_STOP;
316 328
317 unsigned char const *start = data->start; 329 unsigned char const *start = data->start;
318 unsigned long length = data->length; 330 sv_frame_t length = data->length;
319 331
320 #ifdef HAVE_ID3TAG 332 #ifdef HAVE_ID3TAG
321 if (length > ID3_TAG_QUERYSIZE) { 333 while (length > ID3_TAG_QUERYSIZE) {
322 ssize_t taglen = id3_tag_query(start, ID3_TAG_QUERYSIZE); 334 ssize_t taglen = id3_tag_query(start, ID3_TAG_QUERYSIZE);
323 if (taglen > 0) { 335 if (taglen <= 0) {
324 SVDEBUG << "MP3FileReader: ID3 tag length to skip: " << taglen << endl; 336 break;
325 start += taglen; 337 }
326 length -= taglen; 338 SVDEBUG << "MP3FileReader: ID3 tag length to skip: " << taglen << endl;
327 } 339 start += taglen;
340 length -= taglen;
328 } 341 }
329 #endif 342 #endif
330 343
331 mad_stream_buffer(stream, start, length); 344 mad_stream_buffer(stream, start, length);
332 data->length = 0; 345 data->length = 0;
333 346
334 return MAD_FLOW_CONTINUE; 347 return MAD_FLOW_CONTINUE;
335 } 348 }
336 349
337 enum mad_flow 350 enum mad_flow
338 MP3FileReader::output(void *dp, 351 MP3FileReader::filter_callback(void *dp,
339 struct mad_header const *header, 352 struct mad_stream const *stream,
340 struct mad_pcm *pcm) 353 struct mad_frame *frame)
354 {
355 DecoderData *data = (DecoderData *)dp;
356 return data->reader->filter(stream, frame);
357 }
358
359 enum mad_flow
360 MP3FileReader::filter(struct mad_stream const *stream,
361 struct mad_frame *)
362 {
363 struct mad_bitptr ptr = stream->anc_ptr;
364 unsigned long fourcc = mad_bit_read(&ptr, 32);
365 std::string magic("....");
366 for (int i = 0; i < 4; ++i) {
367 magic[3-i] = char((fourcc >> (8*i)) & 0xff);
368 }
369 if (magic == "Xing" || magic == "Info" || magic == "LAME") {
370 SVDEBUG << "MP3FileReader: Discarding metadata frame (magic = \""
371 << magic << "\")" << " at frame " << m_mp3FrameCount << endl;
372 return MAD_FLOW_IGNORE;
373 } else {
374 return MAD_FLOW_CONTINUE;
375 }
376 }
377
378 enum mad_flow
379 MP3FileReader::output_callback(void *dp,
380 struct mad_header const *header,
381 struct mad_pcm *pcm)
341 { 382 {
342 DecoderData *data = (DecoderData *)dp; 383 DecoderData *data = (DecoderData *)dp;
343 return data->reader->accept(header, pcm); 384 return data->reader->accept(header, pcm);
344 } 385 }
345 386
347 MP3FileReader::accept(struct mad_header const *header, 388 MP3FileReader::accept(struct mad_header const *header,
348 struct mad_pcm *pcm) 389 struct mad_pcm *pcm)
349 { 390 {
350 int channels = pcm->channels; 391 int channels = pcm->channels;
351 int frames = pcm->length; 392 int frames = pcm->length;
352 393
353 if (header) { 394 if (header) {
354 m_bitrateNum = m_bitrateNum + double(header->bitrate); 395 m_bitrateNum = m_bitrateNum + double(header->bitrate);
355 m_bitrateDenom ++; 396 m_bitrateDenom ++;
356 } 397 }
357 398
421 } 462 }
422 } 463 }
423 464
424 addSamplesToDecodeCache(m_samplebuffer, frames); 465 addSamplesToDecodeCache(m_samplebuffer, frames);
425 466
467 ++m_mp3FrameCount;
468
426 return MAD_FLOW_CONTINUE; 469 return MAD_FLOW_CONTINUE;
427 } 470 }
428 471
429 enum mad_flow 472 enum mad_flow
430 MP3FileReader::error(void *dp, 473 MP3FileReader::error_callback(void *dp,
431 struct mad_stream *stream, 474 struct mad_stream *stream,
432 struct mad_frame *) 475 struct mad_frame *)
433 { 476 {
434 DecoderData *data = (DecoderData *)dp; 477 DecoderData *data = (DecoderData *)dp;
435 if (!data->reader->m_decodeErrorShown) { 478 if (!data->reader->m_decodeErrorShown) {
436 char buffer[256]; 479 char buffer[256];
437 snprintf(buffer, 255, 480 snprintf(buffer, 255,