diff options
Diffstat (limited to 'lib/rbcodec/codecs/demac/libdemac/predictor.c')
-rw-r--r-- | lib/rbcodec/codecs/demac/libdemac/predictor.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/demac/libdemac/predictor.c b/lib/rbcodec/codecs/demac/libdemac/predictor.c new file mode 100644 index 0000000000..45912dddbd --- /dev/null +++ b/lib/rbcodec/codecs/demac/libdemac/predictor.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | |||
3 | libdemac - A Monkey's Audio decoder | ||
4 | |||
5 | $Id$ | ||
6 | |||
7 | Copyright (C) Dave Chapman 2007 | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include <inttypes.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | #include "parser.h" | ||
29 | #include "predictor.h" | ||
30 | #include "demac_config.h" | ||
31 | |||
32 | /* Return 0 if x is zero, -1 if x is positive, 1 if x is negative */ | ||
33 | #define SIGN(x) (x) ? (((x) > 0) ? -1 : 1) : 0 | ||
34 | |||
35 | static const int32_t initial_coeffs[4] = { | ||
36 | 360, 317, -109, 98 | ||
37 | }; | ||
38 | |||
39 | #define YDELAYA (18 + PREDICTOR_ORDER*4) | ||
40 | #define YDELAYB (18 + PREDICTOR_ORDER*3) | ||
41 | #define XDELAYA (18 + PREDICTOR_ORDER*2) | ||
42 | #define XDELAYB (18 + PREDICTOR_ORDER) | ||
43 | |||
44 | #define YADAPTCOEFFSA (18) | ||
45 | #define XADAPTCOEFFSA (14) | ||
46 | #define YADAPTCOEFFSB (10) | ||
47 | #define XADAPTCOEFFSB (5) | ||
48 | |||
49 | void init_predictor_decoder(struct predictor_t* p) | ||
50 | { | ||
51 | /* Zero the history buffers */ | ||
52 | memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t)); | ||
53 | p->buf = p->historybuffer; | ||
54 | |||
55 | /* Initialise and zero the co-efficients */ | ||
56 | memcpy(p->YcoeffsA, initial_coeffs, sizeof(initial_coeffs)); | ||
57 | memcpy(p->XcoeffsA, initial_coeffs, sizeof(initial_coeffs)); | ||
58 | memset(p->YcoeffsB, 0, sizeof(p->YcoeffsB)); | ||
59 | memset(p->XcoeffsB, 0, sizeof(p->XcoeffsB)); | ||
60 | |||
61 | p->YfilterA = 0; | ||
62 | p->YfilterB = 0; | ||
63 | p->YlastA = 0; | ||
64 | |||
65 | p->XfilterA = 0; | ||
66 | p->XfilterB = 0; | ||
67 | p->XlastA = 0; | ||
68 | } | ||
69 | |||
70 | #if !defined(CPU_ARM) && !defined(CPU_COLDFIRE) | ||
71 | void ICODE_ATTR_DEMAC predictor_decode_stereo(struct predictor_t* p, | ||
72 | int32_t* decoded0, | ||
73 | int32_t* decoded1, | ||
74 | int count) | ||
75 | { | ||
76 | int32_t predictionA, predictionB; | ||
77 | |||
78 | while (LIKELY(count--)) | ||
79 | { | ||
80 | /* Predictor Y */ | ||
81 | p->buf[YDELAYA] = p->YlastA; | ||
82 | p->buf[YADAPTCOEFFSA] = SIGN(p->buf[YDELAYA]); | ||
83 | |||
84 | p->buf[YDELAYA-1] = p->buf[YDELAYA] - p->buf[YDELAYA-1]; | ||
85 | p->buf[YADAPTCOEFFSA-1] = SIGN(p->buf[YDELAYA-1]); | ||
86 | |||
87 | predictionA = (p->buf[YDELAYA] * p->YcoeffsA[0]) + | ||
88 | (p->buf[YDELAYA-1] * p->YcoeffsA[1]) + | ||
89 | (p->buf[YDELAYA-2] * p->YcoeffsA[2]) + | ||
90 | (p->buf[YDELAYA-3] * p->YcoeffsA[3]); | ||
91 | |||
92 | /* Apply a scaled first-order filter compression */ | ||
93 | p->buf[YDELAYB] = p->XfilterA - ((p->YfilterB * 31) >> 5); | ||
94 | p->buf[YADAPTCOEFFSB] = SIGN(p->buf[YDELAYB]); | ||
95 | p->YfilterB = p->XfilterA; | ||
96 | |||
97 | p->buf[YDELAYB-1] = p->buf[YDELAYB] - p->buf[YDELAYB-1]; | ||
98 | p->buf[YADAPTCOEFFSB-1] = SIGN(p->buf[YDELAYB-1]); | ||
99 | |||
100 | predictionB = (p->buf[YDELAYB] * p->YcoeffsB[0]) + | ||
101 | (p->buf[YDELAYB-1] * p->YcoeffsB[1]) + | ||
102 | (p->buf[YDELAYB-2] * p->YcoeffsB[2]) + | ||
103 | (p->buf[YDELAYB-3] * p->YcoeffsB[3]) + | ||
104 | (p->buf[YDELAYB-4] * p->YcoeffsB[4]); | ||
105 | |||
106 | p->YlastA = *decoded0 + ((predictionA + (predictionB >> 1)) >> 10); | ||
107 | p->YfilterA = p->YlastA + ((p->YfilterA * 31) >> 5); | ||
108 | |||
109 | /* Predictor X */ | ||
110 | |||
111 | p->buf[XDELAYA] = p->XlastA; | ||
112 | p->buf[XADAPTCOEFFSA] = SIGN(p->buf[XDELAYA]); | ||
113 | p->buf[XDELAYA-1] = p->buf[XDELAYA] - p->buf[XDELAYA-1]; | ||
114 | p->buf[XADAPTCOEFFSA-1] = SIGN(p->buf[XDELAYA-1]); | ||
115 | |||
116 | predictionA = (p->buf[XDELAYA] * p->XcoeffsA[0]) + | ||
117 | (p->buf[XDELAYA-1] * p->XcoeffsA[1]) + | ||
118 | (p->buf[XDELAYA-2] * p->XcoeffsA[2]) + | ||
119 | (p->buf[XDELAYA-3] * p->XcoeffsA[3]); | ||
120 | |||
121 | /* Apply a scaled first-order filter compression */ | ||
122 | p->buf[XDELAYB] = p->YfilterA - ((p->XfilterB * 31) >> 5); | ||
123 | p->buf[XADAPTCOEFFSB] = SIGN(p->buf[XDELAYB]); | ||
124 | p->XfilterB = p->YfilterA; | ||
125 | p->buf[XDELAYB-1] = p->buf[XDELAYB] - p->buf[XDELAYB-1]; | ||
126 | p->buf[XADAPTCOEFFSB-1] = SIGN(p->buf[XDELAYB-1]); | ||
127 | |||
128 | predictionB = (p->buf[XDELAYB] * p->XcoeffsB[0]) + | ||
129 | (p->buf[XDELAYB-1] * p->XcoeffsB[1]) + | ||
130 | (p->buf[XDELAYB-2] * p->XcoeffsB[2]) + | ||
131 | (p->buf[XDELAYB-3] * p->XcoeffsB[3]) + | ||
132 | (p->buf[XDELAYB-4] * p->XcoeffsB[4]); | ||
133 | |||
134 | p->XlastA = *decoded1 + ((predictionA + (predictionB >> 1)) >> 10); | ||
135 | p->XfilterA = p->XlastA + ((p->XfilterA * 31) >> 5); | ||
136 | |||
137 | if (LIKELY(*decoded0 != 0)) | ||
138 | { | ||
139 | if (*decoded0 > 0) | ||
140 | { | ||
141 | p->YcoeffsA[0] -= p->buf[YADAPTCOEFFSA]; | ||
142 | p->YcoeffsA[1] -= p->buf[YADAPTCOEFFSA-1]; | ||
143 | p->YcoeffsA[2] -= p->buf[YADAPTCOEFFSA-2]; | ||
144 | p->YcoeffsA[3] -= p->buf[YADAPTCOEFFSA-3]; | ||
145 | |||
146 | p->YcoeffsB[0] -= p->buf[YADAPTCOEFFSB]; | ||
147 | p->YcoeffsB[1] -= p->buf[YADAPTCOEFFSB-1]; | ||
148 | p->YcoeffsB[2] -= p->buf[YADAPTCOEFFSB-2]; | ||
149 | p->YcoeffsB[3] -= p->buf[YADAPTCOEFFSB-3]; | ||
150 | p->YcoeffsB[4] -= p->buf[YADAPTCOEFFSB-4]; | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | p->YcoeffsA[0] += p->buf[YADAPTCOEFFSA]; | ||
155 | p->YcoeffsA[1] += p->buf[YADAPTCOEFFSA-1]; | ||
156 | p->YcoeffsA[2] += p->buf[YADAPTCOEFFSA-2]; | ||
157 | p->YcoeffsA[3] += p->buf[YADAPTCOEFFSA-3]; | ||
158 | |||
159 | p->YcoeffsB[0] += p->buf[YADAPTCOEFFSB]; | ||
160 | p->YcoeffsB[1] += p->buf[YADAPTCOEFFSB-1]; | ||
161 | p->YcoeffsB[2] += p->buf[YADAPTCOEFFSB-2]; | ||
162 | p->YcoeffsB[3] += p->buf[YADAPTCOEFFSB-3]; | ||
163 | p->YcoeffsB[4] += p->buf[YADAPTCOEFFSB-4]; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | *(decoded0++) = p->YfilterA; | ||
168 | |||
169 | if (LIKELY(*decoded1 != 0)) | ||
170 | { | ||
171 | if (*decoded1 > 0) | ||
172 | { | ||
173 | p->XcoeffsA[0] -= p->buf[XADAPTCOEFFSA]; | ||
174 | p->XcoeffsA[1] -= p->buf[XADAPTCOEFFSA-1]; | ||
175 | p->XcoeffsA[2] -= p->buf[XADAPTCOEFFSA-2]; | ||
176 | p->XcoeffsA[3] -= p->buf[XADAPTCOEFFSA-3]; | ||
177 | |||
178 | p->XcoeffsB[0] -= p->buf[XADAPTCOEFFSB]; | ||
179 | p->XcoeffsB[1] -= p->buf[XADAPTCOEFFSB-1]; | ||
180 | p->XcoeffsB[2] -= p->buf[XADAPTCOEFFSB-2]; | ||
181 | p->XcoeffsB[3] -= p->buf[XADAPTCOEFFSB-3]; | ||
182 | p->XcoeffsB[4] -= p->buf[XADAPTCOEFFSB-4]; | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | p->XcoeffsA[0] += p->buf[XADAPTCOEFFSA]; | ||
187 | p->XcoeffsA[1] += p->buf[XADAPTCOEFFSA-1]; | ||
188 | p->XcoeffsA[2] += p->buf[XADAPTCOEFFSA-2]; | ||
189 | p->XcoeffsA[3] += p->buf[XADAPTCOEFFSA-3]; | ||
190 | |||
191 | p->XcoeffsB[0] += p->buf[XADAPTCOEFFSB]; | ||
192 | p->XcoeffsB[1] += p->buf[XADAPTCOEFFSB-1]; | ||
193 | p->XcoeffsB[2] += p->buf[XADAPTCOEFFSB-2]; | ||
194 | p->XcoeffsB[3] += p->buf[XADAPTCOEFFSB-3]; | ||
195 | p->XcoeffsB[4] += p->buf[XADAPTCOEFFSB-4]; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | *(decoded1++) = p->XfilterA; | ||
200 | |||
201 | /* Combined */ | ||
202 | p->buf++; | ||
203 | |||
204 | /* Have we filled the history buffer? */ | ||
205 | if (UNLIKELY(p->buf == p->historybuffer + PREDICTOR_HISTORY_SIZE)) { | ||
206 | memmove(p->historybuffer, p->buf, | ||
207 | PREDICTOR_SIZE * sizeof(int32_t)); | ||
208 | p->buf = p->historybuffer; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | void ICODE_ATTR_DEMAC predictor_decode_mono(struct predictor_t* p, | ||
214 | int32_t* decoded0, | ||
215 | int count) | ||
216 | { | ||
217 | int32_t predictionA, currentA, A; | ||
218 | |||
219 | currentA = p->YlastA; | ||
220 | |||
221 | while (LIKELY(count--)) | ||
222 | { | ||
223 | A = *decoded0; | ||
224 | |||
225 | p->buf[YDELAYA] = currentA; | ||
226 | p->buf[YDELAYA-1] = p->buf[YDELAYA] - p->buf[YDELAYA-1]; | ||
227 | |||
228 | predictionA = (p->buf[YDELAYA] * p->YcoeffsA[0]) + | ||
229 | (p->buf[YDELAYA-1] * p->YcoeffsA[1]) + | ||
230 | (p->buf[YDELAYA-2] * p->YcoeffsA[2]) + | ||
231 | (p->buf[YDELAYA-3] * p->YcoeffsA[3]); | ||
232 | |||
233 | currentA = A + (predictionA >> 10); | ||
234 | |||
235 | p->buf[YADAPTCOEFFSA] = SIGN(p->buf[YDELAYA]); | ||
236 | p->buf[YADAPTCOEFFSA-1] = SIGN(p->buf[YDELAYA-1]); | ||
237 | |||
238 | if (LIKELY(A != 0)) | ||
239 | { | ||
240 | if (A > 0) | ||
241 | { | ||
242 | p->YcoeffsA[0] -= p->buf[YADAPTCOEFFSA]; | ||
243 | p->YcoeffsA[1] -= p->buf[YADAPTCOEFFSA-1]; | ||
244 | p->YcoeffsA[2] -= p->buf[YADAPTCOEFFSA-2]; | ||
245 | p->YcoeffsA[3] -= p->buf[YADAPTCOEFFSA-3]; | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | p->YcoeffsA[0] += p->buf[YADAPTCOEFFSA]; | ||
250 | p->YcoeffsA[1] += p->buf[YADAPTCOEFFSA-1]; | ||
251 | p->YcoeffsA[2] += p->buf[YADAPTCOEFFSA-2]; | ||
252 | p->YcoeffsA[3] += p->buf[YADAPTCOEFFSA-3]; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | p->buf++; | ||
257 | |||
258 | /* Have we filled the history buffer? */ | ||
259 | if (UNLIKELY(p->buf == p->historybuffer + PREDICTOR_HISTORY_SIZE)) { | ||
260 | memmove(p->historybuffer, p->buf, | ||
261 | PREDICTOR_SIZE * sizeof(int32_t)); | ||
262 | p->buf = p->historybuffer; | ||
263 | } | ||
264 | |||
265 | p->YfilterA = currentA + ((p->YfilterA * 31) >> 5); | ||
266 | *(decoded0++) = p->YfilterA; | ||
267 | } | ||
268 | |||
269 | p->YlastA = currentA; | ||
270 | } | ||
271 | #endif | ||