diff options
-rw-r--r-- | apps/codecs/libwavpack/bits.c | 26 | ||||
-rw-r--r-- | apps/codecs/libwavpack/unpack.c | 463 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wavpack.h | 2 | ||||
-rw-r--r-- | apps/codecs/libwavpack/words.c | 238 | ||||
-rw-r--r-- | apps/codecs/libwavpack/wputils.c | 13 | ||||
-rw-r--r-- | docs/CREDITS | 1 |
6 files changed, 492 insertions, 251 deletions
diff --git a/apps/codecs/libwavpack/bits.c b/apps/codecs/libwavpack/bits.c index e1700df539..1fe6aacf75 100644 --- a/apps/codecs/libwavpack/bits.c +++ b/apps/codecs/libwavpack/bits.c | |||
@@ -17,28 +17,6 @@ | |||
17 | #include "wavpack.h" | 17 | #include "wavpack.h" |
18 | 18 | ||
19 | #include <string.h> | 19 | #include <string.h> |
20 | #include <ctype.h> | ||
21 | |||
22 | /* dirty fix */ | ||
23 | const char _ctype_[257]={ | ||
24 | 0, | ||
25 | _C, _C, _C, _C, _C, _C, _C, _C, | ||
26 | _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C, | ||
27 | _C, _C, _C, _C, _C, _C, _C, _C, | ||
28 | _C, _C, _C, _C, _C, _C, _C, _C, | ||
29 | _S|_B, _P, _P, _P, _P, _P, _P, _P, | ||
30 | _P, _P, _P, _P, _P, _P, _P, _P, | ||
31 | _N, _N, _N, _N, _N, _N, _N, _N, | ||
32 | _N, _N, _P, _P, _P, _P, _P, _P, | ||
33 | _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, | ||
34 | _U, _U, _U, _U, _U, _U, _U, _U, | ||
35 | _U, _U, _U, _U, _U, _U, _U, _U, | ||
36 | _U, _U, _U, _P, _P, _P, _P, _P, | ||
37 | _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, | ||
38 | _L, _L, _L, _L, _L, _L, _L, _L, | ||
39 | _L, _L, _L, _L, _L, _L, _L, _L, | ||
40 | _L, _L, _L, _P, _P, _P, _P, _C | ||
41 | }; | ||
42 | 20 | ||
43 | ////////////////////////// Bitstream functions //////////////////////////////// | 21 | ////////////////////////// Bitstream functions //////////////////////////////// |
44 | 22 | ||
@@ -118,7 +96,7 @@ void little_endian_to_native (void *data, char *format) | |||
118 | break; | 96 | break; |
119 | 97 | ||
120 | default: | 98 | default: |
121 | if (isdigit (*format)) | 99 | if (*format >= '0' && *format <= '9') |
122 | cp += *format - '0'; | 100 | cp += *format - '0'; |
123 | 101 | ||
124 | break; | 102 | break; |
@@ -150,7 +128,7 @@ void native_to_little_endian (void *data, char *format) | |||
150 | break; | 128 | break; |
151 | 129 | ||
152 | default: | 130 | default: |
153 | if (isdigit (*format)) | 131 | if (*format >= '0' && *format <= '9') |
154 | cp += *format - '0'; | 132 | cp += *format - '0'; |
155 | 133 | ||
156 | break; | 134 | break; |
diff --git a/apps/codecs/libwavpack/unpack.c b/apps/codecs/libwavpack/unpack.c index cc31b8808e..ae473787a7 100644 --- a/apps/codecs/libwavpack/unpack.c +++ b/apps/codecs/libwavpack/unpack.c | |||
@@ -18,20 +18,34 @@ | |||
18 | #include <string.h> | 18 | #include <string.h> |
19 | #include <math.h> | 19 | #include <math.h> |
20 | 20 | ||
21 | static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } | ||
22 | |||
21 | #define LOSSY_MUTE | 23 | #define LOSSY_MUTE |
22 | 24 | ||
23 | //////////////////////////////// local macros ///////////////////////////////// | 25 | //////////////////////////////// local macros ///////////////////////////////// |
24 | 26 | ||
27 | // these macros implement the weight application and update operations | ||
28 | // that are at the heart of the decorrelation loops | ||
29 | |||
25 | #define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10) | 30 | #define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10) |
26 | 31 | ||
27 | #define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \ | 32 | #define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \ |
28 | (((sample & ~0xffff) >> 9) * weight) + 1) >> 1) | 33 | (((sample & ~0xffff) >> 9) * weight) + 1) >> 1) |
29 | 34 | ||
35 | #if 1 // PERFCOND | ||
30 | #define apply_weight(weight, sample) (sample != (short) sample ? \ | 36 | #define apply_weight(weight, sample) (sample != (short) sample ? \ |
31 | apply_weight_f (weight, sample) : apply_weight_i (weight, sample)) | 37 | apply_weight_f (weight, sample) : apply_weight_i (weight, sample)) |
38 | #else | ||
39 | #define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10)) | ||
40 | #endif | ||
32 | 41 | ||
42 | #if 1 // PERFCOND | ||
33 | #define update_weight(weight, delta, source, result) \ | 43 | #define update_weight(weight, delta, source, result) \ |
34 | if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta; | 44 | if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta; |
45 | #else | ||
46 | #define update_weight(weight, delta, source, result) \ | ||
47 | if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta); | ||
48 | #endif | ||
35 | 49 | ||
36 | #define update_weight_clip(weight, delta, source, result) \ | 50 | #define update_weight_clip(weight, delta, source, result) \ |
37 | if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \ | 51 | if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \ |
@@ -61,7 +75,7 @@ int unpack_init (WavpackContext *wpc) | |||
61 | 75 | ||
62 | while (read_metadata_buff (wpc, &wpmd)) { | 76 | while (read_metadata_buff (wpc, &wpmd)) { |
63 | if (!process_metadata (wpc, &wpmd)) { | 77 | if (!process_metadata (wpc, &wpmd)) { |
64 | /*strcpy (wpc->error_message, "invalid metadata!");*/ | 78 | strcpy_loc (wpc->error_message, "invalid metadata!"); |
65 | return FALSE; | 79 | return FALSE; |
66 | } | 80 | } |
67 | 81 | ||
@@ -70,7 +84,7 @@ int unpack_init (WavpackContext *wpc) | |||
70 | } | 84 | } |
71 | 85 | ||
72 | if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) { | 86 | if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) { |
73 | /*strcpy (wpc->error_message, "invalid WavPack file!");*/ | 87 | strcpy_loc (wpc->error_message, "invalid WavPack file!"); |
74 | return FALSE; | 88 | return FALSE; |
75 | } | 89 | } |
76 | 90 | ||
@@ -301,6 +315,9 @@ int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) | |||
301 | // samples unpacked, which can be less than the number requested if an error | 315 | // samples unpacked, which can be less than the number requested if an error |
302 | // occurs or the end of the block is reached. | 316 | // occurs or the end of the block is reached. |
303 | 317 | ||
318 | static void decorr_mono_pass (struct decorr_pass *dpp, long *buffer, long sample_count); | ||
319 | static void decorr_stereo_pass (struct decorr_pass *dpp, long *buffer, long sample_count); | ||
320 | static void decorr_stereo_pass_cont (struct decorr_pass *dpp, long *buffer, long sample_count); | ||
304 | static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count); | 321 | static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count); |
305 | 322 | ||
306 | long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) | 323 | long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) |
@@ -309,8 +326,8 @@ long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) | |||
309 | ulong flags = wps->wphdr.flags, crc = wps->crc, i; | 326 | ulong flags = wps->wphdr.flags, crc = wps->crc, i; |
310 | long mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2; | 327 | long mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2; |
311 | struct decorr_pass *dpp; | 328 | struct decorr_pass *dpp; |
312 | long read_word, *bptr; | 329 | long *bptr, *eptr; |
313 | int tcount, m = 0; | 330 | int tcount; |
314 | 331 | ||
315 | if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples) | 332 | if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples) |
316 | sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index; | 333 | sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index; |
@@ -326,121 +343,59 @@ long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) | |||
326 | 343 | ||
327 | ///////////////////// handle version 4 mono data ///////////////////////// | 344 | ///////////////////// handle version 4 mono data ///////////////////////// |
328 | 345 | ||
329 | if (flags & MONO_FLAG) | 346 | if (flags & MONO_FLAG) { |
330 | for (bptr = buffer, i = 0; i < sample_count; ++i) { | 347 | eptr = buffer + sample_count; |
331 | if ((read_word = get_word (wps, 0)) == WORD_EOF) | 348 | i = get_words (wps, 1, sample_count, buffer); |
332 | break; | ||
333 | |||
334 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { | ||
335 | long sam, temp; | ||
336 | int k; | ||
337 | |||
338 | if (dpp->term > MAX_TERM) { | ||
339 | if (dpp->term & 1) | ||
340 | sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; | ||
341 | else | ||
342 | sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; | ||
343 | 349 | ||
344 | dpp->samples_A [1] = dpp->samples_A [0]; | 350 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) |
345 | k = 0; | 351 | decorr_mono_pass (dpp, buffer, sample_count); |
346 | } | ||
347 | else { | ||
348 | sam = dpp->samples_A [m]; | ||
349 | k = (m + dpp->term) & (MAX_TERM - 1); | ||
350 | } | ||
351 | |||
352 | temp = apply_weight (dpp->weight_A, sam) + read_word; | ||
353 | update_weight (dpp->weight_A, dpp->delta, sam, read_word); | ||
354 | dpp->samples_A [k] = read_word = temp; | ||
355 | } | ||
356 | 352 | ||
357 | if (labs (read_word) > mute_limit) | 353 | for (bptr = buffer; bptr < eptr; ++bptr) { |
354 | if (labs (bptr [0]) > mute_limit) { | ||
355 | i = bptr - buffer; | ||
358 | break; | 356 | break; |
357 | } | ||
359 | 358 | ||
360 | m = (m + 1) & (MAX_TERM - 1); | 359 | crc = crc * 3 + bptr [0]; |
361 | crc = crc * 3 + read_word; | ||
362 | *bptr++ = read_word; | ||
363 | } | 360 | } |
361 | } | ||
364 | 362 | ||
365 | //////////////////// handle version 4 stereo data //////////////////////// | 363 | //////////////////// handle version 4 stereo data //////////////////////// |
366 | 364 | ||
367 | else | 365 | else { |
368 | for (bptr = buffer, i = 0; i < sample_count; ++i) { | 366 | eptr = buffer + (sample_count * 2); |
369 | long left, right, left2, right2; | 367 | i = get_words (wps, 2, sample_count, buffer); |
370 | |||
371 | if ((left = get_word (wps, 0)) == WORD_EOF || | ||
372 | (right = get_word (wps, 1)) == WORD_EOF) | ||
373 | break; | ||
374 | 368 | ||
369 | if (sample_count < 16) | ||
375 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) | 370 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) |
376 | if (dpp->term > 0) { | 371 | decorr_stereo_pass (dpp, buffer, sample_count); |
377 | long sam_A, sam_B; | 372 | else |
378 | int k; | 373 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { |
379 | 374 | decorr_stereo_pass (dpp, buffer, 8); | |
380 | if (dpp->term > MAX_TERM) { | 375 | decorr_stereo_pass_cont (dpp, buffer + 16, sample_count - 8); |
381 | if (dpp->term & 1) { | 376 | } |
382 | sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; | ||
383 | sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1]; | ||
384 | } | ||
385 | else { | ||
386 | sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; | ||
387 | sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; | ||
388 | } | ||
389 | |||
390 | dpp->samples_A [1] = dpp->samples_A [0]; | ||
391 | dpp->samples_B [1] = dpp->samples_B [0]; | ||
392 | k = 0; | ||
393 | } | ||
394 | else { | ||
395 | sam_A = dpp->samples_A [m]; | ||
396 | sam_B = dpp->samples_B [m]; | ||
397 | k = (m + dpp->term) & (MAX_TERM - 1); | ||
398 | } | ||
399 | |||
400 | left2 = apply_weight (dpp->weight_A, sam_A) + left; | ||
401 | right2 = apply_weight (dpp->weight_B, sam_B) + right; | ||
402 | |||
403 | update_weight (dpp->weight_A, dpp->delta, sam_A, left); | ||
404 | update_weight (dpp->weight_B, dpp->delta, sam_B, right); | ||
405 | |||
406 | dpp->samples_A [k] = left = left2; | ||
407 | dpp->samples_B [k] = right = right2; | ||
408 | } | ||
409 | else if (dpp->term == -1) { | ||
410 | left2 = left + apply_weight (dpp->weight_A, dpp->samples_A [0]); | ||
411 | update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], left); | ||
412 | left = left2; | ||
413 | right2 = right + apply_weight (dpp->weight_B, left2); | ||
414 | update_weight_clip (dpp->weight_B, dpp->delta, left2, right); | ||
415 | dpp->samples_A [0] = right = right2; | ||
416 | } | ||
417 | else { | ||
418 | right2 = right + apply_weight (dpp->weight_B, dpp->samples_B [0]); | ||
419 | update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], right); | ||
420 | right = right2; | ||
421 | |||
422 | if (dpp->term == -3) { | ||
423 | right2 = dpp->samples_A [0]; | ||
424 | dpp->samples_A [0] = right; | ||
425 | } | ||
426 | |||
427 | left2 = left + apply_weight (dpp->weight_A, right2); | ||
428 | update_weight_clip (dpp->weight_A, dpp->delta, right2, left); | ||
429 | dpp->samples_B [0] = left = left2; | ||
430 | } | ||
431 | 377 | ||
432 | m = (m + 1) & (MAX_TERM - 1); | 378 | if (flags & JOINT_STEREO) |
379 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
380 | bptr [0] += (bptr [1] -= (bptr [0] >> 1)); | ||
433 | 381 | ||
434 | if (flags & JOINT_STEREO) | 382 | if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) { |
435 | left += (right -= (left >> 1)); | 383 | i = (bptr - buffer) / 2; |
384 | break; | ||
385 | } | ||
436 | 386 | ||
437 | if (labs (left) > mute_limit || labs (right) > mute_limit) | 387 | crc = (crc * 3 + bptr [0]) * 3 + bptr [1]; |
438 | break; | 388 | } |
389 | else | ||
390 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
391 | if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) { | ||
392 | i = (bptr - buffer) / 2; | ||
393 | break; | ||
394 | } | ||
439 | 395 | ||
440 | crc = (crc * 3 + left) * 3 + right; | 396 | crc = (crc * 3 + bptr [0]) * 3 + bptr [1]; |
441 | *bptr++ = left; | 397 | } |
442 | *bptr++ = right; | 398 | } |
443 | } | ||
444 | 399 | ||
445 | if (i != sample_count) { | 400 | if (i != sample_count) { |
446 | memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8)); | 401 | memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8)); |
@@ -448,17 +403,6 @@ long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) | |||
448 | i = sample_count; | 403 | i = sample_count; |
449 | } | 404 | } |
450 | 405 | ||
451 | while (m--) | ||
452 | for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) | ||
453 | if (dpp->term > 0 && dpp->term <= MAX_TERM) { | ||
454 | long temp = dpp->samples_A [0]; | ||
455 | memcpy (dpp->samples_A, dpp->samples_A + 1, sizeof (dpp->samples_A) - sizeof (dpp->samples_A [0])); | ||
456 | dpp->samples_A [MAX_TERM - 1] = temp; | ||
457 | temp = dpp->samples_B [0]; | ||
458 | memcpy (dpp->samples_B, dpp->samples_B + 1, sizeof (dpp->samples_B) - sizeof (dpp->samples_B [0])); | ||
459 | dpp->samples_B [MAX_TERM - 1] = temp; | ||
460 | } | ||
461 | |||
462 | fixup_samples (wps, buffer, i); | 406 | fixup_samples (wps, buffer, i); |
463 | 407 | ||
464 | if (flags & FLOAT_DATA) | 408 | if (flags & FLOAT_DATA) |
@@ -471,6 +415,286 @@ long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) | |||
471 | return i; | 415 | return i; |
472 | } | 416 | } |
473 | 417 | ||
418 | static void decorr_stereo_pass (struct decorr_pass *dpp, long *buffer, long sample_count) | ||
419 | { | ||
420 | long delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B; | ||
421 | long *bptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B; | ||
422 | int m, k; | ||
423 | |||
424 | switch (dpp->term) { | ||
425 | |||
426 | case 17: | ||
427 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
428 | sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; | ||
429 | dpp->samples_A [1] = dpp->samples_A [0]; | ||
430 | dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
431 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
432 | bptr [0] = dpp->samples_A [0]; | ||
433 | |||
434 | sam_A = 2 * dpp->samples_B [0] - dpp->samples_B [1]; | ||
435 | dpp->samples_B [1] = dpp->samples_B [0]; | ||
436 | dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1]; | ||
437 | update_weight (weight_B, delta, sam_A, bptr [1]); | ||
438 | bptr [1] = dpp->samples_B [0]; | ||
439 | } | ||
440 | |||
441 | break; | ||
442 | |||
443 | case 18: | ||
444 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
445 | sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; | ||
446 | dpp->samples_A [1] = dpp->samples_A [0]; | ||
447 | dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
448 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
449 | bptr [0] = dpp->samples_A [0]; | ||
450 | |||
451 | sam_A = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; | ||
452 | dpp->samples_B [1] = dpp->samples_B [0]; | ||
453 | dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1]; | ||
454 | update_weight (weight_B, delta, sam_A, bptr [1]); | ||
455 | bptr [1] = dpp->samples_B [0]; | ||
456 | } | ||
457 | |||
458 | break; | ||
459 | |||
460 | default: | ||
461 | for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { | ||
462 | sam_A = dpp->samples_A [m]; | ||
463 | dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
464 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
465 | bptr [0] = dpp->samples_A [k]; | ||
466 | |||
467 | sam_A = dpp->samples_B [m]; | ||
468 | dpp->samples_B [k] = apply_weight (weight_B, sam_A) + bptr [1]; | ||
469 | update_weight (weight_B, delta, sam_A, bptr [1]); | ||
470 | bptr [1] = dpp->samples_B [k]; | ||
471 | |||
472 | m = (m + 1) & (MAX_TERM - 1); | ||
473 | k = (k + 1) & (MAX_TERM - 1); | ||
474 | } | ||
475 | |||
476 | if (m) { | ||
477 | long temp_samples [MAX_TERM]; | ||
478 | |||
479 | memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A)); | ||
480 | |||
481 | for (k = 0; k < MAX_TERM; k++, m++) | ||
482 | dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)]; | ||
483 | |||
484 | memcpy (temp_samples, dpp->samples_B, sizeof (dpp->samples_B)); | ||
485 | |||
486 | for (k = 0; k < MAX_TERM; k++, m++) | ||
487 | dpp->samples_B [k] = temp_samples [m & (MAX_TERM - 1)]; | ||
488 | } | ||
489 | |||
490 | break; | ||
491 | |||
492 | case -1: | ||
493 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
494 | sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]); | ||
495 | update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]); | ||
496 | bptr [0] = sam_A; | ||
497 | dpp->samples_A [0] = bptr [1] + apply_weight (weight_B, sam_A); | ||
498 | update_weight_clip (weight_B, delta, sam_A, bptr [1]); | ||
499 | bptr [1] = dpp->samples_A [0]; | ||
500 | } | ||
501 | |||
502 | break; | ||
503 | |||
504 | case -2: | ||
505 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
506 | sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]); | ||
507 | update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]); | ||
508 | bptr [1] = sam_B; | ||
509 | dpp->samples_B [0] = bptr [0] + apply_weight (weight_A, sam_B); | ||
510 | update_weight_clip (weight_A, delta, sam_B, bptr [0]); | ||
511 | bptr [0] = dpp->samples_B [0]; | ||
512 | } | ||
513 | |||
514 | break; | ||
515 | |||
516 | case -3: | ||
517 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
518 | sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]); | ||
519 | update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]); | ||
520 | sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]); | ||
521 | update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]); | ||
522 | bptr [0] = dpp->samples_B [0] = sam_A; | ||
523 | bptr [1] = dpp->samples_A [0] = sam_B; | ||
524 | } | ||
525 | |||
526 | break; | ||
527 | } | ||
528 | |||
529 | dpp->weight_A = weight_A; | ||
530 | dpp->weight_B = weight_B; | ||
531 | } | ||
532 | |||
533 | static void decorr_stereo_pass_cont (struct decorr_pass *dpp, long *buffer, long sample_count) | ||
534 | { | ||
535 | long delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B; | ||
536 | long *bptr, *tptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B; | ||
537 | int k; | ||
538 | |||
539 | switch (dpp->term) { | ||
540 | |||
541 | case 17: | ||
542 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
543 | sam_A = 2 * bptr [-2] - bptr [-4]; | ||
544 | bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]); | ||
545 | update_weight (weight_A, delta, sam_A, sam_B); | ||
546 | |||
547 | sam_A = 2 * bptr [-1] - bptr [-3]; | ||
548 | bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]); | ||
549 | update_weight (weight_B, delta, sam_A, sam_B); | ||
550 | } | ||
551 | |||
552 | dpp->samples_B [0] = bptr [-1]; | ||
553 | dpp->samples_A [0] = bptr [-2]; | ||
554 | dpp->samples_B [1] = bptr [-3]; | ||
555 | dpp->samples_A [1] = bptr [-4]; | ||
556 | break; | ||
557 | |||
558 | case 18: | ||
559 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
560 | sam_A = (3 * bptr [-2] - bptr [-4]) >> 1; | ||
561 | bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]); | ||
562 | update_weight (weight_A, delta, sam_A, sam_B); | ||
563 | |||
564 | sam_A = (3 * bptr [-1] - bptr [-3]) >> 1; | ||
565 | bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]); | ||
566 | update_weight (weight_B, delta, sam_A, sam_B); | ||
567 | } | ||
568 | |||
569 | dpp->samples_B [0] = bptr [-1]; | ||
570 | dpp->samples_A [0] = bptr [-2]; | ||
571 | dpp->samples_B [1] = bptr [-3]; | ||
572 | dpp->samples_A [1] = bptr [-4]; | ||
573 | break; | ||
574 | |||
575 | default: | ||
576 | for (bptr = buffer, tptr = buffer - (dpp->term * 2); bptr < eptr; bptr += 2, tptr += 2) { | ||
577 | bptr [0] = apply_weight (weight_A, tptr [0]) + (sam_A = bptr [0]); | ||
578 | update_weight (weight_A, delta, tptr [0], sam_A); | ||
579 | |||
580 | bptr [1] = apply_weight (weight_B, tptr [1]) + (sam_A = bptr [1]); | ||
581 | update_weight (weight_B, delta, tptr [1], sam_A); | ||
582 | } | ||
583 | |||
584 | k = dpp->term; | ||
585 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-1]; | ||
586 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-2]; | ||
587 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-3]; | ||
588 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-4]; | ||
589 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-5]; | ||
590 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-6]; | ||
591 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-7]; | ||
592 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-8]; | ||
593 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-9]; | ||
594 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-10]; | ||
595 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-11]; | ||
596 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-12]; | ||
597 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-13]; | ||
598 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-14]; | ||
599 | dpp->samples_B [--k & (MAX_TERM - 1)] = bptr [-15]; | ||
600 | dpp->samples_A [ k & (MAX_TERM - 1)] = bptr [-16]; | ||
601 | break; | ||
602 | |||
603 | case -1: | ||
604 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
605 | bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]); | ||
606 | update_weight_clip (weight_A, delta, bptr [-1], sam_A); | ||
607 | bptr [1] = apply_weight (weight_B, bptr [0]) + (sam_A = bptr [1]); | ||
608 | update_weight_clip (weight_B, delta, bptr [0], sam_A); | ||
609 | } | ||
610 | |||
611 | dpp->samples_A [0] = bptr [-1]; | ||
612 | break; | ||
613 | |||
614 | case -2: | ||
615 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
616 | bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]); | ||
617 | update_weight_clip (weight_B, delta, bptr [-2], sam_A); | ||
618 | bptr [0] = apply_weight (weight_A, bptr [1]) + (sam_A = bptr [0]); | ||
619 | update_weight_clip (weight_A, delta, bptr [1], sam_A); | ||
620 | } | ||
621 | |||
622 | dpp->samples_B [0] = bptr [-2]; | ||
623 | break; | ||
624 | |||
625 | case -3: | ||
626 | for (bptr = buffer; bptr < eptr; bptr += 2) { | ||
627 | bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]); | ||
628 | update_weight_clip (weight_A, delta, bptr [-1], sam_A); | ||
629 | bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]); | ||
630 | update_weight_clip (weight_B, delta, bptr [-2], sam_A); | ||
631 | } | ||
632 | |||
633 | dpp->samples_A [0] = bptr [-1]; | ||
634 | dpp->samples_B [0] = bptr [-2]; | ||
635 | break; | ||
636 | } | ||
637 | |||
638 | dpp->weight_A = weight_A; | ||
639 | dpp->weight_B = weight_B; | ||
640 | } | ||
641 | |||
642 | static void decorr_mono_pass (struct decorr_pass *dpp, long *buffer, long sample_count) | ||
643 | { | ||
644 | long delta = dpp->delta, weight_A = dpp->weight_A; | ||
645 | long *bptr, *eptr = buffer + sample_count, sam_A; | ||
646 | int m, k; | ||
647 | |||
648 | switch (dpp->term) { | ||
649 | |||
650 | case 17: | ||
651 | for (bptr = buffer; bptr < eptr; bptr++) { | ||
652 | sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; | ||
653 | dpp->samples_A [1] = dpp->samples_A [0]; | ||
654 | dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
655 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
656 | bptr [0] = dpp->samples_A [0]; | ||
657 | } | ||
658 | |||
659 | break; | ||
660 | |||
661 | case 18: | ||
662 | for (bptr = buffer; bptr < eptr; bptr++) { | ||
663 | sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; | ||
664 | dpp->samples_A [1] = dpp->samples_A [0]; | ||
665 | dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
666 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
667 | bptr [0] = dpp->samples_A [0]; | ||
668 | } | ||
669 | |||
670 | break; | ||
671 | |||
672 | default: | ||
673 | for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) { | ||
674 | sam_A = dpp->samples_A [m]; | ||
675 | dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0]; | ||
676 | update_weight (weight_A, delta, sam_A, bptr [0]); | ||
677 | bptr [0] = dpp->samples_A [k]; | ||
678 | m = (m + 1) & (MAX_TERM - 1); | ||
679 | k = (k + 1) & (MAX_TERM - 1); | ||
680 | } | ||
681 | |||
682 | if (m) { | ||
683 | long temp_samples [MAX_TERM]; | ||
684 | |||
685 | memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A)); | ||
686 | |||
687 | for (k = 0; k < MAX_TERM; k++, m++) | ||
688 | dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)]; | ||
689 | } | ||
690 | |||
691 | break; | ||
692 | } | ||
693 | |||
694 | dpp->weight_A = weight_A; | ||
695 | } | ||
696 | |||
697 | |||
474 | // This is a helper function for unpack_samples() that applies several final | 698 | // This is a helper function for unpack_samples() that applies several final |
475 | // operations. First, if the data is 32-bit float data, then that conversion | 699 | // operations. First, if the data is 32-bit float data, then that conversion |
476 | // is done in the float.c module (whether lossy or lossless) and we return. | 700 | // is done in the float.c module (whether lossy or lossless) and we return. |
@@ -513,7 +737,6 @@ static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count) | |||
513 | 737 | ||
514 | if (flags & HYBRID_FLAG) { | 738 | if (flags & HYBRID_FLAG) { |
515 | long min_value, max_value, min_shifted, max_shifted; | 739 | long min_value, max_value, min_shifted, max_shifted; |
516 | min_value = max_value = min_shifted = max_shifted = 0; | ||
517 | 740 | ||
518 | switch (flags & BYTES_STORED) { | 741 | switch (flags & BYTES_STORED) { |
519 | case 0: | 742 | case 0: |
@@ -532,9 +755,9 @@ static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count) | |||
532 | break; | 755 | break; |
533 | 756 | ||
534 | case 3: | 757 | case 3: |
535 | // 0x80000000 is the same as 2147483648 | 758 | default: |
536 | min_shifted = (min_value = -0x80000000 >> shift) << shift; | 759 | min_shifted = (min_value = (long) 0x80000000 >> shift) << shift; |
537 | max_shifted = (max_value = 0x80000000 >> shift) << shift; | 760 | max_shifted = (max_value = (long) 0x7FFFFFFF >> shift) << shift; |
538 | break; | 761 | break; |
539 | } | 762 | } |
540 | 763 | ||
diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h index 6f74d95749..06f86cb15a 100644 --- a/apps/codecs/libwavpack/wavpack.h +++ b/apps/codecs/libwavpack/wavpack.h | |||
@@ -291,7 +291,7 @@ int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); | |||
291 | 291 | ||
292 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); | 292 | int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); |
293 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); | 293 | int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); |
294 | long get_word (WavpackStream *wps, int chan); | 294 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer); |
295 | long exp2s (int log); | 295 | long exp2s (int log); |
296 | int restore_weight (char weight); | 296 | int restore_weight (char weight); |
297 | 297 | ||
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 | ||
diff --git a/apps/codecs/libwavpack/wputils.c b/apps/codecs/libwavpack/wputils.c index 1b8fae0e67..9227b66e46 100644 --- a/apps/codecs/libwavpack/wputils.c +++ b/apps/codecs/libwavpack/wputils.c | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #include <string.h> | 20 | #include <string.h> |
21 | 21 | ||
22 | static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; } | ||
23 | |||
22 | ///////////////////////////// local table storage //////////////////////////// | 24 | ///////////////////////////// local table storage //////////////////////////// |
23 | 25 | ||
24 | const ulong sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050, | 26 | const ulong sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050, |
@@ -49,7 +51,6 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error) | |||
49 | { | 51 | { |
50 | WavpackStream *wps = &wpc.stream; | 52 | WavpackStream *wps = &wpc.stream; |
51 | ulong bcount; | 53 | ulong bcount; |
52 | (void)error; | ||
53 | 54 | ||
54 | CLEAR (wpc); | 55 | CLEAR (wpc); |
55 | wpc.infile = infile; | 56 | wpc.infile = infile; |
@@ -64,12 +65,12 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error) | |||
64 | bcount = read_next_header (wpc.infile, &wps->wphdr); | 65 | bcount = read_next_header (wpc.infile, &wps->wphdr); |
65 | 66 | ||
66 | if (bcount == (ulong) -1) { | 67 | if (bcount == (ulong) -1) { |
67 | /*strcpy (error, "not compatible with this version of WavPack file!");*/ | 68 | strcpy_loc (error, "invalid WavPack file!"); |
68 | return NULL; | 69 | return NULL; |
69 | } | 70 | } |
70 | 71 | ||
71 | if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { | 72 | if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { |
72 | /*strcpy (error, "not compatible with this version of WavPack file!");*/ | 73 | strcpy_loc (error, "invalid WavPack file!"); |
73 | return NULL; | 74 | return NULL; |
74 | } | 75 | } |
75 | 76 | ||
@@ -77,8 +78,8 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error) | |||
77 | wpc.total_samples = wps->wphdr.total_samples; | 78 | wpc.total_samples = wps->wphdr.total_samples; |
78 | 79 | ||
79 | if (!unpack_init (&wpc)) { | 80 | if (!unpack_init (&wpc)) { |
80 | /*strcpy (error, wpc.error_message [0] ? wpc.error_message : | 81 | strcpy_loc (error, wpc.error_message [0] ? wpc.error_message : |
81 | "not compatible with this version of WavPack file!");*/ | 82 | "invalid WavPack file!"); |
82 | 83 | ||
83 | return NULL; | 84 | return NULL; |
84 | } | 85 | } |
@@ -170,7 +171,7 @@ ulong WavpackUnpackSamples (WavpackContext *wpc, long *buffer, ulong samples) | |||
170 | break; | 171 | break; |
171 | 172 | ||
172 | if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { | 173 | if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) { |
173 | /*strcpy (wpc->error_message, "not compatible with this version of WavPack file!");*/ | 174 | strcpy_loc (wpc->error_message, "invalid WavPack file!"); |
174 | break; | 175 | break; |
175 | } | 176 | } |
176 | 177 | ||
diff --git a/docs/CREDITS b/docs/CREDITS index 99c020b807..0dcae977f6 100644 --- a/docs/CREDITS +++ b/docs/CREDITS | |||
@@ -112,3 +112,4 @@ Tapio Karppinen | |||
112 | Richard Ottó O'Brien | 112 | Richard Ottó O'Brien |
113 | Luca Burelli | 113 | Luca Burelli |
114 | Alessio Lenzi | 114 | Alessio Lenzi |
115 | David Bryant | ||