Reduce latency when configuring the EQ.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8609 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2006-02-07 19:17:51 +00:00
parent 69519a97f2
commit 4408b6b70c
3 changed files with 35 additions and 9 deletions

View file

@ -36,11 +36,12 @@
#include "audio.h" #include "audio.h"
#include "dsp.h" #include "dsp.h"
#define CHUNK_SIZE PCMBUF_GUARD #define CHUNK_SIZE 32768
/* Must be a power of 2 */ /* Must be a power of 2 */
#define NUM_PCM_BUFFERS 128 #define NUM_PCM_BUFFERS 128
#define NUM_PCM_BUFFERS_MASK (NUM_PCM_BUFFERS - 1) #define NUM_PCM_BUFFERS_MASK (NUM_PCM_BUFFERS - 1)
#define PCMBUF_WATERMARK (CHUNK_SIZE * 6) /* Watermark level at 1s. */
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 1)
/* Audio buffer related settings. */ /* Audio buffer related settings. */
static long pcmbuf_size = 0; /* Size of the PCM buffer. */ static long pcmbuf_size = 0; /* Size of the PCM buffer. */
@ -83,7 +84,7 @@ struct pcmbufdesc
int size; int size;
/* Call this when the buffer has been played */ /* Call this when the buffer has been played */
void (*callback)(void); void (*callback)(void);
} pcmbuffers[NUM_PCM_BUFFERS] IDATA_ATTR; } pcmbuffers[NUM_PCM_BUFFERS] IDATA_ATTR; /* Do we really need IRAM for this? */
static int pcmbuf_read_index; static int pcmbuf_read_index;
static int pcmbuf_write_index; static int pcmbuf_write_index;
@ -95,6 +96,7 @@ static int pcmbuf_num_used_buffers(void);
static void (*position_callback)(int size); static void (*position_callback)(int size);
static int last_chunksize; static int last_chunksize;
static long mixpos = 0; static long mixpos = 0;
static bool low_latency_mode = false;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ #ifdef HAVE_ADJUSTABLE_CPU_FREQ
static bool boost_mode; static bool boost_mode;
@ -222,12 +224,17 @@ unsigned int pcmbuf_get_latency(void)
return latency<0?0:latency; return latency<0?0:latency;
} }
void pcmbuf_set_low_latency(bool state)
{
low_latency_mode = state;
}
bool pcmbuf_is_lowdata(void) bool pcmbuf_is_lowdata(void)
{ {
if (!pcm_is_playing() || pcm_is_paused() || crossfade_init || crossfade_active) if (!pcm_is_playing() || pcm_is_paused() || crossfade_init || crossfade_active)
return false; return false;
if (pcmbuf_unplayed_bytes < CHUNK_SIZE * 4) if (pcmbuf_unplayed_bytes < pcmbuf_watermark - CHUNK_SIZE)
return true; return true;
return false; return false;
@ -237,7 +244,7 @@ bool pcmbuf_crossfade_init(bool manual_skip)
{ {
if (pcmbuf_size - audiobuffer_free < CHUNK_SIZE * 8 if (pcmbuf_size - audiobuffer_free < CHUNK_SIZE * 8
|| !pcmbuf_is_crossfade_enabled() || !pcmbuf_is_crossfade_enabled()
|| crossfade_active || crossfade_init) { || crossfade_active || crossfade_init || low_latency_mode) {
pcmbuf_flush_audio(); pcmbuf_flush_audio();
return false; return false;
} }
@ -422,7 +429,7 @@ static void crossfade_start(void)
int fade_in_delay = 0; int fade_in_delay = 0;
crossfade_init = 0; crossfade_init = 0;
if (bytesleft < CHUNK_SIZE * 4) { if (bytesleft < NATIVE_FREQUENCY * 4 / 2) {
logf("crossfade rejected"); logf("crossfade rejected");
pcmbuf_play_stop(); pcmbuf_play_stop();
return ; return ;
@ -439,7 +446,7 @@ static void crossfade_start(void)
case CFM_MIX: case CFM_MIX:
case CFM_CROSSFADE: case CFM_CROSSFADE:
/* Initialize the crossfade buffer size. */ /* Initialize the crossfade buffer size. */
crossfade_rem = (bytesleft - (CHUNK_SIZE * 2))/2; crossfade_rem = (bytesleft - (NATIVE_FREQUENCY / 4))/2;
/* Get fade out delay from settings. */ /* Get fade out delay from settings. */
fade_out_delay = NATIVE_FREQUENCY fade_out_delay = NATIVE_FREQUENCY
@ -594,6 +601,14 @@ static bool prepare_insert(long length)
if (crossfade_init) if (crossfade_init)
crossfade_start(); crossfade_start();
if (low_latency_mode)
{
/* 1/4s latency. */
if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 4
&& pcm_is_playing())
return false;
}
if (audiobuffer_free < length + audiobuffer_fillpos if (audiobuffer_free < length + audiobuffer_fillpos
+ CHUNK_SIZE && !crossfade_active) { + CHUNK_SIZE && !crossfade_active) {
pcmbuf_boost(false); pcmbuf_boost(false);
@ -603,7 +618,8 @@ static bool prepare_insert(long length)
if (!pcm_is_playing()) { if (!pcm_is_playing()) {
pcmbuf_boost(true); pcmbuf_boost(true);
crossfade_active = false; crossfade_active = false;
if (audiobuffer_free < pcmbuf_size - CHUNK_SIZE*4) { /* Pre-buffer 1s. */
if (audiobuffer_free < pcmbuf_size - NATIVE_FREQUENCY*4) {
logf("pcm starting"); logf("pcm starting");
pcmbuf_play_start(); pcmbuf_play_start();
} }
@ -840,7 +856,7 @@ void pcmbuf_crossfade_enable(bool on_off)
crossfade_enabled = on_off; crossfade_enabled = on_off;
if (crossfade_enabled) { if (crossfade_enabled) {
pcmbuf_set_watermark_bytes(pcmbuf_size - (CHUNK_SIZE*6)); pcmbuf_set_watermark_bytes(pcmbuf_size - (NATIVE_FREQUENCY*4/2));
} else { } else {
pcmbuf_set_watermark_bytes(PCMBUF_WATERMARK); pcmbuf_set_watermark_bytes(PCMBUF_WATERMARK);
} }

View file

@ -45,6 +45,7 @@ bool pcmbuf_crossfade_init(bool manual_skip);
void pcmbuf_add_event(void (*event_handler)(void)); void pcmbuf_add_event(void (*event_handler)(void));
void pcmbuf_set_position_callback(void (*callback)(int size)); void pcmbuf_set_position_callback(void (*callback)(int size));
unsigned int pcmbuf_get_latency(void); unsigned int pcmbuf_get_latency(void);
void pcmbuf_set_low_latency(bool state);
bool pcmbuf_insert_buffer(char *buf, long length); bool pcmbuf_insert_buffer(char *buf, long length);
void pcmbuf_flush_buffer(long length); void pcmbuf_flush_buffer(long length);
void* pcmbuf_request_buffer(long length, long *realsize); void* pcmbuf_request_buffer(long length, long *realsize);

View file

@ -46,6 +46,7 @@
#if CONFIG_CODEC == SWCODEC #if CONFIG_CODEC == SWCODEC
#include "dsp.h" #include "dsp.h"
#include "eq_menu.h" #include "eq_menu.h"
#include "pcmbuf.h"
#endif #endif
int selected_setting; /* Used by the callback */ int selected_setting; /* Used by the callback */
@ -394,11 +395,19 @@ bool sound_menu(void)
#endif #endif
}; };
#if CONFIG_CODEC == SWCODEC
pcmbuf_set_low_latency(true);
#endif
m=menu_init( items, sizeof(items) / sizeof(*items), NULL, m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
result = menu_run(m); result = menu_run(m);
menu_exit(m); menu_exit(m);
#if CONFIG_CODEC == SWCODEC
pcmbuf_set_low_latency(false);
#endif
return result; return result;
} }