#include #include 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 }