summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/tdspeed.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-12-19 17:34:57 -0500
committerMichael Sevakis <jethead71@rockbox.org>2013-05-04 13:43:33 -0400
commit78a45b47dede5ddf35dfc53e965b486a79177b18 (patch)
treeedb3ad7c101e600a7cc3be4b40380430cbeb3e55 /lib/rbcodec/dsp/tdspeed.c
parentcdb71c707bb434f44368b72f2db3becc37b7a46c (diff)
downloadrockbox-78a45b47dede5ddf35dfc53e965b486a79177b18.tar.gz
rockbox-78a45b47dede5ddf35dfc53e965b486a79177b18.zip
Cleanup and simplify latest DSP code incarnation.
Some things can just be a bit simpler in handling the list of stages and some things, especially format change handling, can be simplified for each stage implementation. Format changes are sent through the configure() callback. Hide some internal details and variables from processing stages and let the core deal with it. Do some miscellaneous cleanup and keep things a bit better factored. Change-Id: I19dd8ce1d0b792ba914d426013088a49a52ecb7e
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)