Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

mpeg.cpp

Go to the documentation of this file.
00001 /*  mpeg.cpp
00002     MPEG format helper functions
00003 
00004     12.09.2001: tk, initial implementation, loosely based on
00005                     some MPG123 functions.
00006 
00007     Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de
00008 
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of
00012     the License, or (at your option) any later version. Read the
00013     full License at http://www.gnu.org/copyleft for more details.
00014 */
00015 
00016 // include files -----
00017 //
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <assert.h>
00021 #include "mpeg.h"
00022 
00023 
00033 bool MPEG_CheckHeader(unsigned long header)
00034 {
00035   if (((header>>21) & 2047) != 2047)
00036     return false;
00037   if (((header>>19) &    3) ==    1)
00038     return false;
00039   if (((header>>17) &    3) ==    0)
00040     return false;
00041   if (((header>>12) &   15) ==    0 ||
00042       ((header>>12) &   15) ==   15)
00043     return false;
00044   if (((header>>10) &    3) ==    3)
00045     return false;
00046   if (((header>> 0) &    3) ==    2)
00047     return false;
00048   return true;
00049 }
00050 
00051 
00061 bool MPEG_FindHeader( char *buffer, unsigned buflen, 
00062                       int numHeads )
00063 {
00064   return false;
00065 }
00066 
00067 
00076 bool MPEG_ParseHeader(unsigned long header, FrameInfo *info)
00077 {
00078   const int  ids[4]    = { 25, 0, 2, 1 };
00079   const int  layers[4] = {  0, 3, 2, 1 };
00080   const long mp1tab[4][16] = { {0},  // bitrates for MPEG 1
00081    {     0,  32000,  64000,  96000, 128000, 160000, 192000, 224000, // layer 1
00082     256000, 288000, 320000, 352000, 384000, 416000, 448000,     -1 },
00083    {     0,  32000,  48000,  56000,  64000,  80000,  96000, 112000, // layer 2
00084     128000, 160000, 192000, 224000, 256000, 320000, 384000,     -1 },
00085    {     0,  32000,  40000,  48000,  56000,  64000,  80000,  96000, // layer 3
00086     112000, 128000, 160000, 192000, 224000, 256000, 320000,     -1 }
00087   };
00088   const long mp2tab[4][16] = { {0},  // bitrates for MPEG2/2.5
00089    {     0,  32000,  48000,  56000,  64000,  80000,  96000, 112000, // layer 1
00090     128000, 144000, 160000, 176000, 192000, 224000, 256000,     -1 },
00091    {     0,   8000,  16000,  24000,  32000,  40000,  48000,  56000, // layer 2
00092      64000,  80000,  96000, 112000, 128000, 144000, 160000,     -1 },
00093    {     0,   8000,  16000,  24000,  32000,  40000,  48000,  56000, // layer 3
00094      64000,  80000,  96000, 112000, 128000, 144000, 160000,     -1 },
00095   };
00096   const long  freqs[4][4] = {
00097     { 11025,  12000,  8000, 0},   // version 2.5
00098     {     0,      0,     0, 0},   // reserved
00099     { 22050,  24000, 16000, 0},   // version 2
00100     { 44100,  48000, 32000, 0}    // version 1
00101   };
00102 
00103   memset(info, 0, sizeof(FrameInfo));
00104   if (!MPEG_CheckHeader(header))
00105     return false;
00106 
00107   info->id        =   ids[(header>>19) & 3];
00108   info->layer     =   layers[(header>>17) & 3];
00109   info->mode      =   (header>>6) & 3;
00110   info->extension =   (header>>4) & 3;
00111   info->emphasis  =   (header>>0) & 3;
00112   info->crc       = !((header>>16) & 1);
00113   info->pad       =   (header>>9) & 1;
00114   info->priv      =   (header>>8) & 1;
00115   info->copyright =   (header>>3) & 1;
00116   info->original  =   (header>>2) & 1;
00117   info->frequency =   freqs[(header>>19) & 3][(header>>10) & 3];
00118 
00119   if (info->id == 1)
00120     info->bitrate = mp1tab[info->layer][(header>>12) & 15];
00121   else
00122     info->bitrate = mp2tab[info->layer][(header>>12) & 15];
00123 
00124   if (info->layer == 1) {
00125     info->length  = 48  * info->bitrate/info->frequency;
00126     info->length += info->pad ? 4:0;
00127   } else {
00128     info->length  = 144 * info->bitrate/info->frequency;
00129     info->length += info->pad ? 1:0;
00130   }
00131   info->length += info->crc ? 2:0;
00132   return true;
00133 }
00134 
00135 
00136 char *MPEG_HeaderToString(unsigned long header)
00137 {
00138   static char buf[40];
00139   const char *mode[] = {"Stereo", "J-Stereo", "DualChn", "Mono"};
00140 
00141   FrameInfo  info;
00142   if (!MPEG_ParseHeader(header, &info))
00143     return "invalid header.";
00144 
00145   assert(
00146     sprintf(buf, "MP%uL%u, %3ldkb, %2ldkHz, %s %s",
00147     info.id, info.layer,
00148     info.bitrate/1000, info.frequency/1000,
00149     mode[info.mode], info.crc ? "CRC" : "")
00150     < sizeof(buf)
00151   );
00152 
00153   return buf;
00154 }

Generated on Sun Aug 4 21:47:28 2002 for k/os mp3v2 by doxygen1.2.16