summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-05-10 21:39:13 -0400
committerMichael Sevakis <jethead71@rockbox.org>2012-05-10 21:41:26 -0400
commit0e5dd0a9cff7e2fe72346d9c014a77a87ada1397 (patch)
tree77b3a84531cb6157ded617bf635f15bd7aa9b96e
parent645680d62b82455d24fcb178f1cc5208f9942e38 (diff)
downloadrockbox-0e5dd0a9cff7e2fe72346d9c014a77a87ada1397.tar.gz
rockbox-0e5dd0a9cff7e2fe72346d9c014a77a87ada1397.zip
TDSpeed: Fix up samples consumed return (FS#12666) + other stuff like...
Wrap up the the stereo case into loops and remove unused calculations hanging out in tdspeed_update(). A wee little bit of code style and column policing. Change-Id: I8dd3ab4b3e7e56b55dc00c00f3e32996228cc457
-rw-r--r--lib/rbcodec/dsp/tdspeed.c194
1 files changed, 82 insertions, 112 deletions
diff --git a/lib/rbcodec/dsp/tdspeed.c b/lib/rbcodec/dsp/tdspeed.c
index ea1013e049..7bf1a13ccb 100644
--- a/lib/rbcodec/dsp/tdspeed.c
+++ b/lib/rbcodec/dsp/tdspeed.c
@@ -54,7 +54,7 @@ static struct tdspeed_state_s
54{ 54{
55 struct dsp_proc_entry *this; /* this stage */ 55 struct dsp_proc_entry *this; /* this stage */
56 struct dsp_config *dsp; /* the DSP we use */ 56 struct dsp_config *dsp; /* the DSP we use */
57 unsigned int channels; /* flags parameter to use in call */ 57 int channels; /* number of audio channels */
58 int32_t samplerate; /* current samplerate of input data */ 58 int32_t samplerate; /* current samplerate of input data */
59 int32_t factor; /* stretch factor (perdecimille) */ 59 int32_t factor; /* stretch factor (perdecimille) */
60 int32_t shift_max; /* maximum displacement on a frame */ 60 int32_t shift_max; /* maximum displacement on a frame */
@@ -63,12 +63,13 @@ static struct tdspeed_state_s
63 int32_t dst_order; /* power of two for dst_step */ 63 int32_t dst_order; /* power of two for dst_step */
64 int32_t ovl_shift; /* overlap buffer frame shift */ 64 int32_t ovl_shift; /* overlap buffer frame shift */
65 int32_t ovl_size; /* overlap buffer used size */ 65 int32_t ovl_size; /* overlap buffer used size */
66 int32_t ovl_space; /* overlap buffer size */
67 int32_t *ovl_buff[2]; /* overlap buffer (L+R) */ 66 int32_t *ovl_buff[2]; /* overlap buffer (L+R) */
68} tdspeed_state; 67} tdspeed_state;
69 68
70static int32_t *buffers[NBUFFERS] = { NULL, NULL, NULL, NULL }; 69static int32_t *buffers[NBUFFERS] = { NULL, NULL, NULL, NULL };
71static const int buffer_sizes[NBUFFERS] = { 70
71static const int buffer_sizes[NBUFFERS] =
72{
72 FIXED_BUFCOUNT * sizeof(int32_t), 73 FIXED_BUFCOUNT * sizeof(int32_t),
73 FIXED_BUFCOUNT * sizeof(int32_t), 74 FIXED_BUFCOUNT * sizeof(int32_t),
74 FIXED_OUTBUFCOUNT * sizeof(int32_t), 75 FIXED_OUTBUFCOUNT * sizeof(int32_t),
@@ -121,21 +122,8 @@ static bool tdspeed_update(int32_t samplerate, int32_t factor)
121 122
122 st->dst_step = (1 << st->dst_order); 123 st->dst_step = (1 << st->dst_order);
123 st->src_step = st->dst_step * factor / PITCH_SPEED_100; 124 st->src_step = st->dst_step * factor / PITCH_SPEED_100;
124 st->shift_max = (st->dst_step > st->src_step) ? st->dst_step : st->src_step; 125 st->shift_max = (st->dst_step > st->src_step) ?
125 126 st->dst_step : st->src_step;
126 int src_frame_sz = st->shift_max + st->dst_step;
127
128 if (st->dst_step > st->src_step)
129 src_frame_sz += st->dst_step - st->src_step;
130
131 st->ovl_space = ((src_frame_sz - 2) / st->src_step) * st->src_step
132 + src_frame_sz;
133
134 if (st->src_step > st->dst_step)
135 st->ovl_space += 2*st->src_step - st->dst_step;
136
137 if (st->ovl_space > FIXED_BUFCOUNT)
138 st->ovl_space = FIXED_BUFCOUNT;
139 127
140 /* just discard remaining input data */ 128 /* just discard remaining input data */
141 st->ovl_size = 0; 129 st->ovl_size = 0;
@@ -151,28 +139,26 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
151 int data_len, enum tdspeed_ops op, int *consumed) 139 int data_len, enum tdspeed_ops op, int *consumed)
152/* data_len in samples */ 140/* data_len in samples */
153{ 141{
154 struct tdspeed_state_s *st = &tdspeed_state; 142 struct tdspeed_state_s *const st = &tdspeed_state;
155 int32_t *dest[2]; 143 int32_t src_frame_sz = st->shift_max + st->dst_step;
156 int32_t next_frame, prev_frame, src_frame_sz;
157 bool stereo = st->channels > 1;
158
159 src_frame_sz = st->shift_max + st->dst_step;
160 144
161 if (st->dst_step > st->src_step) 145 if (st->dst_step > st->src_step)
162 src_frame_sz += st->dst_step - st->src_step; 146 src_frame_sz += st->dst_step - st->src_step;
163 147
148 int32_t *dest[2];
149 int32_t next_frame, prev_frame;
150
164 /* deal with overlap data first, if any */ 151 /* deal with overlap data first, if any */
165 if (st->ovl_size) 152 if (st->ovl_size)
166 { 153 {
167 int32_t have, copy, steps; 154 int32_t have = st->ovl_size;
168 have = st->ovl_size;
169 155
170 if (st->ovl_shift > 0) 156 if (st->ovl_shift > 0)
171 have -= st->ovl_shift; 157 have -= st->ovl_shift;
172 158
173 /* append just enough data to have all of the overlap buffer consumed */ 159 /* append just enough data to have all of the overlap buffer consumed */
174 steps = (have - 1) / st->src_step; 160 int32_t steps = (have - 1) / st->src_step;
175 copy = steps * st->src_step + src_frame_sz - have; 161 int32_t copy = steps * st->src_step + src_frame_sz - have;
176 162
177 if (copy < src_frame_sz - st->dst_step) 163 if (copy < src_frame_sz - st->dst_step)
178 copy += st->src_step; /* one more step to allow for pregap data */ 164 copy += st->src_step; /* one more step to allow for pregap data */
@@ -181,14 +167,15 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
181 copy = data_len; 167 copy = data_len;
182 168
183 assert(st->ovl_size + copy <= FIXED_BUFCOUNT); 169 assert(st->ovl_size + copy <= FIXED_BUFCOUNT);
184 memcpy(st->ovl_buff[0] + st->ovl_size, buf_in[0],
185 copy * sizeof(int32_t));
186 170
187 if (stereo) 171 for (int ch = 0; ch < st->channels; ch++)
188 memcpy(st->ovl_buff[1] + st->ovl_size, buf_in[1], 172 {
173 memcpy(st->ovl_buff[ch] + st->ovl_size, buf_in[ch],
189 copy * sizeof(int32_t)); 174 copy * sizeof(int32_t));
175 }
190 176
191 *consumed += copy; 177 if (consumed)
178 *consumed = copy;
192 179
193 if (op == TDSOP_PROCESS && have + copy < src_frame_sz) 180 if (op == TDSOP_PROCESS && have + copy < src_frame_sz)
194 { 181 {
@@ -201,16 +188,16 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
201 have = st->ovl_size; 188 have = st->ovl_size;
202 st->ovl_size = 0; 189 st->ovl_size = 0;
203 190
191 assert(have + copy <= FIXED_BUFCOUNT);
192
204 if (copy == data_len) 193 if (copy == data_len)
205 { 194 {
206 assert(have + copy <= FIXED_BUFCOUNT); 195 return tdspeed_apply(buf_out, st->ovl_buff, have + copy,
207 return tdspeed_apply(buf_out, st->ovl_buff, have+copy, op, 196 op, NULL);
208 consumed);
209 } 197 }
210 198
211 assert(have + copy <= FIXED_BUFCOUNT); 199 int i = tdspeed_apply(buf_out, st->ovl_buff, have + copy,
212 int i = tdspeed_apply(buf_out, st->ovl_buff, have+copy, 200 TDSOP_LAST, NULL);
213 TDSOP_LAST, consumed);
214 201
215 dest[0] = buf_out[0] + i; 202 dest[0] = buf_out[0] + i;
216 dest[1] = buf_out[1] + i; 203 dest[1] = buf_out[1] + i;
@@ -227,9 +214,9 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
227 next_frame = prev_frame = 0; 214 next_frame = prev_frame = 0;
228 215
229 if (st->ovl_shift > 0) 216 if (st->ovl_shift > 0)
230 next_frame += st->ovl_shift; 217 next_frame = st->ovl_shift;
231 else 218 else
232 prev_frame += -st->ovl_shift; 219 prev_frame = -st->ovl_shift;
233 } 220 }
234 221
235 st->ovl_shift = 0; 222 st->ovl_shift = 0;
@@ -244,33 +231,20 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
244 int64_t min_delta = INT64_MAX; /* most positive */ 231 int64_t min_delta = INT64_MAX; /* most positive */
245 int shift = 0; 232 int shift = 0;
246 233
247 /* Power of 2 of a 28bit number requires 56bits, can accumulate 234 assert(next_frame + st->shift_max - 1 + st->dst_step <= data_len);
248 256times in a 64bit variable. */ 235 assert(prev_frame + st->dst_step <= data_len);
249 assert(st->dst_step / INC2 <= 256);
250 assert(next_frame + st->shift_max - 1 + st->dst_step - 1 < data_len);
251 assert(prev_frame + st->dst_step - 1 < data_len);
252 236
253 for (int i = 0; i < st->shift_max; i += INC1) 237 for (int i = 0; i < st->shift_max; i += INC1)
254 { 238 {
255 int64_t delta = 0; 239 int64_t delta = 0;
256 240
257 int32_t *curr = buf_in[0] + next_frame + i; 241 for (int ch = 0; ch < st->channels; ch++)
258 int32_t *prev = buf_in[0] + prev_frame;
259
260 for (int j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2)
261 {
262 delta += ad_s32(*curr, *prev);
263
264 if (delta >= min_delta)
265 goto skip;
266 }
267
268 if (stereo)
269 { 242 {
270 curr = buf_in[1] + next_frame + i; 243 int32_t *curr = buf_in[ch] + next_frame + i;
271 prev = buf_in[1] + prev_frame; 244 int32_t *prev = buf_in[ch] + prev_frame;
272 245
273 for (int j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2) 246 for (int j = 0; j < st->dst_step;
247 j += INC2, curr += INC2, prev += INC2)
274 { 248 {
275 delta += ad_s32(*curr, *prev); 249 delta += ad_s32(*curr, *prev);
276 250
@@ -285,39 +259,25 @@ skip:;
285 } 259 }
286 260
287 /* overlap fading-out previous frame with fading-in current frame */ 261 /* overlap fading-out previous frame with fading-in current frame */
288 int32_t *curr = buf_in[0] + next_frame + shift; 262 for (int ch = 0; ch < st->channels; ch++)
289 int32_t *prev = buf_in[0] + prev_frame;
290
291 int32_t *d = dest[0];
292
293 assert(next_frame + shift + st->dst_step - 1 < data_len);
294 assert(prev_frame + st->dst_step - 1 < data_len);
295 assert(dest[0] - buf_out[0] + st->dst_step - 1 < out_size);
296
297 for (int i = 0, j = st->dst_step; j; i++, j--)
298 {
299 *d++ = (*curr++ * (int64_t)i +
300 *prev++ * (int64_t)j) >> st->dst_order;
301 }
302
303 dest[0] = d;
304
305 if (stereo)
306 { 263 {
307 curr = buf_in[1] + next_frame + shift; 264 int32_t *curr = buf_in[ch] + next_frame + shift;
308 prev = buf_in[1] + prev_frame; 265 int32_t *prev = buf_in[ch] + prev_frame;
266 int32_t *d = dest[ch];
309 267
310 d = dest[1]; 268 assert(next_frame + shift + st->dst_step <= data_len);
269 assert(prev_frame + st->dst_step <= data_len);
270 assert(dest[ch] - buf_out[ch] + st->dst_step <= out_size);
311 271
312 for (int i = 0, j = st->dst_step; j; i++, j--) 272 for (int i = 0, j = st->dst_step; j; i++, j--)
313 { 273 {
314 assert(d < buf_out[1] + out_size); 274 assert(d < buf_out[ch] + out_size);
315 275
316 *d++ = (*curr++ * (int64_t)i + 276 *d++ = (*curr++ * (int64_t)i +
317 *prev++ * (int64_t)j) >> st->dst_order; 277 *prev++ * (int64_t)j) >> st->dst_order;
318 } 278 }
319 279
320 dest[1] = d; 280 dest[ch] = d;
321 } 281 }
322 282
323 /* adjust pointers for next frame */ 283 /* adjust pointers for next frame */
@@ -326,46 +286,56 @@ skip:;
326 286
327 /* here next_frame - prev_frame = src_step - dst_step - shift */ 287 /* here next_frame - prev_frame = src_step - dst_step - shift */
328 assert(next_frame - prev_frame == st->src_step - st->dst_step - shift); 288 assert(next_frame - prev_frame == st->src_step - st->dst_step - shift);
329 } 289 } /* while */
330 290
331 /* now deal with remaining partial frames */ 291 /* now deal with remaining partial frames */
332 if (op == TDSOP_LAST) 292 switch (op)
293 {
294 case TDSOP_PROCESS:
295 {
296 /* preserve remaining data + needed overlap data for next call */
297 st->ovl_shift = next_frame - prev_frame;
298 int i = (st->ovl_shift < 0) ? next_frame : prev_frame;
299 st->ovl_size = data_len - i;
300 assert(st->ovl_size <= FIXED_BUFCOUNT);
301
302 for (int ch = 0; ch < st->channels; ch++)
303 {
304 memcpy(st->ovl_buff[ch], buf_in[ch] + i,
305 st->ovl_size * sizeof(int32_t));
306 }
307
308 if (consumed)
309 *consumed = data_len;
310
311 break;
312 } /* TDSOP_PROCESS: */
313
314 case TDSOP_LAST:
333 { 315 {
334 /* special overlap buffer processing: remember frame shift only */ 316 /* special overlap buffer processing: remember frame shift only */
335 st->ovl_shift = next_frame - prev_frame; 317 st->ovl_shift = next_frame - prev_frame;
336 } 318 break;
337 else if (op == TDSOP_PURGE) 319 } /* TDSOP_LAST: */
320
321 case TDSOP_PURGE:
338 { 322 {
339 /* last call: purge all remaining data to output buffer */ 323 /* last call: purge all remaining data to output buffer */
340 int i = data_len - prev_frame; 324 int i = data_len - prev_frame;
341 325
342 assert(dest[0] + i <= buf_out[0] + out_size); 326 for (int ch = 0; ch < st->channels; ch++)
343 memcpy(dest[0], buf_in[0] + prev_frame, i * sizeof(int32_t));
344
345 dest[0] += i;
346
347 if (stereo)
348 { 327 {
349 assert(dest[1] + i <= buf_out[1] + out_size); 328 assert(dest[ch] + i <= buf_out[ch] + out_size);
350 memcpy(dest[1], buf_in[1] + prev_frame, i * sizeof(int32_t)); 329 memcpy(dest[ch], buf_in[ch] + prev_frame, i * sizeof(int32_t));
351 dest[1] += i; 330 dest[ch] += i;
352 } 331 }
353 332
354 *consumed += i; 333 if (consumed)
355 } 334 *consumed += i;
356 else
357 {
358 /* preserve remaining data + needed overlap data for next call */
359 st->ovl_shift = next_frame - prev_frame;
360 int i = (st->ovl_shift < 0) ? next_frame : prev_frame;
361 st->ovl_size = data_len - i;
362 335
363 assert(st->ovl_size <= FIXED_BUFCOUNT); 336 break;
364 memcpy(st->ovl_buff[0], buf_in[0] + i, st->ovl_size * sizeof(int32_t)); 337 } /* TDSOP_PURGE: */
365 338 } /* switch */
366 if (stereo)
367 memcpy(st->ovl_buff[1], buf_in[1] + i, st->ovl_size * sizeof(int32_t));
368 }
369 339
370 return dest[0] - buf_out[0]; 340 return dest[0] - buf_out[0];
371} 341}
@@ -471,7 +441,7 @@ static void tdspeed_process_new_format(struct dsp_proc_entry *this,
471 struct tdspeed_state_s *st = &tdspeed_state; 441 struct tdspeed_state_s *st = &tdspeed_state;
472 struct dsp_config *dsp = st->dsp; 442 struct dsp_config *dsp = st->dsp;
473 struct sample_format *format = &src->format; 443 struct sample_format *format = &src->format;
474 unsigned int channels = format->num_channels; 444 int channels = format->num_channels;
475 445
476 if (format->codec_frequency != st->samplerate) 446 if (format->codec_frequency != st->samplerate)
477 { 447 {