forked from len0rd/rockbox
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 "lang.h"
|
||||||
#include "peakmeter.h"
|
#include "peakmeter.h"
|
||||||
|
|
||||||
|
#if CONFIG_HWCODEC == MASNONE
|
||||||
|
#include "pcm_playback.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* no inline in simulator mode */
|
/* no inline in simulator mode */
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
#define inline
|
#define inline
|
||||||
|
|
@ -552,9 +556,9 @@ inline void peak_meter_peek(void)
|
||||||
int left = 8000;
|
int left = 8000;
|
||||||
int right = 9000;
|
int right = 9000;
|
||||||
#elif CONFIG_HWCODEC == MASNONE
|
#elif CONFIG_HWCODEC == MASNONE
|
||||||
/* FIX */
|
int left;
|
||||||
int left = 9000;
|
int right;
|
||||||
int right = 8000;
|
pcm_calculate_peaks(&left, &right);
|
||||||
#else
|
#else
|
||||||
/* read the peak values */
|
/* read the peak values */
|
||||||
int left = mas_codec_readreg(peak_meter_src_l);
|
int left = mas_codec_readreg(peak_meter_src_l);
|
||||||
|
|
@ -729,8 +733,7 @@ static int peak_meter_read_l (void)
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
peak_meter_l = 8000;
|
peak_meter_l = 8000;
|
||||||
#elif CONFIG_HWCODEC == MASNONE
|
#elif CONFIG_HWCODEC == MASNONE
|
||||||
/* FIX */
|
pcm_calculate_peaks(&peak_meter_l, NULL);
|
||||||
peak_meter_l = 8000;
|
|
||||||
#else
|
#else
|
||||||
/* reset peak_meter_l so that subsequent calls of
|
/* reset peak_meter_l so that subsequent calls of
|
||||||
peak_meter_peek doesn't get fooled by an old
|
peak_meter_peek doesn't get fooled by an old
|
||||||
|
|
@ -758,8 +761,7 @@ static int peak_meter_read_r (void) {
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
peak_meter_l = 8000;
|
peak_meter_l = 8000;
|
||||||
#elif CONFIG_HWCODEC == MASNONE
|
#elif CONFIG_HWCODEC == MASNONE
|
||||||
/* FIX */
|
pcm_calculate_peaks(NULL, &peak_meter_r);
|
||||||
peak_meter_r = 8000;
|
|
||||||
#else
|
#else
|
||||||
/* reset peak_meter_r so that subsequent calls of
|
/* reset peak_meter_r so that subsequent calls of
|
||||||
peak_meter_peek doesn't get fooled by an old
|
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 */
|
/* This is for playing "raw" PCM data */
|
||||||
void pcm_play_data(void (*get_more)(unsigned char** start, long* size));
|
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_stop(void);
|
||||||
void pcm_play_pause(bool play);
|
void pcm_play_pause(bool play);
|
||||||
bool pcm_is_paused(void);
|
bool pcm_is_paused(void);
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,89 @@ static void dma_stop(void)
|
||||||
pcm_paused = false;
|
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 */
|
/* sets frequency of input to DAC */
|
||||||
void pcm_set_frequency(unsigned int frequency)
|
void pcm_set_frequency(unsigned int frequency)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue