-rw-r--r-- | core/applets/vmemo/adpcm.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/core/applets/vmemo/adpcm.c b/core/applets/vmemo/adpcm.c index c4dfa50..a123249 100644 --- a/core/applets/vmemo/adpcm.c +++ b/core/applets/vmemo/adpcm.c | |||
@@ -25,228 +25,228 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
25 | /* | 25 | /* |
26 | ** Intel/DVI ADPCM coder/decoder. | 26 | ** Intel/DVI ADPCM coder/decoder. |
27 | ** | 27 | ** |
28 | ** The algorithm for this coder was taken from the IMA Compatability Project | 28 | ** The algorithm for this coder was taken from the IMA Compatability Project |
29 | ** proceedings, Vol 2, Number 2; May 1992. | 29 | ** proceedings, Vol 2, Number 2; May 1992. |
30 | ** | 30 | ** |
31 | ** Version 1.2, 18-Dec-92. | 31 | ** Version 1.2, 18-Dec-92. |
32 | ** | 32 | ** |
33 | ** Change log: | 33 | ** Change log: |
34 | ** - Fixed a stupid bug, where the delta was computed as | 34 | ** - Fixed a stupid bug, where the delta was computed as |
35 | ** stepsize*code/4 in stead of stepsize*(code+0.5)/4. | 35 | ** stepsize*code/4 in stead of stepsize*(code+0.5)/4. |
36 | ** - There was an off-by-one error causing it to pick | 36 | ** - There was an off-by-one error causing it to pick |
37 | ** an incorrect delta once in a blue moon. | 37 | ** an incorrect delta once in a blue moon. |
38 | ** - The NODIVMUL define has been removed. Computations are now always done | 38 | ** - The NODIVMUL define has been removed. Computations are now always done |
39 | ** using shifts, adds and subtracts. It turned out that, because the standard | 39 | ** using shifts, adds and subtracts. It turned out that, because the standard |
40 | ** is defined using shift/add/subtract, you needed bits of fixup code | 40 | ** is defined using shift/add/subtract, you needed bits of fixup code |
41 | ** (because the div/mul simulation using shift/add/sub made some rounding | 41 | ** (because the div/mul simulation using shift/add/sub made some rounding |
42 | ** errors that real div/mul don't make) and all together the resultant code | 42 | ** errors that real div/mul don't make) and all together the resultant code |
43 | ** ran slower than just using the shifts all the time. | 43 | ** ran slower than just using the shifts all the time. |
44 | ** - Changed some of the variable names to be more meaningful. | 44 | ** - Changed some of the variable names to be more meaningful. |
45 | */ | 45 | */ |
46 | 46 | ||
47 | #include "adpcm.h" | 47 | #include "adpcm.h" |
48 | #include <stdio.h> /*DBG*/ | 48 | #include <stdio.h> /*DBG*/ |
49 | 49 | ||
50 | #ifndef __STDC__ | 50 | #ifndef __STDC__ |
51 | #define signed | 51 | #define signed |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | /* Intel ADPCM step variation table */ | 54 | /* Intel ADPCM step variation table */ |
55 | static int indexTable[16] = { | 55 | static int indexTable[16] = { |
56 | -1, -1, -1, -1, 2, 4, 6, 8, | 56 | -1, -1, -1, -1, 2, 4, 6, 8, |
57 | -1, -1, -1, -1, 2, 4, 6, 8, | 57 | -1, -1, -1, -1, 2, 4, 6, 8, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static int stepsizeTable[89] = { | 60 | static int stepsizeTable[89] = { |
61 | 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, | 61 | 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, |
62 | 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | 62 | 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, |
63 | 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | 63 | 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, |
64 | 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | 64 | 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, |
65 | 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | 65 | 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, |
66 | 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | 66 | 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, |
67 | 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | 67 | 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, |
68 | 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | 68 | 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, |
69 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | 69 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 |
70 | }; | 70 | }; |
71 | 71 | ||
72 | void | 72 | void |
73 | adpcm_coder(indata, outdata, len, state) | 73 | adpcm_coder(indata, outdata, len, state) |
74 | short indata[]; | 74 | short indata[]; |
75 | char outdata[]; | 75 | char outdata[]; |
76 | int len; | 76 | int len; |
77 | struct adpcm_state *state; | 77 | struct adpcm_state *state; |
78 | { | 78 | { |
79 | short *inp; /* Input buffer pointer */ | 79 | short *inp; /* Input buffer pointer */ |
80 | signed char *outp; /* output buffer pointer */ | 80 | signed char *outp; /* output buffer pointer */ |
81 | int val; /* Current input sample value */ | 81 | int val; /* Current input sample value */ |
82 | int sign; /* Current adpcm sign bit */ | 82 | int sign; /* Current adpcm sign bit */ |
83 | int delta; /* Current adpcm output value */ | 83 | int delta; /* Current adpcm output value */ |
84 | int diff; /* Difference between val and valprev */ | 84 | int diff; /* Difference between val and valprev */ |
85 | int step; /* Stepsize */ | 85 | int step; /* Stepsize */ |
86 | int valpred; /* Predicted output value */ | 86 | int valpred; /* Predicted output value */ |
87 | int vpdiff; /* Current change to valpred */ | 87 | int vpdiff; /* Current change to valpred */ |
88 | int index; /* Current step change index */ | 88 | int index; /* Current step change index */ |
89 | int outputbuffer; /* place to keep previous 4-bit value */ | 89 | int outputbuffer = 0; /* place to keep previous 4-bit value */ |
90 | int bufferstep; /* toggle between outputbuffer/output */ | 90 | int bufferstep = 0; /* toggle between outputbuffer/output */ |
91 | 91 | ||
92 | outp = (signed char *)outdata; | 92 | outp = (signed char *)outdata; |
93 | inp = indata; | 93 | inp = indata; |
94 | 94 | ||
95 | valpred = state->valprev; | 95 | valpred = state->valprev; |
96 | index = state->index; | 96 | index = state->index; |
97 | step = stepsizeTable[index]; | 97 | step = stepsizeTable[index]; |
98 | 98 | ||
99 | bufferstep = 1; | 99 | bufferstep = 1; |
100 | 100 | ||
101 | for ( ; len > 0 ; len-- ) { | 101 | for ( ; len > 0 ; len-- ) { |
102 | val = *inp++; | 102 | val = *inp++; |
103 | 103 | ||
104 | /* Step 1 - compute difference with previous value */ | 104 | /* Step 1 - compute difference with previous value */ |
105 | diff = val - valpred; | 105 | diff = val - valpred; |
106 | sign = (diff < 0) ? 8 : 0; | 106 | sign = (diff < 0) ? 8 : 0; |
107 | if ( sign ) diff = (-diff); | 107 | if ( sign ) diff = (-diff); |
108 | 108 | ||
109 | /* Step 2 - Divide and clamp */ | 109 | /* Step 2 - Divide and clamp */ |
110 | /* Note: | 110 | /* Note: |
111 | ** This code *approximately* computes: | 111 | ** This code *approximately* computes: |
112 | ** delta = diff*4/step; | 112 | ** delta = diff*4/step; |
113 | ** vpdiff = (delta+0.5)*step/4; | 113 | ** vpdiff = (delta+0.5)*step/4; |
114 | ** but in shift step bits are dropped. The net result of this is | 114 | ** but in shift step bits are dropped. The net result of this is |
115 | ** that even if you have fast mul/div hardware you cannot put it to | 115 | ** that even if you have fast mul/div hardware you cannot put it to |
116 | ** good use since the fixup would be too expensive. | 116 | ** good use since the fixup would be too expensive. |
117 | */ | 117 | */ |
118 | delta = 0; | 118 | delta = 0; |
119 | vpdiff = (step >> 3); | 119 | vpdiff = (step >> 3); |
120 | 120 | ||
121 | if ( diff >= step ) { | 121 | if ( diff >= step ) { |
122 | delta = 4; | 122 | delta = 4; |
123 | diff -= step; | 123 | diff -= step; |
124 | vpdiff += step; | 124 | vpdiff += step; |
125 | } | 125 | } |
126 | step >>= 1; | 126 | step >>= 1; |
127 | if ( diff >= step ) { | 127 | if ( diff >= step ) { |
128 | delta |= 2; | 128 | delta |= 2; |
129 | diff -= step; | 129 | diff -= step; |
130 | vpdiff += step; | 130 | vpdiff += step; |
131 | } | 131 | } |
132 | step >>= 1; | 132 | step >>= 1; |
133 | if ( diff >= step ) { | 133 | if ( diff >= step ) { |
134 | delta |= 1; | 134 | delta |= 1; |
135 | vpdiff += step; | 135 | vpdiff += step; |
136 | } | 136 | } |
137 | 137 | ||
138 | /* Step 3 - Update previous value */ | 138 | /* Step 3 - Update previous value */ |
139 | if ( sign ) | 139 | if ( sign ) |
140 | valpred -= vpdiff; | 140 | valpred -= vpdiff; |
141 | else | 141 | else |
142 | valpred += vpdiff; | 142 | valpred += vpdiff; |
143 | 143 | ||
144 | /* Step 4 - Clamp previous value to 16 bits */ | 144 | /* Step 4 - Clamp previous value to 16 bits */ |
145 | if ( valpred > 32767 ) | 145 | if ( valpred > 32767 ) |
146 | valpred = 32767; | 146 | valpred = 32767; |
147 | else if ( valpred < -32768 ) | 147 | else if ( valpred < -32768 ) |
148 | valpred = -32768; | 148 | valpred = -32768; |
149 | 149 | ||
150 | /* Step 5 - Assemble value, update index and step values */ | 150 | /* Step 5 - Assemble value, update index and step values */ |
151 | delta |= sign; | 151 | delta |= sign; |
152 | 152 | ||
153 | index += indexTable[delta]; | 153 | index += indexTable[delta]; |
154 | if ( index < 0 ) index = 0; | 154 | if ( index < 0 ) index = 0; |
155 | if ( index > 88 ) index = 88; | 155 | if ( index > 88 ) index = 88; |
156 | step = stepsizeTable[index]; | 156 | step = stepsizeTable[index]; |
157 | 157 | ||
158 | /* Step 6 - Output value */ | 158 | /* Step 6 - Output value */ |
159 | if ( bufferstep ) { | 159 | if ( bufferstep ) { |
160 | outputbuffer = (delta << 4) & 0xf0; | 160 | outputbuffer = (delta << 4) & 0xf0; |
161 | } else { | 161 | } else { |
162 | *outp++ = (delta & 0x0f) | outputbuffer; | 162 | *outp++ = (delta & 0x0f) | outputbuffer; |
163 | } | 163 | } |
164 | bufferstep = !bufferstep; | 164 | bufferstep = !bufferstep; |
165 | } | 165 | } |
166 | 166 | ||
167 | /* Output last step, if needed */ | 167 | /* Output last step, if needed */ |
168 | if ( !bufferstep ) | 168 | if ( !bufferstep ) |
169 | *outp++ = outputbuffer; | 169 | *outp++ = outputbuffer; |
170 | 170 | ||
171 | state->valprev = valpred; | 171 | state->valprev = valpred; |
172 | state->index = index; | 172 | state->index = index; |
173 | } | 173 | } |
174 | 174 | ||
175 | void | 175 | void |
176 | adpcm_decoder(indata, outdata, len, state) | 176 | adpcm_decoder(indata, outdata, len, state) |
177 | char indata[]; | 177 | char indata[]; |
178 | short outdata[]; | 178 | short outdata[]; |
179 | int len; | 179 | int len; |
180 | struct adpcm_state *state; | 180 | struct adpcm_state *state; |
181 | { | 181 | { |
182 | signed char *inp; /* Input buffer pointer */ | 182 | signed char *inp; /* Input buffer pointer */ |
183 | short *outp; /* output buffer pointer */ | 183 | short *outp; /* output buffer pointer */ |
184 | int sign; /* Current adpcm sign bit */ | 184 | int sign; /* Current adpcm sign bit */ |
185 | int delta; /* Current adpcm output value */ | 185 | int delta; /* Current adpcm output value */ |
186 | int step; /* Stepsize */ | 186 | int step; /* Stepsize */ |
187 | int valpred; /* Predicted value */ | 187 | int valpred; /* Predicted value */ |
188 | int vpdiff; /* Current change to valpred */ | 188 | int vpdiff; /* Current change to valpred */ |
189 | int index; /* Current step change index */ | 189 | int index; /* Current step change index */ |
190 | int inputbuffer; /* place to keep next 4-bit value */ | 190 | int inputbuffer = 0; /* place to keep next 4-bit value */ |
191 | int bufferstep; /* toggle between inputbuffer/input */ | 191 | int bufferstep = 0; /* toggle between inputbuffer/input */ |
192 | 192 | ||
193 | outp = outdata; | 193 | outp = outdata; |
194 | inp = (signed char *)indata; | 194 | inp = (signed char *)indata; |
195 | 195 | ||
196 | valpred = state->valprev; | 196 | valpred = state->valprev; |
197 | index = state->index; | 197 | index = state->index; |
198 | step = stepsizeTable[index]; | 198 | step = stepsizeTable[index]; |
199 | 199 | ||
200 | bufferstep = 0; | 200 | bufferstep = 0; |
201 | 201 | ||
202 | for ( ; len > 0 ; len-- ) { | 202 | for ( ; len > 0 ; len-- ) { |
203 | 203 | ||
204 | /* Step 1 - get the delta value */ | 204 | /* Step 1 - get the delta value */ |
205 | if ( bufferstep ) { | 205 | if ( bufferstep ) { |
206 | delta = inputbuffer & 0xf; | 206 | delta = inputbuffer & 0xf; |
207 | } else { | 207 | } else { |
208 | inputbuffer = *inp++; | 208 | inputbuffer = *inp++; |
209 | delta = (inputbuffer >> 4) & 0xf; | 209 | delta = (inputbuffer >> 4) & 0xf; |
210 | } | 210 | } |
211 | bufferstep = !bufferstep; | 211 | bufferstep = !bufferstep; |
212 | 212 | ||
213 | /* Step 2 - Find new index value (for later) */ | 213 | /* Step 2 - Find new index value (for later) */ |
214 | index += indexTable[delta]; | 214 | index += indexTable[delta]; |
215 | if ( index < 0 ) index = 0; | 215 | if ( index < 0 ) index = 0; |
216 | if ( index > 88 ) index = 88; | 216 | if ( index > 88 ) index = 88; |
217 | 217 | ||
218 | /* Step 3 - Separate sign and magnitude */ | 218 | /* Step 3 - Separate sign and magnitude */ |
219 | sign = delta & 8; | 219 | sign = delta & 8; |
220 | delta = delta & 7; | 220 | delta = delta & 7; |
221 | 221 | ||
222 | /* Step 4 - Compute difference and new predicted value */ | 222 | /* Step 4 - Compute difference and new predicted value */ |
223 | /* | 223 | /* |
224 | ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment | 224 | ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment |
225 | ** in adpcm_coder. | 225 | ** in adpcm_coder. |
226 | */ | 226 | */ |
227 | vpdiff = step >> 3; | 227 | vpdiff = step >> 3; |
228 | if ( delta & 4 ) vpdiff += step; | 228 | if ( delta & 4 ) vpdiff += step; |
229 | if ( delta & 2 ) vpdiff += step>>1; | 229 | if ( delta & 2 ) vpdiff += step>>1; |
230 | if ( delta & 1 ) vpdiff += step>>2; | 230 | if ( delta & 1 ) vpdiff += step>>2; |
231 | 231 | ||
232 | if ( sign ) | 232 | if ( sign ) |
233 | valpred -= vpdiff; | 233 | valpred -= vpdiff; |
234 | else | 234 | else |
235 | valpred += vpdiff; | 235 | valpred += vpdiff; |
236 | 236 | ||
237 | /* Step 5 - clamp output value */ | 237 | /* Step 5 - clamp output value */ |
238 | if ( valpred > 32767 ) | 238 | if ( valpred > 32767 ) |
239 | valpred = 32767; | 239 | valpred = 32767; |
240 | else if ( valpred < -32768 ) | 240 | else if ( valpred < -32768 ) |
241 | valpred = -32768; | 241 | valpred = -32768; |
242 | 242 | ||
243 | /* Step 6 - Update step value */ | 243 | /* Step 6 - Update step value */ |
244 | step = stepsizeTable[index]; | 244 | step = stepsizeTable[index]; |
245 | 245 | ||
246 | /* Step 7 - Output value */ | 246 | /* Step 7 - Output value */ |
247 | *outp++ = valpred; | 247 | *outp++ = valpred; |
248 | } | 248 | } |
249 | 249 | ||
250 | state->valprev = valpred; | 250 | state->valprev = valpred; |
251 | state->index = index; | 251 | state->index = index; |
252 | } | 252 | } |