1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #define error(x) {puts(x); exit(1);}
5
6 #define MP3_FRAME_SYNC 0xFFE00000
7
8 #define MP3_VERSION 0x00180000
9 #define MP3_VERSION_25 0x00000000
10 #define MP3_VERSION_RESERVED 0x00080000
11 #define MP3_VERSION_2 0x00100000
12 #define MP3_VERSION_1 0x00180000
13
14 #define MP3_LAYER 0x00060000
15 #define MP3_LAYER_RESERVED 0x00000000
16 #define MP3_LAYER_3 0x00020000
17 #define MP3_LAYER_2 0x00040000
18 #define MP3_LAYER_1 0x00060000
19
20 #define MP3_PROTECT 0x00010000 /* 16-bit CRC after header */
21
22 #define MP3_BITRATE 0x0000F000
23 #define MP3_BITRATE_SHIFT 12
24
25 int mp1l1_bitrate_table[] = { 0, 32, 64, 96, 128, 160, 192, 224,
26 256, 288, 320, 352, 382, 416, 448 };
27
28 int mp1l2_bitrate_table[] = { 0, 32, 48, 56, 64, 80, 96, 112,
29 128, 160, 192, 224, 256, 320, 384 };
30
31 int mp1l3_bitrate_table[] = { 0, 32, 40, 48, 56, 64, 80, 96,
32 112, 128, 160, 192, 224, 256, 320 };
33
34 int mp2l1_bitrate_table[] = { 0, 32, 48, 56, 64, 80, 96, 112,
35 128, 144, 160, 176, 192, 224, 256 };
36
37 int mp2l23_bitrate_table[] = { 0, 8, 16, 24, 32, 40, 48, 56,
38 64, 80, 96, 112, 128, 144, 160 };
39
40 #define MP3_SAMPLERATE 0x00000C00
41 #define MP3_SAMPLERATE_SHIFT 10
42 #define MP3_SAMPLERATE_IDX_MAX 2
43
44 int mp1_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 44100, 48000, 32000 };
45 int mp2_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 22050, 24000, 16000 }; /* is this right?? */
46 int mp25_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 11025, 12000, 8000 }; /* fewer samples?? */
47
48 #define MP3_PADDING 0x00000200 /* if set, add an extra slot - 4 bytes
49 for layer 1, 1 byte for 2+3 */
50
51 #define MP3_CHANNEL 0x000000C0
52 #define MP3_CHANNEL_STEREO 0x00000000
53 #define MP3_CHANNEL_JOINT 0x00000040
54 #define MP3_CHANNEL_DUAL 0x00000080
55 #define MP3_CHANNEL_MONO 0x000000C0
56
57 /* rest of the header info doesn't affect frame size.. */
58
skipBytes(FILE * f,int length)59 void skipBytes(FILE *f, int length)
60 {
61 for(; length>0; --length)
62 if(fgetc(f) == EOF)
63 return;
64 }
65
printMP3Headers(FILE * f)66 void printMP3Headers(FILE *f)
67 {
68 unsigned long flags;
69 int frameLen, numFrames = 0;
70 int bitrate=0, bitrate_idx, samplerate=0, samplerate_idx;
71 int version, layer, channels, padding;
72 int bitrateSum = 0;
73 int length;
74
75 for(;;)
76 {
77 int flags_char;
78 int i;
79 /* get 4-byte header, bigendian */
80 if((flags = fgetc(f)) == EOF)
81 break;
82
83 /* XXX - fix this mad hackery */
84 if(flags == 'I' && fgetc(f) == 'D' && fgetc(f) == '3')
85 {
86 do
87 {
88 flags = fgetc(f);
89 }
90 while(flags != 0xFF && flags != EOF);
91 }
92
93 if(flags == EOF)
94 break;
95
96 flags <<= 24;
97 for (i = 2; i >= 0; --i)
98 {
99 if ((flags_char = fgetc(f)) == EOF)
100 {
101 error("truncated file");
102 }
103 else
104 {
105 flags += flags_char << (i * 8);
106 }
107 }
108
109 if((flags & MP3_FRAME_SYNC) != MP3_FRAME_SYNC)
110 break;
111 /* error("bad sync on MP3 block!"); */
112
113 ++numFrames;
114
115 bitrate_idx = (flags & MP3_BITRATE) >> MP3_BITRATE_SHIFT;
116 samplerate_idx = (flags & MP3_SAMPLERATE) >> MP3_SAMPLERATE_SHIFT;
117 if (samplerate_idx < 0 || samplerate_idx > MP3_SAMPLERATE_IDX_MAX)
118 {
119 error("invalid samplerate index");
120 }
121
122 channels = ((flags & MP3_CHANNEL) == MP3_CHANNEL_MONO) ? 1 : 2;
123
124 switch(flags & MP3_VERSION)
125 {
126 case MP3_VERSION_1: version = 1; break;
127 case MP3_VERSION_2: version = 2; break;
128 case MP3_VERSION_25: version = 25; break;
129 default: error("unknown MP3 version!");
130 }
131 switch(flags & MP3_LAYER)
132 {
133 case MP3_LAYER_1: layer = 1; break;
134 case MP3_LAYER_2: layer = 2; break;
135 case MP3_LAYER_3: layer = 3; break;
136 default: error("unknown MP3 layer!");
137 }
138
139 bitrateSum += bitrate;
140
141 if(version == 1)
142 {
143 samplerate = mp1_samplerate_table[samplerate_idx];
144
145 if(layer == 1)
146 bitrate = mp1l1_bitrate_table[bitrate_idx];
147
148 else if(layer == 2)
149 bitrate = mp1l2_bitrate_table[bitrate_idx];
150
151 else if(layer == 3)
152 bitrate = mp1l3_bitrate_table[bitrate_idx];
153 }
154 else
155 {
156 if(version == 2)
157 samplerate = mp2_samplerate_table[samplerate_idx];
158 else
159 samplerate = mp25_samplerate_table[samplerate_idx];
160
161 if(layer == 1)
162 bitrate = mp2l1_bitrate_table[bitrate_idx];
163 else
164 bitrate = mp2l23_bitrate_table[bitrate_idx];
165 }
166
167 padding = (flags & MP3_PADDING) ? 1 : 0;
168
169 if(layer == 1)
170 padding <<= 2;
171
172 if(version == 1)
173 frameLen = 144 * bitrate * 1000 / samplerate + padding;
174 else
175 frameLen = 72 * bitrate * 1000 / samplerate + padding;
176
177 printf("frame %i: MP%i layer %i, %i Hz, %ikbps, %s, length=%i, protect %s\n",
178 numFrames, version, layer, samplerate, bitrate,
179 (channels==2) ? "stereo" : "mono", frameLen,
180 (flags&MP3_PROTECT) ? "on" : "off");
181
182 skipBytes(f, frameLen-4);
183 }
184
185 if (numFrames == 0)
186 error("no valid frame found");
187
188 putchar('\n');
189
190 length = numFrames*(samplerate > 3200 ? 1152 : 576)/samplerate;
191
192 printf("Number of frames: %i\n", numFrames);
193 printf("Average bitrate: %i\n", bitrateSum/numFrames);
194 printf("Length: %i:%02i\n", length/60, length%60);
195 }
196
main(int argc,char * argv[])197 int main(int argc, char *argv[])
198 {
199 FILE *f;
200
201 if(argc<1)
202 error("gimme file name");
203
204 f = fopen(argv[1],"rb");
205
206 if(!f)
207 error("couldn't open file");
208
209 printMP3Headers(f);
210
211 exit(0);
212 }
213