Diffstat (limited to 'core/multimedia/opieplayer/libflash/adpcm.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libflash/adpcm.cc | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/adpcm.cc b/core/multimedia/opieplayer/libflash/adpcm.cc new file mode 100644 index 0000000..a4bc435 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.cc | |||
@@ -0,0 +1,235 @@ | |||
1 | |||
2 | #include "swf.h" | ||
3 | |||
4 | #ifdef RCSID | ||
5 | static char *rcsid = "$Id$"; | ||
6 | #endif | ||
7 | |||
8 | // This file has been rearranged from the code posted | ||
9 | // on news:forums.macromedia.com by Jonathan Gay. | ||
10 | // Courtesy of Macromedia | ||
11 | |||
12 | // | ||
13 | // ADPCM tables | ||
14 | // | ||
15 | |||
16 | static const int indexTable2[2] = { | ||
17 | -1, 2, | ||
18 | }; | ||
19 | |||
20 | // Is this ok? | ||
21 | static const int indexTable3[4] = { | ||
22 | -1, -1, 2, 4, | ||
23 | }; | ||
24 | |||
25 | static const int indexTable4[8] = { | ||
26 | -1, -1, -1, -1, 2, 4, 6, 8, | ||
27 | }; | ||
28 | |||
29 | static const int indexTable5[16] = { | ||
30 | -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, | ||
31 | }; | ||
32 | |||
33 | static const int* indexTables[] = { | ||
34 | indexTable2, | ||
35 | indexTable3, | ||
36 | indexTable4, | ||
37 | indexTable5 | ||
38 | }; | ||
39 | |||
40 | static const int stepsizeTable[89] = { | ||
41 | 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, | ||
42 | 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | ||
43 | 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | ||
44 | 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | ||
45 | 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | ||
46 | 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | ||
47 | 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | ||
48 | 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | ||
49 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | ||
50 | }; | ||
51 | |||
52 | long | ||
53 | Adpcm::GetBits(int n) | ||
54 | { | ||
55 | if ( bitPos < n ) FillBuffer(); | ||
56 | |||
57 | assert(bitPos >= n); | ||
58 | |||
59 | long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n); | ||
60 | bitPos -= n; | ||
61 | |||
62 | return v; | ||
63 | } | ||
64 | |||
65 | long | ||
66 | Adpcm::GetSBits(int n) | ||
67 | { | ||
68 | if ( bitPos < n ) FillBuffer(); | ||
69 | |||
70 | assert(bitPos >= n); | ||
71 | |||
72 | long v = ((long)bitBuf << (32-bitPos)) >> (32-n); | ||
73 | bitPos -= n; | ||
74 | |||
75 | return v; | ||
76 | } | ||
77 | |||
78 | // | ||
79 | // The Decompressor | ||
80 | // | ||
81 | |||
82 | // Constructor | ||
83 | Adpcm::Adpcm(unsigned char *buffer, long isStereo) | ||
84 | { | ||
85 | stereo = isStereo; | ||
86 | src = buffer; | ||
87 | |||
88 | nBits = 0; // flag that it is not inited | ||
89 | nSamples = 0; | ||
90 | |||
91 | bitPos = 0; | ||
92 | bitBuf = 0; | ||
93 | } | ||
94 | |||
95 | void | ||
96 | Adpcm::FillBuffer() | ||
97 | { | ||
98 | while ( bitPos <= 24 /*&& srcSize > 0*/ ) { | ||
99 | bitBuf = (bitBuf<<8) | *src++; | ||
100 | bitPos += 8; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | void | ||
105 | Adpcm::Decompress(short *dst, long n) | ||
106 | { | ||
107 | if ( nBits == 0 ) { | ||
108 | // Get the compression header | ||
109 | nBits = (int)GetBits(2)+2; | ||
110 | } | ||
111 | |||
112 | const int* indexTable = indexTables[nBits-2]; | ||
113 | int k0 = 1 << (nBits-2); | ||
114 | int signmask = 1 << (nBits-1); | ||
115 | |||
116 | if ( !stereo ) { | ||
117 | // Optimize for mono | ||
118 | long vp = valpred[0]; // maybe these can get into registers... | ||
119 | int ind = index[0]; | ||
120 | long ns = nSamples; | ||
121 | |||
122 | while ( n-- > 0 ) { | ||
123 | ns++; | ||
124 | |||
125 | if ( (ns & 0xFFF) == 1 ) { | ||
126 | // Get a new block header | ||
127 | *dst++ = (short)(vp = GetSBits(16)); | ||
128 | |||
129 | ind = (int)GetBits(6); // The first sample in a block does not have a delta | ||
130 | } else { | ||
131 | // Process a delta value | ||
132 | int delta = (int)GetBits(nBits); | ||
133 | |||
134 | // Compute difference and new predicted value | ||
135 | // Computes 'vpdiff = (delta+0.5)*step/4' | ||
136 | int step = stepsizeTable[ind]; | ||
137 | long vpdiff = 0; | ||
138 | int k = k0; | ||
139 | |||
140 | do { | ||
141 | if ( delta & k ) | ||
142 | vpdiff += step; | ||
143 | step >>= 1; | ||
144 | k >>= 1; | ||
145 | } while ( k ); | ||
146 | |||
147 | vpdiff += step; // add 0.5 | ||
148 | |||
149 | if ( delta & signmask ) // the sign bit | ||
150 | vp -= vpdiff; | ||
151 | else | ||
152 | vp += vpdiff; | ||
153 | |||
154 | // Find new index value | ||
155 | ind += indexTable[delta&(~signmask)]; | ||
156 | |||
157 | if ( ind < 0 ) | ||
158 | ind = 0; | ||
159 | else if ( ind > 88 ) | ||
160 | ind = 88; | ||
161 | |||
162 | // clamp output value | ||
163 | if ( vp != (short)vp ) | ||
164 | vp = vp < 0 ? -32768 : 32767; | ||
165 | |||
166 | /* Step 7 - Output value */ | ||
167 | *dst++ = (short)vp; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | valpred[0] = vp; | ||
172 | index[0] = ind; | ||
173 | nSamples = ns; | ||
174 | |||
175 | } else { | ||
176 | int sn = stereo ? 2 : 1; | ||
177 | |||
178 | // Stereo | ||
179 | while ( n-- > 0 ) { | ||
180 | |||
181 | nSamples++; | ||
182 | |||
183 | if ( (nSamples & 0xFFF) == 1 ) { | ||
184 | // Get a new block header | ||
185 | for ( int i = 0; i < sn; i++ ) { | ||
186 | |||
187 | *dst++ = (short)(valpred[i] = GetSBits(16)); | ||
188 | |||
189 | // The first sample in a block does not have a delta | ||
190 | index[i] = (int)GetBits(6); | ||
191 | } | ||
192 | } else { | ||
193 | // Process a delta value | ||
194 | for ( int i = 0; i < sn; i++ ) { | ||
195 | int delta = (int)GetBits(nBits); | ||
196 | |||
197 | // Compute difference and new predicted value | ||
198 | // Computes 'vpdiff = (delta+0.5)*step/4' | ||
199 | |||
200 | int step = stepsizeTable[index[i]]; | ||
201 | long vpdiff = 0; | ||
202 | int k = k0; | ||
203 | |||
204 | do { | ||
205 | if ( delta & k ) vpdiff += step; | ||
206 | step >>= 1; | ||
207 | k >>= 1; | ||
208 | } while ( k ); | ||
209 | vpdiff += step; // add 0.5 | ||
210 | |||
211 | |||
212 | if ( delta & signmask ) // the sign bit | ||
213 | valpred[i] -= vpdiff; | ||
214 | else | ||
215 | valpred[i] += vpdiff; | ||
216 | |||
217 | // Find new index value | ||
218 | index[i] += indexTable[delta&(~signmask)]; | ||
219 | |||
220 | if ( index[i] < 0 ) | ||
221 | index[i] = 0; | ||
222 | else if ( index[i] > 88 ) | ||
223 | index[i] = 88; | ||
224 | |||
225 | // clamp output value | ||
226 | if ( valpred[i] != (short)valpred[i] ) | ||
227 | valpred[i] = valpred[i] < 0 ? -32768 : 32767; | ||
228 | |||
229 | /* Step 7 - Output value */ | ||
230 | *dst++ = (short)valpred[i]; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||