diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-17 19:29:02 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-17 19:29:02 +0000 |
commit | e9919342c558bc6b1f843bbc6e900c5ef540ee8f (patch) | |
tree | d092164b82b50ca660652cf7207d61b7b703b494 /firmware | |
parent | 170bb8eb78703bd6f2ae951e2292c89ae7565a29 (diff) | |
download | rockbox-e9919342c558bc6b1f843bbc6e900c5ef540ee8f.tar.gz rockbox-e9919342c558bc6b1f843bbc6e900c5ef540ee8f.zip |
Initial attempt to support peak meter on iriver. It still has some
strange behaviour and readings might not be correct.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7182 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 83 |
2 files changed, 85 insertions, 0 deletions
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index 3f0b5eee86..6222574ed8 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h | |||
@@ -25,6 +25,8 @@ void pcm_set_frequency(unsigned int frequency); | |||
25 | /* This is for playing "raw" PCM data */ | 25 | /* This is for playing "raw" PCM data */ |
26 | void pcm_play_data(void (*get_more)(unsigned char** start, long* size)); | 26 | void pcm_play_data(void (*get_more)(unsigned char** start, long* size)); |
27 | 27 | ||
28 | void pcm_calculate_peaks(int *left, int *right); | ||
29 | |||
28 | void pcm_play_stop(void); | 30 | void pcm_play_stop(void); |
29 | void pcm_play_pause(bool play); | 31 | void pcm_play_pause(bool play); |
30 | bool pcm_is_paused(void); | 32 | bool pcm_is_paused(void); |
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index 7682ce03c8..fc7239bf86 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -89,6 +89,89 @@ static void dma_stop(void) | |||
89 | pcm_paused = false; | 89 | pcm_paused = false; |
90 | } | 90 | } |
91 | 91 | ||
92 | #define PEEK_SAMPLE_COUNT 64 | ||
93 | static long calculate_channel_peak_average(int channel, unsigned short *addr, | ||
94 | long size) | ||
95 | { | ||
96 | int i; | ||
97 | long min, max; | ||
98 | int count, min_count, max_count; | ||
99 | unsigned long average, zero_point; | ||
100 | |||
101 | addr = &addr[channel]; | ||
102 | average = 0; | ||
103 | |||
104 | if (pcm_playing && !pcm_paused && addr != NULL) | ||
105 | { | ||
106 | /* Calculate the zero point and remove DC offset (should be around 32768) */ | ||
107 | zero_point = 0; | ||
108 | for (i = 0; i < size; i++) | ||
109 | zero_point += addr[i*2]; | ||
110 | zero_point /= i; | ||
111 | |||
112 | /*for (i = 0; i < size; i++) { | ||
113 | long peak = addr[i*2] - 32768; | ||
114 | if (peak < 0) | ||
115 | peak = 0; | ||
116 | average += peak; | ||
117 | } | ||
118 | average /= i;*/ | ||
119 | |||
120 | count = 0; | ||
121 | |||
122 | while (size > PEEK_SAMPLE_COUNT) | ||
123 | { | ||
124 | min = zero_point; | ||
125 | max = zero_point; | ||
126 | min_count = 1; | ||
127 | max_count = 1; | ||
128 | |||
129 | for (i = 0; i < PEEK_SAMPLE_COUNT; i++) | ||
130 | { | ||
131 | unsigned long value = *addr; | ||
132 | if (value < zero_point) { | ||
133 | min += value; | ||
134 | min_count++; | ||
135 | } | ||
136 | if (value > zero_point) { | ||
137 | max += value; | ||
138 | max_count++; | ||
139 | } | ||
140 | addr = &addr[2]; | ||
141 | } | ||
142 | |||
143 | min /= min_count; | ||
144 | max /= max_count; | ||
145 | |||
146 | size -= PEEK_SAMPLE_COUNT; | ||
147 | average += (max - min) / 2; | ||
148 | //average += (max - zero_point) + (zero_point - min); | ||
149 | //average += zero_point - min; | ||
150 | count += 1; | ||
151 | } | ||
152 | |||
153 | if (count) | ||
154 | { | ||
155 | average /= count; | ||
156 | /* I don't know why this is needed. Should be fixed. */ | ||
157 | average = zero_point - average; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | return average; | ||
162 | } | ||
163 | |||
164 | void pcm_calculate_peaks(int *left, int *right) | ||
165 | { | ||
166 | unsigned short *addr = (unsigned short *)SAR0; | ||
167 | long size = MIN(512, BCR0); | ||
168 | |||
169 | if (left != NULL) | ||
170 | *left = calculate_channel_peak_average(0, addr, size); | ||
171 | if (right != NULL) | ||
172 | *right = calculate_channel_peak_average(1, addr, size);; | ||
173 | } | ||
174 | |||
92 | /* sets frequency of input to DAC */ | 175 | /* sets frequency of input to DAC */ |
93 | void pcm_set_frequency(unsigned int frequency) | 176 | void pcm_set_frequency(unsigned int frequency) |
94 | { | 177 | { |