diff options
Diffstat (limited to 'lib/rbcodec/codecs/libcook/cook_fixpoint.h')
-rw-r--r-- | lib/rbcodec/codecs/libcook/cook_fixpoint.h | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libcook/cook_fixpoint.h b/lib/rbcodec/codecs/libcook/cook_fixpoint.h new file mode 100644 index 0000000000..5c4a5d1a5a --- /dev/null +++ b/lib/rbcodec/codecs/libcook/cook_fixpoint.h | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * COOK compatible decoder, fixed point implementation. | ||
3 | * Copyright (c) 2007 Ian Braithwaite | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /** | ||
24 | * @file cook_fixpoint.h | ||
25 | * | ||
26 | * Cook AKA RealAudio G2 fixed point functions. | ||
27 | * | ||
28 | * Fixed point values are represented as 32 bit signed integers, | ||
29 | * which can be added and subtracted directly in C (without checks for | ||
30 | * overflow/saturation. | ||
31 | * Two multiplication routines are provided: | ||
32 | * 1) Multiplication by powers of two (2^-31 .. 2^31), implemented | ||
33 | * with C's bit shift operations. | ||
34 | * 2) Multiplication by 16 bit fractions (0 <= x < 1), implemented | ||
35 | * in C using two 32 bit integer multiplications. | ||
36 | */ | ||
37 | |||
38 | #ifdef ROCKBOX | ||
39 | /* get definitions of MULT31, MULT31_SHIFT16, vect_add, from codelib */ | ||
40 | #include "codeclib_misc.h" | ||
41 | #include "codeclib.h" | ||
42 | #endif | ||
43 | |||
44 | /* cplscales was moved from cookdata_fixpoint.h since only * | ||
45 | * cook_fixpoint.h should see/use it. */ | ||
46 | static const FIXPU* cplscales[5] = { | ||
47 | cplscale2, cplscale3, cplscale4, cplscale5, cplscale6 | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * Fixed point multiply by power of two. | ||
52 | * | ||
53 | * @param x fix point value | ||
54 | * @param i integer power-of-two, -31..+31 | ||
55 | */ | ||
56 | static inline FIXP fixp_pow2(FIXP x, int i) | ||
57 | { | ||
58 | if (i < 0) | ||
59 | return (x >> -i); | ||
60 | else | ||
61 | return x << i; /* no check for overflow */ | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * Fixed point multiply by fraction. | ||
66 | * | ||
67 | * @param a fix point value | ||
68 | * @param b fix point fraction, 0 <= b < 1 | ||
69 | */ | ||
70 | #ifdef ROCKBOX | ||
71 | #define fixp_mult_su(x,y) (MULT31_SHIFT16(x,y)) | ||
72 | #else | ||
73 | static inline FIXP fixp_mult_su(FIXP a, FIXPU b) | ||
74 | { | ||
75 | int32_t hb = (a >> 16) * b; | ||
76 | uint32_t lb = (a & 0xffff) * b; | ||
77 | |||
78 | return hb + (lb >> 16) + ((lb & 0x8000) >> 15); | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | /* Faster version of the above using 32x32=64 bit multiply */ | ||
83 | #ifdef ROCKBOX | ||
84 | #define fixmul31(x,y) (MULT31(x,y)) | ||
85 | #else | ||
86 | static inline int32_t fixmul31(int32_t x, int32_t y) | ||
87 | { | ||
88 | int64_t temp; | ||
89 | |||
90 | temp = x; | ||
91 | temp *= y; | ||
92 | |||
93 | temp >>= 31; //16+31-16 = 31 bits | ||
94 | |||
95 | return (int32_t)temp; | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | /** | ||
100 | * Clips a signed integer value into the amin-amax range. | ||
101 | * @param a value to clip | ||
102 | * @param amin minimum value of the clip range | ||
103 | * @param amax maximum value of the clip range | ||
104 | * @return clipped value | ||
105 | */ | ||
106 | static inline int av_clip(int a, int amin, int amax) | ||
107 | { | ||
108 | if (a < amin) return amin; | ||
109 | else if (a > amax) return amax; | ||
110 | else return a; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * The real requantization of the mltcoefs | ||
115 | * | ||
116 | * @param q pointer to the COOKContext | ||
117 | * @param index index | ||
118 | * @param quant_index quantisation index for this band | ||
119 | * @param subband_coef_index array of indexes to quant_centroid_tab | ||
120 | * @param subband_coef_sign use random noise instead of predetermined value | ||
121 | * @param mlt_ptr pointer to the mlt coefficients | ||
122 | */ | ||
123 | |||
124 | static void scalar_dequant_math(COOKContext *q, int index, | ||
125 | int quant_index, int* subband_coef_index, | ||
126 | int* subband_coef_sign, REAL_T *mlt_p) | ||
127 | ICODE_ATTR_COOK_DECODE; | ||
128 | static void scalar_dequant_math(COOKContext *q, int index, | ||
129 | int quant_index, int* subband_coef_index, | ||
130 | int* subband_coef_sign, REAL_T *mlt_p) | ||
131 | { | ||
132 | /* Num. half bits to right shift */ | ||
133 | const int s = 33 - quant_index + av_log2(q->samples_per_channel); | ||
134 | const FIXP *table = quant_tables[s & 1][index]; | ||
135 | FIXP f; | ||
136 | int i; | ||
137 | |||
138 | |||
139 | if(s >= 64) | ||
140 | memset(mlt_p, 0, sizeof(REAL_T)*SUBBAND_SIZE); | ||
141 | else | ||
142 | { | ||
143 | for(i=0 ; i<SUBBAND_SIZE ; i++) { | ||
144 | f = (table[subband_coef_index[i]]) >> (s >> 1); | ||
145 | /* noise coding if subband_coef_index[i] == 0 */ | ||
146 | if (((subband_coef_index[i] == 0) && cook_random(q)) || | ||
147 | ((subband_coef_index[i] != 0) && subband_coef_sign[i])) | ||
148 | f = -f; | ||
149 | |||
150 | *mlt_p++ = f; | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * The modulated lapped transform, this takes transform coefficients | ||
157 | * and transforms them into timedomain samples. | ||
158 | * A window step is also included. | ||
159 | * | ||
160 | * @param q pointer to the COOKContext | ||
161 | * @param inbuffer pointer to the mltcoefficients | ||
162 | * @param outbuffer pointer to the timedomain buffer | ||
163 | * @param mlt_tmp pointer to temporary storage space | ||
164 | */ | ||
165 | #include "../lib/mdct_lookup.h" | ||
166 | |||
167 | void imlt_math(COOKContext *q, FIXP *in) ICODE_ATTR; | ||
168 | void imlt_math(COOKContext *q, FIXP *in) | ||
169 | { | ||
170 | const int n = q->samples_per_channel; | ||
171 | const int step = 2 << (10 - av_log2(n)); | ||
172 | REAL_T *mdct_out = q->mono_mdct_output; | ||
173 | REAL_T tmp; | ||
174 | int i = 0, j = 0; | ||
175 | |||
176 | ff_imdct_calc(q->mdct_nbits, q->mono_mdct_output, in); | ||
177 | |||
178 | do { | ||
179 | tmp = mdct_out[i]; | ||
180 | mdct_out[i ] = fixmul31(-mdct_out[n+i], (sincos_lookup0[j ])); | ||
181 | mdct_out[n+i] = fixmul31(tmp , (sincos_lookup0[j+1])); | ||
182 | |||
183 | j += step; | ||
184 | } while (++i < n/2); | ||
185 | |||
186 | do { | ||
187 | j -= step; | ||
188 | |||
189 | tmp = mdct_out[i]; | ||
190 | mdct_out[i ] = fixmul31(-mdct_out[n+i], (sincos_lookup0[j+1])); | ||
191 | mdct_out[n+i] = fixmul31(tmp , (sincos_lookup0[j ])); | ||
192 | } while (++i < n); | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * Perform buffer overlapping. | ||
197 | * | ||
198 | * @param q pointer to the COOKContext | ||
199 | * @param gain gain correction to apply first to output buffer | ||
200 | * @param buffer data to overlap | ||
201 | */ | ||
202 | void overlap_math(COOKContext *q, int gain, FIXP buffer[]) ICODE_ATTR; | ||
203 | void overlap_math(COOKContext *q, int gain, FIXP buffer[]) | ||
204 | { | ||
205 | int i; | ||
206 | #ifdef ROCKBOX | ||
207 | if(LIKELY(gain == 0)) | ||
208 | { | ||
209 | vect_add(q->mono_mdct_output, buffer, q->samples_per_channel); | ||
210 | |||
211 | } else if (gain > 0){ | ||
212 | for(i=0 ; i<q->samples_per_channel ; i++) { | ||
213 | q->mono_mdct_output[i] = (q->mono_mdct_output[i]<< gain) + buffer[i]; } | ||
214 | |||
215 | } else { | ||
216 | for(i=0 ; i<q->samples_per_channel ; i++) { | ||
217 | q->mono_mdct_output[i] = (q->mono_mdct_output[i]>>-gain) + buffer[i]; | ||
218 | } | ||
219 | } | ||
220 | #else | ||
221 | for(i=0 ; i<q->samples_per_channel ; i++) { | ||
222 | q->mono_mdct_output[i] = | ||
223 | fixp_pow2(q->mono_mdct_output[i], gain) + buffer[i]; | ||
224 | } | ||
225 | #endif | ||
226 | } | ||
227 | |||
228 | |||
229 | /** | ||
230 | * the actual requantization of the timedomain samples | ||
231 | * | ||
232 | * @param q pointer to the COOKContext | ||
233 | * @param buffer pointer to the timedomain buffer | ||
234 | * @param gain_index index for the block multiplier | ||
235 | * @param gain_index_next index for the next block multiplier | ||
236 | */ | ||
237 | static inline void | ||
238 | interpolate_math(COOKContext *q, register FIXP* buffer, | ||
239 | int gain_index, int gain_index_next) | ||
240 | { | ||
241 | int i; | ||
242 | int gain_size_factor = q->samples_per_channel / 8; | ||
243 | |||
244 | if(gain_index == gain_index_next){ //static gain | ||
245 | for(i = 0; i < gain_size_factor; i++) { | ||
246 | buffer[i] = fixp_pow2(buffer[i], gain_index); | ||
247 | } | ||
248 | } else { //smooth gain | ||
249 | int step = (gain_index_next - gain_index) | ||
250 | << (7 - av_log2(gain_size_factor)); | ||
251 | int x = 0; | ||
252 | register FIXP* bufferend = buffer+gain_size_factor; | ||
253 | while(buffer < bufferend ) | ||
254 | { | ||
255 | *buffer = fixp_pow2( | ||
256 | fixp_mult_su(*buffer, pow128_tab[x]), | ||
257 | gain_index+1); | ||
258 | buffer++; | ||
259 | |||
260 | x += step; | ||
261 | gain_index += ( (x + 128) >> 7 ) - 1; | ||
262 | x = ( (x + 128) & 127 ); | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Decoupling calculation for joint stereo coefficients. | ||
270 | * | ||
271 | * @param x mono coefficient | ||
272 | * @param table number of decoupling table | ||
273 | * @param i table index | ||
274 | */ | ||
275 | static inline FIXP cplscale_math(FIXP x, int table, int i) | ||
276 | { | ||
277 | return fixp_mult_su(x, cplscales[table-2][i]); | ||
278 | } | ||