summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/pcmbuf.c123
1 files changed, 56 insertions, 67 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index e62fc892cc..9bf4c96233 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -690,63 +690,16 @@ static inline int32_t clip_sample_16(int32_t sample)
690} 690}
691 691
692#ifdef HAVE_CROSSFADE 692#ifdef HAVE_CROSSFADE
693/* Completely process the crossfade fade-out effect with current PCM buffer */ 693/* Find the chunk that's (length) deep in the list. Return the position within
694static void crossfade_process_buffer(size_t fade_in_delay, 694 * the chunk, and leave the chunkdesc pointer pointing to the chunk. */
695 size_t fade_out_delay, size_t fade_out_rem) 695static size_t find_chunk(size_t length, struct chunkdesc **chunk)
696{ 696{
697 if (!crossfade_mixmode) 697 while (*chunk && length >= (*chunk)->size)
698 { 698 {
699 /* Fade out the specified amount of the already processed audio */ 699 length -= (*chunk)->size;
700 size_t total_fade_out = fade_out_rem; 700 *chunk = (*chunk)->link;
701 size_t fade_out_sample;
702 struct chunkdesc *fade_out_chunk = crossfade_chunk;
703
704 /* Find the right chunk to start fading out */
705 fade_out_delay += crossfade_sample * 2;
706 while (fade_out_delay != 0 && fade_out_delay >= fade_out_chunk->size)
707 {
708 fade_out_delay -= fade_out_chunk->size;
709 fade_out_chunk = fade_out_chunk->link;
710 }
711 /* The start sample within the chunk */
712 fade_out_sample = fade_out_delay / 2;
713
714 while (fade_out_rem > 0)
715 {
716 /* Each 1/10 second of audio will have the same fade applied */
717 size_t block_rem = MIN(NATIVE_FREQUENCY * 4 / 10, fade_out_rem);
718 int factor = (fade_out_rem << 8) / total_fade_out;
719
720 fade_out_rem -= block_rem;
721
722 /* Fade this block */
723 while (block_rem > 0 && fade_out_chunk != NULL)
724 {
725 /* Fade one sample */
726 int16_t *buf = (int16_t *)fade_out_chunk->addr;
727 int32_t sample = buf[fade_out_sample];
728 buf[fade_out_sample++] = (sample * factor) >> 8;
729
730 block_rem -= 2;
731 /* Move to the next chunk as needed */
732 if (fade_out_sample * 2 >= fade_out_chunk->size)
733 {
734 fade_out_chunk = fade_out_chunk->link;
735 fade_out_sample = 0;
736 }
737 }
738 }
739 }
740
741 /* Find the right chunk and sample to start fading in */
742 fade_in_delay += crossfade_sample * 2;
743 while (fade_in_delay != 0 && fade_in_delay >= crossfade_chunk->size)
744 {
745 fade_in_delay -= crossfade_chunk->size;
746 crossfade_chunk = crossfade_chunk->link;
747 } 701 }
748 crossfade_sample = fade_in_delay / 2; 702 return length / 2;
749 logf("process done!");
750} 703}
751 704
752/* Initializes crossfader, calculates all necessary parameters and performs 705/* Initializes crossfader, calculates all necessary parameters and performs
@@ -777,25 +730,19 @@ static void crossfade_start(void)
777 crossfade_chunk = read_chunk->link; 730 crossfade_chunk = read_chunk->link;
778 crossfade_sample = 0; 731 crossfade_sample = 0;
779 732
780 /* Get fade out delay from settings. */ 733 /* Get fade out info from settings. */
781 fade_out_delay = 734 fade_out_delay =
782 NATIVE_FREQUENCY * global_settings.crossfade_fade_out_delay * 4; 735 NATIVE_FREQUENCY * global_settings.crossfade_fade_out_delay * 4;
783
784 /* Get fade out duration from settings. */
785 fade_out_rem = 736 fade_out_rem =
786 NATIVE_FREQUENCY * global_settings.crossfade_fade_out_duration * 4; 737 NATIVE_FREQUENCY * global_settings.crossfade_fade_out_duration * 4;
787 738
788 crossfade_need = fade_out_delay + fade_out_rem; 739 crossfade_need = fade_out_delay + fade_out_rem;
789 /* We want only to modify the last part of the buffer. */ 740 /* We want only to modify the last part of the buffer, so find
741 * the right chunk and sample to start the crossfade */
790 if (crossfade_rem > crossfade_need) 742 if (crossfade_rem > crossfade_need)
791 { 743 {
792 size_t crossfade_extra = crossfade_rem - crossfade_need; 744 crossfade_sample = find_chunk(crossfade_rem - crossfade_need,
793 while (crossfade_extra > crossfade_chunk->size) 745 &crossfade_chunk);
794 {
795 crossfade_extra -= crossfade_chunk->size;
796 crossfade_chunk = crossfade_chunk->link;
797 }
798 crossfade_sample = crossfade_extra / 2;
799 } 746 }
800 /* Truncate fade out duration if necessary. */ 747 /* Truncate fade out duration if necessary. */
801 else if (crossfade_rem < crossfade_need) 748 else if (crossfade_rem < crossfade_need)
@@ -810,7 +757,46 @@ static void crossfade_start(void)
810 } 757 }
811 } 758 }
812 759
813 /* Get also fade in duration and delays from settings. */ 760 /* Completely process the crossfade fade-out effect with current PCM buffer */
761 if (!crossfade_mixmode)
762 {
763 /* Fade out the specified amount of the already processed audio */
764 size_t total_fade_out = fade_out_rem;
765 size_t fade_out_sample;
766 struct chunkdesc *fade_out_chunk = crossfade_chunk;
767
768 /* Find the right chunk and sample to start fading out */
769 fade_out_delay += crossfade_sample * 2;
770 fade_out_sample = find_chunk(fade_out_delay, &fade_out_chunk);
771
772 while (fade_out_rem > 0)
773 {
774 /* Each 1/10 second of audio will have the same fade applied */
775 size_t block_rem = MIN(NATIVE_FREQUENCY * 4 / 10, fade_out_rem);
776 int factor = (fade_out_rem << 8) / total_fade_out;
777
778 fade_out_rem -= block_rem;
779
780 /* Fade this block */
781 while (block_rem > 0 && fade_out_chunk != NULL)
782 {
783 /* Fade one sample */
784 int16_t *buf = (int16_t *)fade_out_chunk->addr;
785 int32_t sample = buf[fade_out_sample];
786 buf[fade_out_sample++] = (sample * factor) >> 8;
787
788 block_rem -= 2;
789 /* Move to the next chunk as needed */
790 if (fade_out_sample * 2 >= fade_out_chunk->size)
791 {
792 fade_out_chunk = fade_out_chunk->link;
793 fade_out_sample = 0;
794 }
795 }
796 }
797 }
798
799 /* Initialize fade-in counters */
814 crossfade_fade_in_total = 800 crossfade_fade_in_total =
815 NATIVE_FREQUENCY * global_settings.crossfade_fade_in_duration * 4; 801 NATIVE_FREQUENCY * global_settings.crossfade_fade_in_duration * 4;
816 crossfade_fade_in_rem = crossfade_fade_in_total; 802 crossfade_fade_in_rem = crossfade_fade_in_total;
@@ -818,7 +804,10 @@ static void crossfade_start(void)
818 fade_in_delay = 804 fade_in_delay =
819 NATIVE_FREQUENCY * global_settings.crossfade_fade_in_delay * 4; 805 NATIVE_FREQUENCY * global_settings.crossfade_fade_in_delay * 4;
820 806
821 crossfade_process_buffer(fade_in_delay, fade_out_delay, fade_out_rem); 807 /* Find the right chunk and sample to start fading in */
808 fade_in_delay += crossfade_sample * 2;
809 crossfade_sample = find_chunk(fade_in_delay, &crossfade_chunk);
810 logf("crossfade_start done!");
822} 811}
823 812
824/* Returns the number of bytes _NOT_ mixed */ 813/* Returns the number of bytes _NOT_ mixed */