summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rbcodec/dsp/tdspeed.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/lib/rbcodec/dsp/tdspeed.c b/lib/rbcodec/dsp/tdspeed.c
index 7bf1a13ccb..412d889ee8 100644
--- a/lib/rbcodec/dsp/tdspeed.c
+++ b/lib/rbcodec/dsp/tdspeed.c
@@ -83,6 +83,37 @@ static const int buffer_sizes[NBUFFERS] =
83/* Processed buffer passed out to later stages */ 83/* Processed buffer passed out to later stages */
84static struct dsp_buffer dsp_outbuf; 84static struct dsp_buffer dsp_outbuf;
85 85
86/* Blend overlapping frame samples according to position */
87#if defined(CPU_COLDFIRE)
88static inline int32_t blend_frame_samples(int32_t curr, int32_t prev,
89 int i, int j, int order)
90{
91 int32_t a0, a1;
92 asm (
93 "mac.l %2, %3, %%acc0 \n" /* acc = curr*(i<<(30-order)) >> 23 */
94 "mac.l %4, %5, %%acc0 \n" /* acc += prev*(j<<(30-order)) >> 23 */
95 "moveq.l #1, %0 \n" /* Prepare mask */
96 "move.l %%accext01, %1 \n" /* Get extension bits */
97 "lsr.l #7, %1 \n" /* Get bit 7 of LSb extension ... */
98 "and.l %0, %1 \n" /* ... into bit 0 */
99 "movclr.l %%acc0, %0 \n" /* Get result >> 8 */
100 "asl.l #1, %0 \n" /* Everything x2 */
101 "or.l %1, %0 \n" /* Insert proper LSb from extension */
102 : "=d"(a0), "=d"(a1)
103 : "r"(curr), "r"(i << order),
104 "r"(prev), "r"(j << order));
105
106 return a0;
107}
108#else
109/* Generic */
110static inline int32_t blend_frame_samples(int32_t curr, int32_t prev,
111 int i, int j, int order)
112{
113 return (curr * (int64_t)i + prev * (int64_t)j) >> order;
114}
115#endif /* CPU_* */
116
86/* Discard all data */ 117/* Discard all data */
87static void tdspeed_flush(void) 118static void tdspeed_flush(void)
88{ 119{
@@ -121,6 +152,11 @@ static bool tdspeed_update(int32_t samplerate, int32_t factor)
121 st->dst_order++; 152 st->dst_order++;
122 153
123 st->dst_step = (1 << st->dst_order); 154 st->dst_step = (1 << st->dst_order);
155#ifdef CPU_COLDFIRE
156 /* blend_frame_samples works in s0.31 mode. Also must shift by
157 one less bit before mac in order not to overflow. */
158 st->dst_order = 30 - st->dst_order;
159#endif
124 st->src_step = st->dst_step * factor / PITCH_SPEED_100; 160 st->src_step = st->dst_step * factor / PITCH_SPEED_100;
125 st->shift_max = (st->dst_step > st->src_step) ? 161 st->shift_max = (st->dst_step > st->src_step) ?
126 st->dst_step : st->src_step; 162 st->dst_step : st->src_step;
@@ -272,9 +308,8 @@ skip:;
272 for (int i = 0, j = st->dst_step; j; i++, j--) 308 for (int i = 0, j = st->dst_step; j; i++, j--)
273 { 309 {
274 assert(d < buf_out[ch] + out_size); 310 assert(d < buf_out[ch] + out_size);
275 311 *d++ = blend_frame_samples(*curr++, *prev++, i, j,
276 *d++ = (*curr++ * (int64_t)i + 312 st->dst_order);
277 *prev++ * (int64_t)j) >> st->dst_order;
278 } 313 }
279 314
280 dest[ch] = d; 315 dest[ch] = d;