summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/demac/libdemac/predictor.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/demac/libdemac/predictor.c')
-rw-r--r--lib/rbcodec/codecs/demac/libdemac/predictor.c271
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
3libdemac - A Monkey's Audio decoder
4
5$Id$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, 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
35static 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
49void 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)
71void 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
213void 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