diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libfaad/ic_predict.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libfaad/ic_predict.c')
-rw-r--r-- | lib/rbcodec/codecs/libfaad/ic_predict.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libfaad/ic_predict.c b/lib/rbcodec/codecs/libfaad/ic_predict.c new file mode 100644 index 0000000000..02cadd65b1 --- /dev/null +++ b/lib/rbcodec/codecs/libfaad/ic_predict.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | ||
3 | ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com | ||
4 | ** | ||
5 | ** This program is free software; you can redistribute it and/or modify | ||
6 | ** it under the terms of the GNU General Public License as published by | ||
7 | ** the Free Software Foundation; either version 2 of the License, or | ||
8 | ** (at your option) any later version. | ||
9 | ** | ||
10 | ** This program is distributed in the hope that it will be useful, | ||
11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | ** GNU General Public License for more details. | ||
14 | ** | ||
15 | ** You should have received a copy of the GNU General Public License | ||
16 | ** along with this program; if not, write to the Free Software | ||
17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | ** | ||
19 | ** Any non-GPL usage of this software or parts of this software is strictly | ||
20 | ** forbidden. | ||
21 | ** | ||
22 | ** Commercial non-GPL licensing of this software is possible. | ||
23 | ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | ||
24 | ** | ||
25 | ** $Id$ | ||
26 | **/ | ||
27 | |||
28 | #include "common.h" | ||
29 | #include "structs.h" | ||
30 | |||
31 | #ifdef MAIN_DEC | ||
32 | |||
33 | #include "syntax.h" | ||
34 | #include "ic_predict.h" | ||
35 | #include "pns.h" | ||
36 | |||
37 | |||
38 | static void flt_round(float32_t *pf) | ||
39 | { | ||
40 | int32_t flg; | ||
41 | uint32_t tmp, tmp1, tmp2; | ||
42 | |||
43 | tmp = *(uint32_t*)pf; | ||
44 | flg = tmp & (uint32_t)0x00008000; | ||
45 | tmp &= (uint32_t)0xffff0000; | ||
46 | tmp1 = tmp; | ||
47 | /* round 1/2 lsb toward infinity */ | ||
48 | if (flg) | ||
49 | { | ||
50 | tmp &= (uint32_t)0xff800000; /* extract exponent and sign */ | ||
51 | tmp |= (uint32_t)0x00010000; /* insert 1 lsb */ | ||
52 | tmp2 = tmp; /* add 1 lsb and elided one */ | ||
53 | tmp &= (uint32_t)0xff800000; /* extract exponent and sign */ | ||
54 | |||
55 | *pf = *(float32_t*)&tmp1 + *(float32_t*)&tmp2 - *(float32_t*)&tmp; | ||
56 | } else { | ||
57 | *pf = *(float32_t*)&tmp; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static int16_t quant_pred(float32_t x) | ||
62 | { | ||
63 | int16_t q; | ||
64 | uint32_t *tmp = (uint32_t*)&x; | ||
65 | |||
66 | q = (int16_t)(*tmp>>16); | ||
67 | |||
68 | return q; | ||
69 | } | ||
70 | |||
71 | static float32_t inv_quant_pred(int16_t q) | ||
72 | { | ||
73 | float32_t x; | ||
74 | uint32_t *tmp = (uint32_t*)&x; | ||
75 | *tmp = ((uint32_t)q)<<16; | ||
76 | |||
77 | return x; | ||
78 | } | ||
79 | |||
80 | static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred) | ||
81 | { | ||
82 | uint16_t tmp; | ||
83 | int16_t i, j; | ||
84 | real_t dr1, predictedvalue; | ||
85 | real_t e0, e1; | ||
86 | real_t k1, k2; | ||
87 | |||
88 | real_t r[2]; | ||
89 | real_t COR[2]; | ||
90 | real_t VAR[2]; | ||
91 | |||
92 | r[0] = inv_quant_pred(state->r[0]); | ||
93 | r[1] = inv_quant_pred(state->r[1]); | ||
94 | COR[0] = inv_quant_pred(state->COR[0]); | ||
95 | COR[1] = inv_quant_pred(state->COR[1]); | ||
96 | VAR[0] = inv_quant_pred(state->VAR[0]); | ||
97 | VAR[1] = inv_quant_pred(state->VAR[1]); | ||
98 | |||
99 | |||
100 | #if 1 | ||
101 | tmp = state->VAR[0]; | ||
102 | j = (tmp >> 7); | ||
103 | i = tmp & 0x7f; | ||
104 | if (j >= 128) | ||
105 | { | ||
106 | j -= 128; | ||
107 | k1 = COR[0] * exp_table[j] * mnt_table[i]; | ||
108 | } else { | ||
109 | k1 = REAL_CONST(0); | ||
110 | } | ||
111 | #else | ||
112 | |||
113 | { | ||
114 | #define B 0.953125 | ||
115 | real_t c = COR[0]; | ||
116 | real_t v = VAR[0]; | ||
117 | real_t tmp; | ||
118 | if (c == 0 || v <= 1) | ||
119 | { | ||
120 | k1 = 0; | ||
121 | } else { | ||
122 | tmp = B / v; | ||
123 | flt_round(&tmp); | ||
124 | k1 = c * tmp; | ||
125 | } | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | if (pred) | ||
130 | { | ||
131 | #if 1 | ||
132 | tmp = state->VAR[1]; | ||
133 | j = (tmp >> 7); | ||
134 | i = tmp & 0x7f; | ||
135 | if (j >= 128) | ||
136 | { | ||
137 | j -= 128; | ||
138 | k2 = COR[1] * exp_table[j] * mnt_table[i]; | ||
139 | } else { | ||
140 | k2 = REAL_CONST(0); | ||
141 | } | ||
142 | #else | ||
143 | |||
144 | #define B 0.953125 | ||
145 | real_t c = COR[1]; | ||
146 | real_t v = VAR[1]; | ||
147 | real_t tmp; | ||
148 | if (c == 0 || v <= 1) | ||
149 | { | ||
150 | k2 = 0; | ||
151 | } else { | ||
152 | tmp = B / v; | ||
153 | flt_round(&tmp); | ||
154 | k2 = c * tmp; | ||
155 | } | ||
156 | #endif | ||
157 | |||
158 | predictedvalue = k1*r[0] + k2*r[1]; | ||
159 | flt_round(&predictedvalue); | ||
160 | *output = input + predictedvalue; | ||
161 | } | ||
162 | |||
163 | /* calculate new state data */ | ||
164 | e0 = *output; | ||
165 | e1 = e0 - k1*r[0]; | ||
166 | dr1 = k1*e0; | ||
167 | |||
168 | VAR[0] = ALPHA*VAR[0] + 0.5f * (r[0]*r[0] + e0*e0); | ||
169 | COR[0] = ALPHA*COR[0] + r[0]*e0; | ||
170 | VAR[1] = ALPHA*VAR[1] + 0.5f * (r[1]*r[1] + e1*e1); | ||
171 | COR[1] = ALPHA*COR[1] + r[1]*e1; | ||
172 | |||
173 | r[1] = A * (r[0]-dr1); | ||
174 | r[0] = A * e0; | ||
175 | |||
176 | state->r[0] = quant_pred(r[0]); | ||
177 | state->r[1] = quant_pred(r[1]); | ||
178 | state->COR[0] = quant_pred(COR[0]); | ||
179 | state->COR[1] = quant_pred(COR[1]); | ||
180 | state->VAR[0] = quant_pred(VAR[0]); | ||
181 | state->VAR[1] = quant_pred(VAR[1]); | ||
182 | } | ||
183 | |||
184 | static void reset_pred_state(pred_state *state) | ||
185 | { | ||
186 | state->r[0] = 0; | ||
187 | state->r[1] = 0; | ||
188 | state->COR[0] = 0; | ||
189 | state->COR[1] = 0; | ||
190 | state->VAR[0] = 0x3F80; | ||
191 | state->VAR[1] = 0x3F80; | ||
192 | } | ||
193 | |||
194 | void pns_reset_pred_state(ic_stream *ics, pred_state *state) | ||
195 | { | ||
196 | uint8_t sfb, g, b; | ||
197 | uint16_t i, offs, offs2; | ||
198 | |||
199 | /* prediction only for long blocks */ | ||
200 | if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) | ||
201 | return; | ||
202 | |||
203 | for (g = 0; g < ics->num_window_groups; g++) | ||
204 | { | ||
205 | for (b = 0; b < ics->window_group_length[g]; b++) | ||
206 | { | ||
207 | for (sfb = 0; sfb < ics->max_sfb; sfb++) | ||
208 | { | ||
209 | if (is_noise(ics, g, sfb)) | ||
210 | { | ||
211 | offs = ics->swb_offset[sfb]; | ||
212 | offs2 = ics->swb_offset[sfb+1]; | ||
213 | |||
214 | for (i = offs; i < offs2; i++) | ||
215 | reset_pred_state(&state[i]); | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | void reset_all_predictors(pred_state *state, uint16_t frame_len) | ||
223 | { | ||
224 | uint16_t i; | ||
225 | |||
226 | for (i = 0; i < frame_len; i++) | ||
227 | reset_pred_state(&state[i]); | ||
228 | } | ||
229 | |||
230 | /* intra channel prediction */ | ||
231 | void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state, | ||
232 | uint16_t frame_len, uint8_t sf_index) | ||
233 | { | ||
234 | uint8_t sfb; | ||
235 | uint16_t bin; | ||
236 | |||
237 | if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) | ||
238 | { | ||
239 | reset_all_predictors(state, frame_len); | ||
240 | } else { | ||
241 | for (sfb = 0; sfb < max_pred_sfb(sf_index); sfb++) | ||
242 | { | ||
243 | uint16_t low = ics->swb_offset[sfb]; | ||
244 | uint16_t high = ics->swb_offset[sfb+1]; | ||
245 | |||
246 | for (bin = low; bin < high; bin++) | ||
247 | { | ||
248 | ic_predict(&state[bin], spec[bin], &spec[bin], | ||
249 | (ics->predictor_data_present && ics->pred.prediction_used[sfb])); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | if (ics->predictor_data_present) | ||
254 | { | ||
255 | if (ics->pred.predictor_reset) | ||
256 | { | ||
257 | for (bin = ics->pred.predictor_reset_group_number - 1; | ||
258 | bin < frame_len; bin += 30) | ||
259 | { | ||
260 | reset_pred_state(&state[bin]); | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | #endif | ||