summaryrefslogtreecommitdiff
path: root/firmware/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/pcm.c')
-rw-r--r--firmware/pcm.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/firmware/pcm.c b/firmware/pcm.c
index b7415f329b..c2ebc67687 100644
--- a/firmware/pcm.c
+++ b/firmware/pcm.c
@@ -93,6 +93,9 @@ unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT;
93/* samplerate frequency selection index */ 93/* samplerate frequency selection index */
94int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT; 94int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT;
95 95
96/* peak data for the global peak values - i.e. what the final output is */
97static struct pcm_peaks global_peaks;
98
96/* Called internally by functions to reset the state */ 99/* Called internally by functions to reset the state */
97static void pcm_play_stopped(void) 100static void pcm_play_stopped(void)
98{ 101{
@@ -107,7 +110,7 @@ static void pcm_play_stopped(void)
107 * 110 *
108 * Used for recording and playback. 111 * Used for recording and playback.
109 */ 112 */
110static void pcm_peak_peeker(const int32_t *addr, int count, int peaks[2]) 113static void pcm_peak_peeker(const int32_t *addr, int count, uint16_t peaks[2])
111{ 114{
112 int peak_l = 0, peak_r = 0; 115 int peak_l = 0, peak_r = 0;
113 const int32_t * const end = addr + count; 116 const int32_t * const end = addr + count;
@@ -145,18 +148,13 @@ static void pcm_peak_peeker(const int32_t *addr, int count, int peaks[2])
145 peaks[1] = peak_r; 148 peaks[1] = peak_r;
146} 149}
147 150
148void pcm_calculate_peaks(int *left, int *right) 151void pcm_do_peak_calculation(struct pcm_peaks *peaks, bool active,
152 const void *addr, int count)
149{ 153{
150 static int peaks[2] = { 0, 0 };
151 static unsigned long last_peak_tick = 0;
152 static unsigned long frame_period = 0;
153
154 long tick = current_tick; 154 long tick = current_tick;
155 int count;
156 const void *addr;
157 155
158 /* Throttled peak ahead based on calling period */ 156 /* Peak no farther ahead than expected period to avoid overcalculation */
159 long period = tick - last_peak_tick; 157 long period = tick - peaks->tick;
160 158
161 /* Keep reasonable limits on period */ 159 /* Keep reasonable limits on period */
162 if (period < 1) 160 if (period < 1)
@@ -164,33 +162,38 @@ void pcm_calculate_peaks(int *left, int *right)
164 else if (period > HZ/5) 162 else if (period > HZ/5)
165 period = HZ/5; 163 period = HZ/5;
166 164
167 frame_period = (3*frame_period + period) >> 2; 165 peaks->period = (3*peaks->period + period) >> 2;
168 166 peaks->tick = tick;
169 last_peak_tick = tick;
170 167
171 addr = pcm_play_dma_get_peak_buffer(&count); 168 if (active)
172
173 if (pcm_playing && !pcm_paused)
174 { 169 {
175 int framecount; 170 int framecount = peaks->period*pcm_curr_sampr / HZ;
176
177 framecount = frame_period*pcm_curr_sampr / HZ;
178 count = MIN(framecount, count); 171 count = MIN(framecount, count);
179 172
180 if (count > 0) 173 if (count > 0)
181 pcm_peak_peeker((int32_t *)addr, count, peaks); 174 pcm_peak_peeker((int32_t *)addr, count, peaks->val);
182 /* else keep previous peak values */ 175 /* else keep previous peak values */
183 } 176 }
184 else 177 else
185 { 178 {
186 peaks[0] = peaks[1] = 0; 179 /* peaks are zero */
180 peaks->val[0] = peaks->val[1] = 0;
187 } 181 }
182}
183
184void pcm_calculate_peaks(int *left, int *right)
185{
186 int count;
187 const void *addr = pcm_play_dma_get_peak_buffer(&count);
188
189 pcm_do_peak_calculation(&global_peaks, pcm_playing && !pcm_paused,
190 addr, count);
188 191
189 if (left) 192 if (left)
190 *left = peaks[0]; 193 *left = global_peaks.val[0];
191 194
192 if (right) 195 if (right)
193 *right = peaks[1]; 196 *right = global_peaks.val[1];
194} 197}
195 198
196const void* pcm_get_peak_buffer(int * count) 199const void* pcm_get_peak_buffer(int * count)
@@ -437,7 +440,7 @@ static void pcm_recording_stopped(void)
437 */ 440 */
438void pcm_calculate_rec_peaks(int *left, int *right) 441void pcm_calculate_rec_peaks(int *left, int *right)
439{ 442{
440 static int peaks[2]; 443 static uint16_t peaks[2];
441 444
442 if (pcm_recording) 445 if (pcm_recording)
443 { 446 {
@@ -484,10 +487,8 @@ void pcm_init_recording(void)
484{ 487{
485 logf("pcm_init_recording"); 488 logf("pcm_init_recording");
486 489
487#ifndef HAVE_PCM_FULL_DUPLEX
488 /* Stop the beasty before attempting recording */ 490 /* Stop the beasty before attempting recording */
489 mixer_reset(); 491 mixer_reset();
490#endif
491 492
492 /* Recording init is locked unlike general pcm init since this is not 493 /* Recording init is locked unlike general pcm init since this is not
493 * just a one-time event at startup and it should and must be safe by 494 * just a one-time event at startup and it should and must be safe by