summaryrefslogtreecommitdiff
path: root/apps/tdspeed.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tdspeed.c')
-rw-r--r--apps/tdspeed.c142
1 files changed, 99 insertions, 43 deletions
diff --git a/apps/tdspeed.c b/apps/tdspeed.c
index 8cb495c08f..b940c928fc 100644
--- a/apps/tdspeed.c
+++ b/apps/tdspeed.c
@@ -38,7 +38,7 @@
38 38
39#define FIXED_BUFSIZE 3072 /* 48KHz factor 3.0 */ 39#define FIXED_BUFSIZE 3072 /* 48KHz factor 3.0 */
40 40
41struct tdspeed_state_s 41static struct tdspeed_state_s
42{ 42{
43 bool stereo; 43 bool stereo;
44 int32_t shift_max; /* maximum displacement on a frame */ 44 int32_t shift_max; /* maximum displacement on a frame */
@@ -49,26 +49,28 @@ struct tdspeed_state_s
49 int32_t ovl_size; /* overlap buffer used size */ 49 int32_t ovl_size; /* overlap buffer used size */
50 int32_t ovl_space; /* overlap buffer size */ 50 int32_t ovl_space; /* overlap buffer size */
51 int32_t *ovl_buff[2]; /* overlap buffer */ 51 int32_t *ovl_buff[2]; /* overlap buffer */
52}; 52} tdspeed_state;
53static struct tdspeed_state_s tdspeed_state;
54 53
55static int32_t *overlap_buffer[2] = { NULL, NULL }; 54static int32_t *overlap_buffer[2] = { NULL, NULL };
56static int32_t *outbuf[2] = { NULL, NULL }; 55static int32_t *outbuf[2] = { NULL, NULL };
57 56
58void tdspeed_init() 57void tdspeed_init(void)
59{ 58{
60 if (global_settings.timestretch_enabled) 59 if (!global_settings.timestretch_enabled)
61 { 60 return;
62 /* Allocate buffers */ 61
63 if (overlap_buffer[0] == NULL) 62 /* Allocate buffers */
64 overlap_buffer[0] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t)); 63 if (overlap_buffer[0] == NULL)
65 if (overlap_buffer[1] == NULL) 64 overlap_buffer[0] = (int32_t *)buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
66 overlap_buffer[1] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t)); 65
67 if (outbuf[0] == NULL) 66 if (overlap_buffer[1] == NULL)
68 outbuf[0] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t)); 67 overlap_buffer[1] = (int32_t *)buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
69 if (outbuf[1] == NULL) 68
70 outbuf[1] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t)); 69 if (outbuf[0] == NULL)
71 } 70 outbuf[0] = (int32_t *)buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
71
72 if (outbuf[1] == NULL)
73 outbuf[1] = (int32_t *)buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
72} 74}
73 75
74 76
@@ -80,14 +82,17 @@ bool tdspeed_config(int samplerate, bool stereo, int32_t factor)
80 /* Check buffers were allocated ok */ 82 /* Check buffers were allocated ok */
81 if (overlap_buffer[0] == NULL || overlap_buffer[1] == NULL) 83 if (overlap_buffer[0] == NULL || overlap_buffer[1] == NULL)
82 return false; 84 return false;
85
83 if (outbuf[0] == NULL || outbuf[1] == NULL) 86 if (outbuf[0] == NULL || outbuf[1] == NULL)
84 return false; 87 return false;
85 88
86 /* Check parameters */ 89 /* Check parameters */
87 if (factor == PITCH_SPEED_100) 90 if (factor == PITCH_SPEED_100)
88 return false; 91 return false;
92
89 if (samplerate < MIN_RATE || samplerate > MAX_RATE) 93 if (samplerate < MIN_RATE || samplerate > MAX_RATE)
90 return false; 94 return false;
95
91 if (factor < STRETCH_MIN || factor > STRETCH_MAX) 96 if (factor < STRETCH_MIN || factor > STRETCH_MAX)
92 return false; 97 return false;
93 98
@@ -96,19 +101,24 @@ bool tdspeed_config(int samplerate, bool stereo, int32_t factor)
96 101
97 if (factor > PITCH_SPEED_100) 102 if (factor > PITCH_SPEED_100)
98 st->dst_step = st->dst_step * PITCH_SPEED_100 / factor; 103 st->dst_step = st->dst_step * PITCH_SPEED_100 / factor;
104
99 st->dst_order = 1; 105 st->dst_order = 1;
100 106
101 while (st->dst_step >>= 1) 107 while (st->dst_step >>= 1)
102 st->dst_order++; 108 st->dst_order++;
109
103 st->dst_step = (1 << st->dst_order); 110 st->dst_step = (1 << st->dst_order);
104 st->src_step = st->dst_step * factor / PITCH_SPEED_100; 111 st->src_step = st->dst_step * factor / PITCH_SPEED_100;
105 st->shift_max = (st->dst_step > st->src_step) ? st->dst_step : st->src_step; 112 st->shift_max = (st->dst_step > st->src_step) ? st->dst_step : st->src_step;
106 113
107 src_frame_sz = st->shift_max + st->dst_step; 114 src_frame_sz = st->shift_max + st->dst_step;
115
108 if (st->dst_step > st->src_step) 116 if (st->dst_step > st->src_step)
109 src_frame_sz += st->dst_step - st->src_step; 117 src_frame_sz += st->dst_step - st->src_step;
110 st->ovl_space = ((src_frame_sz - 2)/st->src_step) * st->src_step 118
111 + src_frame_sz; 119 st->ovl_space = ((src_frame_sz - 2) / st->src_step) * st->src_step
120 + src_frame_sz;
121
112 if (st->src_step > st->dst_step) 122 if (st->src_step > st->dst_step)
113 st->ovl_space += 2*st->src_step - st->dst_step; 123 st->ovl_space += 2*st->src_step - st->dst_step;
114 124
@@ -119,6 +129,7 @@ bool tdspeed_config(int samplerate, bool stereo, int32_t factor)
119 st->ovl_shift = 0; 129 st->ovl_shift = 0;
120 130
121 st->ovl_buff[0] = overlap_buffer[0]; 131 st->ovl_buff[0] = overlap_buffer[0];
132
122 if (stereo) 133 if (stereo)
123 st->ovl_buff[1] = overlap_buffer[1]; 134 st->ovl_buff[1] = overlap_buffer[1];
124 else 135 else
@@ -135,9 +146,11 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
135 int32_t *curr, *prev, *dest[2], *d; 146 int32_t *curr, *prev, *dest[2], *d;
136 int32_t i, j, next_frame, prev_frame, shift, src_frame_sz; 147 int32_t i, j, next_frame, prev_frame, shift, src_frame_sz;
137 bool stereo = buf_in[0] != buf_in[1]; 148 bool stereo = buf_in[0] != buf_in[1];
149
138 assert(stereo == st->stereo); 150 assert(stereo == st->stereo);
139 151
140 src_frame_sz = st->shift_max + st->dst_step; 152 src_frame_sz = st->shift_max + st->dst_step;
153
141 if (st->dst_step > st->src_step) 154 if (st->dst_step > st->src_step)
142 src_frame_sz += st->dst_step - st->src_step; 155 src_frame_sz += st->dst_step - st->src_step;
143 156
@@ -146,20 +159,28 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
146 { 159 {
147 int32_t have, copy, steps; 160 int32_t have, copy, steps;
148 have = st->ovl_size; 161 have = st->ovl_size;
162
149 if (st->ovl_shift > 0) 163 if (st->ovl_shift > 0)
150 have -= st->ovl_shift; 164 have -= st->ovl_shift;
165
151 /* append just enough data to have all of the overlap buffer consumed */ 166 /* append just enough data to have all of the overlap buffer consumed */
152 steps = (have - 1) / st->src_step; 167 steps = (have - 1) / st->src_step;
153 copy = steps * st->src_step + src_frame_sz - have; 168 copy = steps * st->src_step + src_frame_sz - have;
169
154 if (copy < src_frame_sz - st->dst_step) 170 if (copy < src_frame_sz - st->dst_step)
155 copy += st->src_step; /* one more step to allow for pregap data */ 171 copy += st->src_step; /* one more step to allow for pregap data */
156 if (copy > data_len) copy = data_len; 172
157 assert(st->ovl_size +copy <= FIXED_BUFSIZE); 173 if (copy > data_len)
174 copy = data_len;
175
176 assert(st->ovl_size + copy <= FIXED_BUFSIZE);
158 memcpy(st->ovl_buff[0] + st->ovl_size, buf_in[0], 177 memcpy(st->ovl_buff[0] + st->ovl_size, buf_in[0],
159 copy * sizeof(int32_t)); 178 copy * sizeof(int32_t));
179
160 if (stereo) 180 if (stereo)
161 memcpy(st->ovl_buff[1] + st->ovl_size, buf_in[1], 181 memcpy(st->ovl_buff[1] + st->ovl_size, buf_in[1],
162 copy * sizeof(int32_t)); 182 copy * sizeof(int32_t));
183
163 if (!last && have + copy < src_frame_sz) 184 if (!last && have + copy < src_frame_sz)
164 { 185 {
165 /* still not enough to process at least one frame */ 186 /* still not enough to process at least one frame */
@@ -170,14 +191,17 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
170 /* recursively call ourselves to process the overlap buffer */ 191 /* recursively call ourselves to process the overlap buffer */
171 have = st->ovl_size; 192 have = st->ovl_size;
172 st->ovl_size = 0; 193 st->ovl_size = 0;
194
173 if (copy == data_len) 195 if (copy == data_len)
174 { 196 {
175 assert( (have+copy) <= FIXED_BUFSIZE); 197 assert(have + copy <= FIXED_BUFSIZE);
176 return tdspeed_apply(buf_out, st->ovl_buff, have+copy, last, 198 return tdspeed_apply(buf_out, st->ovl_buff, have+copy, last,
177 out_size); 199 out_size);
178 } 200 }
179 assert( (have+copy) <= FIXED_BUFSIZE); 201
202 assert(have + copy <= FIXED_BUFSIZE);
180 i = tdspeed_apply(buf_out, st->ovl_buff, have+copy, -1, out_size); 203 i = tdspeed_apply(buf_out, st->ovl_buff, have+copy, -1, out_size);
204
181 dest[0] = buf_out[0] + i; 205 dest[0] = buf_out[0] + i;
182 dest[1] = buf_out[1] + i; 206 dest[1] = buf_out[1] + i;
183 207
@@ -189,51 +213,64 @@ static int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2],
189 { 213 {
190 dest[0] = buf_out[0]; 214 dest[0] = buf_out[0];
191 dest[1] = buf_out[1]; 215 dest[1] = buf_out[1];
216
192 next_frame = prev_frame = 0; 217 next_frame = prev_frame = 0;
218
193 if (st->ovl_shift > 0) 219 if (st->ovl_shift > 0)
194 next_frame += st->ovl_shift; 220 next_frame += st->ovl_shift;
195 else 221 else
196 prev_frame += -st->ovl_shift; 222 prev_frame += -st->ovl_shift;
197 } 223 }
224
198 st->ovl_shift = 0; 225 st->ovl_shift = 0;
199 226
200 /* process all complete frames */ 227 /* process all complete frames */
201 while (data_len - next_frame >= src_frame_sz) 228 while (data_len - next_frame >= src_frame_sz)
202 { 229 {
203 /* find frame overlap by autocorelation */ 230 /* find frame overlap by autocorelation */
231 int32_t const INC1 = 8;
232 int32_t const INC2 = 32;
233
204 int64_t min_delta = ~(1ll << 63); /* most positive */ 234 int64_t min_delta = ~(1ll << 63); /* most positive */
205 shift = 0; 235 shift = 0;
206#define INC1 8 236
207#define INC2 32
208 /* Power of 2 of a 28bit number requires 56bits, can accumulate 237 /* Power of 2 of a 28bit number requires 56bits, can accumulate
209 256times in a 64bit variable. */ 238 256times in a 64bit variable. */
210 assert(st->dst_step / INC2 <= 256); 239 assert(st->dst_step / INC2 <= 256);
211 assert(next_frame + st->shift_max - 1 + st->dst_step-1 < data_len); 240 assert(next_frame + st->shift_max - 1 + st->dst_step - 1 < data_len);
212 assert(prev_frame + st->dst_step - 1 < data_len); 241 assert(prev_frame + st->dst_step - 1 < data_len);
242
213 for (i = 0; i < st->shift_max; i += INC1) 243 for (i = 0; i < st->shift_max; i += INC1)
214 { 244 {
215 int64_t delta = 0; 245 int64_t delta = 0;
246
216 curr = buf_in[0] + next_frame + i; 247 curr = buf_in[0] + next_frame + i;
217 prev = buf_in[0] + prev_frame; 248 prev = buf_in[0] + prev_frame;
249
218 for (j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2) 250 for (j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2)
219 { 251 {
220 int32_t diff = *curr - *prev; 252 int32_t diff = *curr - *prev;
221 delta += (int64_t)diff * diff; 253 delta += (int64_t)diff * diff;
254
222 if (delta >= min_delta) 255 if (delta >= min_delta)
223 goto skip; 256 goto skip;
224 } 257 }
258
225 if (stereo) 259 if (stereo)
226 { 260 {
227 curr = buf_in[1] +next_frame + i; 261 curr = buf_in[1] + next_frame + i;
228 prev = buf_in[1] +prev_frame; 262 prev = buf_in[1] + prev_frame;
263
229 for (j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2) 264 for (j = 0; j < st->dst_step; j += INC2, curr += INC2, prev += INC2)
230 { 265 {
231 int32_t diff = *curr - *prev; 266 int32_t diff = *curr - *prev;
232 delta += (int64_t)diff * diff; 267 delta += (int64_t)diff * diff;
268
233 if (delta >= min_delta) 269 if (delta >= min_delta)
234 goto skip; 270 goto skip;
235 } 271 }
236 } 272 }
273
237 min_delta = delta; 274 min_delta = delta;
238 shift = i; 275 shift = i;
239skip:; 276skip:;
@@ -242,27 +279,36 @@ skip:;
242 /* overlap fading-out previous frame with fading-in current frame */ 279 /* overlap fading-out previous frame with fading-in current frame */
243 curr = buf_in[0] + next_frame + shift; 280 curr = buf_in[0] + next_frame + shift;
244 prev = buf_in[0] + prev_frame; 281 prev = buf_in[0] + prev_frame;
282
245 d = dest[0]; 283 d = dest[0];
284
246 assert(next_frame + shift + st->dst_step - 1 < data_len); 285 assert(next_frame + shift + st->dst_step - 1 < data_len);
247 assert(prev_frame + st->dst_step - 1 < data_len); 286 assert(prev_frame + st->dst_step - 1 < data_len);
248 assert(dest[0] - buf_out[0] + st->dst_step - 1 < out_size); 287 assert(dest[0] - buf_out[0] + st->dst_step - 1 < out_size);
288
249 for (i = 0, j = st->dst_step; j; i++, j--) 289 for (i = 0, j = st->dst_step; j; i++, j--)
250 { 290 {
251 *d++ = (*curr++ * (int64_t)i 291 *d++ = (*curr++ * (int64_t)i +
252 + *prev++ * (int64_t)j) >> st->dst_order; 292 *prev++ * (int64_t)j) >> st->dst_order;
253 } 293 }
294
254 dest[0] = d; 295 dest[0] = d;
296
255 if (stereo) 297 if (stereo)
256 { 298 {
257 curr = buf_in[1] +next_frame + shift; 299 curr = buf_in[1] + next_frame + shift;
258 prev = buf_in[1] +prev_frame; 300 prev = buf_in[1] + prev_frame;
301
259 d = dest[1]; 302 d = dest[1];
303
260 for (i = 0, j = st->dst_step; j; i++, j--) 304 for (i = 0, j = st->dst_step; j; i++, j--)
261 { 305 {
262 assert(d < buf_out[1] +out_size); 306 assert(d < buf_out[1] + out_size);
263 *d++ = (*curr++ * (int64_t) i 307
264 + *prev++ * (int64_t) j) >> st->dst_order; 308 *d++ = (*curr++ * (int64_t)i +
309 *prev++ * (int64_t)j) >> st->dst_order;
265 } 310 }
311
266 dest[1] = d; 312 dest[1] = d;
267 } 313 }
268 314
@@ -283,14 +329,17 @@ skip:;
283 else if (last != 0) 329 else if (last != 0)
284 { 330 {
285 /* last call: purge all remaining data to output buffer */ 331 /* last call: purge all remaining data to output buffer */
286 i = data_len -prev_frame; 332 i = data_len - prev_frame;
287 assert(dest[0] +i <= buf_out[0] +out_size); 333
288 memcpy(dest[0], buf_in[0] +prev_frame, i * sizeof(int32_t)); 334 assert(dest[0] + i <= buf_out[0] + out_size);
335 memcpy(dest[0], buf_in[0] + prev_frame, i * sizeof(int32_t));
336
289 dest[0] += i; 337 dest[0] += i;
338
290 if (stereo) 339 if (stereo)
291 { 340 {
292 assert(dest[1] +i <= buf_out[1] +out_size); 341 assert(dest[1] + i <= buf_out[1] + out_size);
293 memcpy(dest[1], buf_in[1] +prev_frame, i * sizeof(int32_t)); 342 memcpy(dest[1], buf_in[1] + prev_frame, i * sizeof(int32_t));
294 dest[1] += i; 343 dest[1] += i;
295 } 344 }
296 } 345 }
@@ -300,10 +349,12 @@ skip:;
300 st->ovl_shift = next_frame - prev_frame; 349 st->ovl_shift = next_frame - prev_frame;
301 i = (st->ovl_shift < 0) ? next_frame : prev_frame; 350 i = (st->ovl_shift < 0) ? next_frame : prev_frame;
302 st->ovl_size = data_len - i; 351 st->ovl_size = data_len - i;
352
303 assert(st->ovl_size <= FIXED_BUFSIZE); 353 assert(st->ovl_size <= FIXED_BUFSIZE);
304 memcpy(st->ovl_buff[0], buf_in[0]+i, st->ovl_size * sizeof(int32_t)); 354 memcpy(st->ovl_buff[0], buf_in[0] + i, st->ovl_size * sizeof(int32_t));
355
305 if (stereo) 356 if (stereo)
306 memcpy(st->ovl_buff[1], buf_in[1]+i, st->ovl_size * sizeof(int32_t)); 357 memcpy(st->ovl_buff[1], buf_in[1] + i, st->ovl_size * sizeof(int32_t));
307 } 358 }
308 359
309 return dest[0] - buf_out[0]; 360 return dest[0] - buf_out[0];
@@ -317,9 +368,12 @@ long tdspeed_est_output_size()
317long tdspeed_est_input_size(long size) 368long tdspeed_est_input_size(long size)
318{ 369{
319 struct tdspeed_state_s *st = &tdspeed_state; 370 struct tdspeed_state_s *st = &tdspeed_state;
320 size = (size -st->ovl_size) *st->src_step / st->dst_step; 371
372 size = (size - st->ovl_size) * st->src_step / st->dst_step;
373
321 if (size < 0) 374 if (size < 0)
322 size = 0; 375 size = 0;
376
323 return size; 377 return size;
324} 378}
325 379
@@ -327,8 +381,10 @@ int tdspeed_doit(int32_t *src[], int count)
327{ 381{
328 count = tdspeed_apply( (int32_t *[2]) { outbuf[0], outbuf[1] }, 382 count = tdspeed_apply( (int32_t *[2]) { outbuf[0], outbuf[1] },
329 src, count, 0, TDSPEED_OUTBUFSIZE); 383 src, count, 0, TDSPEED_OUTBUFSIZE);
384
330 src[0] = outbuf[0]; 385 src[0] = outbuf[0];
331 src[1] = outbuf[1]; 386 src[1] = outbuf[1];
387
332 return count; 388 return count;
333} 389}
334 390