summaryrefslogtreecommitdiffstats
path: root/uisimulator/sdl
diff options
context:
space:
mode:
authorDan Everton <dan@iocaine.org>2006-02-23 21:13:03 +0000
committerDan Everton <dan@iocaine.org>2006-02-23 21:13:03 +0000
commite37654521144e1d224f0044268643f20e3b8a363 (patch)
treed6f617b340c3f22d10f938eb54dcb0442966914a /uisimulator/sdl
parentf0d1c96ee435e03af0c92aa5ac5260499ae589ed (diff)
downloadrockbox-e37654521144e1d224f0044268643f20e3b8a363.tar.gz
rockbox-e37654521144e1d224f0044268643f20e3b8a363.zip
Make peak meter work in simulator for SWCODEC targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8815 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/sdl')
-rw-r--r--uisimulator/sdl/sound.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/uisimulator/sdl/sound.c b/uisimulator/sdl/sound.c
index 23d8718411..ae9d5f9053 100644
--- a/uisimulator/sdl/sound.c
+++ b/uisimulator/sdl/sound.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <memory.h>
+#include "kernel.h"
#include "sound.h"
#include "SDL.h"
@@ -142,6 +143,70 @@ bool pcm_is_playing(void)
return pcm_playing;
}
+/*
+ * This function goes directly into the DMA buffer to calculate the left and
+ * right peak values. To avoid missing peaks it tries to look forward two full
+ * peek periods (2/HZ sec, 100% overlap), although it's always possible that
+ * the entire period will not be visible. To reduce CPU load it only looks at
+ * every third sample, and this can be reduced even further if needed (even
+ * every tenth sample would still be pretty accurate).
+ */
+
+#define PEAK_SAMPLES (44100*2/HZ) /* 44100 samples * 2 / 100 Hz tick */
+#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
+
+void pcm_calculate_peaks(int *left, int *right)
+{
+ long samples = pcm_data_size / 4;
+ short *addr = pcm_data;
+
+ if (samples > PEAK_SAMPLES)
+ samples = PEAK_SAMPLES;
+
+ samples /= PEAK_STRIDE;
+
+ if (left && right) {
+ int left_peak = 0, right_peak = 0, value;
+
+ while (samples--) {
+ if ((value = addr [0]) > left_peak)
+ left_peak = value;
+ else if (-value > left_peak)
+ left_peak = -value;
+
+ if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
+ right_peak = value;
+ else if (-value > right_peak)
+ right_peak = -value;
+
+ addr += PEAK_STRIDE * 2;
+ }
+
+ *left = left_peak;
+ *right = right_peak;
+ }
+ else if (left || right) {
+ int peak_value = 0, value;
+
+ if (right)
+ addr += (PEAK_STRIDE | 1);
+
+ while (samples--) {
+ if ((value = addr [0]) > peak_value)
+ peak_value = value;
+ else if (-value > peak_value)
+ peak_value = -value;
+
+ addr += PEAK_STRIDE * 2;
+ }
+
+ if (left)
+ *left = peak_value;
+ else
+ *right = peak_value;
+ }
+}
+
Uint8 overflow[8192];
Uint32 overflow_amount = 0;