summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/tdspeed.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/dsp/tdspeed.c')
-rw-r--r--lib/rbcodec/dsp/tdspeed.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/lib/rbcodec/dsp/tdspeed.c b/lib/rbcodec/dsp/tdspeed.c
index 6a495bd989..e668c85032 100644
--- a/lib/rbcodec/dsp/tdspeed.c
+++ b/lib/rbcodec/dsp/tdspeed.c
@@ -53,7 +53,6 @@ enum tdspeed_ops
53static struct tdspeed_state_s 53static 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 */
57 int channels; /* number of audio channels */ 56 int channels; /* number of audio channels */
58 int32_t samplerate; /* current samplerate of input data */ 57 int32_t samplerate; /* current samplerate of input data */
59 int32_t factor; /* stretch factor (perdecimille) */ 58 int32_t factor; /* stretch factor (perdecimille) */
@@ -131,6 +130,10 @@ static bool tdspeed_update(int32_t samplerate, int32_t factor)
131 st->samplerate = samplerate; 130 st->samplerate = samplerate;
132 st->factor = factor; 131 st->factor = factor;
133 132
133 /* just discard remaining input data */
134 st->ovl_size = 0;
135 st->ovl_shift = 0;
136
134 /* Check parameters */ 137 /* Check parameters */
135 if (factor == PITCH_SPEED_100) 138 if (factor == PITCH_SPEED_100)
136 return false; 139 return false;
@@ -161,10 +164,6 @@ static bool tdspeed_update(int32_t samplerate, int32_t factor)
161 st->shift_max = (st->dst_step > st->src_step) ? 164 st->shift_max = (st->dst_step > st->src_step) ?
162 st->dst_step : st->src_step; 165 st->dst_step : st->src_step;
163 166
164 /* just discard remaining input data */
165 st->ovl_size = 0;
166 st->ovl_shift = 0;
167
168 st->ovl_buff[0] = overlap_buffer[0]; 167 st->ovl_buff[0] = overlap_buffer[0];
169 st->ovl_buff[1] = overlap_buffer[1]; /* ignored if mono */ 168 st->ovl_buff[1] = overlap_buffer[1]; /* ignored if mono */
170 169
@@ -378,17 +377,14 @@ skip:;
378 377
379/** DSP interface **/ 378/** DSP interface **/
380 379
381static void tdspeed_process_new_format(struct dsp_proc_entry *this,
382 struct dsp_buffer **buf_p);
383
384/* Enable or disable the availability of timestretch */ 380/* Enable or disable the availability of timestretch */
385void dsp_timestretch_enable(bool enabled) 381void dsp_timestretch_enable(bool enabled)
386{ 382{
387 if (enabled != !tdspeed_state.this) 383 if (enabled != !tdspeed_state.this)
388 return; /* No change */ 384 return; /* No change */
389 385
390 dsp_proc_enable(dsp_get_config(CODEC_IDX_AUDIO), DSP_PROC_TIMESTRETCH, 386 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
391 enabled); 387 dsp_proc_enable(dsp, DSP_PROC_TIMESTRETCH, enabled);
392} 388}
393 389
394/* Set the timestretch ratio */ 390/* Set the timestretch ratio */
@@ -405,7 +401,8 @@ void dsp_set_timestretch(int32_t percent)
405 if (percent == st->factor) 401 if (percent == st->factor)
406 return; /* no change */ 402 return; /* no change */
407 403
408 dsp_configure(st->dsp, TIMESTRETCH_SET_FACTOR, percent); 404 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
405 dsp_configure(dsp, TIMESTRETCH_SET_FACTOR, percent);
409} 406}
410 407
411/* Return the timestretch ratio */ 408/* Return the timestretch ratio */
@@ -459,27 +456,22 @@ static void tdspeed_process(struct dsp_proc_entry *this,
459} 456}
460 457
461/* Process format changes and settings changes */ 458/* Process format changes and settings changes */
462static void tdspeed_process_new_format(struct dsp_proc_entry *this, 459static intptr_t tdspeed_new_format(struct dsp_proc_entry *this,
463 struct dsp_buffer **buf_p) 460 struct dsp_config *dsp,
461 struct sample_format *format)
464{ 462{
465 struct dsp_buffer *src = *buf_p;
466 struct dsp_buffer *dst = &dsp_outbuf; 463 struct dsp_buffer *dst = &dsp_outbuf;
467 464
468 if (dst->remcount > 0) 465 if (dst->remcount > 0)
469 { 466 return PROC_NEW_FORMAT_TRANSITION;
470 *buf_p = dst;
471 return; /* output remains from an earlier call */
472 }
473 467
474 DSP_PRINT_FORMAT(DSP_PROC_TIMESTRETCH, DSP_PROC_TIMESTRETCH, src->format); 468 DSP_PRINT_FORMAT(DSP_PROC_TIMESTRETCH, *format);
475 469
470 bool active = dsp_proc_active(dsp, DSP_PROC_TIMESTRETCH);
476 struct tdspeed_state_s *st = &tdspeed_state; 471 struct tdspeed_state_s *st = &tdspeed_state;
477 struct dsp_config *dsp = st->dsp;
478 struct sample_format *format = &src->format;
479 int channels = format->num_channels; 472 int channels = format->num_channels;
480 473
481 if (format->codec_frequency != st->samplerate || 474 if (format->codec_frequency != st->samplerate)
482 !dsp_proc_active(dsp, DSP_PROC_TIMESTRETCH))
483 { 475 {
484 /* relevent parameters are changing - all overlap will be discarded */ 476 /* relevent parameters are changing - all overlap will be discarded */
485 st->channels = channels; 477 st->channels = channels;
@@ -489,17 +481,10 @@ static void tdspeed_process_new_format(struct dsp_proc_entry *this,
489 channels, 481 channels,
490 format->codec_frequency, 482 format->codec_frequency,
491 st->factor / 100, st->factor % 100); 483 st->factor / 100, st->factor % 100);
492 bool active = tdspeed_update(format->codec_frequency, st->factor); 484 active = tdspeed_update(format->codec_frequency, st->factor);
493 dsp_proc_activate(dsp, DSP_PROC_TIMESTRETCH, active); 485 dsp_proc_activate(dsp, DSP_PROC_TIMESTRETCH, active);
494
495 if (!active)
496 {
497 DEBUGF(" DSP_PROC_RESAMPLE- not active\n");
498 dst->format = src->format; /* Keep track */
499 return; /* no more for now */
500 }
501 } 486 }
502 else if (channels != st->channels) 487 else if (active && channels != st->channels)
503 { 488 {
504 /* channel count transistion - have to make old data in overlap 489 /* channel count transistion - have to make old data in overlap
505 buffer compatible with new format */ 490 buffer compatible with new format */
@@ -525,20 +510,25 @@ static void tdspeed_process_new_format(struct dsp_proc_entry *this,
525 } 510 }
526 } 511 }
527 512
528 struct sample_format f = *format; 513 dst->format = *format;
529 format_change_ack(format);
530 514
531 if (EQU_SAMPLE_FORMAT(f, dst->format)) 515 if (active)
532 { 516 return PROC_NEW_FORMAT_OK;
533 DEBUGF(" DSP_PROC_TIMESTRETCH- same dst format\n");
534 format_change_ack(&f); /* nothing changed that matters downstream */
535 }
536 517
537 dst->format = f; 518 /* Nothing to do */
519 DEBUGF(" DSP_PROC_RESAMPLE- deactivated\n");
520 return PROC_NEW_FORMAT_DEACTIVATED;
538 521
539 /* return to normal processing */ 522 (void)this;
540 this->process[0] = tdspeed_process; 523}
541 dsp_proc_call(this, buf_p, 0); 524
525static void INIT_ATTR tdspeed_dsp_init(struct tdspeed_state_s *st,
526 enum dsp_ids dsp_id)
527{
528 /* everything is at 100% until dsp_set_timestretch is called with
529 some other value and timestretch is enabled at the time */
530 if (dsp_id == CODEC_IDX_AUDIO)
531 st->factor = PITCH_SPEED_100;
542} 532}
543 533
544/* DSP message hook */ 534/* DSP message hook */
@@ -547,15 +537,14 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this,
547 unsigned int setting, 537 unsigned int setting,
548 intptr_t value) 538 intptr_t value)
549{ 539{
540 intptr_t retval = 0;
541
550 struct tdspeed_state_s *st = &tdspeed_state; 542 struct tdspeed_state_s *st = &tdspeed_state;
551 543
552 switch (setting) 544 switch (setting)
553 { 545 {
554 case DSP_INIT: 546 case DSP_INIT:
555 /* everything is at 100% until dsp_set_timestretch is called with 547 tdspeed_dsp_init(st, (enum dsp_ids)value);
556 some other value and timestretch is enabled at the time */
557 if (value == CODEC_IDX_AUDIO)
558 st->factor = PITCH_SPEED_100;
559 break; 548 break;
560 549
561 case DSP_FLUSH: 550 case DSP_FLUSH:
@@ -567,10 +556,8 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this,
567 return -1; /* fail the init */ 556 return -1; /* fail the init */
568 557
569 st->this = this; 558 st->this = this;
570 st->dsp = dsp; 559 dsp_proc_set_in_place(dsp, DSP_PROC_TIMESTRETCH, false);
571 this->ip_mask = 0; /* not in-place */ 560 this->process = tdspeed_process;
572 this->process[0] = tdspeed_process;
573 this->process[1] = tdspeed_process_new_format;
574 break; 561 break;
575 562
576 case DSP_PROC_CLOSE: 563 case DSP_PROC_CLOSE:
@@ -580,17 +567,18 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this,
580 tdspeed_free_buffers(buffers, NBUFFERS); 567 tdspeed_free_buffers(buffers, NBUFFERS);
581 break; 568 break;
582 569
570 case DSP_PROC_NEW_FORMAT:
571 retval = tdspeed_new_format(this, dsp, (struct sample_format *)value);
572 break;
573
583 case TIMESTRETCH_SET_FACTOR: 574 case TIMESTRETCH_SET_FACTOR:
584 /* force update as a format change */
585 st->samplerate = 0; 575 st->samplerate = 0;
586 st->factor = (int32_t)value; 576 st->factor = (int32_t)value;
587 st->this->process[0] = tdspeed_process_new_format; 577 dsp_proc_want_format_update(dsp, DSP_PROC_TIMESTRETCH);
588 dsp_proc_activate(st->dsp, DSP_PROC_TIMESTRETCH, true);
589 break; 578 break;
590 } 579 }
591 580
592 return 1; 581 return retval;
593 (void)value;
594} 582}
595 583
596void tdspeed_move(int i, void* current, void* new) 584void tdspeed_move(int i, void* current, void* new)