xref: /third_party/libsnd/src/ALAC/dp_dec.c (revision b815c7f3)
1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License") ;
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *	 http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21/*
22	File:		dp_dec.c
23
24	Contains:	Dynamic Predictor decode routines
25
26	Copyright:	(c) 2001-2011 Apple, Inc.
27*/
28
29
30#include <string.h>
31
32#include "dplib.h"
33#include "shift.h"
34
35#if __GNUC__
36#define ALWAYS_INLINE		__attribute__ ((always_inline))
37#elif defined _MSC_VER
38#define ALWAYS_INLINE		__forceinline
39#else
40#define ALWAYS_INLINE
41#endif
42
43#define LOOP_ALIGN
44
45static inline int32_t ALWAYS_INLINE
46sign_of_int (int32_t i)
47{
48	int32_t negishift ;
49
50	negishift = ((uint32_t) - i) >> 31 ;
51	return negishift | (i >> 31) ;
52}
53
54void
55unpc_block (const int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift)
56{
57	register int16_t	a0, a1, a2, a3 ;
58	register int32_t	b0, b1, b2, b3 ;
59	int32_t					j, k, lim ;
60	int32_t				sum1, sg, sgn, top, dd ;
61	int32_t *			pout ;
62	int32_t				del, del0 ;
63	uint32_t			chanshift = 32 - chanbits ;
64	int32_t				denhalf = 1 << (denshift - 1) ;
65
66	out [0] = pc1 [0] ;
67	if (numactive == 0)
68	{
69		// just copy if numactive == 0 (but don't bother if in/out pointers the same)
70		if ((num > 1) && (pc1 != out))
71			memcpy (&out [1], &pc1 [1], (num - 1) * sizeof (int32_t)) ;
72		return ;
73	}
74	if (numactive == 31)
75	{
76		// short-circuit if numactive == 31
77		int32_t		prev ;
78
79		/*	this code is written such that the in/out buffers can be the same
80			to conserve buffer space on embedded devices like the iPod
81
82			(original code)
83			for (j = 1 ; j < num ; j++)
84				del = pc1 [j] + out [j-1] ;
85				out [j] = (del << chanshift) >> chanshift ;
86		*/
87		prev = out [0] ;
88		for (j = 1 ; j < num ; j++)
89		{
90			del = pc1 [j] + prev ;
91			prev = (del << chanshift) >> chanshift ;
92			out [j] = prev ;
93		}
94		return ;
95	}
96
97	for (j = 1 ; j <= numactive ; j++)
98	{
99		del = pc1 [j] + out [j-1] ;
100		out [j] = arith_shift_left (del, chanshift) >> chanshift ;
101	}
102
103	lim = numactive + 1 ;
104
105	if (numactive == 4)
106	{
107		// optimization for numactive == 4
108		register int16_t	ia0, ia1, ia2, ia3 ;
109		register int32_t	ib0, ib1, ib2, ib3 ;
110
111		ia0 = coefs [0] ;
112		ia1 = coefs [1] ;
113		ia2 = coefs [2] ;
114		ia3 = coefs [3] ;
115
116		for (j = lim ; j < num ; j++)
117		{
118			LOOP_ALIGN
119
120			top = out [j - lim] ;
121			pout = out + j - 1 ;
122
123			ib0 = top - pout [0] ;
124			ib1 = top - pout [-1] ;
125			ib2 = top - pout [-2] ;
126			ib3 = top - pout [-3] ;
127
128			sum1 = (denhalf - ia0 * ib0 - ia1 * ib1 - ia2 * ib2 - ia3 * ib3) >> denshift ;
129
130			del = pc1 [j] ;
131			del0 = del ;
132			sg = sign_of_int (del) ;
133			del += top + sum1 ;
134
135			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
136
137			if (sg > 0)
138			{
139				sgn = sign_of_int (ib3) ;
140				ia3 -= sgn ;
141				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
142				if (del0 <= 0)
143					continue ;
144
145				sgn = sign_of_int (ib2) ;
146				ia2 -= sgn ;
147				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
148				if (del0 <= 0)
149					continue ;
150
151				sgn = sign_of_int (ib1) ;
152				ia1 -= sgn ;
153				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
154				if (del0 <= 0)
155					continue ;
156
157				ia0 -= sign_of_int (ib0) ;
158			}
159			else if (sg < 0)
160			{
161				// note: to avoid unnecessary negations, we flip the value of "sgn"
162				sgn = -sign_of_int (ib3) ;
163				ia3 -= sgn ;
164				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
165				if (del0 >= 0)
166					continue ;
167
168				sgn = -sign_of_int (ib2) ;
169				ia2 -= sgn ;
170				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
171				if (del0 >= 0)
172					continue ;
173
174				sgn = -sign_of_int (ib1) ;
175				ia1 -= sgn ;
176				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
177				if (del0 >= 0)
178					continue ;
179
180				ia0 += sign_of_int (ib0) ;
181			}
182		}
183
184		coefs [0] = ia0 ;
185		coefs [1] = ia1 ;
186		coefs [2] = ia2 ;
187		coefs [3] = ia3 ;
188	}
189	else if (numactive == 8)
190	{
191		register int16_t	a4, a5, a6, a7 ;
192		register int32_t	b4, b5, b6, b7 ;
193
194		// optimization for numactive == 8
195		a0 = coefs [0] ;
196		a1 = coefs [1] ;
197		a2 = coefs [2] ;
198		a3 = coefs [3] ;
199		a4 = coefs [4] ;
200		a5 = coefs [5] ;
201		a6 = coefs [6] ;
202		a7 = coefs [7] ;
203
204		for (j = lim ; j < num ; j++)
205		{
206			LOOP_ALIGN
207
208			top = out [j - lim] ;
209			pout = out + j - 1 ;
210
211			b0 = top - (*pout--) ;
212			b1 = top - (*pout--) ;
213			b2 = top - (*pout--) ;
214			b3 = top - (*pout--) ;
215			b4 = top - (*pout--) ;
216			b5 = top - (*pout--) ;
217			b6 = top - (*pout--) ;
218			b7 = top - (*pout) ;
219			pout += 8 ;
220
221			sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
222					- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift ;
223
224			del = pc1 [j] ;
225			del0 = del ;
226			sg = sign_of_int (del) ;
227			del += top + sum1 ;
228
229			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
230
231			if (sg > 0)
232			{
233				sgn = sign_of_int (b7) ;
234				a7 -= sgn ;
235				del0 -= 1 * ((sgn * b7) >> denshift) ;
236				if (del0 <= 0)
237					continue ;
238
239				sgn = sign_of_int (b6) ;
240				a6 -= sgn ;
241				del0 -= 2 * ((sgn * b6) >> denshift) ;
242				if (del0 <= 0)
243					continue ;
244
245				sgn = sign_of_int (b5) ;
246				a5 -= sgn ;
247				del0 -= 3 * ((sgn * b5) >> denshift) ;
248				if (del0 <= 0)
249					continue ;
250
251				sgn = sign_of_int (b4) ;
252				a4 -= sgn ;
253				del0 -= 4 * ((sgn * b4) >> denshift) ;
254				if (del0 <= 0)
255					continue ;
256
257				sgn = sign_of_int (b3) ;
258				a3 -= sgn ;
259				del0 -= 5 * ((sgn * b3) >> denshift) ;
260				if (del0 <= 0)
261					continue ;
262
263				sgn = sign_of_int (b2) ;
264				a2 -= sgn ;
265				del0 -= 6 * ((sgn * b2) >> denshift) ;
266				if (del0 <= 0)
267					continue ;
268
269				sgn = sign_of_int (b1) ;
270				a1 -= sgn ;
271				del0 -= 7 * ((sgn * b1) >> denshift) ;
272				if (del0 <= 0)
273					continue ;
274
275				a0 -= sign_of_int (b0) ;
276			}
277			else if (sg < 0)
278			{
279				// note: to avoid unnecessary negations, we flip the value of "sgn"
280				sgn = -sign_of_int (b7) ;
281				a7 -= sgn ;
282				del0 -= 1 * ((sgn * b7) >> denshift) ;
283				if (del0 >= 0)
284					continue ;
285
286				sgn = -sign_of_int (b6) ;
287				a6 -= sgn ;
288				del0 -= 2 * ((sgn * b6) >> denshift) ;
289				if (del0 >= 0)
290					continue ;
291
292				sgn = -sign_of_int (b5) ;
293				a5 -= sgn ;
294				del0 -= 3 * ((sgn * b5) >> denshift) ;
295				if (del0 >= 0)
296					continue ;
297
298				sgn = -sign_of_int (b4) ;
299				a4 -= sgn ;
300				del0 -= 4 * ((sgn * b4) >> denshift) ;
301				if (del0 >= 0)
302					continue ;
303
304				sgn = -sign_of_int (b3) ;
305				a3 -= sgn ;
306				del0 -= 5 * ((sgn * b3) >> denshift) ;
307				if (del0 >= 0)
308					continue ;
309
310				sgn = -sign_of_int (b2) ;
311				a2 -= sgn ;
312				del0 -= 6 * ((sgn * b2) >> denshift) ;
313				if (del0 >= 0)
314					continue ;
315
316				sgn = -sign_of_int (b1) ;
317				a1 -= sgn ;
318				del0 -= 7 * ((sgn * b1) >> denshift) ;
319				if (del0 >= 0)
320					continue ;
321
322				a0 += sign_of_int (b0) ;
323			}
324		}
325
326		coefs [0] = a0 ;
327		coefs [1] = a1 ;
328		coefs [2] = a2 ;
329		coefs [3] = a3 ;
330		coefs [4] = a4 ;
331		coefs [5] = a5 ;
332		coefs [6] = a6 ;
333		coefs [7] = a7 ;
334	}
335	else
336	{
337		// general case
338		for (j = lim ; j < num ; j++)
339		{
340			LOOP_ALIGN
341
342			sum1 = 0 ;
343			pout = out + j - 1 ;
344			top = out [j-lim] ;
345
346			for (k = 0 ; k < numactive ; k++)
347				sum1 += coefs [k] * (pout [-k] - top) ;
348
349			del = pc1 [j] ;
350			del0 = del ;
351			sg = sign_of_int (del) ;
352			del += top + ((sum1 + denhalf) >> denshift) ;
353			out [j] = (del << chanshift) >> chanshift ;
354
355			if (sg > 0)
356			{
357				for (k = (numactive - 1) ; k >= 0 ; k--)
358				{
359					dd = top - pout [-k] ;
360					sgn = sign_of_int (dd) ;
361					coefs [k] -= sgn ;
362					del0 -= (numactive - k) * ((sgn * dd) >> denshift) ;
363					if (del0 <= 0)
364						break ;
365				}
366			}
367			else if (sg < 0)
368			{
369				for (k = (numactive - 1) ; k >= 0 ; k--)
370				{
371					dd = top - pout [-k] ;
372					sgn = sign_of_int (dd) ;
373					coefs [k] += sgn ;
374					del0 -= (numactive - k) * ((-sgn * dd) >> denshift) ;
375					if (del0 >= 0)
376						break ;
377				}
378			}
379		}
380	}
381}
382