summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/adpcm.cc
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/adpcm.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/adpcm.cc235
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
5static 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
16static const int indexTable2[2] = {
17 -1, 2,
18};
19
20// Is this ok?
21static const int indexTable3[4] = {
22 -1, -1, 2, 4,
23};
24
25static const int indexTable4[8] = {
26 -1, -1, -1, -1, 2, 4, 6, 8,
27};
28
29static const int indexTable5[16] = {
30 -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
31};
32
33static const int* indexTables[] = {
34 indexTable2,
35 indexTable3,
36 indexTable4,
37 indexTable5
38};
39
40static 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
52long
53Adpcm::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
65long
66Adpcm::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
83Adpcm::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
95void
96Adpcm::FillBuffer()
97{
98 while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
99 bitBuf = (bitBuf<<8) | *src++;
100 bitPos += 8;
101 }
102}
103
104void
105Adpcm::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}