summaryrefslogtreecommitdiff
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
parent49483bc4885a31f9554a285d9448499e89359cb2 (diff)
iriver: slightly faster replaygain processing and clipping.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7353 a1c6a512-1295-4272-9138-f99709370657
-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 @@
: [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \
t; \
})
-/* Multiply one S.31-bit and one S7.24 fractional integer and return the
+
+/* Multiply one S.31-bit and one S8.23 fractional integer and return the
* sign bit and the 31 most significant bits of the result.
*/
#define FRACMUL_8(x, y) \
@@ -66,14 +67,37 @@
"move.l %%accext01, %[u]\n\t" \
"movclr.l %%acc0, %[t]\n\t" \
: [t] "=r" (t), [u] "=r" (u) : [a] "r" (x), [b] "r" (y)); \
- (t << 7) | ((u & 0xff) >> 1); \
+ (t << 8) | (u & 0xff); \
+})
+
+/* Multiply one S.31-bit and one S8.23 fractional integer and return the
+ * sign bit and the 31 most significant bits of the result. Load next value
+ * to multiply with into x from s (and increase s); x must contain the
+ * initial value.
+ */
+#define FRACMUL_8_LOOP(x, y, s) \
+({ \
+ long t; \
+ long u; \
+ asm volatile ("mac.l %[a], %[b], (%[c])+, %[a], %%acc0\n\t" \
+ "move.l %%accext01, %[u]\n\t" \
+ "movclr.l %%acc0, %[t]\n\t" \
+ : [a] "+r" (x), [c] "+a" (s), [t] "=r" (t), [u] "=r" (u) \
+ : [b] "r" (y)); \
+ (t << 8) | (u & 0xff); \
})
#else
#define INIT()
#define FRACMUL(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 31))
-#define FRACMUL_8(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 24))
+#define FRACMUL_8(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 23))
+#define FRACMUL_8_LOOP(x, y, s) \
+({ \
+ long t = x; \
+ x = *(s)++; \
+ (long) (((((long long) (t)) * ((long long) (y))) >> 23)); \
+})
#endif
@@ -86,7 +110,7 @@ struct dsp_config
long album_gain;
long track_peak;
long album_peak;
- long replaygain;
+ long replaygain; /* Note that this is in S8.23 format. */
int sample_depth;
int sample_bytes;
int stereo_mode;
@@ -323,15 +347,15 @@ static inline int resample(long* src[], int count)
return new_count;
}
-static inline long clip_sample(long sample)
+static inline long clip_sample(long sample, long min, long max)
{
- if (sample > dsp.clip_max)
+ if (sample > max)
{
- sample = dsp.clip_max;
+ sample = max;
}
- else if (sample < dsp.clip_min)
+ else if (sample < min)
{
- sample = dsp.clip_min;
+ sample = min;
}
return sample;
@@ -346,6 +370,8 @@ static long dither_sample(long sample, long bias, long mask,
{
long output;
long random;
+ long min;
+ long max;
/* Noise shape and bias */
@@ -363,8 +389,10 @@ static long dither_sample(long sample, long bias, long mask,
/* Clip and quantize */
- sample = clip_sample(sample);
- output = clip_sample(output) & ~mask;
+ min = dsp.clip_min;
+ max = dsp.clip_max;
+ sample = clip_sample(sample, min, max);
+ output = clip_sample(output, min, max) & ~mask;
/* Error feedback */
@@ -386,21 +414,25 @@ static void apply_gain(long* src[], int count)
long* d0 = &sample_buf[0];
long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2];
long gain = dsp.replaygain;
+ long s;
long i;
src[0] = d0;
src[1] = d1;
+ s = *s0++;
for (i = 0; i < count; i++)
{
- *d0++ = FRACMUL_8(*s0++, gain);
+ *d0++ = FRACMUL_8_LOOP(s, gain, s0);
}
if (src [0] != src [1])
{
+ s = *s1++;
+
for (i = 0; i < count; i++)
{
- *d1++ = FRACMUL_8(*s1++, gain);
+ *d1++ = FRACMUL_8_LOOP(s, gain, s1);
}
}
}
@@ -427,10 +459,13 @@ static void write_samples(short* dst, long* src[], int count)
}
else
{
+ long min = dsp.clip_min;
+ long max = dsp.clip_max;
+
while (count-- > 0)
{
- *dst++ = (short) (clip_sample(*s0++) >> scale);
- *dst++ = (short) (clip_sample(*s1++) >> scale);
+ *dst++ = (short) (clip_sample(*s0++, min, max) >> scale);
+ *dst++ = (short) (clip_sample(*s1++, min, max) >> scale);
}
}
}
@@ -682,6 +717,7 @@ void dsp_set_replaygain(bool always)
}
}
- dsp.replaygain = gain;
+ /* Store in S8.23 format to simplify calculations. */
+ dsp.replaygain = gain >> 1;
}
}