summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/pcm_playback.c142
1 files changed, 72 insertions, 70 deletions
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index d6a196d649..a9e1e1ff99 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -107,70 +107,6 @@ static void dma_stop(void)
107 pcm_paused = false; 107 pcm_paused = false;
108} 108}
109 109
110/*
111 * This function goes directly into the DMA buffer to calculate the left and
112 * right peak values. To avoid missing peaks it tries to look forward two full
113 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
114 * the entire period will not be visible. To reduce CPU load it only looks at
115 * every third sample, and this can be reduced even further if needed (even
116 * every tenth sample would still be pretty accurate).
117 */
118
119#define PEAK_SAMPLES (44100*2/HZ) /* 44100 samples * 2 / 100 Hz tick */
120#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
121
122void pcm_calculate_peaks(int *left, int *right)
123{
124 long samples = (BCR0 & 0xffffff) / 4;
125 short *addr = (short *) (SAR0 & ~3);
126
127 if (samples > PEAK_SAMPLES)
128 samples = PEAK_SAMPLES;
129
130 samples /= PEAK_STRIDE;
131
132 if (left && right) {
133 int left_peak = 0, right_peak = 0, value;
134
135 while (samples--) {
136 if ((value = addr [0]) > left_peak)
137 left_peak = value;
138 else if (-value > left_peak)
139 left_peak = -value;
140
141 if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
142 right_peak = value;
143 else if (-value > right_peak)
144 right_peak = -value;
145
146 addr += PEAK_STRIDE * 2;
147 }
148
149 *left = left_peak;
150 *right = right_peak;
151 }
152 else if (left || right) {
153 int peak_value = 0, value;
154
155 if (right)
156 addr += (PEAK_STRIDE | 1);
157
158 while (samples--) {
159 if ((value = addr [0]) > peak_value)
160 peak_value = value;
161 else if (-value > peak_value)
162 peak_value = -value;
163
164 addr += PEAK_STRIDE * 2;
165 }
166
167 if (left)
168 *left = peak_value;
169 else
170 *right = peak_value;
171 }
172}
173
174/* sets frequency of input to DAC */ 110/* sets frequency of input to DAC */
175void pcm_set_frequency(unsigned int frequency) 111void pcm_set_frequency(unsigned int frequency)
176{ 112{
@@ -510,12 +446,6 @@ bool pcm_is_playing(void)
510 return pcm_playing; 446 return pcm_playing;
511} 447}
512 448
513void pcm_calculate_peaks(int *left, int *right)
514{
515 *left=0;
516 *right=0;
517}
518
519long pcm_get_bytes_waiting(void) 449long pcm_get_bytes_waiting(void)
520{ 450{
521 return size; 451 return size;
@@ -578,3 +508,75 @@ long pcm_get_bytes_waiting(void)
578} 508}
579 509
580#endif 510#endif
511
512#if CONFIG_CPU != PNX0101
513/*
514 * This function goes directly into the DMA buffer to calculate the left and
515 * right peak values. To avoid missing peaks it tries to look forward two full
516 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
517 * the entire period will not be visible. To reduce CPU load it only looks at
518 * every third sample, and this can be reduced even further if needed (even
519 * every tenth sample would still be pretty accurate).
520 */
521
522#define PEAK_SAMPLES (44100*2/HZ) /* 44100 samples * 2 / 100 Hz tick */
523#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
524
525void pcm_calculate_peaks(int *left, int *right)
526{
527#ifdef HAVE_UDA1380
528 long samples = (BCR0 & 0xffffff) / 4;
529 short *addr = (short *) (SAR0 & ~3);
530#elif defined(HAVE_WM8975)
531 long samples = size / 4;
532 short *addr = p;
533#endif
534
535 if (samples > PEAK_SAMPLES)
536 samples = PEAK_SAMPLES;
537
538 samples /= PEAK_STRIDE;
539
540 if (left && right) {
541 int left_peak = 0, right_peak = 0, value;
542
543 while (samples--) {
544 if ((value = addr [0]) > left_peak)
545 left_peak = value;
546 else if (-value > left_peak)
547 left_peak = -value;
548
549 if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
550 right_peak = value;
551 else if (-value > right_peak)
552 right_peak = -value;
553
554 addr += PEAK_STRIDE * 2;
555 }
556
557 *left = left_peak;
558 *right = right_peak;
559 }
560 else if (left || right) {
561 int peak_value = 0, value;
562
563 if (right)
564 addr += (PEAK_STRIDE | 1);
565
566 while (samples--) {
567 if ((value = addr [0]) > peak_value)
568 peak_value = value;
569 else if (-value > peak_value)
570 peak_value = -value;
571
572 addr += PEAK_STRIDE * 2;
573 }
574
575 if (left)
576 *left = peak_value;
577 else
578 *right = peak_value;
579 }
580}
581
582#endif