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:
parent
170bb8eb78
commit
e9919342c5
3 changed files with 94 additions and 7 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue