1b815c7f3Sopenharmony_ci/*
2b815c7f3Sopenharmony_ci * Copyright (c) 2011 Apple Inc. All rights reserved.
3b815c7f3Sopenharmony_ci * Copyright (C) 2012-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
4b815c7f3Sopenharmony_ci *
5b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_START@
6b815c7f3Sopenharmony_ci *
7b815c7f3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License") ;
8b815c7f3Sopenharmony_ci * you may not use this file except in compliance with the License.
9b815c7f3Sopenharmony_ci * You may obtain a copy of the License at
10b815c7f3Sopenharmony_ci *
11b815c7f3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
12b815c7f3Sopenharmony_ci *
13b815c7f3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14b815c7f3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15b815c7f3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16b815c7f3Sopenharmony_ci * See the License for the specific language governing permissions and
17b815c7f3Sopenharmony_ci * limitations under the License.
18b815c7f3Sopenharmony_ci *
19b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_END@
20b815c7f3Sopenharmony_ci */
21b815c7f3Sopenharmony_ci
22b815c7f3Sopenharmony_ci/*
23b815c7f3Sopenharmony_ci	File:		matrix_dec.c
24b815c7f3Sopenharmony_ci
25b815c7f3Sopenharmony_ci	Contains:	ALAC mixing/matrixing decode routines.
26b815c7f3Sopenharmony_ci
27b815c7f3Sopenharmony_ci	Copyright:	(c) 2004-2011 Apple, Inc.
28b815c7f3Sopenharmony_ci*/
29b815c7f3Sopenharmony_ci
30b815c7f3Sopenharmony_ci#include "matrixlib.h"
31b815c7f3Sopenharmony_ci#include "ALACAudioTypes.h"
32b815c7f3Sopenharmony_ci#include "shift.h"
33b815c7f3Sopenharmony_ci
34b815c7f3Sopenharmony_ci// up to 24-bit "offset" macros for the individual bytes of a 20/24-bit word
35b815c7f3Sopenharmony_ci#if TARGET_RT_BIG_ENDIAN
36b815c7f3Sopenharmony_ci	#define LBYTE	2
37b815c7f3Sopenharmony_ci	#define MBYTE	1
38b815c7f3Sopenharmony_ci	#define HBYTE	0
39b815c7f3Sopenharmony_ci#else
40b815c7f3Sopenharmony_ci	#define LBYTE	0
41b815c7f3Sopenharmony_ci	#define MBYTE	1
42b815c7f3Sopenharmony_ci	#define HBYTE	2
43b815c7f3Sopenharmony_ci#endif
44b815c7f3Sopenharmony_ci
45b815c7f3Sopenharmony_ci/*
46b815c7f3Sopenharmony_ci    There is no plain middle-side option ; instead there are various mixing
47b815c7f3Sopenharmony_ci    modes including middle-side, each lossless, as embodied in the mix ()
48b815c7f3Sopenharmony_ci    and unmix () functions.  These functions exploit a generalized middle-side
49b815c7f3Sopenharmony_ci    transformation:
50b815c7f3Sopenharmony_ci
51b815c7f3Sopenharmony_ci    u := [(rL + (m-r)R)/m] ;
52b815c7f3Sopenharmony_ci    v := L - R ;
53b815c7f3Sopenharmony_ci
54b815c7f3Sopenharmony_ci    where [ ] denotes integer floor.  The (lossless) inverse is
55b815c7f3Sopenharmony_ci
56b815c7f3Sopenharmony_ci    L = u + v - [rV/m] ;
57b815c7f3Sopenharmony_ci    R = L - v ;
58b815c7f3Sopenharmony_ci*/
59b815c7f3Sopenharmony_ci
60b815c7f3Sopenharmony_ci// 16-bit routines
61b815c7f3Sopenharmony_ci
62b815c7f3Sopenharmony_civoid
63b815c7f3Sopenharmony_ciunmix16 (const int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres)
64b815c7f3Sopenharmony_ci{
65b815c7f3Sopenharmony_ci	int32_t 	j ;
66b815c7f3Sopenharmony_ci
67b815c7f3Sopenharmony_ci	if (mixres != 0)
68b815c7f3Sopenharmony_ci	{
69b815c7f3Sopenharmony_ci		/* matrixed stereo */
70b815c7f3Sopenharmony_ci		for (j = 0 ; j < numSamples ; j++)
71b815c7f3Sopenharmony_ci		{
72b815c7f3Sopenharmony_ci			int32_t		l, r ;
73b815c7f3Sopenharmony_ci
74b815c7f3Sopenharmony_ci			l = u [j] + v [j] - ((mixres * v [j]) >> mixbits) ;
75b815c7f3Sopenharmony_ci			r = l - v [j] ;
76b815c7f3Sopenharmony_ci
77b815c7f3Sopenharmony_ci			out [0] = arith_shift_left (l, 16) ;
78b815c7f3Sopenharmony_ci			out [1] = arith_shift_left (r, 16) ;
79b815c7f3Sopenharmony_ci			out += stride ;
80b815c7f3Sopenharmony_ci		}
81b815c7f3Sopenharmony_ci	}
82b815c7f3Sopenharmony_ci	else
83b815c7f3Sopenharmony_ci	{
84b815c7f3Sopenharmony_ci		/* Conventional separated stereo. */
85b815c7f3Sopenharmony_ci		for (j = 0 ; j < numSamples ; j++)
86b815c7f3Sopenharmony_ci		{
87b815c7f3Sopenharmony_ci			out [0] = u [j] << 16 ;
88b815c7f3Sopenharmony_ci			out [1] = v [j] << 16 ;
89b815c7f3Sopenharmony_ci			out += stride ;
90b815c7f3Sopenharmony_ci		}
91b815c7f3Sopenharmony_ci	}
92b815c7f3Sopenharmony_ci}
93b815c7f3Sopenharmony_ci
94b815c7f3Sopenharmony_ci// 20-bit routines
95b815c7f3Sopenharmony_ci// - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers
96b815c7f3Sopenharmony_ci
97b815c7f3Sopenharmony_civoid
98b815c7f3Sopenharmony_ciunmix20 (const int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres)
99b815c7f3Sopenharmony_ci{
100b815c7f3Sopenharmony_ci	int32_t 	j ;
101b815c7f3Sopenharmony_ci
102b815c7f3Sopenharmony_ci	if (mixres != 0)
103b815c7f3Sopenharmony_ci	{
104b815c7f3Sopenharmony_ci		/* matrixed stereo */
105b815c7f3Sopenharmony_ci		for (j = 0 ; j < numSamples ; j++)
106b815c7f3Sopenharmony_ci		{
107b815c7f3Sopenharmony_ci			int32_t		l, r ;
108b815c7f3Sopenharmony_ci
109b815c7f3Sopenharmony_ci			l = u [j] + v [j] - ((mixres * v [j]) >> mixbits) ;
110b815c7f3Sopenharmony_ci			r = l - v [j] ;
111b815c7f3Sopenharmony_ci
112b815c7f3Sopenharmony_ci			out [0] = arith_shift_left (l, 12) ;
113b815c7f3Sopenharmony_ci			out [1] = arith_shift_left (r, 12) ;
114b815c7f3Sopenharmony_ci			out += stride ;
115b815c7f3Sopenharmony_ci		}
116b815c7f3Sopenharmony_ci	}
117b815c7f3Sopenharmony_ci	else
118b815c7f3Sopenharmony_ci	{
119b815c7f3Sopenharmony_ci		/* Conventional separated stereo. */
120b815c7f3Sopenharmony_ci		for (j = 0 ; j < numSamples ; j++)
121b815c7f3Sopenharmony_ci		{
122b815c7f3Sopenharmony_ci			out [0] = arith_shift_left (u [j], 12) ;
123b815c7f3Sopenharmony_ci			out [1] = arith_shift_left (v [j], 12) ;
124b815c7f3Sopenharmony_ci			out += stride ;
125b815c7f3Sopenharmony_ci		}
126b815c7f3Sopenharmony_ci	}
127b815c7f3Sopenharmony_ci}
128b815c7f3Sopenharmony_ci
129b815c7f3Sopenharmony_ci// 24-bit routines
130b815c7f3Sopenharmony_ci// - the 24 bits of data are right-justified in the input/output predictor buffers
131b815c7f3Sopenharmony_ci
132b815c7f3Sopenharmony_civoid
133b815c7f3Sopenharmony_ciunmix24 (const int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
134b815c7f3Sopenharmony_ci				int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted)
135b815c7f3Sopenharmony_ci{
136b815c7f3Sopenharmony_ci	int32_t		shift = bytesShifted * 8 ;
137b815c7f3Sopenharmony_ci	int32_t		l, r ;
138b815c7f3Sopenharmony_ci	int32_t 		j, k ;
139b815c7f3Sopenharmony_ci
140b815c7f3Sopenharmony_ci	if (mixres != 0)
141b815c7f3Sopenharmony_ci	{
142b815c7f3Sopenharmony_ci		/* matrixed stereo */
143b815c7f3Sopenharmony_ci		if (bytesShifted != 0)
144b815c7f3Sopenharmony_ci		{
145b815c7f3Sopenharmony_ci			for (j = 0, k = 0 ; j < numSamples ; j++, k += 2)
146b815c7f3Sopenharmony_ci			{
147b815c7f3Sopenharmony_ci				l = u [j] + v [j] - ((mixres * v [j]) >> mixbits) ;
148b815c7f3Sopenharmony_ci				r = l - v [j] ;
149b815c7f3Sopenharmony_ci
150b815c7f3Sopenharmony_ci				l = arith_shift_left (l, shift) | (uint32_t) shiftUV [k + 0] ;
151b815c7f3Sopenharmony_ci				r = arith_shift_left (r, shift) | (uint32_t) shiftUV [k + 1] ;
152b815c7f3Sopenharmony_ci
153b815c7f3Sopenharmony_ci				out [0] = arith_shift_left (l, 8) ;
154b815c7f3Sopenharmony_ci				out [1] = arith_shift_left (r, 8) ;
155b815c7f3Sopenharmony_ci				out += stride ;
156b815c7f3Sopenharmony_ci			}
157b815c7f3Sopenharmony_ci		}
158b815c7f3Sopenharmony_ci		else
159b815c7f3Sopenharmony_ci		{
160b815c7f3Sopenharmony_ci			for (j = 0 ; j < numSamples ; j++)
161b815c7f3Sopenharmony_ci			{
162b815c7f3Sopenharmony_ci				l = u [j] + v [j] - ((mixres * v [j]) >> mixbits) ;
163b815c7f3Sopenharmony_ci				r = l - v [j] ;
164b815c7f3Sopenharmony_ci
165b815c7f3Sopenharmony_ci				out [0] = l << 8 ;
166b815c7f3Sopenharmony_ci				out [1] = r << 8 ;
167b815c7f3Sopenharmony_ci				out += stride ;
168b815c7f3Sopenharmony_ci			}
169b815c7f3Sopenharmony_ci		}
170b815c7f3Sopenharmony_ci	}
171b815c7f3Sopenharmony_ci	else
172b815c7f3Sopenharmony_ci	{
173b815c7f3Sopenharmony_ci		/* Conventional separated stereo. */
174b815c7f3Sopenharmony_ci		if (bytesShifted != 0)
175b815c7f3Sopenharmony_ci		{
176b815c7f3Sopenharmony_ci			for (j = 0, k = 0 ; j < numSamples ; j++, k += 2)
177b815c7f3Sopenharmony_ci			{
178b815c7f3Sopenharmony_ci				l = u [j] ;
179b815c7f3Sopenharmony_ci				r = v [j] ;
180b815c7f3Sopenharmony_ci
181b815c7f3Sopenharmony_ci				l = (l << shift) | (uint32_t) shiftUV [k + 0] ;
182b815c7f3Sopenharmony_ci				r = (r << shift) | (uint32_t) shiftUV [k + 1] ;
183b815c7f3Sopenharmony_ci
184b815c7f3Sopenharmony_ci				out [0] = l << 8 ;
185b815c7f3Sopenharmony_ci				out [1] = r << 8 ;
186b815c7f3Sopenharmony_ci				out += stride ;
187b815c7f3Sopenharmony_ci			}
188b815c7f3Sopenharmony_ci		}
189b815c7f3Sopenharmony_ci		else
190b815c7f3Sopenharmony_ci		{
191b815c7f3Sopenharmony_ci			for (j = 0 ; j < numSamples ; j++)
192b815c7f3Sopenharmony_ci			{
193b815c7f3Sopenharmony_ci				out [0] = u [j] << 8 ;
194b815c7f3Sopenharmony_ci				out [1] = v [j] << 8 ;
195b815c7f3Sopenharmony_ci				out += stride ;
196b815c7f3Sopenharmony_ci			}
197b815c7f3Sopenharmony_ci		}
198b815c7f3Sopenharmony_ci	}
199b815c7f3Sopenharmony_ci}
200b815c7f3Sopenharmony_ci
201b815c7f3Sopenharmony_ci// 32-bit routines
202b815c7f3Sopenharmony_ci// - note that these really expect the internal data width to be < 32 but the arrays are 32-bit
203b815c7f3Sopenharmony_ci// - otherwise, the calculations might overflow into the 33rd bit and be lost
204b815c7f3Sopenharmony_ci// - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers
205b815c7f3Sopenharmony_ci
206b815c7f3Sopenharmony_civoid
207b815c7f3Sopenharmony_ciunmix32 (const int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
208b815c7f3Sopenharmony_ci				int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted)
209b815c7f3Sopenharmony_ci{
210b815c7f3Sopenharmony_ci	int32_t		shift = bytesShifted * 8 ;
211b815c7f3Sopenharmony_ci	int32_t		l, r ;
212b815c7f3Sopenharmony_ci	int32_t 	j, k ;
213b815c7f3Sopenharmony_ci
214b815c7f3Sopenharmony_ci	if (mixres != 0)
215b815c7f3Sopenharmony_ci	{
216b815c7f3Sopenharmony_ci		//Assert (bytesShifted != 0) ;
217b815c7f3Sopenharmony_ci
218b815c7f3Sopenharmony_ci		/* matrixed stereo with shift */
219b815c7f3Sopenharmony_ci		for (j = 0, k = 0 ; j < numSamples ; j++, k += 2)
220b815c7f3Sopenharmony_ci		{
221b815c7f3Sopenharmony_ci			int32_t		lt, rt ;
222b815c7f3Sopenharmony_ci
223b815c7f3Sopenharmony_ci			lt = u [j] ;
224b815c7f3Sopenharmony_ci			rt = v [j] ;
225b815c7f3Sopenharmony_ci
226b815c7f3Sopenharmony_ci			l = lt + rt - ((mixres * rt) >> mixbits) ;
227b815c7f3Sopenharmony_ci			r = l - rt ;
228b815c7f3Sopenharmony_ci
229b815c7f3Sopenharmony_ci			out [0] = arith_shift_left (l, shift) | (uint32_t) shiftUV [k + 0] ;
230b815c7f3Sopenharmony_ci			out [1] = arith_shift_left (r, shift) | (uint32_t) shiftUV [k + 1] ;
231b815c7f3Sopenharmony_ci			out += stride ;
232b815c7f3Sopenharmony_ci		}
233b815c7f3Sopenharmony_ci	}
234b815c7f3Sopenharmony_ci	else
235b815c7f3Sopenharmony_ci	{
236b815c7f3Sopenharmony_ci		if (bytesShifted == 0)
237b815c7f3Sopenharmony_ci		{
238b815c7f3Sopenharmony_ci			/* interleaving w/o shift */
239b815c7f3Sopenharmony_ci			for (j = 0 ; j < numSamples ; j++)
240b815c7f3Sopenharmony_ci			{
241b815c7f3Sopenharmony_ci				out [0] = u [j] ;
242b815c7f3Sopenharmony_ci				out [1] = v [j] ;
243b815c7f3Sopenharmony_ci				out += stride ;
244b815c7f3Sopenharmony_ci			}
245b815c7f3Sopenharmony_ci		}
246b815c7f3Sopenharmony_ci		else
247b815c7f3Sopenharmony_ci		{
248b815c7f3Sopenharmony_ci			/* interleaving with shift */
249b815c7f3Sopenharmony_ci			for (j = 0, k = 0 ; j < numSamples ; j++, k += 2)
250b815c7f3Sopenharmony_ci			{
251b815c7f3Sopenharmony_ci				out [0] = (u [j] << shift) | (uint32_t) shiftUV [k + 0] ;
252b815c7f3Sopenharmony_ci				out [1] = (v [j] << shift) | (uint32_t) shiftUV [k + 1] ;
253b815c7f3Sopenharmony_ci				out += stride ;
254b815c7f3Sopenharmony_ci			}
255b815c7f3Sopenharmony_ci		}
256b815c7f3Sopenharmony_ci	}
257b815c7f3Sopenharmony_ci}
258b815c7f3Sopenharmony_ci
259b815c7f3Sopenharmony_ci// 20/24-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
260b815c7f3Sopenharmony_ci
261b815c7f3Sopenharmony_civoid
262b815c7f3Sopenharmony_cicopyPredictorTo24 (const int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples)
263b815c7f3Sopenharmony_ci{
264b815c7f3Sopenharmony_ci	int32_t		j ;
265b815c7f3Sopenharmony_ci
266b815c7f3Sopenharmony_ci	for (j = 0 ; j < numSamples ; j++)
267b815c7f3Sopenharmony_ci	{
268b815c7f3Sopenharmony_ci		out [0] = in [j] << 8 ;
269b815c7f3Sopenharmony_ci		out += stride ;
270b815c7f3Sopenharmony_ci	}
271b815c7f3Sopenharmony_ci}
272b815c7f3Sopenharmony_ci
273b815c7f3Sopenharmony_civoid
274b815c7f3Sopenharmony_cicopyPredictorTo24Shift (const int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted)
275b815c7f3Sopenharmony_ci{
276b815c7f3Sopenharmony_ci	int32_t		shiftVal = bytesShifted * 8 ;
277b815c7f3Sopenharmony_ci	int32_t		j ;
278b815c7f3Sopenharmony_ci
279b815c7f3Sopenharmony_ci	//Assert (bytesShifted != 0) ;
280b815c7f3Sopenharmony_ci
281b815c7f3Sopenharmony_ci	for (j = 0 ; j < numSamples ; j++)
282b815c7f3Sopenharmony_ci	{
283b815c7f3Sopenharmony_ci		int32_t		val = in [j] ;
284b815c7f3Sopenharmony_ci
285b815c7f3Sopenharmony_ci		val = arith_shift_left (val, shiftVal) | (uint32_t) shift [j] ;
286b815c7f3Sopenharmony_ci		out [0] = arith_shift_left (val, 8) ;
287b815c7f3Sopenharmony_ci		out += stride ;
288b815c7f3Sopenharmony_ci	}
289b815c7f3Sopenharmony_ci}
290b815c7f3Sopenharmony_ci
291b815c7f3Sopenharmony_civoid
292b815c7f3Sopenharmony_cicopyPredictorTo20 (const int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples)
293b815c7f3Sopenharmony_ci{
294b815c7f3Sopenharmony_ci	int32_t		j ;
295b815c7f3Sopenharmony_ci
296b815c7f3Sopenharmony_ci	// 32-bit predictor values are right-aligned but 20-bit output values should be left-aligned
297b815c7f3Sopenharmony_ci	// in the 24-bit output buffer
298b815c7f3Sopenharmony_ci	for (j = 0 ; j < numSamples ; j++)
299b815c7f3Sopenharmony_ci	{
300b815c7f3Sopenharmony_ci		out [0] = arith_shift_left (in [j], 12) ;
301b815c7f3Sopenharmony_ci		out += stride ;
302b815c7f3Sopenharmony_ci	}
303b815c7f3Sopenharmony_ci}
304b815c7f3Sopenharmony_ci
305b815c7f3Sopenharmony_civoid
306b815c7f3Sopenharmony_cicopyPredictorTo32 (const int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples)
307b815c7f3Sopenharmony_ci{
308b815c7f3Sopenharmony_ci	int32_t			i, j ;
309b815c7f3Sopenharmony_ci
310b815c7f3Sopenharmony_ci	// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
311b815c7f3Sopenharmony_ci	for (i = 0, j = 0 ; i < numSamples ; i++, j += stride)
312b815c7f3Sopenharmony_ci		out [j] = arith_shift_left (in [i], 8) ;
313b815c7f3Sopenharmony_ci}
314b815c7f3Sopenharmony_ci
315b815c7f3Sopenharmony_civoid
316b815c7f3Sopenharmony_cicopyPredictorTo32Shift (const int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted)
317b815c7f3Sopenharmony_ci{
318b815c7f3Sopenharmony_ci	int32_t *		op = out ;
319b815c7f3Sopenharmony_ci	uint32_t		shiftVal = bytesShifted * 8 ;
320b815c7f3Sopenharmony_ci	int32_t			j ;
321b815c7f3Sopenharmony_ci
322b815c7f3Sopenharmony_ci	//Assert (bytesShifted != 0) ;
323b815c7f3Sopenharmony_ci
324b815c7f3Sopenharmony_ci	// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
325b815c7f3Sopenharmony_ci	for (j = 0 ; j < numSamples ; j++)
326b815c7f3Sopenharmony_ci	{
327b815c7f3Sopenharmony_ci		op [0] = arith_shift_left (in [j], shiftVal) | (uint32_t) shift [j] ;
328b815c7f3Sopenharmony_ci		op += stride ;
329b815c7f3Sopenharmony_ci	}
330b815c7f3Sopenharmony_ci}
331