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