summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-10-10 19:12:05 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-10-10 19:12:05 +0000
commit02d756dfd4f0ca89fcf31a0c8b1ce86c739a5b2e (patch)
tree67b6cb7cdee8e1629b31e69fc689707bfe580cca
parent2740914ee1d9274d77dfb4be6624fb557272ab6f (diff)
downloadrockbox-02d756dfd4f0ca89fcf31a0c8b1ce86c739a5b2e.tar.gz
rockbox-02d756dfd4f0ca89fcf31a0c8b1ce86c739a5b2e.zip
Messing with the peak calculation in pcm_playback.c for Coldfire ports.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11178 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/pcm_playback.c113
1 files changed, 107 insertions, 6 deletions
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 16e8f5e3af..7382661f48 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -98,6 +98,8 @@ size_t pcm_get_bytes_waiting(void)
98 98
99static int pcm_freq = 0x6; /* 44.1 is default */ 99static int pcm_freq = 0x6; /* 44.1 is default */
100 100
101int peak_left = 0, peak_right = 0;
102
101/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ 103/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
102static void dma_start(const void *addr, size_t size) 104static void dma_start(const void *addr, size_t size)
103{ 105{
@@ -205,7 +207,6 @@ void DMA0(void)
205 SAR0 = (unsigned long)next_start; /* Source address */ 207 SAR0 = (unsigned long)next_start; /* Source address */
206 BCR0 = next_size; /* Bytes to transfer */ 208 BCR0 = next_size; /* Bytes to transfer */
207 DCR0 |= DMA_EEXT; 209 DCR0 |= DMA_EEXT;
208
209 } 210 }
210 else 211 else
211 { 212 {
@@ -846,6 +847,109 @@ bool pcm_is_paused(void) {
846 return pcm_paused; 847 return pcm_paused;
847} 848}
848 849
850
851#if defined(CPU_COLDFIRE)
852/* Peaks ahead in the DMA buffer based upon the calling period to
853 attempt to compensate for the delay. Keeps a moving average of
854 length four. */
855void pcm_calculate_peaks(int *left, int *right)
856{
857 unsigned long samples;
858 unsigned long *addr, *end;
859 long peak_p, peak_n;
860
861 static unsigned long last_peak_tick = 0;
862 static unsigned long frame_period = 0;
863
864 /* Throttled peak ahead based on calling period */
865 unsigned long period = current_tick - last_peak_tick;
866
867 /* Keep reasonable limits on period */
868 if (period < 1)
869 period = 1;
870 else if (period > HZ/5)
871 period = HZ/5;
872
873 frame_period = (3*frame_period + period) >> 2;
874
875 last_peak_tick = current_tick;
876
877 if (!pcm_playing || pcm_paused)
878 {
879 peak_left = peak_right = 0;
880 goto peak_done;
881 }
882
883 samples = (BCR0 & 0xffffff) >> 2;
884 addr = (long *)(SAR0 & ~3);
885 samples = MIN(frame_period*44100/HZ, samples);
886 end = addr + samples;
887 peak_p = peak_n = 0;
888
889 if (left && right)
890 {
891 if (samples > 0)
892 {
893 long peak_rp = 0, peak_rn = 0;
894
895 do
896 {
897 long value = *addr;
898 long ch;
899
900 ch = value >> 16;
901 if (ch > peak_p) peak_p = ch;
902 else if (ch < peak_n) peak_n = ch;
903
904 ch = (short)value;
905 if (ch > peak_rp) peak_rp = ch;
906 else if (ch < peak_rn) peak_rn = ch;
907
908 addr += 4;
909 }
910 while (addr < end);
911
912 peak_left = MAX(peak_p, -peak_n);
913 peak_right = MAX(peak_rp, -peak_rn);
914 }
915 }
916 else if (left || right)
917 {
918 if (samples > 0)
919 {
920 if (left)
921 {
922 /* Put left channel in low word */
923 addr = (long *)((short *)addr - 1);
924 end = (long *)((short *)end - 1);
925 }
926
927 do
928 {
929 long value = *(short *)addr;
930
931 if (value > peak_p) peak_p = value;
932 else if (value < peak_n) peak_n = value;
933
934 addr += 4;
935 }
936 while (addr < end);
937
938 if (left)
939 peak_left = MAX(peak_p, -peak_n);
940 else
941 peak_right = MAX(peak_p, -peak_n);
942 }
943 }
944
945peak_done:
946 if (left)
947 *left = peak_left;
948
949 if (right)
950 *right = peak_right;
951}
952#else
849/* 953/*
850 * This function goes directly into the DMA buffer to calculate the left and 954 * This function goes directly into the DMA buffer to calculate the left and
851 * right peak values. To avoid missing peaks it tries to look forward two full 955 * right peak values. To avoid missing peaks it tries to look forward two full
@@ -860,7 +964,6 @@ bool pcm_is_paused(void) {
860/* Up to 1/50th of a second of audio for peak calculation */ 964/* Up to 1/50th of a second of audio for peak calculation */
861/* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */ 965/* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
862#define PEAK_SAMPLES (44100/50) 966#define PEAK_SAMPLES (44100/50)
863
864void pcm_calculate_peaks(int *left, int *right) 967void pcm_calculate_peaks(int *left, int *right)
865{ 968{
866#if (CONFIG_CPU == S3C2440) 969#if (CONFIG_CPU == S3C2440)
@@ -870,10 +973,7 @@ void pcm_calculate_peaks(int *left, int *right)
870 short *addr; 973 short *addr;
871 short *end; 974 short *end;
872 { 975 {
873#ifdef CPU_COLDFIRE 976#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
874 size_t samples = (BCR0 & 0xffffff) / 4;
875 addr = (short *) (SAR0 & ~3);
876#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
877 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \ 977 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
878 || (CONFIG_CPU == PNX0101) 978 || (CONFIG_CPU == PNX0101)
879 size_t samples = p_size / 4; 979 size_t samples = p_size / 4;
@@ -931,3 +1031,4 @@ void pcm_calculate_peaks(int *left, int *right)
931 } 1031 }
932#endif 1032#endif
933} 1033}
1034#endif /* CPU_COLDFIRE */