diff options
Diffstat (limited to 'lib/rbcodec/dsp/tdspeed.c')
-rw-r--r-- | lib/rbcodec/dsp/tdspeed.c | 100 |
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 | |||
53 | static struct tdspeed_state_s | 53 | 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 */ | ||
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 | ||
381 | static 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 */ |
385 | void dsp_timestretch_enable(bool enabled) | 381 | void 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 */ |
462 | static void tdspeed_process_new_format(struct dsp_proc_entry *this, | 459 | static 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 | |
525 | static 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 | ||
596 | void tdspeed_move(int i, void* current, void* new) | 584 | void tdspeed_move(int i, void* current, void* new) |