MP3Parser.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: MP3Parser.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #include "MP3Parser.hpp" 00045 00046 #define readMarkerBit() readMarkerBitFunc(__LINE__) 00047 00048 // Table 6-3: Start code values 00049 #define MPEG_AUDIO_HEADER_START_CODE 0xFFF 00050 00051 static u32 __inline 00052 log2bin(u32 value) 00053 { 00054 /* Changed by Chenm001 */ 00055 // #if !defined(_MSC_VER) 00056 int n = 0; 00057 00058 while (value) { 00059 value >>= 1; 00060 n++; 00061 } 00062 return n; 00063 /* 00064 #else 00065 __asm { 00066 bsr eax, value 00067 inc eax 00068 } 00069 #endif 00070 */ 00071 } 00072 00073 MP3Parser::MP3Parser() { 00074 } 00075 00076 00077 MP3Parser::~MP3Parser() { 00078 } 00079 00080 00081 structMPEGaudioHeader MP3Parser::parseMPEGaudioHeader(u8 * pFrame, u32 iSize) { 00082 initializeMPEGaudioHeaderStruct(); 00083 initializeParser((u8 *) pFrame, iSize); 00084 00085 int offset = 0, num_channels = 2; 00086 if (getBits(11) == 0x07FF) 00087 { 00088 mp3Header.frame_sync = 0x07FF; 00089 mp3Header.mpeg_audio_version_ID = (MpegAudioVersionID)getBits(2); 00090 mp3Header.mpeg_audio_layer_no = (MpegAudioLayerNo)getBits(2); 00091 mp3Header.protection = getBits(1); 00092 switch(mp3Header.mpeg_audio_version_ID) { 00093 case MPEG_VERSION_2: 00094 switch(mp3Header.mpeg_audio_layer_no) { 00095 case LAYER_III: 00096 case LAYER_II : offset = 64; break; 00097 case LAYER_I : offset = 48; break; 00098 default : offset = 64; 00099 }; 00100 break; 00101 case MPEG_VERSION_1: 00102 switch(mp3Header.mpeg_audio_layer_no) { 00103 case LAYER_III: offset = 32; break; 00104 case LAYER_II : offset = 16; break; 00105 case LAYER_I : offset = 0; break; 00106 default : offset = 32; 00107 }; 00108 break; 00109 default: offset = 64; 00110 }; 00111 mp3Header.bitrate = mp3Header.mpeg_audio_bitrate_index_table[offset + getBits(4)]; 00112 switch(mp3Header.mpeg_audio_version_ID) { 00113 case MPEG_VERSION_2: 00114 offset = 4; break; 00115 case MPEG_VERSION_1: 00116 offset = 0; break; 00117 case MPEG_VESION_2_5: 00118 offset = 8; break; 00119 default: offset = 4; 00120 }; 00121 mp3Header.sampling_rate = mp3Header.mpeg_audio_sampling_rate_index_table[offset + getBits(2)]; 00122 mp3Header.padding = getBits(1); 00123 mp3Header.private_bit = getBits(1); 00124 mp3Header.channel_mod = (ChannelMod)getBits(2); 00125 mp3Header.mode_extension = getBits(2); 00126 mp3Header.copyright = getBits(1); 00127 mp3Header.original = getBits(1); 00128 mp3Header.emphasis = (Emphasis)getBits(2); 00129 00130 switch(mp3Header.mpeg_audio_layer_no) { 00131 case LAYER_I : 00132 mp3Header.frame_size_in_bytes = (12 * mp3Header.bitrate*1000 / mp3Header.sampling_rate + mp3Header.padding) * 4; 00133 break; 00134 case LAYER_II : 00135 case LAYER_III: 00136 mp3Header.frame_size_in_bytes = 144 * mp3Header.bitrate*1000 / mp3Header.sampling_rate + mp3Header.padding; 00137 break; 00138 default: 00139 mp3Header.frame_size_in_bytes = 418; 00140 }; 00141 00142 if(mp3Header.channel_mod == 3) 00143 num_channels = 1; 00144 else 00145 num_channels = 2; 00146 /* bits per sample is calculated as: 00147 * (uncompressed frame_size_in_bits)/(num of samples per frame*num_channels); 00148 * where frame_size_in_bits = 4608*8 for each wav frame 00149 */ 00150 switch(mp3Header.mpeg_audio_version_ID) { 00151 case MPEG_VERSION_2: 00152 switch(mp3Header.mpeg_audio_layer_no) { 00153 case LAYER_III: mp3Header.frame_duration = (576*90000)/mp3Header.sampling_rate; 00154 mp3Header.bits_per_sample = (36864)/(576*num_channels); break; 00155 case LAYER_II : mp3Header.frame_duration = (1152*90000)/mp3Header.sampling_rate; 00156 mp3Header.bits_per_sample = (36864)/(1152*num_channels); break; 00157 case LAYER_I : mp3Header.frame_duration = (192*90000)/mp3Header.sampling_rate; 00158 mp3Header.bits_per_sample = (36864)/(192*num_channels); break; 00159 default : mp3Header.frame_duration = (576*90000)/mp3Header.sampling_rate; 00160 mp3Header.bits_per_sample = (36864)/(576*num_channels); break; 00161 }; 00162 break; 00163 case MPEG_VERSION_1: 00164 switch(mp3Header.mpeg_audio_layer_no) { 00165 case LAYER_III: mp3Header.frame_duration = (1152*90000)/mp3Header.sampling_rate; 00166 mp3Header.bits_per_sample = (36864)/(1152*num_channels); break; 00167 case LAYER_II : mp3Header.frame_duration = (1152*90000)/mp3Header.sampling_rate; 00168 mp3Header.bits_per_sample = (36864)/(1152*num_channels); break; 00169 case LAYER_I : mp3Header.frame_duration = (384*90000)/mp3Header.sampling_rate; 00170 mp3Header.bits_per_sample = (36864)/(384*num_channels); break; 00171 default : mp3Header.frame_duration = (1152*90000)/mp3Header.sampling_rate; 00172 mp3Header.bits_per_sample = (36864)/(1152*num_channels); break; 00173 }; 00174 break; 00175 default: mp3Header.frame_duration = (1152*90000)/mp3Header.sampling_rate; break; 00176 mp3Header.bits_per_sample = (36864)/(1152*num_channels); break; 00177 }; 00178 00179 00180 } 00181 else 00182 { 00183 return mp3Header; 00184 } 00185 return mp3Header; 00186 } 00187 00188 00189 void MP3Parser::initializeParser(u8 * pFrame, u32 iSize) { 00190 mcByte = 0; 00191 if (pFrame != NULL) 00192 { 00193 mpcData = pFrame; 00194 miSize = iSize; 00195 00196 00197 /* 00198 u8 * bla = new u8[miSize*2+1]; 00199 ISOMP4ContainerFile::encodeDecoderConfig(bla, mpcData, miSize); 00200 dprintf("---Decoder %s\n", bla); 00201 fflush(stdout); 00202 fflush(stderr); 00203 */ 00204 } 00205 00206 else 00207 { 00208 mpcData = NULL; 00209 miSize = 0; 00210 } 00211 mbEOD = false; 00212 miCurrentNoBytes = 0; 00213 miCurrentBit = -1; 00214 } 00215 00216 00217 void MP3Parser::initializeMPEGaudioHeaderStruct() { 00218 unsigned int mpeg_audio_bitrate_index_table[80] = { 00219 1,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0, 00220 1,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0, 00221 1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0, 00222 1,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0, 00223 1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0 00224 }; 00225 00226 unsigned int mpeg_audio_sampling_rate_index_table[12] = { 00227 44100, 48000, 32000, 0, 00228 22050, 24000, 16000, 0, 00229 11025, 12000, 8000, 0 00230 }; 00231 00232 mp3Header.frame_sync = 0; 00233 mp3Header.mpeg_audio_version_ID = MPEG_VERSION_2; 00234 mp3Header.mpeg_audio_layer_no = LAYER_III; 00235 mp3Header.protection = 1; 00236 mp3Header.bitrate = 0; 00237 mp3Header.sampling_rate = 44100; 00238 mp3Header.padding = 0; 00239 mp3Header.frame_size_in_bytes = 0; 00240 mp3Header.private_bit = 0; 00241 mp3Header.channel_mod = STEREO; 00242 mp3Header.mode_extension = 0; 00243 mp3Header.copyright = 0; 00244 mp3Header.original = 0; 00245 mp3Header.emphasis = NONE_; 00246 mp3Header.bits_per_sample = 16; 00247 00248 memcpy(mp3Header.mpeg_audio_bitrate_index_table, mpeg_audio_bitrate_index_table, 00249 sizeof(mp3Header.mpeg_audio_bitrate_index_table)); 00250 memcpy(mp3Header.mpeg_audio_sampling_rate_index_table, mpeg_audio_sampling_rate_index_table, 00251 sizeof(mp3Header.mpeg_audio_sampling_rate_index_table)); 00252 } 00253 00254 00255 void MP3Parser::nextByte() { 00256 mcByte = mpcData[miCurrentNoBytes]; 00257 miCurrentBit = 7; 00258 miCurrentNoBytes++; 00259 if (miCurrentNoBytes > miSize) 00260 mbEOD = true; 00261 } 00262 00263 00264 bool MP3Parser::bytealigned() { 00265 if (miCurrentBit == 7) 00266 return true; 00267 00268 else 00269 { 00270 nextByte(); 00271 return true; 00272 } 00273 } 00274 00275 00276 int MP3Parser::getBit() { 00277 int ret = 0; 00278 if (miCurrentBit == -1) 00279 nextByte(); 00280 ret = (mcByte >> miCurrentBit) & 0x01; 00281 miCurrentBit--; 00282 if (mbEOD == false) 00283 return ret; 00284 00285 else 00286 return EOF; 00287 } 00288 00289 00290 int MP3Parser::getBits(int iNumber) { 00291 int ret = 0; 00292 int i; 00293 for (i = 0; i < iNumber; i++) 00294 ret = (ret << 1) | getBit(); 00295 if (mbEOD == false) 00296 return ret; 00297 00298 else 00299 return EOF; 00300 } 00301 00302 00303 int MP3Parser::nextBits(int noBits) { 00304 int ret = 0; 00305 bookmark(); 00306 ret = getBits(32); 00307 restore(); 00308 if (mbEOD == false) 00309 return ret; 00310 00311 else 00312 return EOF; 00313 } 00314 00315 00316 void MP3Parser::nextStartCode() { 00317 while (!bytealigned()) 00318 getBit(); 00319 } 00320 00321 00322 void MP3Parser::loadQuantizerMatrix(unsigned int puiMatrix[]) { 00323 int i; // row counter 00324 int j; // column counter 00325 int lastValue = 0; 00326 bool readLastValue = false; 00327 for (i = 0; i < 8; i++) 00328 { 00329 for (j = 0; j < 8; j++) 00330 { 00331 if (!readLastValue) 00332 { 00333 puiMatrix[j + i * 8] = getBits(8); 00334 if (puiMatrix[j + i * 8] == 0) 00335 readLastValue = true; 00336 00337 else 00338 lastValue = puiMatrix[j + i * 8]; 00339 } 00340 00341 else 00342 puiMatrix[j + i * 8] = lastValue; 00343 } 00344 } 00345 } 00346 00347 00348 void MP3Parser::readMarkerBitFunc(int iLine) { 00349 if (getBit() != 1) 00350 { 00351 dprintf_small("Marker bit invalid at line %d\n", iLine); 00352 } 00353 } 00354 00355 00356 void MP3Parser::bookmark() { 00357 miBookmarkedCurrentBit = miCurrentBit; 00358 miBookmarkedByte = mcByte; 00359 miBookmarkedCurrentNoBytes = miCurrentNoBytes; 00360 } 00361 00362 00363 void MP3Parser::restore() { 00364 miCurrentBit = miBookmarkedCurrentBit; 00365 mcByte = miBookmarkedByte; 00366 miCurrentNoBytes = miBookmarkedCurrentNoBytes; 00367 } 00368 00369