summaryrefslogtreecommitdiff
path: root/apps/pcmbuf.c
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2009-11-10 03:46:08 +0000
committerJeffrey Goode <jeffg7@gmail.com>2009-11-10 03:46:08 +0000
commit9e0953432a3a73cd42e77c804a4557b5337e0d0f (patch)
tree49b5a4fadb1d64e9e03228cebd78e4011fde70b1 /apps/pcmbuf.c
parent78f8667d57e13ef579c892ccc5483b8baafd2fe6 (diff)
downloadrockbox-9e0953432a3a73cd42e77c804a4557b5337e0d0f.tar.gz
rockbox-9e0953432a3a73cd42e77c804a4557b5337e0d0f.zip
Crossfade: carved out crossfade related code with lots of HAVE_CORSSFADE conditionals, eliminated fade buffer on low memory targets
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23597 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r--apps/pcmbuf.c102
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;
79static size_t pcmbuffer_pos IDATA_ATTR; 79static size_t pcmbuffer_pos IDATA_ATTR;
80/* Amount pcmbuffer_pos will be increased.*/ 80/* Amount pcmbuffer_pos will be increased.*/
81static size_t pcmbuffer_fillpos IDATA_ATTR; 81static size_t pcmbuffer_fillpos IDATA_ATTR;
82static char *fadebuf IDATA_ATTR;
83static char *voicebuf IDATA_ATTR;
84 82
83/* Gapless playback */
85static bool end_of_track IDATA_ATTR; 84static bool end_of_track IDATA_ATTR;
86bool track_transition IDATA_ATTR; 85bool track_transition IDATA_ATTR;
87 86
87#ifdef HAVE_CROSSFADE
88/* Crossfade buffer */
89static char *fadebuf IDATA_ATTR;
90
88/* Crossfade related state */ 91/* Crossfade related state */
89static bool crossfade_enabled; 92static bool crossfade_enabled;
90static bool crossfade_enable_request; 93static 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 */
96static struct chunkdesc *crossfade_chunk IDATA_ATTR; 99static struct chunkdesc *crossfade_chunk IDATA_ATTR;
97#ifdef HAVE_CROSSFADE
98static size_t crossfade_sample IDATA_ATTR; 100static 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;
111static size_t pcmbuf_unplayed_bytes IDATA_ATTR; 113static size_t pcmbuf_unplayed_bytes IDATA_ATTR;
112static size_t pcmbuf_watermark IDATA_ATTR; 114static size_t pcmbuf_watermark IDATA_ATTR;
113 115
116/* Voice */
117static char *voicebuf IDATA_ATTR;
114static struct chunkdesc *mix_chunk IDATA_ATTR; 118static struct chunkdesc *mix_chunk IDATA_ATTR;
115static size_t pcmbuf_mix_sample IDATA_ATTR; 119static 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
134static void crossfade_start(void); 138static void crossfade_start(void);
135static void flush_crossfade(char *buf, size_t length); 139static void flush_crossfade(char *buf, size_t length);
136#endif
137static void pcmbuf_finish_crossfade_enable(void); 140static void pcmbuf_finish_crossfade_enable(void);
138static 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. */
464static void start_gapless_track_change(void) 479static 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
473static void start_crossfade_track_change(bool auto_skip) 489#ifdef HAVE_CROSSFADE
490static 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
499static 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
503void pcmbuf_start_track_change(bool auto_skip) 540void 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
911static void pcmbuf_finish_crossfade_enable(void) 950static 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
923static 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
931bool pcmbuf_is_crossfade_active(void) 962bool 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
1101bool pcmbuf_is_lowdata(void) 1133bool 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