Initial attempt to support peak meter on iriver. It still has some

strange behaviour and readings might not be correct.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7182 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2005-07-17 19:29:02 +00:00
parent 170bb8eb78
commit e9919342c5
3 changed files with 94 additions and 7 deletions

View file

@ -32,6 +32,10 @@
#include "lang.h"
#include "peakmeter.h"
#if CONFIG_HWCODEC == MASNONE
#include "pcm_playback.h"
#endif
/* no inline in simulator mode */
#ifdef SIMULATOR
#define inline
@ -552,9 +556,9 @@ inline void peak_meter_peek(void)
int left = 8000;
int right = 9000;
#elif CONFIG_HWCODEC == MASNONE
/* FIX */
int left = 9000;
int right = 8000;
int left;
int right;
pcm_calculate_peaks(&left, &right);
#else
/* read the peak values */
int left = mas_codec_readreg(peak_meter_src_l);
@ -729,8 +733,7 @@ static int peak_meter_read_l (void)
#ifdef SIMULATOR
peak_meter_l = 8000;
#elif CONFIG_HWCODEC == MASNONE
/* FIX */
peak_meter_l = 8000;
pcm_calculate_peaks(&peak_meter_l, NULL);
#else
/* reset peak_meter_l so that subsequent calls of
peak_meter_peek doesn't get fooled by an old
@ -758,8 +761,7 @@ static int peak_meter_read_r (void) {
#ifdef SIMULATOR
peak_meter_l = 8000;
#elif CONFIG_HWCODEC == MASNONE
/* FIX */
peak_meter_r = 8000;
pcm_calculate_peaks(NULL, &peak_meter_r);
#else
/* reset peak_meter_r so that subsequent calls of
peak_meter_peek doesn't get fooled by an old

View file

@ -25,6 +25,8 @@ void pcm_set_frequency(unsigned int frequency);
/* This is for playing "raw" PCM data */
void pcm_play_data(void (*get_more)(unsigned char** start, long* size));
void pcm_calculate_peaks(int *left, int *right);
void pcm_play_stop(void);
void pcm_play_pause(bool play);
bool pcm_is_paused(void);

View file

@ -89,6 +89,89 @@ static void dma_stop(void)
pcm_paused = false;
}
#define PEEK_SAMPLE_COUNT 64
static long calculate_channel_peak_average(int channel, unsigned short *addr,
long size)
{
int i;
long min, max;
int count, min_count, max_count;
unsigned long average, zero_point;
addr = &addr[channel];
average = 0;
if (pcm_playing && !pcm_paused && addr != NULL)
{
/* Calculate the zero point and remove DC offset (should be around 32768) */
zero_point = 0;
for (i = 0; i < size; i++)
zero_point += addr[i*2];
zero_point /= i;
/*for (i = 0; i < size; i++) {
long peak = addr[i*2] - 32768;
if (peak < 0)
peak = 0;
average += peak;
}
average /= i;*/
count = 0;
while (size > PEEK_SAMPLE_COUNT)
{
min = zero_point;
max = zero_point;
min_count = 1;
max_count = 1;
for (i = 0; i < PEEK_SAMPLE_COUNT; i++)
{
unsigned long value = *addr;
if (value < zero_point) {
min += value;
min_count++;
}
if (value > zero_point) {
max += value;
max_count++;
}
addr = &addr[2];
}
min /= min_count;
max /= max_count;
size -= PEEK_SAMPLE_COUNT;
average += (max - min) / 2;
//average += (max - zero_point) + (zero_point - min);
//average += zero_point - min;
count += 1;
}
if (count)
{
average /= count;
/* I don't know why this is needed. Should be fixed. */
average = zero_point - average;
}
}
return average;
}
void pcm_calculate_peaks(int *left, int *right)
{
unsigned short *addr = (unsigned short *)SAR0;
long size = MIN(512, BCR0);
if (left != NULL)
*left = calculate_channel_peak_average(0, addr, size);
if (right != NULL)
*right = calculate_channel_peak_average(1, addr, size);;
}
/* sets frequency of input to DAC */
void pcm_set_frequency(unsigned int frequency)
{