1 /*
2 Copyright (C) 2007 Ben Levitt
3  * This file is based on the mp3 decoding plugin of the K3b project.
4  * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
5 
6 This file is part of Traverso
7 
8 Traverso is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
21 
22 */
23 
24 #include "MadAudioReader.h"
25 #include <QFile>
26 #include <QString>
27 #include <QVector>
28 
29 #include "Utils.h"
30 
31 RELAYTOOL_MAD;
32 
33 // Always put me below _all_ includes, this is needed
34 // in case we run with memory leak detection enabled!
35 #include "Debugger.h"
36 
37 
38 
39 
40 static const int INPUT_BUFFER_SIZE = 5*8192;
41 
42 class K3bMad
43 {
44 public:
45 	K3bMad();
46 	~K3bMad();
47 
48 	bool open(const QString& filename);
49 
50 	/**
51 	 * @return true if the mad stream contains data
52 	 *         false if there is no data left or an error occurred.
53 	 *         In the latter case inputError() returns true.
54 	 */
55 	bool fillStreamBuffer();
56 
57 	/**
58 	 * Skip id3 tags.
59 	 *
60 	 * This will reset the input file.
61 	 */
62 	bool skipTag();
63 
64 	/**
65 	 * Find first frame and seek to the beginning of that frame.
66 	 * This is used to skip the junk that many mp3 files start with.
67 	 */
68 	bool seekFirstHeader();
69 
70 	bool eof() const;
71 	bool inputError() const;
72 
73 	/**
74 	 * Current position in theinput file. This does NOT
75 	 * care about the status of the mad stream. Use streamPos()
76 	 * in that case.
77 	 */
78 	qint64 inputPos() const;
79 
80 	/**
81 	 * Current absolut position of the decoder stream.
82 	 */
83 	qint64 streamPos() const;
84 	bool inputSeek(qint64 pos);
85 
86 	void initMad();
87 	void cleanup();
88 
89 	bool decodeNextFrame();
90 	bool findNextHeader();
91 	bool checkFrameHeader(mad_header* header) const;
92 
93 	void createInputBuffer();
94 	void clearInputBuffer();
95 
96 	mad_stream*   madStream;
97 	mad_frame*    madFrame;
98 	mad_synth*    madSynth;
99 	mad_timer_t*  madTimer;
100 
101 private:
102 	QFile m_inputFile;
103 	bool m_madStructuresInitialized;
104 	unsigned char* m_inputBuffer;
105 	bool m_bInputError;
106 
107 	int m_channels;
108 	int m_sampleRate;
109 };
110 
111 
K3bMad()112 K3bMad::K3bMad()
113   : m_madStructuresInitialized(false),
114     m_bInputError(false)
115 {
116 	madStream = new mad_stream;
117 	madFrame  = new mad_frame;
118 	madSynth  = new mad_synth;
119 	madTimer  = new mad_timer_t;
120 
121 	m_inputBuffer = 0;
122 }
123 
124 
~K3bMad()125 K3bMad::~K3bMad()
126 {
127 	cleanup();
128 
129 	delete madStream;
130 	delete madFrame;
131 	delete madSynth;
132 	delete madTimer;
133 
134 	clearInputBuffer();
135 }
136 
137 
createInputBuffer()138 void K3bMad::createInputBuffer()
139 {
140 	if (!m_inputBuffer) {
141 		//
142 		// we allocate additional MAD_BUFFER_GUARD bytes to always be able to append the
143 		// zero bytes needed for decoding the last frame.
144 		//
145 		m_inputBuffer = new unsigned char[INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD];
146 		memset(m_inputBuffer, 0, INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD);
147 	}
148 }
149 
150 
clearInputBuffer()151 void K3bMad::clearInputBuffer()
152 {
153 	if (m_inputBuffer) {
154 		delete [] m_inputBuffer;
155 		m_inputBuffer = 0;
156 	}
157 }
158 
159 
open(const QString & filename)160 bool K3bMad::open(const QString& filename)
161 {
162 	cleanup();
163 
164 	m_bInputError = false;
165 	m_channels = m_sampleRate = 0;
166 
167 	m_inputFile.setFileName(filename);
168 
169 	if (!m_inputFile.open(QIODevice::ReadOnly)) {
170 		PERROR("could not open file %s", QS_C(filename));
171 		return false;
172 	}
173 
174 	initMad();
175 
176 	return true;
177 }
178 
179 
inputError() const180 bool K3bMad::inputError() const
181 {
182 	return m_bInputError;
183 }
184 
185 
fillStreamBuffer()186 bool K3bMad::fillStreamBuffer()
187 {
188 	/* The input bucket must be filled if it becomes empty or if
189 	* it's the first execution of the loop.
190 	*/
191 	if (madStream->buffer == 0 || madStream->error == MAD_ERROR_BUFLEN) {
192 		if (eof()) {
193 			return false;
194 		}
195 
196 		if (!m_inputBuffer) {
197 			createInputBuffer();
198 		}
199 
200 		long readSize, remaining;
201 		unsigned char* readStart;
202 
203 		if (madStream->next_frame != 0) {
204 			remaining = madStream->bufend - madStream->next_frame;
205 			memmove(m_inputBuffer, madStream->next_frame, remaining);
206 			readStart = m_inputBuffer + remaining;
207 			readSize = INPUT_BUFFER_SIZE - remaining;
208 		}
209 		else {
210 			readSize  = INPUT_BUFFER_SIZE;
211 			readStart = m_inputBuffer;
212 			remaining = 0;
213 		}
214 
215 		// Fill-in the buffer.
216 		long result = m_inputFile.read((char*)readStart, readSize);
217 		if (result < 0) {
218 			//kdDebug() << "(K3bMad) read error on bitstream)" << endl;
219 			m_bInputError = true;
220 			return false;
221 		}
222 		else if (result == 0) {
223 			//kdDebug() << "(K3bMad) end of input stream" << endl;
224 			return false;
225 		}
226 		else {
227 			readStart += result;
228 
229 			if (eof()) {
230 				//kdDebug() << "(K3bMad::fillStreamBuffer) MAD_BUFFER_GUARD" << endl;
231 				memset(readStart, 0, MAD_BUFFER_GUARD);
232 				result += MAD_BUFFER_GUARD;
233 			}
234 
235 			// Pipe the new buffer content to libmad's stream decoder facility.
236 			mad_stream_buffer(madStream, m_inputBuffer, result + remaining);
237 			madStream->error = MAD_ERROR_NONE;
238 		}
239 	}
240 
241 	return true;
242 }
243 
244 
skipTag()245 bool K3bMad::skipTag()
246 {
247 	// skip the tag at the beginning of the file
248 	m_inputFile.seek(0);
249 
250 	//
251 	// now check if the file starts with an id3 tag and skip it if so
252 	//
253 	char buf[4096];
254 	int bufLen = 4096;
255 	if (m_inputFile.read(buf, bufLen) < bufLen) {
256 		//kdDebug() << "(K3bMad) unable to read " << bufLen << " bytes from "
257 		//	      << m_inputFile.name() << endl;
258 		return false;
259 	}
260 
261 	if ((buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') &&
262 	   ((unsigned short)buf[3] < 0xff && (unsigned short)buf[4] < 0xff)) {
263 		// do we have a footer?
264 		bool footer = (buf[5] & 0x10);
265 
266 		// the size is saved as a synched int meaning bit 7 is always cleared to 0
267 		unsigned int size =
268 			( (buf[6] & 0x7f) << 21 ) |
269 			( (buf[7] & 0x7f) << 14 ) |
270 			( (buf[8] & 0x7f) << 7) |
271 			(buf[9] & 0x7f);
272 		unsigned int offset = size + 10;
273 
274 		if (footer) {
275 			offset += 10;
276 		}
277 
278 		// skip the id3 tag
279 		if (!m_inputFile.seek(offset)) {
280 			PERROR("Couldn't seek to %u in %s", offset, QS_C(m_inputFile.fileName()));
281 			return false;
282 		}
283 	}
284 	else {
285 		// reset file
286 		return m_inputFile.seek(0);
287 	}
288 
289 	return true;
290 }
291 
292 
seekFirstHeader()293 bool K3bMad::seekFirstHeader()
294 {
295 	//
296 	// A lot of mp3 files start with a lot of junk which confuses mad.
297 	// We "allow" an mp3 file to start with at most 1 KB of junk. This is just
298 	// some random value since we do not want to search the hole file. That would
299 	// take way to long for non-mp3 files.
300 	//
301 	bool headerFound = findNextHeader();
302 	qint64 inputPos = streamPos();
303 	while (!headerFound &&
304 	   !m_inputFile.atEnd() &&
305 	   streamPos() <= inputPos+1024) {
306 		headerFound = findNextHeader();
307 	}
308 
309 	// seek back to the begin of the frame
310 	if (headerFound) {
311 		int streamSize = madStream->bufend - madStream->buffer;
312 		int bytesToFrame = madStream->this_frame - madStream->buffer;
313 		m_inputFile.seek(m_inputFile.pos() - streamSize + bytesToFrame);
314 
315 		//kdDebug() << "(K3bMad) found first header at " << m_inputFile.pos() << endl;
316 	}
317 
318 	// reset the stream to make sure mad really starts decoding at out seek position
319 	mad_stream_finish(madStream);
320 	mad_stream_init(madStream);
321 
322 	return headerFound;
323 }
324 
325 
eof() const326 bool K3bMad::eof() const
327 {
328 	return m_inputFile.atEnd();
329 }
330 
331 
inputPos() const332 qint64 K3bMad::inputPos() const
333 {
334 	return m_inputFile.pos();
335 }
336 
337 
streamPos() const338 qint64 K3bMad::streamPos() const
339 {
340 	return inputPos() - (madStream->bufend - madStream->this_frame + 1);
341 }
342 
343 
inputSeek(qint64 pos)344 bool K3bMad::inputSeek(qint64 pos)
345 {
346 	return m_inputFile.seek(pos);
347 }
348 
349 
initMad()350 void K3bMad::initMad()
351 {
352 	if (!m_madStructuresInitialized) {
353 		mad_stream_init(madStream);
354 		mad_timer_set(madTimer, 0, 0, 0);
355 		mad_frame_init(madFrame);
356 		mad_synth_init(madSynth);
357 
358 		m_madStructuresInitialized = true;
359 	}
360 }
361 
362 
cleanup()363 void K3bMad::cleanup()
364 {
365 	if (m_inputFile.isOpen()) {
366 		//kdDebug() << "(K3bMad) cleanup at offset: "
367 		//	      << "Input file at: " << m_inputFile.pos() << " "
368 		//	      << "Input file size: " << m_inputFile.size() << " "
369 		//	      << "stream pos: "
370 		//	      << ( m_inputFile.pos() - (madStream->bufend - madStream->this_frame + 1) )
371 		//	      << endl;
372 		m_inputFile.close();
373 	}
374 
375 	if (m_madStructuresInitialized) {
376 		mad_frame_finish(madFrame);
377 		mad_synth_finish(madSynth);
378 		mad_stream_finish(madStream);
379 	}
380 
381 	m_madStructuresInitialized = false;
382 }
383 
384 
385 //
386 // LOSTSYNC could happen when mad encounters the id3 tag...
387 //
findNextHeader()388 bool K3bMad::findNextHeader()
389 {
390 	if (!fillStreamBuffer()) {
391 		return false;
392 	}
393 
394 	//
395 	// MAD_RECOVERABLE == true:  frame was read, decoding failed (about to skip frame)
396 	// MAD_RECOVERABLE == false: frame was not read, need data
397 	//
398 
399 	if (mad_header_decode( &madFrame->header, madStream ) < 0) {
400 		if (MAD_RECOVERABLE(madStream->error) ||
401 		   madStream->error == MAD_ERROR_BUFLEN) {
402 			return findNextHeader();
403 		}
404 		else
405 		//      kdDebug() << "(K3bMad::findNextHeader) error: " << mad_stream_errorstr( madStream ) << endl;
406 
407 		// FIXME probably we should not do this here since we don't do it
408 		// in the frame decoding
409 		//     if(!checkFrameHeader(&madFrame->header))
410 		//       return findNextHeader();
411 
412 		return false;
413 	}
414 
415 	if (!m_channels) {
416 		m_channels = MAD_NCHANNELS(&madFrame->header);
417 		m_sampleRate = madFrame->header.samplerate;
418 	}
419 
420 	mad_timer_add(madTimer, madFrame->header.duration);
421 
422 	return true;
423 }
424 
425 
decodeNextFrame()426 bool K3bMad::decodeNextFrame()
427 {
428 	if (!fillStreamBuffer()) {
429 		return false;
430 	}
431 
432 	if (mad_frame_decode(madFrame, madStream) < 0) {
433 		if (MAD_RECOVERABLE(madStream->error) ||
434 		    madStream->error == MAD_ERROR_BUFLEN) {
435 			return decodeNextFrame();
436 		}
437 
438 		return false;
439 	}
440 
441 	if (!m_channels) {
442 		m_channels = MAD_NCHANNELS(&madFrame->header);
443 		m_sampleRate = madFrame->header.samplerate;
444 	}
445 
446 	mad_timer_add(madTimer, madFrame->header.duration);
447 
448 	return true;
449 }
450 
451 
452 //
453 // This is from the arts mad decoder
454 //
checkFrameHeader(mad_header * header) const455 bool K3bMad::checkFrameHeader(mad_header* header) const
456 {
457 	int frameSize = MAD_NSBSAMPLES(header) * 32;
458 
459 	if (frameSize <= 0) {
460 		return false;
461 	}
462 
463 	if (m_channels && m_channels != MAD_NCHANNELS(header)) {
464 		return false;
465 	}
466 
467 	return true;
468 }
469 
470 
471 
472 class MadAudioReader::MadDecoderPrivate
473 {
474 public:
MadDecoderPrivate()475 	MadDecoderPrivate()
476 	{
477 		outputBuffers = 0;
478 		outputPos = 0;
479 		outputSize = 0;
480 		overflowSize = 0;
481 		overflowStart = 0;
482 
483 		mad_header_init( &firstHeader );
484 	}
485 
486 	K3bMad* handle;
487 
488 	QVector<unsigned long long> seekPositions;
489 
490 	bool bOutputFinished;
491 
492 	audio_sample_t** outputBuffers;
493 	nframes_t	outputPos;
494 	nframes_t	outputSize;
495 
496 	audio_sample_t** overflowBuffers;
497 	nframes_t	overflowSize;
498 	nframes_t	overflowStart;
499 
500 	// the first frame header for technical info
501 	mad_header firstHeader;
502 	bool vbr;
503 };
504 
505 
MadAudioReader(QString filename)506 MadAudioReader::MadAudioReader(QString filename)
507  : AbstractAudioReader(filename)
508 {
509 	d = new MadDecoderPrivate();
510 	d->handle = new K3bMad();
511 
512 	initDecoderInternal();
513 
514 	m_nframes = countFrames();
515 
516 	switch( d->firstHeader.mode ) {
517 		case MAD_MODE_SINGLE_CHANNEL:
518 			m_channels = 1;
519 			break;
520 		case MAD_MODE_DUAL_CHANNEL:
521 		case MAD_MODE_JOINT_STEREO:
522 		case MAD_MODE_STEREO:
523 			m_channels = 2;
524 	}
525 
526 	if (m_nframes <= 0) {
527 		d->handle->cleanup();
528 		delete d->handle;
529 		delete d;
530 		d = 0;
531 		return;
532 	}
533 
534 	m_rate = d->firstHeader.samplerate;
535 	m_length = TimeRef(m_nframes, m_rate);
536 
537 	d->overflowBuffers = 0;
538 
539 	seek_private(0);
540 	clear_buffers();
541 }
542 
543 
~MadAudioReader()544 MadAudioReader::~MadAudioReader()
545 {
546 	if (d) {
547 		d->handle->cleanup();
548 		delete d->handle;
549 		clear_buffers();
550 		delete d;
551 	}
552 }
553 
554 
create_buffers()555 void MadAudioReader::create_buffers()
556 {
557 	if (!d->overflowBuffers) {
558 		d->overflowBuffers = new audio_sample_t*[m_channels];
559 		for (int chan = 0; chan < m_channels; chan++) {
560 			d->overflowBuffers[chan] = new audio_sample_t[1152];
561 		}
562 	}
563 }
564 
565 
clear_buffers()566 void MadAudioReader::clear_buffers()
567 {
568 	if (d->overflowBuffers) {
569 		for (int chan = 0; chan < m_channels; chan++) {
570 			delete [] d->overflowBuffers[chan];
571 		}
572 		delete [] d->overflowBuffers;
573 		d->overflowBuffers = 0;
574 		d->overflowStart = 0;
575 		d->overflowSize = 0;
576 	}
577 
578 	if (d && d->handle) {
579 		d->handle->clearInputBuffer();
580 	}
581 }
582 
583 
can_decode(QString filename)584 bool MadAudioReader::can_decode(QString filename)
585 {
586 	if (!libmad_is_present) {
587 		return false;
588 	}
589 
590 	//
591 	// HACK:
592 	//
593 	// I am simply no good at this and this detection code is no good as well
594 	// It always takes waves for mp3 files so we introduce this hack to
595 	// filter out wave files. :(
596 	//
597 	QFile f(filename);
598 	if (!f.open( QIODevice::ReadOnly)) {
599 		return false;
600 	}
601 
602 	char buffer[12];
603 	if (f.read(buffer, 12) != 12) {
604 		return false;
605 	}
606 	if (!qstrncmp(buffer, "RIFF", 4) && !qstrncmp(buffer + 8, "WAVE", 4)) {
607 		return false;
608 	}
609 	f.close();
610 
611 
612 	K3bMad handle;
613 	if (!handle.open(filename)) {
614 		return false;
615 	}
616 	handle.skipTag();
617 	if (!handle.seekFirstHeader()) {
618 		return false;
619 	}
620 	if (handle.findNextHeader()) {
621 		int c = MAD_NCHANNELS(&handle.madFrame->header);
622 		int layer = handle.madFrame->header.layer;
623 		unsigned int s = handle.madFrame->header.samplerate;
624 
625 		//
626 		// find 4 more mp3 headers (random value since 2 was not enough)
627 		// This way we get most of the mp3 files while sorting out
628 		// for example wave files.
629 		//
630 		int cnt = 1;
631 		while (handle.findNextHeader()) {
632 			// compare the found headers
633 			if (MAD_NCHANNELS(&handle.madFrame->header) == c &&
634 			    handle.madFrame->header.layer == layer &&
635 			    handle.madFrame->header.samplerate == s) {
636 				// only support layer III for now since otherwise some wave files
637 				// are taken for layer I
638 				if (++cnt >= 5) {
639 					//stdout << "(MadDecoder) valid mpeg 1 layer " << layer
640 					//<< " file with " << c << " channels and a samplerate of "
641 					//<< s << endl;
642 					return (layer == MAD_LAYER_III);
643 				}
644 			}
645 			else {
646 				break;
647 			}
648 		}
649 	}
650 
651 	//PERROR("unsupported format: %s",QS_C(filename));
652 
653 	return false;
654 }
655 
656 
seek_private(nframes_t start)657 bool MadAudioReader::seek_private(nframes_t start)
658 {
659 	Q_ASSERT(d);
660 
661 	if (start >= m_nframes) {
662 		return false;
663 	}
664 
665 	//
666 	// we need to reset the complete mad stuff
667 	//
668 	if (!initDecoderInternal()) {
669 		return false;
670 	}
671 
672 	//
673 	// search a position
674 	// This is all hacking, I don't really know what I am doing here... ;)
675 	//
676 	double mp3FrameSecs = static_cast<double>(d->firstHeader.duration.seconds) + static_cast<double>(d->firstHeader.duration.fraction) / static_cast<double>(MAD_TIMER_RESOLUTION);
677 
678 	double posSecs = static_cast<double>(start) / m_rate;
679 
680 	// seekPosition to seek after frame i
681 	unsigned int frame = static_cast<unsigned int>(posSecs / mp3FrameSecs);
682 	nframes_t frameOffset = (nframes_t)(start - (frame * mp3FrameSecs * m_rate + 0.5));
683 
684 	// K3b source: Rob said: 29 frames is the theoretically max frame reservoir limit
685 	// (whatever that means...) it seems that mad needs at most 29 frames to get ready
686 	//
687 	// Ben says: It looks like Rob (the author of MAD) implies here:
688 	//    http://www.mars.org/mailman/public/mad-dev/2001-August/000321.html
689 	// that 3 frames (1 + 2 extra) is enough... much faster, and seems to work fine...
690 	unsigned int frameReservoirProtect = (frame > 3 ? 3 : frame);
691 
692 	frame -= frameReservoirProtect;
693 
694 	// seek in the input file behind the already decoded data
695 	d->handle->inputSeek( d->seekPositions[frame] );
696 
697 	// decode some frames ignoring MAD_ERROR_BADDATAPTR errors
698 	unsigned int i = 1;
699 	while (i <= frameReservoirProtect) {
700 		d->handle->fillStreamBuffer();
701 		if (mad_frame_decode( d->handle->madFrame, d->handle->madStream)) {
702 			if (MAD_RECOVERABLE( d->handle->madStream->error)) {
703 				if (d->handle->madStream->error == MAD_ERROR_BUFLEN) {
704 					continue;
705 				}
706 				else if (d->handle->madStream->error != MAD_ERROR_BADDATAPTR) {
707 					//kdDebug() << "(K3bMadDecoder) Seeking: recoverable mad error ("
708 					//<< mad_stream_errorstr(d->handle->madStream) << ")" << endl;
709 					continue;
710 				}
711 				else {
712 					//kdDebug() << "(K3bMadDecoder) Seeking: ignoring ("
713 					//<< mad_stream_errorstr(d->handle->madStream) << ")" << endl;
714 				}
715 			}
716 			else {
717 				return false;
718 			}
719 		}
720 
721 		if (i == frameReservoirProtect) {  // synth only the last frame (Rob said so ;)
722 			mad_synth_frame( d->handle->madSynth, d->handle->madFrame );
723 		}
724 
725 		++i;
726 	}
727 
728 	d->overflowStart = 0;
729 	d->overflowSize = 0;
730 
731 	// Seek to exact traverso frame, within this mp3 frame
732 	if (frameOffset > 0) {
733 		//printf("seekOffset: %lu (start: %lu)\n", frameOffset, start);
734 		d->outputBuffers = 0; // Zeros so that we write to overflow
735 		d->outputSize = 0;
736 		d->outputPos = 0;
737 		createPcmSamples(d->handle->madSynth);
738 		d->overflowStart = frameOffset;
739 		d->overflowSize -= frameOffset;
740 	}
741 
742 	return true;
743 }
744 
745 
initDecoderInternal()746 bool MadAudioReader::initDecoderInternal()
747 {
748 	d->handle->cleanup();
749 
750 	d->bOutputFinished = false;
751 
752 	if (!d->handle->open(m_fileName)) {
753 		return false;
754 	}
755 
756 	if (!d->handle->skipTag()) {
757 		return false;
758 	}
759 
760 	if (!d->handle->seekFirstHeader()) {
761 		return false;
762 	}
763 
764 	return true;
765 }
766 
767 
countFrames()768 unsigned long MadAudioReader::countFrames()
769 {
770 	unsigned long frames = 0;
771 	bool error = false;
772 	d->vbr = false;
773 	bool bFirstHeaderSaved = false;
774 
775 	d->seekPositions.clear();
776 
777 	while (!error && d->handle->findNextHeader()) {
778 		if (!bFirstHeaderSaved) {
779 			bFirstHeaderSaved = true;
780 			d->firstHeader = d->handle->madFrame->header;
781 		}
782 		else if (d->handle->madFrame->header.bitrate != d->firstHeader.bitrate) {
783 			d->vbr = true;
784 		}
785 		//
786 		// position in stream: position in file minus the not yet used buffer
787 		//
788 		unsigned long long seekPos = d->handle->inputPos() -
789 		(d->handle->madStream->bufend - d->handle->madStream->this_frame + 1);
790 
791 		// save the number of bytes to be read to decode i-1 frames at position i
792 		// in other words: when seeking to seekPos the next decoded frame will be i
793 		d->seekPositions.append(seekPos);
794 	}
795 
796 	if (!d->handle->inputError() && !error) {
797 		frames =  d->firstHeader.samplerate * (d->handle->madTimer->seconds + (unsigned long)(
798 			(float)d->handle->madTimer->fraction/(float)MAD_TIMER_RESOLUTION));
799 	}
800 
801 	d->handle->cleanup();
802 
803 	return frames;
804 }
805 
806 
read_private(DecodeBuffer * buffer,nframes_t frameCount)807 nframes_t MadAudioReader::read_private(DecodeBuffer* buffer, nframes_t frameCount)
808 {
809 	d->outputBuffers = buffer->destination;
810 	d->outputSize = frameCount;
811 	d->outputPos = 0;
812 
813 	bool bOutputBufferFull = false;
814 
815 	// Deal with existing overflow
816 	if (d->overflowSize > 0) {
817 		if (d->overflowSize < frameCount) {
818 			//printf("output all %d overflow samples\n", d->overflowSize);
819 			for (int chan = 0; chan < m_channels; chan++) {
820 				memcpy(d->outputBuffers[chan], d->overflowBuffers[chan] + d->overflowStart, d->overflowSize * sizeof(audio_sample_t));
821 			}
822 			d->outputPos += d->overflowSize;
823 			d->overflowSize = 0;
824 			d->overflowStart = 0;
825 		}
826 		else {
827 			//printf("output %d overflow frames, returned from overflow\n", frameCount);
828 			for (int chan = 0; chan < m_channels; chan++) {
829 				memcpy(d->outputBuffers[chan], d->overflowBuffers[chan] + d->overflowStart, frameCount * sizeof(audio_sample_t));
830 			}
831 			d->overflowSize -= frameCount;
832 			d->overflowStart += frameCount;
833 			return frameCount;
834 		}
835 	}
836 
837 	while (!bOutputBufferFull && d->handle->fillStreamBuffer()) {
838 		// a mad_synth contains of the data of one mad_frame
839 		// one mad_frame represents a mp3-frame which is always 1152 samples
840 		// for us that means we need 1152 samples per channel of output buffer
841 		// for every frame
842 		if (d->outputPos >= d->outputSize) {
843 			bOutputBufferFull = true;
844 		}
845 		else if (d->handle->decodeNextFrame()) {
846 			//
847 			// Once decoded the frame is synthesized to PCM samples. No errors
848 			// are reported by mad_synth_frame();
849 			//
850 			mad_synth_frame( d->handle->madSynth, d->handle->madFrame );
851 
852 			// this fills the output buffer
853 			if (!createPcmSamples(d->handle->madSynth)) {
854 				PERROR("createPcmSamples");
855 				return 0;
856 			}
857 		}
858 		else if (d->handle->inputError()) {
859 			PERROR("inputError");
860 			return 0;
861 		}
862 	}
863 
864 	nframes_t framesWritten = d->outputPos;
865 
866 	return framesWritten;
867 }
868 
869 
createPcmSamples(mad_synth * synth)870 bool MadAudioReader::createPcmSamples(mad_synth* synth)
871 {
872 	audio_sample_t	**writeBuffers = d->outputBuffers;
873 	int		offset = d->outputPos;
874 	nframes_t	nframes = synth->pcm.length;
875 	bool		overflow = false;
876 	nframes_t	i;
877 
878 	if (!d->overflowBuffers) {
879 		create_buffers();
880 	}
881 
882 	if (writeBuffers && (m_readPos + d->outputPos + nframes) > m_nframes) {
883 		nframes = m_nframes - (m_readPos + offset);
884 	}
885 
886 	// now create the output
887 	for (i = 0; i < nframes; i++) {
888 		if (overflow == false && d->outputPos + i >= d->outputSize) {
889 			writeBuffers = d->overflowBuffers;
890 			offset = 0 - i;
891 			overflow = true;
892 		}
893 
894 		/* Left channel */
895 		writeBuffers[0][offset + i] = mad_f_todouble(synth->pcm.samples[0][i]);
896 
897 		/* Right channel. If the decoded stream is monophonic then no right channel
898 		*/
899 		if (synth->pcm.channels == 2) {
900 			writeBuffers[1][offset + i] = mad_f_todouble(synth->pcm.samples[1][i]);
901 		}
902 	} // pcm conversion
903 
904 	if (overflow) {
905 		d->overflowSize = i + offset;
906 		d->overflowStart = 0;
907 		d->outputPos -= offset; // i was stored here when we switched to writing to overflow
908 		//printf("written: %d (overflow: %u)\n",  nframes - d->overflowSize, d->overflowSize);
909 	}
910 	else {
911 		d->outputPos += i;
912 		//printf("written: %d (os=%lu)\n",  i, d->overflowSize);
913 	}
914 
915 	return true;
916 }
917 
918 
919