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