annotate src/libsndfile-1.0.27/src/ALAC/dp_dec.c @ 164:9fa11135915a

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