#include <stdio.h>
#include <stdlib.h>

typedef struct rate_node
 {
  int value;
  int count;
  struct rate_node *next;
 } MP3_RATE_NODE;

MP3_RATE_NODE *mp3_rate_head = 0;  



static
void free_mp3_rate_list()
{
 while(mp3_rate_head)
  {
    mp3_rate_head = mp3_rate_head->next;
    free(mp3_rate_head);
  }
}

  



static
void mp3_add_rate(int rate)
{
 MP3_RATE_NODE *ptr;
 
 if(!mp3_rate_head)
  {
    mp3_rate_head = (MP3_RATE_NODE *) malloc(sizeof(MP3_RATE_NODE));
    mp3_rate_head->value = rate;
    mp3_rate_head->count = 1;
    mp3_rate_head ->next = 0;
  }
 else
  {
   for(ptr = mp3_rate_head; ptr->next && (ptr->value != rate); ptr = ptr->next);
   if(ptr->value == rate)
    {
      ptr->count = ptr->count + 1;
    }
   else 
    {
     ptr->next = (MP3_RATE_NODE *) malloc(sizeof(MP3_RATE_NODE));
     ptr = ptr->next;
     ptr->value = rate;
     ptr->count = 1;
     ptr -> next = 0;
    }
  }  
}    




static
int mp3_most_common_bitrate()
{
 MP3_RATE_NODE *rate_ptr;
 int the_rate = -1;
 int highest_count = 0;
 
 if(!mp3_rate_head)
    return  -1;

 for(rate_ptr = mp3_rate_head; rate_ptr; rate_ptr = rate_ptr->next)
  {
   if(rate_ptr->count > highest_count)
    {
     highest_count = rate_ptr->count;
     the_rate = rate_ptr->value;
    }
  }
 return the_rate;    

}



int
mp3_bitrate(const char *filepath)
{
#define MAX_FRAMES 1000
 FILE *fp = 0;
 unsigned char byte;
 int layer; 
 int is_v1;
 unsigned char layer_bits;
 unsigned char version;
 int rate;
 int done;
 int frames_found = 0;
 

 fp = fopen(filepath, "r");
 if(!fp)
    return -1;
 
 done = 0;
 do
 { 
  if(fread(&byte, 1, 1, fp) != 1)
   {
    done = 1;
    break;
   }
  else
   {
     if(byte == 0xFF)
      {
        if(fread(&byte, 1, 1, fp) != 1)
         {
           done = 1;
           break;
         }

         if((byte >> 5) == 0x07)
           {
             version =  byte << 3;
             version   >>= 6;
             if(version == 0x01)   /* reserved - this is not a frame header */
                 continue;    
             is_v1 = (version == 0x03);

             layer_bits = byte << 5;
             layer_bits >>= 6; 
             switch(layer_bits)
              {
                case 0x00: continue; break;   /* reserved = this is not a frame header */
                case 0x01: layer = 3; break;
                case 0x02: layer = 2; break;
                default:   layer = 1; break;
              }


             if(fread(&byte, 1, 1, fp) != 1)
              {
                done = 1;
                break;
              }
 
              byte >>= 4;

              if( (byte == 0x0F) || (byte == 0x00))  /* bad value - this is not a frame header */
                  continue;
             
              if(is_v1)
               {
                 switch(layer)
                  {
                    case 1: rate = 32 * byte;
                            break;


                    case 2: switch(byte)
                    {
                     case 0x00: rate = -1; break;
                     case 0x01: rate = 32; break;
                     case 0x02: rate = 48; break;
                     case 0x03: rate = 56; break;
                     case 0x04: rate = 64; break;
                     case 0x05: rate = 80; break;
                     case 0x06: rate = 96; break;
                     case 0x07: rate = 112; break;
                     case 0x08: rate = 128; break;
                     case 0x09: rate = 160; break;
                     case 0x0A: rate = 192; break;
                     case 0x0B: rate = 224; break;
                     case 0x0C: rate = 256; break;
                     case 0x0D: rate = 320; break;
                     case 0x0E: rate = 384; break;
                     case 0x0F: rate = -1; break;
                   }
                   break; 


                   default:  switch(byte)
                    {
                     case 0x00: rate = -1; break;
                     case 0x01: rate = 32; break;
                     case 0x02: rate = 40; break;
                     case 0x03: rate = 48; break;
                     case 0x04: rate = 56; break;
                     case 0x05: rate = 64; break;
                     case 0x06: rate = 80; break;
                     case 0x07: rate =  96; break;
                     case 0x08: rate = 112; break;
                     case 0x09: rate = 128; break;
                     case 0x0A: rate = 160; break;
                     case 0x0B: rate = 192; break;
                     case 0x0C: rate = 224; break;
                     case 0x0D: rate = 256; break;
                     case 0x0E: rate = 320; break;
                     default:   rate = -1; break;
                    } 
                    break; 
                  }          
               }  
              else
               {
                switch(layer)
                 {
                  case 1:  switch(byte)
                       {
                          case 0x01: rate = 32; break;
                          case 0x02: rate = 48; break;
                          case 0x03: rate = 56; break;
                          case 0x04: rate = 64; break;
                          case 0x05: rate = 80; break;
                          case 0x06: rate = 96; break;
                          case 0x07: rate = 112; break;
                          case 0x08: rate = 128; break;
                          case 0x09: rate = 144; break;
                          case 0x0A: rate = 160; break;
                          case 0x0B: rate = 176; break;
                          case 0x0C: rate = 192; break;
                          case 0x0D: rate = 224; break;
                          case 0x0E: rate = 256; break;
                          default: rate = -1; break;
                      }
                      break; 


                  default:  switch(byte)
                       {
                          case 0x01: rate =  8; break;
                          case 0x02: rate = 16; break;
                          case 0x03: rate = 24; break;
                          case 0x04: rate = 32; break;
                          case 0x05: rate = 40; break;
                          case 0x06: rate = 48; break;
                          case 0x07: rate =  56; break;
                          case 0x08: rate =  64; break;
                          case 0x09: rate =  80; break;
                          case 0x0A: rate =  96; break;
                          case 0x0B: rate = 112; break;
                          case 0x0C: rate = 128; break;
                          case 0x0D: rate = 144; break;
                          case 0x0E: rate = 160; break;
                          default:   rate = -1; break;
                       }
                       break; 
                 }
               }
             if(rate != -1)
               {
                 mp3_add_rate(rate);
                 frames_found++;
                 done = (frames_found >= MAX_FRAMES);
               }  
           }
      }
   }  
 } while (!done);

 
 if(fp)
    fclose(fp);
 
 rate = mp3_most_common_bitrate();  
 free_mp3_rate_list();  

 return rate;  
 
 #undef MAX_FRAMES

}  




