diff options
Diffstat (limited to 'lib/rbcodec')
-rw-r--r-- | lib/rbcodec/dsp/tdspeed.c | 41 |
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 */ |
84 | static struct dsp_buffer dsp_outbuf; | 84 | static struct dsp_buffer dsp_outbuf; |
85 | 85 | ||
86 | /* Blend overlapping frame samples according to position */ | ||
87 | #if defined(CPU_COLDFIRE) | ||
88 | static 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 */ | ||
110 | static 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 */ |
87 | static void tdspeed_flush(void) | 118 | static 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; |