diff options
-rw-r--r-- | apps/recorder/peakmeter.c | 16 | ||||
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 83 |
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 */ |
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 | { |