KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > http > client > Mp3FrameStream


1 package com.quadcap.http.client;
2
3 import java.io.BufferedOutputStream JavaDoc;
4 import java.io.ByteArrayOutputStream JavaDoc;
5 import java.io.FileInputStream JavaDoc;
6 import java.io.FileOutputStream JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.io.OutputStream JavaDoc;
9
10 import com.quadcap.util.Debug;
11
12 import com.quadcap.io.IO;
13
14 /*
15  * Copyright 2004 by Stan Bailes and Quadcap Software.
16  *
17  **/

18 public class Mp3FrameStream extends OutputStream JavaDoc {
19     ByteArrayOutputStream JavaDoc frame = new ByteArrayOutputStream JavaDoc();
20     OutputStream JavaDoc frameData;
21     OutputStream JavaDoc nonFrameData;
22     int state = 0;
23
24     int id = 0;
25     int layer = 0;
26     int protection = 0;
27     int bitrateEnc = 0;
28     int frequency = 0;
29     int pad = 0;
30     int priv = 0;
31     int mode = 0;
32     int modeExt = 0;
33     int copy = 0;
34     int home = 0;
35     int emph = 0;
36
37     double bitrate = 0;
38     double samplerate = 0;
39     int framesize = 0;
40     int count = 0;
41
42     int totalBytes = 0;
43     int nonFrameCount = 0;
44
45     boolean started = false;
46     int bitrateEncStart = 0;
47     int frequencyStart = 0;
48     
49     public Mp3FrameStream() {}
50
51     public void init(OutputStream JavaDoc frameData, OutputStream JavaDoc nonFrameData) {
52         this.frameData = frameData;
53         this.nonFrameData = nonFrameData;
54         started = false;
55     }
56
57     public void write(int b) throws IOException JavaDoc {
58         totalBytes++;
59         if (false && (totalBytes % 100000) == 99999) {
60             msg("totalBytes: " + totalBytes + ", state: " + state +
61                 ", count: " + count + ", framesize: " + framesize);
62         }
63                                                  
64         b &= 0xff;
65         switch (state) {
66         case 0:
67             if (b == 0xff) {
68                 state = 1;
69             } else {
70                 nonFrameData.write(b);
71                 nonFrameCount++;
72             }
73             break;
74         case 1:
75             if ((b & 0xe0) == 0xe0) {
76                 if (nonFrameCount > 0) {
77                     msg("" + nonFrameCount + " non frame bytes @ " +
78                         totalBytes);
79                 }
80                 nonFrameCount = 0;
81                 //msg("Frame starts at byte " + ((totalBytes) - 2));
82
frame.reset();
83                 frame.write(0xff);
84                 frame.write(b);
85                 id = (b & 0x8) >> 3;
86                 layer = (b & 0x6) >> 1;
87                 protection = (b & 0x1);
88                 state = 2;
89             } else {
90                 nonFrameData.write(0xff);
91                 nonFrameData.write(b);
92                 nonFrameCount++;
93                 state = 0;
94             }
95             break;
96         case 2:
97             frame.write(b);
98             bitrateEnc = (b & 0xf0) >> 4;
99             frequency = (b & 0xc) >> 2;
100             pad = (b & 0x2) >> 1;
101             priv = (b & 0x1);
102             state = 3;
103             break;
104         case 3:
105             frame.write(b);
106             mode = (b & 0xc0) >> 6;
107             modeExt = (b & 0x3) >> 4;
108             copy = (b & 0x8) >> 3;
109             home = (b & 0x4) >> 2;
110             emph = (b & 0x3);
111             bitrate = bitrates[bitrateEnc][(id << 2) | layer] * 1000;
112             samplerate = samplerates[(id << 2) | frequency];
113             if (samplerate == 0) {
114                 state = 0;
115                 nonFrameData.write(frame.toByteArray());
116                 nonFrameCount += 4;
117             } else if (started && bitrateEnc != bitrateEncStart ||
118                        frequency != frequencyStart) {
119                 nonFrameData.write(frame.toByteArray());
120                 nonFrameCount += 4;
121                 state = 0;
122             } else {
123                 framesize = (int) (144 * (bitrate / samplerate) + pad);
124                 if (!started) {
125                     msg("bitrate: " + bitrate + ", samplerate: " + samplerate +
126                         ", framesize: " + framesize + " brEnc: " + bitrateEnc +
127                         " id: " + id + " layer: " + layer + " freq: " +
128                         frequency);
129                     started = true;
130                 }
131                 bitrateEncStart = bitrateEnc;
132                 frequencyStart = frequency;
133                 count = 4;
134                 state = 4;
135             }
136             break;
137         case 4:
138             frame.write(b);
139             if (++count >= framesize) {
140                 byte[] data = frame.toByteArray();
141                 frameData.write(data);
142                 state = 0;
143             }
144             break;
145         }
146     }
147
148     int[] samplerates = {
149         22050, 24000, 16000, 0, // MPEG-2
150
44100, 48000, 32000, 0 // MPEG-1
151
};
152     
153     int[][] bitrates = {
154         // MPEG-2 MPEG-1
155
// layer layer
156
// I II III I II III
157
{0, 8, 32, 32, 0, 32, 32, 32}, // 0
158
{0, 8, 32, 32, 0, 32, 32, 32}, // 1
159
{0, 16, 48, 64, 0, 40, 48, 64}, // 2
160
{0, 24, 56, 96, 0, 48, 56, 96}, // 3
161
{0, 32, 64, 128, 0, 56, 64, 128}, // 4
162
{0, 64, 80, 160, 0, 64, 80, 160}, // 5
163
{0, 80, 96, 192, 0, 80, 96, 192}, // 6
164
{0, 96, 112, 224, 0, 96, 112, 224}, // 7
165
{0, 112, 128, 256, 0, 112, 128, 256}, // 8
166
{0, 128, 160, 288, 0, 128, 160, 288}, // 9
167
{0, 160, 192, 320, 0, 160, 192, 320}, // 10
168
{0, 112, 224, 352, 0, 192, 224, 352}, // 11
169
{0, 128, 256, 384, 0, 224, 256, 384}, // 12
170
{0, 256, 320, 416, 0, 256, 320, 416}, // 13
171
{0, 320, 384, 448, 0, 320, 384, 448}, // 14
172
{0, 320, 384, 448, 0, 320, 384, 448} // 15
173
};
174
175     void msg(String JavaDoc s) {
176         Debug.println(s);
177     }
178
179     public static void main(String JavaDoc[] args) {
180         Mp3FrameStream mp = new Mp3FrameStream();
181         for (int i = 0; i < args.length; i++) {
182             String JavaDoc s = args[i];
183             try {
184                 if (false) {
185                     FileInputStream JavaDoc fi = new FileInputStream JavaDoc(s);
186                     int b;
187                     int state = 0;
188                     int count = 0;
189                     while ((b = fi.read()) >= 0) {
190                         count++;
191                         switch (state) {
192                         case 0:
193                             if (b == 0xff) {
194                                 state = 1;
195                             }
196                             break;
197                         case 1:
198                             if (b == 251) {
199                                 state = 2;
200                             } else if (b != 0xff) {
201                                 state = 0;
202                             }
203                             break;
204                         case 2:
205                             if (b == 146) {
206                                 mp.msg("Sync at " + (count-3));
207                             }
208                             state = 0;
209                             break;
210                         }
211                     }
212                     fi.close();
213                 }
214                 FileInputStream JavaDoc fis = new FileInputStream JavaDoc(s);
215                 try {
216                     FileOutputStream JavaDoc raw = new FileOutputStream JavaDoc(s + ".out");
217                     FileOutputStream JavaDoc skp = new FileOutputStream JavaDoc(s + ".skp");
218                     mp.init(raw, skp);
219                     try {
220                         IO.copyStream(fis, mp);
221                     } finally {
222                         mp.close();
223                     }
224                 } finally {
225                     fis.close();
226                 }
227             } catch (Throwable JavaDoc t) {
228                 Debug.print(t);
229             }
230         }
231     }
232
233     public void close() throws IOException JavaDoc {
234         Debug.println("close()");
235         frameData.close();
236         nonFrameData.close();
237         if (nonFrameCount > 0) {
238             Debug.println("" + nonFrameCount + " trailing bytes no sync");
239         }
240     }
241 }
242
Popular Tags