38 const int MpegBitstream::mInputBufferSize = 5*8192;
41 static std::string
MadError(
enum mad_error error)
44 case MAD_ERROR_BUFLEN:
45 case MAD_ERROR_BUFPTR:
49 case MAD_ERROR_NOMEM:
return (
"not enough memory");
50 case MAD_ERROR_LOSTSYNC:
return (
"lost synchronization");
51 case MAD_ERROR_BADLAYER:
return (
"reserved header layer value");
52 case MAD_ERROR_BADBITRATE:
return (
"forbidden bitrate value");
53 case MAD_ERROR_BADSAMPLERATE:
return (
"reserved sample frequency value");
54 case MAD_ERROR_BADEMPHASIS:
return (
"reserved emphasis value");
55 case MAD_ERROR_BADCRC:
return (
"CRC check failed");
56 case MAD_ERROR_BADBITALLOC:
return (
"forbidden bit allocation value");
57 case MAD_ERROR_BADSCALEFACTOR:
return (
"bad scalefactor index");
58 case MAD_ERROR_BADFRAMELEN:
return (
"bad frame length");
59 case MAD_ERROR_BADBIGVALUES:
return (
"bad big_values count");
60 case MAD_ERROR_BADBLOCKTYPE:
return (
"reserved block_type");
61 case MAD_ERROR_BADSCFSI:
return (
"bad scalefactor selection info");
62 case MAD_ERROR_BADDATAPTR:
return (
"bad main_data_begin pointer");
63 case MAD_ERROR_BADPART3LEN:
return (
"bad audio data length");
64 case MAD_ERROR_BADHUFFTABLE:
return (
"bad Huffman table select");
65 case MAD_ERROR_BADHUFFDATA:
return (
"Huffman data overrun");
66 case MAD_ERROR_BADSTEREO:
return (
"incompatible block_type for JS");
69 std::ostringstream os;
70 os <<
"error 0x" << std::setbase(16) << std::setfill(
'4') << std::setw(4) << error;
77 mInputBuffer =
new unsigned char[mInputBufferSize];
83 delete [] mInputBuffer;
94 mad_stream_init( &mBitstream );
95 mad_frame_init( &mCurrentFrame );
96 mad_synth_init( &mMpegSynth );
97 mad_timer_reset( &mStreamTimer );
103 mad_synth_finish( &mMpegSynth );
104 mad_frame_finish( &mCurrentFrame );
105 mad_stream_finish( &mBitstream );
107 return (
TTime)mad_timer_count( mStreamTimer, MAD_UNITS_MILLISECONDS );
112 if ( feof( mpFile ) )
119 return mFatalError || ferror(mpFile)!=0;
124 bool firstFrameAfterSeek = mBitstream.buffer ==
NULL;
125 bool lastDecodeNeededMoreData = mBitstream.error == MAD_ERROR_BUFLEN;
126 if ( not firstFrameAfterSeek and not lastDecodeNeededMoreData)
return true;
129 if (not firstFrameAfterSeek)
131 remaining = mBitstream.bufend - mBitstream.next_frame;
132 memmove( mInputBuffer, mBitstream.next_frame, remaining );
134 unsigned char * readStart = mInputBuffer + remaining;
135 TSize readSize = mInputBufferSize - remaining;
136 mBufferFileOffset = ftell(mpFile) - remaining;
137 TSize actuallyRead = fread( readStart,
sizeof(
unsigned char), readSize, mpFile );
139 if ( actuallyRead == 0 )
return false;
141 if ( actuallyRead < readSize )
143 CLAM_ASSERT( readStart + actuallyRead + MAD_BUFFER_GUARD <= mInputBuffer + mInputBufferSize,
144 "Whoops! no room left for buffer guard bytes" );
146 memset(readStart+actuallyRead, 0, MAD_BUFFER_GUARD);
147 actuallyRead += MAD_BUFFER_GUARD;
150 mad_stream_buffer( &mBitstream, mInputBuffer, actuallyRead+remaining );
151 mBitstream.error = MAD_ERROR_NONE;
159 while( not ferror(mpFile) )
163 int error = mad_frame_decode(&mCurrentFrame, &mBitstream);
168 mad_timer_add( &mStreamTimer, mCurrentFrame.header.duration );
172 if ( MAD_RECOVERABLE( mBitstream.error ) )
177 if ( mBitstream.error == MAD_ERROR_BUFLEN )
continue;
180 std::cerr <<
"MP3 fatal error: " <<
MadError(mBitstream.error) << std::endl;
188 unsigned long frameOffset = mBitstream.this_frame - mInputBuffer;
189 return mBufferFileOffset + frameOffset;
194 mad_synth_frame( &mMpegSynth, &mCurrentFrame );
199 return mCurrentFrame;