diff options
author | Magnus Holmgren <magnushol@gmail.com> | 2005-08-18 19:25:39 +0000 |
---|---|---|
committer | Magnus Holmgren <magnushol@gmail.com> | 2005-08-18 19:25:39 +0000 |
commit | 75ef3129c9382a413afe897c362c9444df734c59 (patch) | |
tree | 4b7138482cbaf034376f43345db81d17833293a8 /apps/dsp.c | |
parent | 49483bc4885a31f9554a285d9448499e89359cb2 (diff) | |
download | rockbox-75ef3129c9382a413afe897c362c9444df734c59.tar.gz rockbox-75ef3129c9382a413afe897c362c9444df734c59.zip |
iriver: slightly faster replaygain processing and clipping.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7353 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/dsp.c')
-rw-r--r-- | apps/dsp.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index 27780af611..2ba7fb99f6 100644 --- a/apps/dsp.c +++ b/apps/dsp.c | |||
@@ -55,7 +55,8 @@ | |||
55 | : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \ | 55 | : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \ |
56 | t; \ | 56 | t; \ |
57 | }) | 57 | }) |
58 | /* Multiply one S.31-bit and one S7.24 fractional integer and return the | 58 | |
59 | /* Multiply one S.31-bit and one S8.23 fractional integer and return the | ||
59 | * sign bit and the 31 most significant bits of the result. | 60 | * sign bit and the 31 most significant bits of the result. |
60 | */ | 61 | */ |
61 | #define FRACMUL_8(x, y) \ | 62 | #define FRACMUL_8(x, y) \ |
@@ -66,14 +67,37 @@ | |||
66 | "move.l %%accext01, %[u]\n\t" \ | 67 | "move.l %%accext01, %[u]\n\t" \ |
67 | "movclr.l %%acc0, %[t]\n\t" \ | 68 | "movclr.l %%acc0, %[t]\n\t" \ |
68 | : [t] "=r" (t), [u] "=r" (u) : [a] "r" (x), [b] "r" (y)); \ | 69 | : [t] "=r" (t), [u] "=r" (u) : [a] "r" (x), [b] "r" (y)); \ |
69 | (t << 7) | ((u & 0xff) >> 1); \ | 70 | (t << 8) | (u & 0xff); \ |
71 | }) | ||
72 | |||
73 | /* Multiply one S.31-bit and one S8.23 fractional integer and return the | ||
74 | * sign bit and the 31 most significant bits of the result. Load next value | ||
75 | * to multiply with into x from s (and increase s); x must contain the | ||
76 | * initial value. | ||
77 | */ | ||
78 | #define FRACMUL_8_LOOP(x, y, s) \ | ||
79 | ({ \ | ||
80 | long t; \ | ||
81 | long u; \ | ||
82 | asm volatile ("mac.l %[a], %[b], (%[c])+, %[a], %%acc0\n\t" \ | ||
83 | "move.l %%accext01, %[u]\n\t" \ | ||
84 | "movclr.l %%acc0, %[t]\n\t" \ | ||
85 | : [a] "+r" (x), [c] "+a" (s), [t] "=r" (t), [u] "=r" (u) \ | ||
86 | : [b] "r" (y)); \ | ||
87 | (t << 8) | (u & 0xff); \ | ||
70 | }) | 88 | }) |
71 | 89 | ||
72 | #else | 90 | #else |
73 | 91 | ||
74 | #define INIT() | 92 | #define INIT() |
75 | #define FRACMUL(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 31)) | 93 | #define FRACMUL(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 31)) |
76 | #define FRACMUL_8(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 24)) | 94 | #define FRACMUL_8(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 23)) |
95 | #define FRACMUL_8_LOOP(x, y, s) \ | ||
96 | ({ \ | ||
97 | long t = x; \ | ||
98 | x = *(s)++; \ | ||
99 | (long) (((((long long) (t)) * ((long long) (y))) >> 23)); \ | ||
100 | }) | ||
77 | 101 | ||
78 | #endif | 102 | #endif |
79 | 103 | ||
@@ -86,7 +110,7 @@ struct dsp_config | |||
86 | long album_gain; | 110 | long album_gain; |
87 | long track_peak; | 111 | long track_peak; |
88 | long album_peak; | 112 | long album_peak; |
89 | long replaygain; | 113 | long replaygain; /* Note that this is in S8.23 format. */ |
90 | int sample_depth; | 114 | int sample_depth; |
91 | int sample_bytes; | 115 | int sample_bytes; |
92 | int stereo_mode; | 116 | int stereo_mode; |
@@ -323,15 +347,15 @@ static inline int resample(long* src[], int count) | |||
323 | return new_count; | 347 | return new_count; |
324 | } | 348 | } |
325 | 349 | ||
326 | static inline long clip_sample(long sample) | 350 | static inline long clip_sample(long sample, long min, long max) |
327 | { | 351 | { |
328 | if (sample > dsp.clip_max) | 352 | if (sample > max) |
329 | { | 353 | { |
330 | sample = dsp.clip_max; | 354 | sample = max; |
331 | } | 355 | } |
332 | else if (sample < dsp.clip_min) | 356 | else if (sample < min) |
333 | { | 357 | { |
334 | sample = dsp.clip_min; | 358 | sample = min; |
335 | } | 359 | } |
336 | 360 | ||
337 | return sample; | 361 | return sample; |
@@ -346,6 +370,8 @@ static long dither_sample(long sample, long bias, long mask, | |||
346 | { | 370 | { |
347 | long output; | 371 | long output; |
348 | long random; | 372 | long random; |
373 | long min; | ||
374 | long max; | ||
349 | 375 | ||
350 | /* Noise shape and bias */ | 376 | /* Noise shape and bias */ |
351 | 377 | ||
@@ -363,8 +389,10 @@ static long dither_sample(long sample, long bias, long mask, | |||
363 | 389 | ||
364 | /* Clip and quantize */ | 390 | /* Clip and quantize */ |
365 | 391 | ||
366 | sample = clip_sample(sample); | 392 | min = dsp.clip_min; |
367 | output = clip_sample(output) & ~mask; | 393 | max = dsp.clip_max; |
394 | sample = clip_sample(sample, min, max); | ||
395 | output = clip_sample(output, min, max) & ~mask; | ||
368 | 396 | ||
369 | /* Error feedback */ | 397 | /* Error feedback */ |
370 | 398 | ||
@@ -386,21 +414,25 @@ static void apply_gain(long* src[], int count) | |||
386 | long* d0 = &sample_buf[0]; | 414 | long* d0 = &sample_buf[0]; |
387 | long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2]; | 415 | long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2]; |
388 | long gain = dsp.replaygain; | 416 | long gain = dsp.replaygain; |
417 | long s; | ||
389 | long i; | 418 | long i; |
390 | 419 | ||
391 | src[0] = d0; | 420 | src[0] = d0; |
392 | src[1] = d1; | 421 | src[1] = d1; |
422 | s = *s0++; | ||
393 | 423 | ||
394 | for (i = 0; i < count; i++) | 424 | for (i = 0; i < count; i++) |
395 | { | 425 | { |
396 | *d0++ = FRACMUL_8(*s0++, gain); | 426 | *d0++ = FRACMUL_8_LOOP(s, gain, s0); |
397 | } | 427 | } |
398 | 428 | ||
399 | if (src [0] != src [1]) | 429 | if (src [0] != src [1]) |
400 | { | 430 | { |
431 | s = *s1++; | ||
432 | |||
401 | for (i = 0; i < count; i++) | 433 | for (i = 0; i < count; i++) |
402 | { | 434 | { |
403 | *d1++ = FRACMUL_8(*s1++, gain); | 435 | *d1++ = FRACMUL_8_LOOP(s, gain, s1); |
404 | } | 436 | } |
405 | } | 437 | } |
406 | } | 438 | } |
@@ -427,10 +459,13 @@ static void write_samples(short* dst, long* src[], int count) | |||
427 | } | 459 | } |
428 | else | 460 | else |
429 | { | 461 | { |
462 | long min = dsp.clip_min; | ||
463 | long max = dsp.clip_max; | ||
464 | |||
430 | while (count-- > 0) | 465 | while (count-- > 0) |
431 | { | 466 | { |
432 | *dst++ = (short) (clip_sample(*s0++) >> scale); | 467 | *dst++ = (short) (clip_sample(*s0++, min, max) >> scale); |
433 | *dst++ = (short) (clip_sample(*s1++) >> scale); | 468 | *dst++ = (short) (clip_sample(*s1++, min, max) >> scale); |
434 | } | 469 | } |
435 | } | 470 | } |
436 | } | 471 | } |
@@ -682,6 +717,7 @@ void dsp_set_replaygain(bool always) | |||
682 | } | 717 | } |
683 | } | 718 | } |
684 | 719 | ||
685 | dsp.replaygain = gain; | 720 | /* Store in S8.23 format to simplify calculations. */ |
721 | dsp.replaygain = gain >> 1; | ||
686 | } | 722 | } |
687 | } | 723 | } |