diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-02-07 00:51:50 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-02-07 00:51:50 +0000 |
commit | aba6ca0881d1481b4047b2d7834d70ca2eb5c64b (patch) | |
tree | 6635b98840dcf4936b3c1ca641c00c32ea1b3e7f /apps/pcmbuf.c | |
parent | dd50c863e60488662dee8f28f7292389ade42bac (diff) | |
download | rockbox-aba6ca0881d1481b4047b2d7834d70ca2eb5c64b.tar.gz rockbox-aba6ca0881d1481b4047b2d7834d70ca2eb5c64b.zip |
Fix resampling clicking as much as possible at the moment. 1) Upsampling clicked because of size inaccuracies returned by DSP. Fix by simplifying audio system to use per-channel sample count from codec to pcm buffer. 2) Downsampling affected by 1) and was often starting passed the end of the data when not enough was available to generate an output sample. Fix by clamping input range to last sample in buffer and using the last sample value in the buffer. A perfect fix will require a double buffering scheme on the resampler to sufficient data during small data transients on both ends at all times of the down ratio on input and the up ratio on output.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12218 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index f9d60e9b58..e2b1d7f87b 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -791,21 +791,20 @@ static bool prepare_insert(size_t length) | |||
791 | return true; | 791 | return true; |
792 | } | 792 | } |
793 | 793 | ||
794 | void* pcmbuf_request_buffer(size_t length, size_t *realsize) | 794 | void* pcmbuf_request_buffer(int *count) |
795 | { | 795 | { |
796 | if (crossfade_init) | 796 | if (crossfade_init) |
797 | crossfade_start(); | 797 | crossfade_start(); |
798 | 798 | ||
799 | if (crossfade_active) { | 799 | if (crossfade_active) { |
800 | *realsize = MIN(length, PCMBUF_MIX_CHUNK); | 800 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); |
801 | return fadebuf; | 801 | return fadebuf; |
802 | } | 802 | } |
803 | else | 803 | else |
804 | { | 804 | { |
805 | if(prepare_insert(length)) | 805 | if(prepare_insert(*count << 2)) |
806 | { | 806 | { |
807 | size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; | 807 | size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; |
808 | *realsize = length; | ||
809 | if (pcmbuf_size - audiobuffer_index >= PCMBUF_MIN_CHUNK) | 808 | if (pcmbuf_size - audiobuffer_index >= PCMBUF_MIN_CHUNK) |
810 | { | 809 | { |
811 | /* Usual case, there's space here */ | 810 | /* Usual case, there's space here */ |
@@ -821,34 +820,31 @@ void* pcmbuf_request_buffer(size_t length, size_t *realsize) | |||
821 | } | 820 | } |
822 | else | 821 | else |
823 | { | 822 | { |
824 | *realsize = 0; | ||
825 | return NULL; | 823 | return NULL; |
826 | } | 824 | } |
827 | } | 825 | } |
828 | } | 826 | } |
829 | 827 | ||
830 | void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix) | 828 | void* pcmbuf_request_voice_buffer(int *count, bool mix) |
831 | { | 829 | { |
832 | if (mix) | 830 | if (mix) |
833 | { | 831 | { |
834 | if (pcmbuf_read == NULL) | 832 | if (pcmbuf_read == NULL) |
835 | { | 833 | { |
836 | *realsize = 0; | ||
837 | return NULL; | 834 | return NULL; |
838 | } | 835 | } |
839 | else if (pcmbuf_mix_chunk || pcmbuf_read->link) | 836 | else if (pcmbuf_mix_chunk || pcmbuf_read->link) |
840 | { | 837 | { |
841 | *realsize = MIN(length, PCMBUF_MIX_CHUNK); | 838 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); |
842 | return voicebuf; | 839 | return voicebuf; |
843 | } | 840 | } |
844 | else | 841 | else |
845 | { | 842 | { |
846 | *realsize = 0; | ||
847 | return NULL; | 843 | return NULL; |
848 | } | 844 | } |
849 | } | 845 | } |
850 | else | 846 | else |
851 | return pcmbuf_request_buffer(length, realsize); | 847 | return pcmbuf_request_buffer(count); |
852 | } | 848 | } |
853 | 849 | ||
854 | bool pcmbuf_is_crossfade_active(void) | 850 | bool pcmbuf_is_crossfade_active(void) |
@@ -856,8 +852,10 @@ bool pcmbuf_is_crossfade_active(void) | |||
856 | return crossfade_active || crossfade_init; | 852 | return crossfade_active || crossfade_init; |
857 | } | 853 | } |
858 | 854 | ||
859 | void pcmbuf_write_complete(size_t length) | 855 | void pcmbuf_write_complete(int count) |
860 | { | 856 | { |
857 | size_t length = (size_t)(unsigned int)count << 2; | ||
858 | |||
861 | if (crossfade_active) | 859 | if (crossfade_active) |
862 | { | 860 | { |
863 | flush_crossfade(fadebuf, length); | 861 | flush_crossfade(fadebuf, length); |
@@ -874,8 +872,10 @@ void pcmbuf_write_complete(size_t length) | |||
874 | } | 872 | } |
875 | 873 | ||
876 | #if 0 | 874 | #if 0 |
877 | bool pcmbuf_insert_buffer(char *buf, size_t length) | 875 | bool pcmbuf_insert_buffer(char *buf, int count) |
878 | { | 876 | { |
877 | size_t length = (size_t)(unsigned int)count << 2; | ||
878 | |||
879 | if (crossfade_active) | 879 | if (crossfade_active) |
880 | { | 880 | { |
881 | flush_crossfade(buf, length); | 881 | flush_crossfade(buf, length); |
@@ -980,7 +980,7 @@ int pcmbuf_mix_free(void) | |||
980 | return 100; | 980 | return 100; |
981 | } | 981 | } |
982 | 982 | ||
983 | void pcmbuf_mix_voice(size_t length) | 983 | void pcmbuf_mix_voice(int count) |
984 | { | 984 | { |
985 | short *ibuf = (short *)voicebuf; | 985 | short *ibuf = (short *)voicebuf; |
986 | short *obuf; | 986 | short *obuf; |
@@ -998,9 +998,9 @@ void pcmbuf_mix_voice(size_t length) | |||
998 | obuf = (short *)pcmbuf_mix_chunk->addr; | 998 | obuf = (short *)pcmbuf_mix_chunk->addr; |
999 | chunk_samples = pcmbuf_mix_chunk->size / 2; | 999 | chunk_samples = pcmbuf_mix_chunk->size / 2; |
1000 | 1000 | ||
1001 | length /= 2; | 1001 | count <<= 1; |
1002 | 1002 | ||
1003 | while (length-- > 0) { | 1003 | while (count-- > 0) { |
1004 | int sample = *ibuf++; | 1004 | int sample = *ibuf++; |
1005 | if (pcmbuf_mix_sample >= chunk_samples) | 1005 | if (pcmbuf_mix_sample >= chunk_samples) |
1006 | { | 1006 | { |