summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2009-11-15 04:57:40 +0000
committerJeffrey Goode <jeffg7@gmail.com>2009-11-15 04:57:40 +0000
commit873c5b6d18dd691e5c096d3a52f8b4de7c2aabdf (patch)
tree5dc3c1bf897cb11de3839313f45ebe244766cf13
parenta19000b594b5d8b51453f0393b21244e47212161 (diff)
downloadrockbox-873c5b6d18dd691e5c096d3a52f8b4de7c2aabdf.tar.gz
rockbox-873c5b6d18dd691e5c096d3a52f8b4de7c2aabdf.zip
pcmbuf: consolidate some similar code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23628 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/pcmbuf.c103
1 files changed, 49 insertions, 54 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 20eafb5865..f573a29e7c 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -705,25 +705,51 @@ static size_t find_chunk(size_t length, struct chunkdesc **chunk)
705 return length / 2; 705 return length / 2;
706} 706}
707 707
708/* Fade samples in the PCM buffer */ 708/* Returns the number of bytes _NOT_ mixed/faded */
709static void fade_block(int factor, size_t length, size_t *fade_sample, 709static size_t crossfade_mix_fade(int factor, size_t length, const char *buf,
710 struct chunkdesc **fade_chunk) 710 size_t *out_sample, struct chunkdesc **out_chunk)
711{ 711{
712 while (length > 0 && *fade_chunk != NULL) 712 const int16_t *input_buf = (const int16_t *)buf;
713 int16_t *output_buf = (int16_t *)((*out_chunk)->addr);
714 int16_t *chunk_end = SKIPBYTES(output_buf, (*out_chunk)->size);
715 output_buf = &output_buf[*out_sample];
716 int32_t sample;
717
718 while (length)
713 { 719 {
714 /* Fade one sample */ 720 /* fade left and right channel at once to keep buffer alignment */
715 int16_t *buf = (int16_t *)((*fade_chunk)->addr); 721 int i;
716 int32_t sample = buf[*fade_sample]; 722 for (i = 0; i < 2; i++)
717 buf[(*fade_sample)++] = (sample * factor) >> 8; 723 {
718 length -= 2; 724 if (input_buf)
719 725 /* fade the input buffer and mix into the chunk */
720 /* Move to the next chunk as needed */ 726 {
721 if (*fade_sample * 2 >= (*fade_chunk)->size) 727 sample = *input_buf++;
728 sample = ((sample * factor) >> 8) + *output_buf;
729 *output_buf++ = clip_sample_16(sample);
730 }
731 else
732 /* fade the chunk only */
733 {
734 sample = *output_buf;
735 *output_buf++ = (sample * factor) >> 8;
736 }
737 }
738
739 length -= 4; /* 2 samples, each 16 bit -> 4 bytes */
740
741 /* move to next chunk as needed */
742 if (output_buf >= chunk_end)
722 { 743 {
723 *fade_chunk = (*fade_chunk)->link; 744 *out_chunk = (*out_chunk)->link;
724 *fade_sample = 0; 745 if (!(*out_chunk))
746 return length;
747 output_buf = (int16_t *)((*out_chunk)->addr);
748 chunk_end = SKIPBYTES(output_buf, (*out_chunk)->size);
725 } 749 }
726 } 750 }
751 *out_sample = output_buf - (int16_t *)((*out_chunk)->addr);
752 return 0;
727} 753}
728 754
729/* Initializes crossfader, calculates all necessary parameters and performs 755/* Initializes crossfader, calculates all necessary parameters and performs
@@ -812,11 +838,13 @@ static void crossfade_start(void)
812 838
813 fade_out_rem -= block_rem; 839 fade_out_rem -= block_rem;
814 840
815 fade_block(factor, block_rem, &fade_out_sample, &fade_out_chunk); 841 crossfade_mix_fade(factor, block_rem, NULL,
842 &fade_out_sample, &fade_out_chunk);
816 } 843 }
817 844
818 /* zero out the rest of the buffer */ 845 /* zero out the rest of the buffer */
819 fade_block(0, crossfade_rem, &fade_out_sample, &fade_out_chunk); 846 crossfade_mix_fade(0, crossfade_rem, NULL,
847 &fade_out_sample, &fade_out_chunk);
820 } 848 }
821 849
822 /* Initialize fade-in counters */ 850 /* Initialize fade-in counters */
@@ -833,41 +861,6 @@ static void crossfade_start(void)
833 logf("crossfade_start done!"); 861 logf("crossfade_start done!");
834} 862}
835 863
836/* Returns the number of bytes _NOT_ mixed */
837static size_t crossfade_mix(int factor, const char *buf, size_t length)
838{
839 const int16_t *input_buf = (const int16_t *)buf;
840 int16_t *output_buf = (int16_t *)(crossfade_chunk->addr);
841 int16_t *chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
842 output_buf = &output_buf[crossfade_sample];
843 int32_t sample;
844
845 while (length)
846 {
847 /* fade left and right channel at once to keep buffer alignment */
848 int i;
849 for (i = 0; i < 2; i++)
850 {
851 sample = *input_buf++;
852 sample = ((sample * factor) >> 8) + *output_buf;
853 *output_buf++ = clip_sample_16(sample);
854 }
855
856 length -= 4; /* 2 samples, each 16 bit -> 4 bytes */
857
858 if (output_buf >= chunk_end)
859 {
860 crossfade_chunk = crossfade_chunk->link;
861 if (!crossfade_chunk)
862 return length;
863 output_buf = (int16_t *)crossfade_chunk->addr;
864 chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
865 }
866 }
867 crossfade_sample = output_buf - (int16_t *)crossfade_chunk->addr;
868 return 0;
869}
870
871/* Perform fade-in of new track */ 864/* Perform fade-in of new track */
872static void write_to_crossfade(char *buf, size_t length) 865static void write_to_crossfade(char *buf, size_t length)
873{ 866{
@@ -892,7 +885,8 @@ static void write_to_crossfade(char *buf, size_t length)
892 { 885 {
893 /* Mix the data */ 886 /* Mix the data */
894 size_t fade_total = fade_rem; 887 size_t fade_total = fade_rem;
895 fade_rem = crossfade_mix(factor, buf, fade_rem); 888 fade_rem = crossfade_mix_fade(factor, fade_rem, buf,
889 &crossfade_sample, &crossfade_chunk);
896 length -= fade_total - fade_rem; 890 length -= fade_total - fade_rem;
897 buf += fade_total - fade_rem; 891 buf += fade_total - fade_rem;
898 if (!length) 892 if (!length)
@@ -913,8 +907,9 @@ static void write_to_crossfade(char *buf, size_t length)
913 { 907 {
914 /* Mix the data */ 908 /* Mix the data */
915 size_t mix_total = length; 909 size_t mix_total = length;
916 /* A factor of 256 means no fading */ 910 /* A factor of 256 means mix only, no fading */
917 length = crossfade_mix(256, buf, length); 911 length = crossfade_mix_fade(256, length, buf,
912 &crossfade_sample, &crossfade_chunk);
918 buf += mix_total - length; 913 buf += mix_total - length;
919 if (!length) 914 if (!length)
920 return; 915 return;