From e37654521144e1d224f0044268643f20e3b8a363 Mon Sep 17 00:00:00 2001 From: Dan Everton Date: Thu, 23 Feb 2006 21:13:03 +0000 Subject: Make peak meter work in simulator for SWCODEC targets. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8815 a1c6a512-1295-4272-9138-f99709370657 --- uisimulator/sdl/sound.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'uisimulator') 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 #include #include +#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; -- cgit