// // C++ Implementation: ADM_MP3Info // // Description: // Decode an mp3 frame an fill the info field // The second is a template to check we do not do bogus frame detection // // Author: mean , (C) 2004 // // Copyright: See COPYING file that comes with this distribution // // /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "ADM_default.h" #include "ADM_mp3info.h" static uint32_t MP3Fq[4] = { 44100, 48000, 32000, 0 }; static uint32_t MP2Fq[4] = { 22050, 24000, 16000, 0 }; static uint32_t Bitrate[8][16]= { // Level 1 / Layer 0 {0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0}, // Level 1/ Layer 1 {0,32,64,96,128,160,192,224 ,256,288,320,352,384,416,448,0}, // Level 1/Layer 2 { 0, 32, 48, 56,64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, //Level 1 / Layer 3 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}, //----------------------- // Level 2/Layer 0 {0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0}, // Level 2 Layer 1 { 0, 32, 48, 56,64, 80, 96, 112, 128, 144, 160,176, 192, 224, 256, 0}, // Level 2 Layer 2 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Id for Layer 3 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, }; uint8_t getMpegFrameInfo(const uint8_t *stream,uint32_t maxSearch, MpegAudioInfo *mpegInfo,MpegAudioInfo *templ,uint32_t *offset) { uint32_t start=0,found=0; uint8_t a[4]; uint32_t nfq,fqindex,brindex,index; memcpy(a+1,stream,3); do { memmove(a,a+1,3); a[3]=stream[start+3]; if(start>=maxSearch-3) break; start++; if(a[0]==0xff && ((a[1]&0xE0)==0xE0)) { // Layer mpegInfo->layer=4-((a[1]>>1)&3); mpegInfo->level=4-((a[1]>>3)&3); if(mpegInfo->level==3) continue; if(mpegInfo->level==4) { mpegInfo->level=3; // mpeg 2.5 } mpegInfo->protect=(a[1]&1)^1; mpegInfo->padding=(a[2]>>1)&1; mpegInfo->privatebit=(a[2]&1); mpegInfo->mode=(a[3])>>6; mpegInfo->mode_extension=((a[3])>>4)&3; fqindex=(a[2]>>2)&3; brindex=(a[2]>>4); // Remove impossible case if(mpegInfo->layer==4) continue; // Check fq if((a[1]>>4)&1) { mpegInfo->lsf=0; } else mpegInfo->lsf=1; // switch(mpegInfo->level) { case 1: mpegInfo->samplerate=MP3Fq[fqindex];break; case 2: mpegInfo->samplerate=MP2Fq[fqindex];break; case 3: mpegInfo->samplerate=MP2Fq[fqindex]>>1;break; default: mpegInfo->samplerate=0;break; } // impossible fq if(!mpegInfo->samplerate) continue; // Bitrate now // Compute bitrate switch(mpegInfo->level) { case 2: case 3: index=4+mpegInfo->layer; break; case 1: index=mpegInfo->layer; break; default: continue; } mpegInfo->bitrate=Bitrate[index][brindex]; if(!mpegInfo->bitrate) continue; // Check consistency if(templ) { if(templ->samplerate!=mpegInfo->samplerate) { printf("[MP3]samplerate does not match\n"); continue; } } found=1; } }while(!found && startlevel==1) { if(1==mpegInfo->layer) mpegInfo->samples=384; else mpegInfo->samples=1152; *offset=start-1; } else { // Mpeg2/2.5 if(1==mpegInfo->layer) mpegInfo->samples=384; else mpegInfo->samples=576; *offset=start-1; } #else switch(mpegInfo->layer) { case 1: mpegInfo->samples=384;break; case 2: mpegInfo->samples=1152;break; default: case 3: if(mpegInfo->level==1) // mpeg 2.5 mpegInfo->samples=1152; else mpegInfo->samples=576; break; } *offset=start-1; #endif // Packet size //L1:FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4 switch(mpegInfo->layer) { case 1: mpegInfo->size=((12*1000*mpegInfo->bitrate)/mpegInfo->samplerate) +mpegInfo->padding; mpegInfo->size=mpegInfo->size*4; break; default: //FrameLengthInBytes = 144 * BitRate / SampleRate + Padding uint32_t slot_per_frame; if(mpegInfo->layer==3 && (mpegInfo->level&2)==2) slot_per_frame=72; else slot_per_frame=144; mpegInfo->size=(slot_per_frame*mpegInfo->bitrate*1000)/mpegInfo->samplerate; mpegInfo->size+=mpegInfo->padding; } if(*offset) { printf("MP3: Skipped %" PRIu32" bytes\n",*offset); } #if 0 printf("%02x %02x %02x %02x\n",a[0],a[1],a[2],a[3]); printf("Packet found : at :%d level:%d layer:%d fq:%d bitrate:%d mode:%d\n", start-1,mpegInfo->level,mpegInfo->layer,mpegInfo->samplerate, mpegInfo->bitrate,mpegInfo->mode); printf("Private :%d cop:%d ext:%d ",mpegInfo->privatebit, 0,mpegInfo->mode_extension); printf("Padd:%lu, crc on:%lu size:%lu\n",mpegInfo->padding,mpegInfo->protect, mpegInfo->size); #endif return 1; } //____________