summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2005-08-18 19:25:39 +0000
committerMagnus Holmgren <magnushol@gmail.com>2005-08-18 19:25:39 +0000
commit75ef3129c9382a413afe897c362c9444df734c59 (patch)
tree4b7138482cbaf034376f43345db81d17833293a8 /apps/dsp.c
parent49483bc4885a31f9554a285d9448499e89359cb2 (diff)
downloadrockbox-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.c68
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
326static inline long clip_sample(long sample) 350static 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}