diff options
author | Jeffrey Goode <jeffg7@gmail.com> | 2009-11-15 04:57:40 +0000 |
---|---|---|
committer | Jeffrey Goode <jeffg7@gmail.com> | 2009-11-15 04:57:40 +0000 |
commit | 873c5b6d18dd691e5c096d3a52f8b4de7c2aabdf (patch) | |
tree | 5dc3c1bf897cb11de3839313f45ebe244766cf13 | |
parent | a19000b594b5d8b51453f0393b21244e47212161 (diff) | |
download | rockbox-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.c | 103 |
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 */ |
709 | static void fade_block(int factor, size_t length, size_t *fade_sample, | 709 | static 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 */ | ||
837 | static 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 */ |
872 | static void write_to_crossfade(char *buf, size_t length) | 865 | static 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; |