summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-07-17 19:29:02 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-07-17 19:29:02 +0000
commite9919342c558bc6b1f843bbc6e900c5ef540ee8f (patch)
treed092164b82b50ca660652cf7207d61b7b703b494
parent170bb8eb78703bd6f2ae951e2292c89ae7565a29 (diff)
downloadrockbox-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
-rw-r--r--apps/recorder/peakmeter.c16
-rw-r--r--firmware/export/pcm_playback.h2
-rw-r--r--firmware/pcm_playback.c83
3 files changed, 94 insertions, 7 deletions
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index 7746fb9f9f..002a3c48d5 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -32,6 +32,10 @@
32#include "lang.h" 32#include "lang.h"
33#include "peakmeter.h" 33#include "peakmeter.h"
34 34
35#if CONFIG_HWCODEC == MASNONE
36#include "pcm_playback.h"
37#endif
38
35/* no inline in simulator mode */ 39/* no inline in simulator mode */
36#ifdef SIMULATOR 40#ifdef SIMULATOR
37#define inline 41#define inline
@@ -552,9 +556,9 @@ inline void peak_meter_peek(void)
552 int left = 8000; 556 int left = 8000;
553 int right = 9000; 557 int right = 9000;
554#elif CONFIG_HWCODEC == MASNONE 558#elif CONFIG_HWCODEC == MASNONE
555 /* FIX */ 559 int left;
556 int left = 9000; 560 int right;
557 int right = 8000; 561 pcm_calculate_peaks(&left, &right);
558#else 562#else
559 /* read the peak values */ 563 /* read the peak values */
560 int left = mas_codec_readreg(peak_meter_src_l); 564 int left = mas_codec_readreg(peak_meter_src_l);
@@ -729,8 +733,7 @@ static int peak_meter_read_l (void)
729#ifdef SIMULATOR 733#ifdef SIMULATOR
730 peak_meter_l = 8000; 734 peak_meter_l = 8000;
731#elif CONFIG_HWCODEC == MASNONE 735#elif CONFIG_HWCODEC == MASNONE
732 /* FIX */ 736 pcm_calculate_peaks(&peak_meter_l, NULL);
733 peak_meter_l = 8000;
734#else 737#else
735 /* reset peak_meter_l so that subsequent calls of 738 /* reset peak_meter_l so that subsequent calls of
736 peak_meter_peek doesn't get fooled by an old 739 peak_meter_peek doesn't get fooled by an old
@@ -758,8 +761,7 @@ static int peak_meter_read_r (void) {
758#ifdef SIMULATOR 761#ifdef SIMULATOR
759 peak_meter_l = 8000; 762 peak_meter_l = 8000;
760#elif CONFIG_HWCODEC == MASNONE 763#elif CONFIG_HWCODEC == MASNONE
761 /* FIX */ 764 pcm_calculate_peaks(NULL, &peak_meter_r);
762 peak_meter_r = 8000;
763#else 765#else
764 /* reset peak_meter_r so that subsequent calls of 766 /* reset peak_meter_r so that subsequent calls of
765 peak_meter_peek doesn't get fooled by an old 767 peak_meter_peek doesn't get fooled by an old
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 */
26void pcm_play_data(void (*get_more)(unsigned char** start, long* size)); 26void pcm_play_data(void (*get_more)(unsigned char** start, long* size));
27 27
28void pcm_calculate_peaks(int *left, int *right);
29
28void pcm_play_stop(void); 30void pcm_play_stop(void);
29void pcm_play_pause(bool play); 31void pcm_play_pause(bool play);
30bool pcm_is_paused(void); 32bool 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
93static 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
164void 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 */
93void pcm_set_frequency(unsigned int frequency) 176void pcm_set_frequency(unsigned int frequency)
94{ 177{