diff options
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 102 |
1 files changed, 69 insertions, 33 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 975d254424..6f3dd80ed2 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -79,12 +79,15 @@ static char *pcmbuffer IDATA_ATTR; | |||
79 | static size_t pcmbuffer_pos IDATA_ATTR; | 79 | static size_t pcmbuffer_pos IDATA_ATTR; |
80 | /* Amount pcmbuffer_pos will be increased.*/ | 80 | /* Amount pcmbuffer_pos will be increased.*/ |
81 | static size_t pcmbuffer_fillpos IDATA_ATTR; | 81 | static size_t pcmbuffer_fillpos IDATA_ATTR; |
82 | static char *fadebuf IDATA_ATTR; | ||
83 | static char *voicebuf IDATA_ATTR; | ||
84 | 82 | ||
83 | /* Gapless playback */ | ||
85 | static bool end_of_track IDATA_ATTR; | 84 | static bool end_of_track IDATA_ATTR; |
86 | bool track_transition IDATA_ATTR; | 85 | bool track_transition IDATA_ATTR; |
87 | 86 | ||
87 | #ifdef HAVE_CROSSFADE | ||
88 | /* Crossfade buffer */ | ||
89 | static char *fadebuf IDATA_ATTR; | ||
90 | |||
88 | /* Crossfade related state */ | 91 | /* Crossfade related state */ |
89 | static bool crossfade_enabled; | 92 | static bool crossfade_enabled; |
90 | static bool crossfade_enable_request; | 93 | static bool crossfade_enable_request; |
@@ -94,7 +97,6 @@ static bool crossfade_track_change_started IDATA_ATTR; | |||
94 | 97 | ||
95 | /* Track the current location for processing crossfade */ | 98 | /* Track the current location for processing crossfade */ |
96 | static struct chunkdesc *crossfade_chunk IDATA_ATTR; | 99 | static struct chunkdesc *crossfade_chunk IDATA_ATTR; |
97 | #ifdef HAVE_CROSSFADE | ||
98 | static size_t crossfade_sample IDATA_ATTR; | 100 | static size_t crossfade_sample IDATA_ATTR; |
99 | 101 | ||
100 | /* Counters for fading in new data */ | 102 | /* Counters for fading in new data */ |
@@ -111,6 +113,8 @@ static size_t last_chunksize IDATA_ATTR; | |||
111 | static size_t pcmbuf_unplayed_bytes IDATA_ATTR; | 113 | static size_t pcmbuf_unplayed_bytes IDATA_ATTR; |
112 | static size_t pcmbuf_watermark IDATA_ATTR; | 114 | static size_t pcmbuf_watermark IDATA_ATTR; |
113 | 115 | ||
116 | /* Voice */ | ||
117 | static char *voicebuf IDATA_ATTR; | ||
114 | static struct chunkdesc *mix_chunk IDATA_ATTR; | 118 | static struct chunkdesc *mix_chunk IDATA_ATTR; |
115 | static size_t pcmbuf_mix_sample IDATA_ATTR; | 119 | static size_t pcmbuf_mix_sample IDATA_ATTR; |
116 | 120 | ||
@@ -133,9 +137,8 @@ extern unsigned int codec_thread_id; | |||
133 | #ifdef HAVE_CROSSFADE | 137 | #ifdef HAVE_CROSSFADE |
134 | static void crossfade_start(void); | 138 | static void crossfade_start(void); |
135 | static void flush_crossfade(char *buf, size_t length); | 139 | static void flush_crossfade(char *buf, size_t length); |
136 | #endif | ||
137 | static void pcmbuf_finish_crossfade_enable(void); | 140 | static void pcmbuf_finish_crossfade_enable(void); |
138 | static bool pcmbuf_is_crossfade_enabled(void); | 141 | #endif |
139 | 142 | ||
140 | 143 | ||
141 | /**************************************/ | 144 | /**************************************/ |
@@ -315,11 +318,13 @@ static bool prepare_insert(size_t length) | |||
315 | } | 318 | } |
316 | } | 319 | } |
317 | 320 | ||
321 | #ifdef HAVE_CROSSFADE | ||
318 | /* Disable crossfade if < .5s of audio */ | 322 | /* Disable crossfade if < .5s of audio */ |
319 | if (LOW_DATA(2)) | 323 | if (LOW_DATA(2)) |
320 | { | 324 | { |
321 | crossfade_active = false; | 325 | crossfade_active = false; |
322 | } | 326 | } |
327 | #endif | ||
323 | } | 328 | } |
324 | else /* pcm_is_playing */ | 329 | else /* pcm_is_playing */ |
325 | { | 330 | { |
@@ -346,13 +351,13 @@ void *pcmbuf_request_buffer(int *count) | |||
346 | #ifdef HAVE_CROSSFADE | 351 | #ifdef HAVE_CROSSFADE |
347 | if (crossfade_track_change_started) | 352 | if (crossfade_track_change_started) |
348 | crossfade_start(); | 353 | crossfade_start(); |
349 | #endif | ||
350 | 354 | ||
351 | if (crossfade_active) { | 355 | if (crossfade_active) { |
352 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); | 356 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); |
353 | return fadebuf; | 357 | return fadebuf; |
354 | } | 358 | } |
355 | else | 359 | else |
360 | #endif | ||
356 | { | 361 | { |
357 | if(prepare_insert(*count << 2)) | 362 | if(prepare_insert(*count << 2)) |
358 | { | 363 | { |
@@ -417,9 +422,11 @@ static size_t get_next_required_pcmbuf_size(void) | |||
417 | { | 422 | { |
418 | size_t seconds = 1; | 423 | size_t seconds = 1; |
419 | 424 | ||
425 | #ifdef HAVE_CROSSFADE | ||
420 | if (crossfade_enable_request) | 426 | if (crossfade_enable_request) |
421 | seconds += global_settings.crossfade_fade_out_delay | 427 | seconds += global_settings.crossfade_fade_out_delay + |
422 | + global_settings.crossfade_fade_out_duration; | 428 | global_settings.crossfade_fade_out_duration; |
429 | #endif | ||
423 | 430 | ||
424 | #if MEMORYSIZE > 2 | 431 | #if MEMORYSIZE > 2 |
425 | /* Buffer has to be at least 2s long. */ | 432 | /* Buffer has to be at least 2s long. */ |
@@ -438,8 +445,12 @@ size_t pcmbuf_init(unsigned char *bufend) | |||
438 | write_chunk = (struct chunkdesc *)pcmbuf_bufend - | 445 | write_chunk = (struct chunkdesc *)pcmbuf_bufend - |
439 | NUM_CHUNK_DESCS(pcmbuf_size); | 446 | NUM_CHUNK_DESCS(pcmbuf_size); |
440 | voicebuf = (char *)write_chunk - PCMBUF_MIX_CHUNK; | 447 | voicebuf = (char *)write_chunk - PCMBUF_MIX_CHUNK; |
448 | #ifdef HAVE_CROSSFADE | ||
441 | fadebuf = voicebuf - PCMBUF_MIX_CHUNK; | 449 | fadebuf = voicebuf - PCMBUF_MIX_CHUNK; |
442 | pcmbuffer = fadebuf - pcmbuf_size; | 450 | pcmbuffer = fadebuf - pcmbuf_size; |
451 | #else | ||
452 | pcmbuffer = voicebuf - pcmbuf_size; | ||
453 | #endif | ||
443 | 454 | ||
444 | init_pcmbuffers(); | 455 | init_pcmbuffers(); |
445 | 456 | ||
@@ -447,7 +458,11 @@ size_t pcmbuf_init(unsigned char *bufend) | |||
447 | end_of_track = false; | 458 | end_of_track = false; |
448 | track_transition = false; | 459 | track_transition = false; |
449 | 460 | ||
461 | #ifdef HAVE_CROSSFADE | ||
450 | pcmbuf_finish_crossfade_enable(); | 462 | pcmbuf_finish_crossfade_enable(); |
463 | #else | ||
464 | pcmbuf_watermark = PCMBUF_WATERMARK; | ||
465 | #endif | ||
451 | 466 | ||
452 | pcmbuf_play_stop(); | 467 | pcmbuf_play_stop(); |
453 | 468 | ||
@@ -463,6 +478,7 @@ size_t pcmbuf_init(unsigned char *bufend) | |||
463 | * last one in the track. */ | 478 | * last one in the track. */ |
464 | static void start_gapless_track_change(void) | 479 | static void start_gapless_track_change(void) |
465 | { | 480 | { |
481 | logf(" gapless track change"); | ||
466 | /* we're starting a track transition */ | 482 | /* we're starting a track transition */ |
467 | track_transition = true; | 483 | track_transition = true; |
468 | 484 | ||
@@ -470,13 +486,28 @@ static void start_gapless_track_change(void) | |||
470 | end_of_track = true; | 486 | end_of_track = true; |
471 | } | 487 | } |
472 | 488 | ||
473 | static void start_crossfade_track_change(bool auto_skip) | 489 | #ifdef HAVE_CROSSFADE |
490 | static bool pcmbuf_is_crossfade_enabled(void) | ||
474 | { | 491 | { |
492 | if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE) | ||
493 | return global_settings.playlist_shuffle; | ||
494 | |||
495 | return crossfade_enabled; | ||
496 | } | ||
497 | #endif | ||
498 | |||
499 | static void start_processed_track_change(bool auto_skip) | ||
500 | { | ||
501 | logf(" processed track change"); | ||
475 | /* Notify the wps that the track change starts now */ | 502 | /* Notify the wps that the track change starts now */ |
476 | audio_post_track_change(false); | 503 | audio_post_track_change(false); |
477 | 504 | ||
478 | /* Can't do two crossfades at once and, no fade if pcm is off now */ | 505 | /* Can't do two crossfades at once and, no fade if pcm is off now */ |
479 | if (pcmbuf_is_crossfade_active() || !pcm_is_playing()) | 506 | if ( |
507 | #ifdef HAVE_CROSSFADE | ||
508 | pcmbuf_is_crossfade_active() || | ||
509 | #endif | ||
510 | !pcm_is_playing()) | ||
480 | { | 511 | { |
481 | pcmbuf_play_stop(); | 512 | pcmbuf_play_stop(); |
482 | return; | 513 | return; |
@@ -485,7 +516,11 @@ static void start_crossfade_track_change(bool auto_skip) | |||
485 | trigger_cpu_boost(); | 516 | trigger_cpu_boost(); |
486 | 517 | ||
487 | /* Not enough data, or crossfade disabled, flush the old data instead */ | 518 | /* Not enough data, or crossfade disabled, flush the old data instead */ |
488 | if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode) | 519 | if (LOW_DATA(2) || |
520 | #ifdef HAVE_CROSSFADE | ||
521 | !pcmbuf_is_crossfade_enabled() || | ||
522 | #endif | ||
523 | low_latency_mode) | ||
489 | { | 524 | { |
490 | /* commit everything to this point and keep going, but... */ | 525 | /* commit everything to this point and keep going, but... */ |
491 | commit_chunk(); | 526 | commit_chunk(); |
@@ -494,19 +529,22 @@ static void start_crossfade_track_change(bool auto_skip) | |||
494 | return; | 529 | return; |
495 | } | 530 | } |
496 | 531 | ||
532 | #ifdef HAVE_CROSSFADE | ||
497 | /* Don't enable mix mode when skipping tracks manually. */ | 533 | /* Don't enable mix mode when skipping tracks manually. */ |
498 | crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode; | 534 | crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode; |
499 | 535 | ||
500 | crossfade_track_change_started = true; | 536 | crossfade_track_change_started = true; |
537 | #endif | ||
501 | } | 538 | } |
502 | 539 | ||
503 | void pcmbuf_start_track_change(bool auto_skip) | 540 | void pcmbuf_start_track_change(bool auto_skip) |
504 | { | 541 | { |
505 | bool crossfade = false; | 542 | bool process = false; |
506 | /* Manual track change (always crossfade or flush audio). */ | 543 | /* Manual track change (always crossfade or flush audio). */ |
507 | if (!auto_skip) | 544 | if (!auto_skip) |
508 | crossfade = true; | 545 | process = true; |
509 | 546 | ||
547 | #ifdef HAVE_CROSSFADE | ||
510 | /* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */ | 548 | /* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */ |
511 | else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active() | 549 | else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active() |
512 | && global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP) | 550 | && global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP) |
@@ -514,17 +552,18 @@ void pcmbuf_start_track_change(bool auto_skip) | |||
514 | if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE_AND_TRACKSKIP) | 552 | if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE_AND_TRACKSKIP) |
515 | { | 553 | { |
516 | if (global_settings.playlist_shuffle) | 554 | if (global_settings.playlist_shuffle) |
517 | crossfade = true; | 555 | process = true; |
518 | } | 556 | } |
519 | else | 557 | else |
520 | crossfade = true; | 558 | process = true; |
521 | } | 559 | } |
560 | #endif | ||
522 | 561 | ||
523 | if (crossfade) | 562 | if (process) |
524 | /* crossfade to next track */ | 563 | /* process track change (manual skip or crossfade) */ |
525 | start_crossfade_track_change(auto_skip); | 564 | start_processed_track_change(auto_skip); |
526 | else | 565 | else |
527 | /* normal gapless playback. */ | 566 | /* normal gapless playback */ |
528 | start_gapless_track_change(); | 567 | start_gapless_track_change(); |
529 | } | 568 | } |
530 | 569 | ||
@@ -573,9 +612,12 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size) | |||
573 | /* If we've read over the mix chunk while it's still mixing there */ | 612 | /* If we've read over the mix chunk while it's still mixing there */ |
574 | if (pcmbuf_current == mix_chunk) | 613 | if (pcmbuf_current == mix_chunk) |
575 | mix_chunk = NULL; | 614 | mix_chunk = NULL; |
615 | |||
616 | #ifdef HAVE_CROSSFADE | ||
576 | /* If we've read over the crossfade chunk while it's still fading */ | 617 | /* If we've read over the crossfade chunk while it's still fading */ |
577 | if (pcmbuf_current == crossfade_chunk) | 618 | if (pcmbuf_current == crossfade_chunk) |
578 | crossfade_chunk = read_chunk; | 619 | crossfade_chunk = read_chunk; |
620 | #endif | ||
579 | } | 621 | } |
580 | 622 | ||
581 | { | 623 | { |
@@ -636,8 +678,10 @@ void pcmbuf_play_stop(void) | |||
636 | } | 678 | } |
637 | pcmbuffer_pos = 0; | 679 | pcmbuffer_pos = 0; |
638 | pcmbuffer_fillpos = 0; | 680 | pcmbuffer_fillpos = 0; |
681 | #ifdef HAVE_CROSSFADE | ||
639 | crossfade_track_change_started = false; | 682 | crossfade_track_change_started = false; |
640 | crossfade_active = false; | 683 | crossfade_active = false; |
684 | #endif | ||
641 | flush_pcmbuf = false; | 685 | flush_pcmbuf = false; |
642 | DISPLAY_DESC("play_stop"); | 686 | DISPLAY_DESC("play_stop"); |
643 | 687 | ||
@@ -664,10 +708,6 @@ static inline int32_t clip_sample_16(int32_t sample) | |||
664 | return sample; | 708 | return sample; |
665 | } | 709 | } |
666 | 710 | ||
667 | /** | ||
668 | * Low memory targets don't have crossfade, so don't compile crossfade | ||
669 | * specific code in order to save some memory. */ | ||
670 | |||
671 | #ifdef HAVE_CROSSFADE | 711 | #ifdef HAVE_CROSSFADE |
672 | /** | 712 | /** |
673 | * Completely process the crossfade fade out effect with current pcm buffer. | 713 | * Completely process the crossfade fade out effect with current pcm buffer. |
@@ -906,7 +946,6 @@ static void flush_crossfade(char *buf, size_t length) | |||
906 | } | 946 | } |
907 | } | 947 | } |
908 | } | 948 | } |
909 | #endif /* HAVE_CROSSFADE */ | ||
910 | 949 | ||
911 | static void pcmbuf_finish_crossfade_enable(void) | 950 | static void pcmbuf_finish_crossfade_enable(void) |
912 | { | 951 | { |
@@ -920,14 +959,6 @@ static void pcmbuf_finish_crossfade_enable(void) | |||
920 | PCMBUF_WATERMARK; | 959 | PCMBUF_WATERMARK; |
921 | } | 960 | } |
922 | 961 | ||
923 | static bool pcmbuf_is_crossfade_enabled(void) | ||
924 | { | ||
925 | if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE) | ||
926 | return global_settings.playlist_shuffle; | ||
927 | |||
928 | return crossfade_enabled; | ||
929 | } | ||
930 | |||
931 | bool pcmbuf_is_crossfade_active(void) | 962 | bool pcmbuf_is_crossfade_active(void) |
932 | { | 963 | { |
933 | return crossfade_active || crossfade_track_change_started; | 964 | return crossfade_active || crossfade_track_change_started; |
@@ -951,6 +982,7 @@ bool pcmbuf_is_same_size(void) | |||
951 | 982 | ||
952 | return same_size; | 983 | return same_size; |
953 | } | 984 | } |
985 | #endif /* HAVE_CROSSFADE */ | ||
954 | 986 | ||
955 | 987 | ||
956 | /* Voice */ | 988 | /* Voice */ |
@@ -1100,7 +1132,11 @@ unsigned char * pcmbuf_get_meminfo(size_t *length) | |||
1100 | 1132 | ||
1101 | bool pcmbuf_is_lowdata(void) | 1133 | bool pcmbuf_is_lowdata(void) |
1102 | { | 1134 | { |
1103 | if (!pcm_is_playing() || pcm_is_paused() || pcmbuf_is_crossfade_active()) | 1135 | if (!pcm_is_playing() || pcm_is_paused() |
1136 | #ifdef HAVE_CROSSFADE | ||
1137 | || pcmbuf_is_crossfade_active() | ||
1138 | #endif | ||
1139 | ) | ||
1104 | return false; | 1140 | return false; |
1105 | 1141 | ||
1106 | #if MEMORYSIZE > 2 | 1142 | #if MEMORYSIZE > 2 |