|
CLAM-Development
1.3
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "MpegBitstream.hxx" 00023 #include "Assert.hxx" 00024 #include <cstring> 00025 #include <iostream> 00026 #include <sstream> 00027 #include <iomanip> 00028 00029 namespace CLAM 00030 { 00031 00032 namespace AudioCodecs 00033 { 00034 // MRJ: This number was extracted from Underbit's own 00035 // mp3 player code ( mad-0.14.2b2, player.c:86 ). As they 00036 // say: 40000 bytes is worth 2.5 secs of audio on a stream 00037 // with 128 kpbs, 1s with 320 kbps 00038 const int MpegBitstream::mInputBufferSize = 5*8192; 00039 00040 // Taken from alsaplayer 00041 static std::string MadError(enum mad_error error) 00042 { 00043 switch (error) { 00044 case MAD_ERROR_BUFLEN: 00045 case MAD_ERROR_BUFPTR: 00046 /* these errors are handled specially and/or should not occur */ 00047 break; 00048 00049 case MAD_ERROR_NOMEM: return ("not enough memory"); 00050 case MAD_ERROR_LOSTSYNC: return ("lost synchronization"); 00051 case MAD_ERROR_BADLAYER: return ("reserved header layer value"); 00052 case MAD_ERROR_BADBITRATE: return ("forbidden bitrate value"); 00053 case MAD_ERROR_BADSAMPLERATE: return ("reserved sample frequency value"); 00054 case MAD_ERROR_BADEMPHASIS: return ("reserved emphasis value"); 00055 case MAD_ERROR_BADCRC: return ("CRC check failed"); 00056 case MAD_ERROR_BADBITALLOC: return ("forbidden bit allocation value"); 00057 case MAD_ERROR_BADSCALEFACTOR: return ("bad scalefactor index"); 00058 case MAD_ERROR_BADFRAMELEN: return ("bad frame length"); 00059 case MAD_ERROR_BADBIGVALUES: return ("bad big_values count"); 00060 case MAD_ERROR_BADBLOCKTYPE: return ("reserved block_type"); 00061 case MAD_ERROR_BADSCFSI: return ("bad scalefactor selection info"); 00062 case MAD_ERROR_BADDATAPTR: return ("bad main_data_begin pointer"); 00063 case MAD_ERROR_BADPART3LEN: return ("bad audio data length"); 00064 case MAD_ERROR_BADHUFFTABLE: return ("bad Huffman table select"); 00065 case MAD_ERROR_BADHUFFDATA: return ("Huffman data overrun"); 00066 case MAD_ERROR_BADSTEREO: return ("incompatible block_type for JS"); 00067 default:; 00068 } 00069 std::ostringstream os; 00070 os << "error 0x" << std::setbase(16) << std::setfill('4') << std::setw(4) << error; 00071 return os.str(); 00072 } 00073 00074 MpegBitstream::MpegBitstream() 00075 : mpFile(NULL) 00076 { 00077 mInputBuffer = new unsigned char[mInputBufferSize]; 00078 } 00079 00080 MpegBitstream::~MpegBitstream() 00081 { 00082 if ( mInputBuffer ) 00083 delete [] mInputBuffer; 00084 } 00085 00086 void MpegBitstream::Init( FILE* fp ) 00087 { 00088 mpFile = fp; 00089 Init(); 00090 } 00091 00092 void MpegBitstream::Init() 00093 { 00094 mad_stream_init( &mBitstream ); 00095 mad_frame_init( &mCurrentFrame ); 00096 mad_synth_init( &mMpegSynth ); 00097 mad_timer_reset( &mStreamTimer ); 00098 mFatalError = false; 00099 } 00100 00101 TTime MpegBitstream::Finish() 00102 { 00103 mad_synth_finish( &mMpegSynth ); 00104 mad_frame_finish( &mCurrentFrame ); 00105 mad_stream_finish( &mBitstream ); 00106 00107 return (TTime)mad_timer_count( mStreamTimer, MAD_UNITS_MILLISECONDS ); 00108 } 00109 00110 bool MpegBitstream::EOS() 00111 { 00112 if ( feof( mpFile ) ) // no more frames 00113 return true; 00114 return false; 00115 } 00116 00117 bool MpegBitstream::FatalError() 00118 { 00119 return mFatalError || ferror(mpFile)!=0; 00120 } 00121 00122 bool MpegBitstream::EnsureEnoughBufferData() 00123 { 00124 bool firstFrameAfterSeek = mBitstream.buffer == NULL; 00125 bool lastDecodeNeededMoreData = mBitstream.error == MAD_ERROR_BUFLEN; 00126 if ( not firstFrameAfterSeek and not lastDecodeNeededMoreData) return true; 00127 00128 TSize remaining = 0; 00129 if (not firstFrameAfterSeek) 00130 { 00131 remaining = mBitstream.bufend - mBitstream.next_frame; 00132 memmove( mInputBuffer, mBitstream.next_frame, remaining ); 00133 } 00134 unsigned char * readStart = mInputBuffer + remaining; 00135 TSize readSize = mInputBufferSize - remaining; 00136 mBufferFileOffset = ftell(mpFile) - remaining; 00137 TSize actuallyRead = fread( readStart, sizeof(unsigned char), readSize, mpFile ); 00138 00139 if ( actuallyRead == 0 ) return false; // Eof or ferror 00140 // Less bytes than expected were read, add buffer guard 00141 if ( actuallyRead < readSize ) 00142 { 00143 CLAM_ASSERT( readStart + actuallyRead + MAD_BUFFER_GUARD <= mInputBuffer + mInputBufferSize, 00144 "Whoops! no room left for buffer guard bytes" ); 00145 // Add mad buffer guard 00146 memset(readStart+actuallyRead, 0, MAD_BUFFER_GUARD); 00147 actuallyRead += MAD_BUFFER_GUARD; 00148 } 00149 00150 mad_stream_buffer( &mBitstream, mInputBuffer, actuallyRead+remaining ); 00151 mBitstream.error = MAD_ERROR_NONE; // DGG: Why that? 00152 return true; 00153 } 00154 00157 bool MpegBitstream::NextFrame() 00158 { 00159 while( not ferror(mpFile) ) 00160 { 00161 if (not EnsureEnoughBufferData()) return false; 00162 00163 int error = mad_frame_decode(&mCurrentFrame, &mBitstream); 00164 if (error != -1) 00165 { 00166 // frame was decoded right 00167 // we add this frame duration to the bitstream internal timer 00168 mad_timer_add( &mStreamTimer, mCurrentFrame.header.duration ); 00169 return true; 00170 } 00171 00172 if ( MAD_RECOVERABLE( mBitstream.error ) ) 00173 { 00174 // std::cerr << "MP3 recoverable error ignored: " << MadError(mBitstream.error) << std::endl; 00175 continue; // Recoverable error, ignore 00176 } 00177 if ( mBitstream.error == MAD_ERROR_BUFLEN ) continue; // Not enough data, take more 00178 // Some fatal error happened! 00179 mFatalError = true; 00180 std::cerr << "MP3 fatal error: " << MadError(mBitstream.error) << std::endl; 00181 return false; 00182 } 00183 return false; // file error 00184 } 00185 00186 unsigned long MpegBitstream::CurrentFrameFileOffset() const 00187 { 00188 unsigned long frameOffset = mBitstream.this_frame - mInputBuffer; 00189 return mBufferFileOffset + frameOffset; 00190 } 00191 00192 void MpegBitstream::SynthesizeCurrent() 00193 { 00194 mad_synth_frame( &mMpegSynth, &mCurrentFrame ); 00195 } 00196 00197 struct mad_frame& MpegBitstream::CurrentFrame() 00198 { 00199 return mCurrentFrame; 00200 } 00201 00202 struct mad_synth& MpegBitstream::CurrentSynthesis() 00203 { 00204 return mMpegSynth; 00205 } 00206 00207 } 00208 00209 } 00210
1.7.6.1