diff options
Diffstat (limited to 'apps/codecs/libwavpack/words.c')
-rw-r--r-- | apps/codecs/libwavpack/words.c | 238 |
1 files changed, 138 insertions, 100 deletions
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c index 35061b69a9..370c0d4857 100644 --- a/apps/codecs/libwavpack/words.c +++ b/apps/codecs/libwavpack/words.c | |||
@@ -123,9 +123,20 @@ static const uchar exp2_table [] = { | |||
123 | 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff | 123 | 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static const char ones_count_table [] = { | ||
127 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, | ||
128 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, | ||
129 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, | ||
130 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7, | ||
131 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, | ||
132 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, | ||
133 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, | ||
134 | 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 | ||
135 | }; | ||
136 | |||
126 | ///////////////////////////// executable code //////////////////////////////// | 137 | ///////////////////////////// executable code //////////////////////////////// |
127 | 138 | ||
128 | static int log2 (unsigned long avalue); | 139 | static int mylog2 (unsigned long avalue); |
129 | 140 | ||
130 | // Read the median log2 values from the specifed metadata structure, convert | 141 | // Read the median log2 values from the specifed metadata structure, convert |
131 | // them back to 32-bit unsigned values and store them. If length is not | 142 | // them back to 32-bit unsigned values and store them. If length is not |
@@ -270,140 +281,167 @@ static ulong read_code (Bitstream *bs, ulong maxcode); | |||
270 | // of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or | 281 | // of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or |
271 | // some other error occurred. | 282 | // some other error occurred. |
272 | 283 | ||
273 | long get_word (WavpackStream *wps, int chan) | 284 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) |
274 | { | 285 | { |
275 | ulong ones_count, low, mid, high; | 286 | ulong tsamples = nsamples * nchans, ones_count, low, mid, high; |
276 | int sign; | 287 | int next8, sign, chan; |
288 | long *bptr = buffer; | ||
277 | 289 | ||
278 | if (wps->w.zeros_acc) { | 290 | while (tsamples--) { |
279 | if (--wps->w.zeros_acc) { | ||
280 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
281 | return 0; | ||
282 | } | ||
283 | } | ||
284 | else if (!wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [0] & ~1) && !(wps->w.median [0] [1] & ~1)) { | ||
285 | ulong mask; | ||
286 | int cbits; | ||
287 | 291 | ||
288 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | 292 | chan = (nchans == 1) ? 0 : (~tsamples & 1); |
289 | 293 | ||
290 | if (cbits == 33) | 294 | if (!(wps->w.median [0] [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [1] & ~1)) { |
291 | return WORD_EOF; | 295 | ulong mask; |
296 | int cbits; | ||
297 | |||
298 | if (wps->w.zeros_acc) { | ||
299 | if (--wps->w.zeros_acc) { | ||
300 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
301 | *bptr++ = 0; | ||
302 | continue; | ||
303 | } | ||
304 | } | ||
305 | else { | ||
306 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | ||
307 | |||
308 | if (cbits == 33) | ||
309 | break; | ||
310 | |||
311 | if (cbits < 2) | ||
312 | wps->w.zeros_acc = cbits; | ||
313 | else { | ||
314 | for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) | ||
315 | if (getbit (&wps->wvbits)) | ||
316 | wps->w.zeros_acc |= mask; | ||
292 | 317 | ||
293 | if (cbits < 2) | ||
294 | wps->w.zeros_acc = cbits; | ||
295 | else { | ||
296 | for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) | ||
297 | if (getbit (&wps->wvbits)) | ||
298 | wps->w.zeros_acc |= mask; | 318 | wps->w.zeros_acc |= mask; |
319 | } | ||
299 | 320 | ||
300 | wps->w.zeros_acc |= mask; | 321 | if (wps->w.zeros_acc) { |
322 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
323 | CLEAR (wps->w.median); | ||
324 | *bptr++ = 0; | ||
325 | continue; | ||
326 | } | ||
327 | } | ||
301 | } | 328 | } |
302 | 329 | ||
303 | if (wps->w.zeros_acc) { | 330 | if (wps->w.holding_zero) |
304 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | 331 | ones_count = wps->w.holding_zero = 0; |
305 | CLEAR (wps->w.median); | 332 | else { |
306 | return 0; | 333 | if (wps->wvbits.bc < 8) { |
307 | } | 334 | if (++(wps->wvbits.ptr) == wps->wvbits.end) |
308 | } | 335 | wps->wvbits.wrap (&wps->wvbits); |
309 | 336 | ||
310 | if (wps->w.holding_zero) | 337 | next8 = (wps->wvbits.sr |= *(wps->wvbits.ptr) << wps->wvbits.bc) & 0xff; |
311 | ones_count = wps->w.holding_zero = 0; | 338 | wps->wvbits.bc += 8; |
312 | else { | 339 | } |
313 | #ifdef LIMIT_ONES | 340 | else |
314 | for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); | 341 | next8 = wps->wvbits.sr & 0xff; |
315 | 342 | ||
316 | if (ones_count == (LIMIT_ONES + 1)) | 343 | if (next8 == 0xff) { |
317 | return WORD_EOF; | 344 | wps->wvbits.bc -= 8; |
345 | wps->wvbits.sr >>= 8; | ||
318 | 346 | ||
319 | if (ones_count == LIMIT_ONES) { | 347 | for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); |
320 | ulong mask; | ||
321 | int cbits; | ||
322 | 348 | ||
323 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | 349 | if (ones_count == (LIMIT_ONES + 1)) |
350 | break; | ||
324 | 351 | ||
325 | if (cbits == 33) | 352 | if (ones_count == LIMIT_ONES) { |
326 | return WORD_EOF; | 353 | ulong mask; |
354 | int cbits; | ||
355 | |||
356 | for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); | ||
357 | |||
358 | if (cbits == 33) | ||
359 | break; | ||
360 | |||
361 | if (cbits < 2) | ||
362 | ones_count = cbits; | ||
363 | else { | ||
364 | for (mask = 1, ones_count = 0; --cbits; mask <<= 1) | ||
365 | if (getbit (&wps->wvbits)) | ||
366 | ones_count |= mask; | ||
327 | 367 | ||
328 | if (cbits < 2) | ||
329 | ones_count = cbits; | ||
330 | else { | ||
331 | for (mask = 1, ones_count = 0; --cbits; mask <<= 1) | ||
332 | if (getbit (&wps->wvbits)) | ||
333 | ones_count |= mask; | 368 | ones_count |= mask; |
369 | } | ||
334 | 370 | ||
335 | ones_count |= mask; | 371 | ones_count += LIMIT_ONES; |
372 | } | ||
373 | } | ||
374 | else { | ||
375 | wps->wvbits.bc -= (ones_count = ones_count_table [next8]) + 1; | ||
376 | wps->wvbits.sr >>= ones_count + 1; | ||
336 | } | 377 | } |
337 | 378 | ||
338 | ones_count += LIMIT_ONES; | 379 | if (wps->w.holding_one) { |
339 | } | 380 | wps->w.holding_one = ones_count & 1; |
340 | #else | 381 | ones_count = (ones_count >> 1) + 1; |
341 | for (ones_count = 0; getbit (&wps->wvbits); ++ones_count); | 382 | } |
342 | #endif | 383 | else { |
384 | wps->w.holding_one = ones_count & 1; | ||
385 | ones_count >>= 1; | ||
386 | } | ||
343 | 387 | ||
344 | if (wps->w.holding_one) { | 388 | wps->w.holding_zero = ~wps->w.holding_one & 1; |
345 | wps->w.holding_one = ones_count & 1; | ||
346 | ones_count = (ones_count >> 1) + 1; | ||
347 | } | 389 | } |
348 | else { | ||
349 | wps->w.holding_one = ones_count & 1; | ||
350 | ones_count >>= 1; | ||
351 | } | ||
352 | |||
353 | wps->w.holding_zero = ~wps->w.holding_one & 1; | ||
354 | } | ||
355 | 390 | ||
356 | if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) | 391 | if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) |
357 | update_error_limit (wps); | 392 | update_error_limit (wps); |
358 | |||
359 | if (ones_count == 0) { | ||
360 | low = 0; | ||
361 | high = GET_MED (0) - 1; | ||
362 | DEC_MED0 (); | ||
363 | } | ||
364 | else { | ||
365 | low = GET_MED (0); | ||
366 | INC_MED0 (); | ||
367 | 393 | ||
368 | if (ones_count == 1) { | 394 | if (ones_count == 0) { |
369 | high = low + GET_MED (1) - 1; | 395 | low = 0; |
370 | DEC_MED1 (); | 396 | high = GET_MED (0) - 1; |
397 | DEC_MED0 (); | ||
371 | } | 398 | } |
372 | else { | 399 | else { |
373 | low += GET_MED (1); | 400 | low = GET_MED (0); |
374 | INC_MED1 (); | 401 | INC_MED0 (); |
375 | 402 | ||
376 | if (ones_count == 2) { | 403 | if (ones_count == 1) { |
377 | high = low + GET_MED (2) - 1; | 404 | high = low + GET_MED (1) - 1; |
378 | DEC_MED2 (); | 405 | DEC_MED1 (); |
379 | } | 406 | } |
380 | else { | 407 | else { |
381 | low += (ones_count - 2) * GET_MED (2); | 408 | low += GET_MED (1); |
382 | high = low + GET_MED (2) - 1; | 409 | INC_MED1 (); |
383 | INC_MED2 (); | 410 | |
411 | if (ones_count == 2) { | ||
412 | high = low + GET_MED (2) - 1; | ||
413 | DEC_MED2 (); | ||
414 | } | ||
415 | else { | ||
416 | low += (ones_count - 2) * GET_MED (2); | ||
417 | high = low + GET_MED (2) - 1; | ||
418 | INC_MED2 (); | ||
419 | } | ||
384 | } | 420 | } |
385 | } | 421 | } |
386 | } | ||
387 | 422 | ||
388 | mid = (high + low + 1) >> 1; | 423 | mid = (high + low + 1) >> 1; |
389 | 424 | ||
390 | if (!wps->w.error_limit [chan]) | 425 | if (!wps->w.error_limit [chan]) |
391 | mid = read_code (&wps->wvbits, high - low) + low; | 426 | mid = read_code (&wps->wvbits, high - low) + low; |
392 | else while (high - low > wps->w.error_limit [chan]) { | 427 | else while (high - low > wps->w.error_limit [chan]) { |
393 | if (getbit (&wps->wvbits)) | 428 | if (getbit (&wps->wvbits)) |
394 | mid = (high + (low = mid) + 1) >> 1; | 429 | mid = (high + (low = mid) + 1) >> 1; |
395 | else | 430 | else |
396 | mid = ((high = mid - 1) + low + 1) >> 1; | 431 | mid = ((high = mid - 1) + low + 1) >> 1; |
397 | } | 432 | } |
398 | 433 | ||
399 | sign = getbit (&wps->wvbits); | 434 | sign = getbit (&wps->wvbits); |
400 | 435 | ||
401 | if (wps->wphdr.flags & HYBRID_BITRATE) { | 436 | if (wps->wphdr.flags & HYBRID_BITRATE) { |
402 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | 437 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; |
403 | wps->w.slow_level [chan] += log2 (mid); | 438 | wps->w.slow_level [chan] += mylog2 (mid); |
439 | } | ||
440 | |||
441 | *bptr++ = sign ? ~mid : mid; | ||
404 | } | 442 | } |
405 | 443 | ||
406 | return sign ? ~mid : mid; | 444 | return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2); |
407 | } | 445 | } |
408 | 446 | ||
409 | // Read a single unsigned value from the specified bitstream with a value | 447 | // Read a single unsigned value from the specified bitstream with a value |
@@ -448,7 +486,7 @@ static ulong read_code (Bitstream *bs, ulong maxcode) | |||
448 | // This function returns the log2 for the specified 32-bit unsigned value. | 486 | // This function returns the log2 for the specified 32-bit unsigned value. |
449 | // The maximum value allowed is about 0xff800000 and returns 8447. | 487 | // The maximum value allowed is about 0xff800000 and returns 8447. |
450 | 488 | ||
451 | static int log2 (unsigned long avalue) | 489 | static int mylog2 (unsigned long avalue) |
452 | { | 490 | { |
453 | int dbits; | 491 | int dbits; |
454 | 492 | ||