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 --- apps/recorder/peakmeter.c | 13 +++++----- uisimulator/sdl/sound.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 0142a9d093..f70e9ae709 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c @@ -44,9 +44,7 @@ #include "pcm_record.h" #endif -#ifndef SIMULATOR /* this is not used in the sim */ static bool pm_playback = true; /* selects between playback and recording peaks */ -#endif #endif @@ -539,11 +537,7 @@ void peak_meter_peek(void) { int left, right; /* read current values */ -#ifdef SIMULATOR - pm_cur_left = left = 8000; - pm_cur_right = right = 9000; -#elif CONFIG_CODEC == SWCODEC - +#if CONFIG_CODEC == SWCODEC if (pm_playback) pcm_calculate_peaks(&pm_cur_left, &pm_cur_right); #ifdef HAVE_RECORDING @@ -555,8 +549,13 @@ void peak_meter_peek(void) left = pm_cur_left; right = pm_cur_right; #else +#ifndef SIMULATOR pm_cur_left = left = mas_codec_readreg(pm_src_left); pm_cur_right = right = mas_codec_readreg(pm_src_right); +#else + pm_cur_left = left = 8000; + pm_cur_right = right = 9000; +#endif #endif /* check for clips 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