summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/libwavpack/bits.c26
-rw-r--r--apps/codecs/libwavpack/unpack.c463
-rw-r--r--apps/codecs/libwavpack/wavpack.h2
-rw-r--r--apps/codecs/libwavpack/words.c238
-rw-r--r--apps/codecs/libwavpack/wputils.c13
-rw-r--r--docs/CREDITS1
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 */
23const 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
21static 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
318static void decorr_mono_pass (struct decorr_pass *dpp, long *buffer, long sample_count);
319static void decorr_stereo_pass (struct decorr_pass *dpp, long *buffer, long sample_count);
320static void decorr_stereo_pass_cont (struct decorr_pass *dpp, long *buffer, long sample_count);
304static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count); 321static void fixup_samples (WavpackStream *wps, long *buffer, ulong sample_count);
305 322
306long unpack_samples (WavpackContext *wpc, long *buffer, ulong sample_count) 323long 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
418static 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
533static 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
642static 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
292int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); 292int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
293int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); 293int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
294long get_word (WavpackStream *wps, int chan); 294long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer);
295long exp2s (int log); 295long exp2s (int log);
296int restore_weight (char weight); 296int 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
126static 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
128static int log2 (unsigned long avalue); 139static 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
273long get_word (WavpackStream *wps, int chan) 284long 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
451static int log2 (unsigned long avalue) 489static 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
22static void strcpy_loc (char *dst, char *src) { while (*src) *dst++ = *src++; *dst = 0; }
23
22///////////////////////////// local table storage //////////////////////////// 24///////////////////////////// local table storage ////////////////////////////
23 25
24const ulong sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050, 26const 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
112Richard Ottó O'Brien 112Richard Ottó O'Brien
113Luca Burelli 113Luca Burelli
114Alessio Lenzi 114Alessio Lenzi
115David Bryant