summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2007-12-04 16:59:45 +0000
committerThom Johansen <thomj@rockbox.org>2007-12-04 16:59:45 +0000
commitb911ee822ac5b628f2d21d3839fd3d4cd2e35398 (patch)
tree60870620f49561c0899b478d404beef3d901db77
parent91c35ff7739a60026d4b1892950a2f09af8e3df7 (diff)
downloadrockbox-b911ee822ac5b628f2d21d3839fd3d4cd2e35398.tar.gz
rockbox-b911ee822ac5b628f2d21d3839fd3d4cd2e35398.zip
FS #8106. Fix overflow when dithering files that clip a lot, caused by noise shaping error being calculated after clipping instead of before.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15873 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dsp.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index 6b2c698532..1e0ae1fb8d 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -468,7 +468,7 @@ static void sample_output_dithered(int count, struct dsp_data *data,
468 int32_t output, sample; 468 int32_t output, sample;
469 int32_t random; 469 int32_t random;
470 470
471 /* Noise shape and bias */ 471 /* Noise shape and bias (for correct rounding later) */
472 sample = *s; 472 sample = *s;
473 sample += dither->error[0] - dither->error[1] + dither->error[2]; 473 sample += dither->error[0] - dither->error[1] + dither->error[2];
474 dither->error[2] = dither->error[1]; 474 dither->error[2] = dither->error[1];
@@ -476,11 +476,17 @@ static void sample_output_dithered(int count, struct dsp_data *data,
476 476
477 output = sample + bias; 477 output = sample + bias;
478 478
479 /* Dither */ 479 /* Dither, highpass triangle PDF */
480 random = dither->random*0x0019660dL + 0x3c6ef35fL; 480 random = dither->random*0x0019660dL + 0x3c6ef35fL;
481 output += (random & mask) - (dither->random & mask); 481 output += (random & mask) - (dither->random & mask);
482 dither->random = random; 482 dither->random = random;
483 483
484 /* Round sample to output range */
485 output &= ~mask;
486
487 /* Error feedback */
488 dither->error[0] = sample - output;
489
484 /* Clip */ 490 /* Clip */
485 if ((uint32_t)(output - min) > (uint32_t)range) 491 if ((uint32_t)(output - min) > (uint32_t)range)
486 { 492 {
@@ -490,12 +496,7 @@ static void sample_output_dithered(int count, struct dsp_data *data,
490 output = c; 496 output = c;
491 } 497 }
492 498
493 output &= ~mask; 499 /* Quantize and store */
494
495 /* Error feedback */
496 dither->error[0] = sample - output;
497
498 /* Quantize */
499 *d = output >> scale; 500 *d = output >> scale;
500 } 501 }
501 } 502 }