2 * COOK compatible decoder, fixed point implementation.
3 * Copyright (c) 2007 Ian Braithwaite
5 * This file is part of FFmpeg.
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.
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.
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
24 * @file cook_fixpoint.h
26 * Cook AKA RealAudio G2 fixed point functions.
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.
39 /* get definitions of MULT31, MULT31_SHIFT15, CLIP_TO_15, vect_add, from codelib */
41 #include "asm_mcf5249.h"
42 #include "codeclib_misc.h"
46 /* cplscales was moved from cookdata_fixpoint.h since only *
47 * cook_fixpoint.h should see/use it. */
48 static const FIXPU
* cplscales
[5] = {
49 cplscale2
, cplscale3
, cplscale4
, cplscale5
, cplscale6
53 * Fixed point multiply by power of two.
55 * @param x fix point value
56 * @param i integer power-of-two, -31..+31
58 static inline FIXP
fixp_pow2(FIXP x
, int i
)
61 return (x
>> -i
) + ((x
>> (-i
-1)) & 1);
63 return x
<< i
; /* no check for overflow */
66 static inline FIXP
fixp_pow2_neg(FIXP x
, int i
)
68 return (x
>> i
) + ((x
>> (i
-1)) & 1);
72 * Fixed point multiply by fraction.
74 * @param a fix point value
75 * @param b fix point fraction, 0 <= b < 1
78 #define fixp_mult_su(x,y) (MULT31_SHIFT15(x,y))
80 static inline FIXP
fixp_mult_su(FIXP a
, FIXPU b
)
82 int32_t hb
= (a
>> 16) * b
;
83 uint32_t lb
= (a
& 0xffff) * b
;
85 return hb
+ (lb
>> 16) + ((lb
& 0x8000) >> 15);
89 /* Faster version of the above using 32x32=64 bit multiply */
91 #define fixmul31(x,y) (MULT31(x,y))
93 static inline int32_t fixmul31(int32_t x
, int32_t y
)
100 temp
>>= 31; //16+31-16 = 31 bits
102 return (int32_t)temp
;
107 * Clips a signed integer value into the amin-amax range.
108 * @param a value to clip
109 * @param amin minimum value of the clip range
110 * @param amax maximum value of the clip range
111 * @return clipped value
113 static inline int av_clip(int a
, int amin
, int amax
)
115 if (a
< amin
) return amin
;
116 else if (a
> amax
) return amax
;
121 * The real requantization of the mltcoefs
123 * @param q pointer to the COOKContext
125 * @param quant_index quantisation index for this band
126 * @param subband_coef_index array of indexes to quant_centroid_tab
127 * @param subband_coef_sign use random noise instead of predetermined value
128 * @param mlt_ptr pointer to the mlt coefficients
130 static void scalar_dequant_math(COOKContext
*q
, int index
,
131 int quant_index
, int* subband_coef_index
,
132 int* subband_coef_sign
, REAL_T
*mlt_p
)
134 /* Num. half bits to right shift */
135 const int s
= (33 - quant_index
+ av_log2(q
->samples_per_channel
)) >> 1;
136 const FIXP
*table
= quant_tables
[s
& 1][index
];
142 memset(mlt_p
, 0, sizeof(REAL_T
)*SUBBAND_SIZE
);
145 for(i
=0 ; i
<SUBBAND_SIZE
; i
++) {
146 f
= table
[subband_coef_index
[i
]];
147 /* noise coding if subband_coef_index[i] == 0 */
148 if (((subband_coef_index
[i
] == 0) && cook_random(q
)) ||
149 ((subband_coef_index
[i
] != 0) && subband_coef_sign
[i
]))
152 *mlt_p
++ = fixp_pow2_neg(f
, s
);
158 * The modulated lapped transform, this takes transform coefficients
159 * and transforms them into timedomain samples.
160 * A window step is also included.
162 * @param q pointer to the COOKContext
163 * @param inbuffer pointer to the mltcoefficients
164 * @param outbuffer pointer to the timedomain buffer
165 * @param mlt_tmp pointer to temporary storage space
167 #include "../lib/mdct_lookup.h"
169 void imlt_math(COOKContext
*q
, FIXP
*in
) ICODE_ATTR
;
170 void imlt_math(COOKContext
*q
, FIXP
*in
)
172 const int n
= q
->samples_per_channel
;
173 const int step
= 2 << (10 - av_log2(n
));
176 ff_imdct_calc(q
->mdct_nbits
, q
->mono_mdct_output
, in
);
179 FIXP tmp
= q
->mono_mdct_output
[i
];
181 q
->mono_mdct_output
[i
] =
182 fixmul31(-q
->mono_mdct_output
[n
+ i
], (sincos_lookup0
[j
]));
184 q
->mono_mdct_output
[n
+ i
] = fixmul31(tmp
, (sincos_lookup0
[j
+1]) );
191 FIXP tmp
= q
->mono_mdct_output
[i
];
194 q
->mono_mdct_output
[i
] =
195 fixmul31(-q
->mono_mdct_output
[n
+ i
], (sincos_lookup0
[j
+1]) );
196 q
->mono_mdct_output
[n
+ i
] = fixmul31(tmp
, (sincos_lookup0
[j
]) );
201 * Perform buffer overlapping.
203 * @param q pointer to the COOKContext
204 * @param gain gain correction to apply first to output buffer
205 * @param buffer data to overlap
207 void overlap_math(COOKContext
*q
, int gain
, FIXP buffer
[]) ICODE_ATTR
;
208 void overlap_math(COOKContext
*q
, int gain
, FIXP buffer
[])
212 if(LIKELY(gain
== 0))
214 vect_add(q
->mono_mdct_output
, buffer
, q
->samples_per_channel
);
216 } else if (gain
> 0){
217 for(i
=0 ; i
<q
->samples_per_channel
; i
++) {
218 q
->mono_mdct_output
[i
] = (q
->mono_mdct_output
[i
]<< gain
) + buffer
[i
]; }
221 for(i
=0 ; i
<q
->samples_per_channel
; i
++) {
222 q
->mono_mdct_output
[i
] =
223 (q
->mono_mdct_output
[i
] >> -gain
) + ((q
->mono_mdct_output
[i
] >> (-gain
-1)) & 1)+ buffer
[i
];
227 for(i
=0 ; i
<q
->samples_per_channel
; i
++) {
228 q
->mono_mdct_output
[i
] =
229 fixp_pow2(q
->mono_mdct_output
[i
], gain
) + buffer
[i
];
236 * the actual requantization of the timedomain samples
238 * @param q pointer to the COOKContext
239 * @param buffer pointer to the timedomain buffer
240 * @param gain_index index for the block multiplier
241 * @param gain_index_next index for the next block multiplier
244 interpolate_math(COOKContext
*q
, register FIXP
* buffer
,
245 int gain_index
, int gain_index_next
)
248 int gain_size_factor
= q
->samples_per_channel
/ 8;
250 if(gain_index
== gain_index_next
){ //static gain
251 for(i
= 0; i
< gain_size_factor
; i
++) {
252 buffer
[i
] = fixp_pow2(buffer
[i
], gain_index
);
254 } else { //smooth gain
255 int step
= (gain_index_next
- gain_index
)
256 << (7 - av_log2(gain_size_factor
));
258 register FIXP
* bufferend
= buffer
+gain_size_factor
;
259 while(buffer
< bufferend
)
262 fixp_mult_su(*buffer
, pow128_tab
[x
]),
267 gain_index
+= ( (x
+ 128) >> 7 ) - 1;
268 x
= ( (x
+ 128) & 127 );
275 * Decoupling calculation for joint stereo coefficients.
277 * @param x mono coefficient
278 * @param table number of decoupling table
279 * @param i table index
281 static inline FIXP
cplscale_math(FIXP x
, int table
, int i
)
283 return fixp_mult_su(x
, cplscales
[table
-2][i
]);