forked from len0rd/rockbox
Calculate watermark from bitrate and harddisk spinup time.
Use a smaller PCM buffer on targets with 2MB or less ram. (FS#9703) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19743 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
12b8f8de89
commit
6427d127aa
27 changed files with 85 additions and 121 deletions
|
@ -56,11 +56,7 @@
|
||||||
#include "albumart.h"
|
#include "albumart.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MEM > 1
|
|
||||||
#define GUARD_BUFSIZE (32*1024)
|
#define GUARD_BUFSIZE (32*1024)
|
||||||
#else
|
|
||||||
#define GUARD_BUFSIZE (8*1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define LOGF_ENABLE to enable logf output in this file */
|
/* Define LOGF_ENABLE to enable logf output in this file */
|
||||||
/*#define LOGF_ENABLE*/
|
/*#define LOGF_ENABLE*/
|
||||||
|
@ -88,11 +84,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* default point to start buffer refill */
|
/* default point to start buffer refill */
|
||||||
#define BUFFERING_DEFAULT_WATERMARK (1024*512)
|
#define BUFFERING_DEFAULT_WATERMARK (1024*128)
|
||||||
/* amount of data to read in one read() call */
|
/* amount of data to read in one read() call */
|
||||||
#define BUFFERING_DEFAULT_FILECHUNK (1024*32)
|
#define BUFFERING_DEFAULT_FILECHUNK (1024*32)
|
||||||
/* point at which the file buffer will fight for CPU time */
|
|
||||||
#define BUFFERING_CRITICAL_LEVEL (1024*128)
|
|
||||||
|
|
||||||
#define BUF_HANDLE_MASK 0x7FFFFFFF
|
#define BUF_HANDLE_MASK 0x7FFFFFFF
|
||||||
|
|
||||||
|
@ -173,7 +167,6 @@ enum {
|
||||||
Q_BASE_HANDLE, /* Set the reference handle for buf_useful_data */
|
Q_BASE_HANDLE, /* Set the reference handle for buf_useful_data */
|
||||||
|
|
||||||
/* Configuration: */
|
/* Configuration: */
|
||||||
Q_SET_WATERMARK,
|
|
||||||
Q_START_FILL, /* Request that the buffering thread initiate a buffer
|
Q_START_FILL, /* Request that the buffering thread initiate a buffer
|
||||||
fill at its earliest convenience */
|
fill at its earliest convenience */
|
||||||
Q_HANDLE_ADDED, /* Inform the buffering thread that a handle was added,
|
Q_HANDLE_ADDED, /* Inform the buffering thread that a handle was added,
|
||||||
|
@ -555,7 +548,7 @@ static void update_data_counters(void)
|
||||||
static inline bool buffer_is_low(void)
|
static inline bool buffer_is_low(void)
|
||||||
{
|
{
|
||||||
update_data_counters();
|
update_data_counters();
|
||||||
return data_counters.useful < BUFFERING_CRITICAL_LEVEL;
|
return data_counters.useful < (conf_watermark / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer data for the given handle.
|
/* Buffer data for the given handle.
|
||||||
|
@ -1313,8 +1306,7 @@ size_t buf_used(void)
|
||||||
|
|
||||||
void buf_set_watermark(size_t bytes)
|
void buf_set_watermark(size_t bytes)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("buffering > Q_SET_WATERMARK %ld", (long)bytes);
|
conf_watermark = bytes;
|
||||||
queue_post(&buffering_queue, Q_SET_WATERMARK, bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shrink_buffer_inner(struct memory_handle *h)
|
static void shrink_buffer_inner(struct memory_handle *h)
|
||||||
|
@ -1386,17 +1378,6 @@ void buffering_thread(void)
|
||||||
base_handle_id = (int)ev.data;
|
base_handle_id = (int)ev.data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_SET_WATERMARK:
|
|
||||||
LOGFQUEUE("buffering < Q_SET_WATERMARK");
|
|
||||||
conf_watermark = (size_t)ev.data;
|
|
||||||
if (conf_watermark < BUFFERING_DEFAULT_FILECHUNK)
|
|
||||||
{
|
|
||||||
logf("wmark<chunk %ld<%d",
|
|
||||||
(long)conf_watermark, BUFFERING_DEFAULT_FILECHUNK);
|
|
||||||
conf_watermark = BUFFERING_DEFAULT_FILECHUNK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
case SYS_USB_CONNECTED:
|
case SYS_USB_CONNECTED:
|
||||||
LOGFQUEUE("buffering < SYS_USB_CONNECTED");
|
LOGFQUEUE("buffering < SYS_USB_CONNECTED");
|
||||||
|
|
|
@ -55,8 +55,6 @@ enum codec_status codec_main(void)
|
||||||
unsigned char c = 0;
|
unsigned char c = 0;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ enum codec_status codec_main(void)
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
if (codec_init()) {
|
if (codec_init()) {
|
||||||
|
|
|
@ -44,8 +44,6 @@ enum codec_status codec_main(void)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
|
||||||
|
|
||||||
|
|
|
@ -147,8 +147,6 @@ enum codec_status codec_main(void)
|
||||||
size_t resume_offset;
|
size_t resume_offset;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
|
@ -38,9 +38,6 @@ enum codec_status codec_main(void)
|
||||||
char* module;
|
char* module;
|
||||||
int bytesPerSample =2;
|
int bytesPerSample =2;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
if (codec_init()) {
|
if (codec_init()) {
|
||||||
DEBUGF("codec init failed\n");
|
DEBUGF("codec init failed\n");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
libdemac - A Monkey's Audio decoder
|
libdemac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
demac - A Monkey's Audio decoder
|
demac - A Monkey's Audio decoder
|
||||||
|
|
||||||
$Id:$
|
$Id$
|
||||||
|
|
||||||
Copyright (C) Dave Chapman 2007
|
Copyright (C) Dave Chapman 2007
|
||||||
|
|
||||||
|
|
|
@ -423,8 +423,6 @@ enum codec_status codec_main(void)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, FLAC_OUTPUT_DEPTH-1);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, FLAC_OUTPUT_DEPTH-1);
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
|
@ -1229,9 +1229,6 @@ enum codec_status codec_main(void)
|
||||||
|
|
||||||
int bytesdone;
|
int bytesdone;
|
||||||
|
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
if (codec_init()) {
|
if (codec_init()) {
|
||||||
return CODEC_ERROR;
|
return CODEC_ERROR;
|
||||||
|
|
|
@ -47,8 +47,6 @@ enum codec_status codec_main(void)
|
||||||
size_t bytesleft;
|
size_t bytesleft;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
|
||||||
|
|
||||||
|
|
|
@ -1215,9 +1215,6 @@ enum codec_status codec_main(void)
|
||||||
int nSamplesPerCall = 882; /* This is PAL SID single speed (44100/50Hz) */
|
int nSamplesPerCall = 882; /* This is PAL SID single speed (44100/50Hz) */
|
||||||
int nSamplesToRender = 0;
|
int nSamplesToRender = 0;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
if (codec_init()) {
|
if (codec_init()) {
|
||||||
return CODEC_ERROR;
|
return CODEC_ERROR;
|
||||||
|
|
|
@ -559,8 +559,6 @@ enum codec_status codec_main(void)
|
||||||
|
|
||||||
/* Read the entire file */
|
/* Read the entire file */
|
||||||
DEBUGF("SPC: request initial buffer\n");
|
DEBUGF("SPC: request initial buffer\n");
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, ci->filesize);
|
|
||||||
|
|
||||||
ci->seek_buffer(0);
|
ci->seek_buffer(0);
|
||||||
size_t buffersize;
|
size_t buffersize;
|
||||||
uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize);
|
uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize);
|
||||||
|
|
|
@ -228,7 +228,6 @@ enum codec_status codec_main(void)
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
if (codec_init()) {
|
if (codec_init()) {
|
||||||
|
|
|
@ -44,8 +44,6 @@ enum codec_status codec_main(void)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
|
@ -468,8 +468,6 @@ enum codec_status codec_main(void)
|
||||||
int errcount = 0;
|
int errcount = 0;
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
|
@ -329,14 +329,14 @@ static bool dbg_buffering_thread(void)
|
||||||
|
|
||||||
bufused = bufsize - pcmbuf_free();
|
bufused = bufsize - pcmbuf_free();
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
|
snprintf(buf, sizeof(buf), "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
|
gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
|
||||||
bufsize, 0, bufused, HORIZONTAL);
|
bufsize, 0, bufused, HORIZONTAL);
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
|
snprintf(buf, sizeof(buf), "alloc: %6ld/%ld", audio_filebufused(),
|
||||||
(long) filebuflen);
|
(long) filebuflen);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ static bool dbg_buffering_thread(void)
|
||||||
filebuflen, 0, audio_filebufused(), HORIZONTAL);
|
filebuflen, 0, audio_filebufused(), HORIZONTAL);
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
|
snprintf(buf, sizeof(buf), "real: %6ld/%ld", (long)d.buffered_data,
|
||||||
(long)filebuflen);
|
(long)filebuflen);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ static bool dbg_buffering_thread(void)
|
||||||
line++;
|
line++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
|
snprintf(buf, sizeof(buf), "usefl: %6ld/%ld", (long)(d.useful_data),
|
||||||
(long)filebuflen);
|
(long)filebuflen);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ static bool dbg_buffering_thread(void)
|
||||||
{
|
{
|
||||||
int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
|
int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
|
||||||
int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
|
int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
|
||||||
snprintf(buf, sizeof(buf), "boost ratio: %3d.%d%% (%2d.%dMHz)",
|
snprintf(buf, sizeof(buf), "boost:%3d.%d%% (%d.%dMHz)",
|
||||||
boostquota/10, boostquota%10, avgclock/10, avgclock%10);
|
boostquota/10, boostquota%10, avgclock/10, avgclock%10);
|
||||||
lcd_puts(0, line++, buf);
|
lcd_puts(0, line++, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@ enum
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CODEC_SET_FILEBUF_WATERMARK = 1,
|
DSP_MYDSP = 1,
|
||||||
DSP_MYDSP,
|
|
||||||
DSP_SET_FREQUENCY,
|
DSP_SET_FREQUENCY,
|
||||||
DSP_SWITCH_FREQUENCY,
|
DSP_SWITCH_FREQUENCY,
|
||||||
DSP_SET_SAMPLE_DEPTH,
|
DSP_SET_SAMPLE_DEPTH,
|
||||||
|
|
|
@ -48,8 +48,12 @@ static inline int32_t clip_sample_16(int32_t sample)
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MEMORYSIZE > 2
|
||||||
/* Keep watermark high for iPods at least (2s) */
|
/* Keep watermark high for iPods at least (2s) */
|
||||||
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2)
|
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2)
|
||||||
|
#else
|
||||||
|
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 1) /* 0.25 seconds */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Structure we can use to queue pcm chunks in memory to be played
|
/* Structure we can use to queue pcm chunks in memory to be played
|
||||||
* by the driver code. */
|
* by the driver code. */
|
||||||
|
@ -125,7 +129,7 @@ extern unsigned int codec_thread_id;
|
||||||
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
||||||
|
|
||||||
static bool prepare_insert(size_t length);
|
static bool prepare_insert(size_t length);
|
||||||
static void pcmbuf_under_watermark(void);
|
static void pcmbuf_under_watermark(bool under);
|
||||||
static bool pcmbuf_flush_fillpos(void);
|
static bool pcmbuf_flush_fillpos(void);
|
||||||
|
|
||||||
#define CALL_IF_EXISTS(function, args...) if (function) function(args)
|
#define CALL_IF_EXISTS(function, args...) if (function) function(args)
|
||||||
|
@ -194,7 +198,7 @@ static void pcmbuf_set_watermark_bytes(void)
|
||||||
pcmbuf_watermark = (crossfade_enabled && pcmbuf_size) ?
|
pcmbuf_watermark = (crossfade_enabled && pcmbuf_size) ?
|
||||||
/* If crossfading, try to keep the buffer full other than 1 second */
|
/* If crossfading, try to keep the buffer full other than 1 second */
|
||||||
(pcmbuf_size - (NATIVE_FREQUENCY * 4 * 1)) :
|
(pcmbuf_size - (NATIVE_FREQUENCY * 4 * 1)) :
|
||||||
/* Otherwise, just keep it above 2 second */
|
/* Otherwise, just use the default */
|
||||||
PCMBUF_WATERMARK;
|
PCMBUF_WATERMARK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +275,7 @@ static void boost_codec_thread(bool boost)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PRIORITY_SCHEDULING */
|
#endif /* HAVE_PRIORITY_SCHEDULING */
|
||||||
|
|
||||||
static void pcmbuf_under_watermark(void)
|
static void pcmbuf_under_watermark(bool under)
|
||||||
{
|
{
|
||||||
/* Only codec thread initiates boost - voice boosts the cpu when playing
|
/* Only codec thread initiates boost - voice boosts the cpu when playing
|
||||||
a clip */
|
a clip */
|
||||||
|
@ -279,13 +283,21 @@ static void pcmbuf_under_watermark(void)
|
||||||
if (thread_get_current() == codec_thread_id)
|
if (thread_get_current() == codec_thread_id)
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
{
|
{
|
||||||
|
if (under)
|
||||||
|
{
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
/* If buffer is critically low, override UI priority, else
|
/* If buffer is critically low, override UI priority, else
|
||||||
set back to the original priority. */
|
set back to the original priority. */
|
||||||
boost_codec_thread(LOW_DATA(2) && pcm_is_playing());
|
boost_codec_thread(LOW_DATA(2) && pcm_is_playing());
|
||||||
#endif
|
#endif
|
||||||
/* Fill audio buffer by boosting cpu */
|
/* Fill audio buffer by boosting cpu */
|
||||||
trigger_cpu_boost();
|
trigger_cpu_boost();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost_codec_thread(false);
|
||||||
|
cancel_cpu_boost();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable crossfade if < .5s of audio */
|
/* Disable crossfade if < .5s of audio */
|
||||||
|
@ -318,8 +330,13 @@ bool pcmbuf_is_lowdata(void)
|
||||||
crossfade_init || crossfade_active)
|
crossfade_init || crossfade_active)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#if MEMORYSIZE > 2
|
||||||
/* 1 seconds of buffer is low data */
|
/* 1 seconds of buffer is low data */
|
||||||
return LOW_DATA(4);
|
return LOW_DATA(4);
|
||||||
|
#else
|
||||||
|
/* under watermark is low data */
|
||||||
|
return (pcmbuf_unplayed_bytes < pcmbuf_watermark);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Amount of bytes left in the buffer. */
|
/* Amount of bytes left in the buffer. */
|
||||||
|
@ -421,20 +438,18 @@ static void pcmbuf_init_pcmbuffers(void)
|
||||||
|
|
||||||
static size_t pcmbuf_get_next_required_pcmbuf_size(void)
|
static size_t pcmbuf_get_next_required_pcmbuf_size(void)
|
||||||
{
|
{
|
||||||
#if MEM > 1
|
|
||||||
size_t seconds = 1;
|
size_t seconds = 1;
|
||||||
|
|
||||||
if (crossfade_enabled_pending)
|
if (crossfade_enabled_pending)
|
||||||
seconds += global_settings.crossfade_fade_out_delay
|
seconds += global_settings.crossfade_fade_out_delay
|
||||||
+ global_settings.crossfade_fade_out_duration;
|
+ global_settings.crossfade_fade_out_duration;
|
||||||
|
|
||||||
|
#if MEMORYSIZE > 2
|
||||||
/* Buffer has to be at least 2s long. */
|
/* Buffer has to be at least 2s long. */
|
||||||
seconds += 2;
|
seconds += 2;
|
||||||
logf("pcmbuf len: %ld", seconds);
|
|
||||||
return seconds * (NATIVE_FREQUENCY*4);
|
|
||||||
#else
|
|
||||||
return NATIVE_FREQUENCY*2;
|
|
||||||
#endif
|
#endif
|
||||||
|
logf("pcmbuf len: %ld", seconds);
|
||||||
|
return seconds * (NATIVE_FREQUENCY*4); /* 2 channels + 2 bytes/sample */
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *pcmbuf_calc_audiobuffer_ptr(size_t bufsize)
|
static char *pcmbuf_calc_audiobuffer_ptr(size_t bufsize)
|
||||||
|
@ -817,8 +832,7 @@ static bool prepare_insert(size_t length)
|
||||||
if (low_latency_mode)
|
if (low_latency_mode)
|
||||||
{
|
{
|
||||||
/* 1/4s latency. */
|
/* 1/4s latency. */
|
||||||
if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 2
|
if (!LOW_DATA(1) && pcm_is_playing())
|
||||||
&& pcm_is_playing())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,11 +844,11 @@ static bool prepare_insert(size_t length)
|
||||||
{
|
{
|
||||||
trigger_cpu_boost();
|
trigger_cpu_boost();
|
||||||
|
|
||||||
/* Pre-buffer 1s. */
|
/* Pre-buffer up to watermark */
|
||||||
#if MEM <= 1
|
#if MEMORYSIZE > 2
|
||||||
if (!LOW_DATA(1))
|
|
||||||
#else
|
|
||||||
if (!LOW_DATA(4))
|
if (!LOW_DATA(4))
|
||||||
|
#else
|
||||||
|
if (pcmbuf_unplayed_bytes > pcmbuf_watermark)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
logf("pcm starting");
|
logf("pcm starting");
|
||||||
|
@ -842,8 +856,8 @@ static bool prepare_insert(size_t length)
|
||||||
pcmbuf_play_start();
|
pcmbuf_play_start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pcmbuf_unplayed_bytes <= pcmbuf_watermark)
|
else
|
||||||
pcmbuf_under_watermark();
|
pcmbuf_under_watermark(pcmbuf_unplayed_bytes <= pcmbuf_watermark);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1119,11 +1133,8 @@ void pcmbuf_write_voice_complete(int count)
|
||||||
|
|
||||||
void pcmbuf_crossfade_enable(bool on_off)
|
void pcmbuf_crossfade_enable(bool on_off)
|
||||||
{
|
{
|
||||||
#if MEM > 1
|
|
||||||
/* Next setting to be used, not applied now */
|
/* Next setting to be used, not applied now */
|
||||||
crossfade_enabled_pending = on_off;
|
crossfade_enabled_pending = on_off;
|
||||||
#endif
|
|
||||||
(void)on_off;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcmbuf_crossfade_enable_finished(void)
|
void pcmbuf_crossfade_enable_finished(void)
|
||||||
|
|
|
@ -21,18 +21,12 @@
|
||||||
#ifndef PCMBUF_H
|
#ifndef PCMBUF_H
|
||||||
#define PCMBUF_H
|
#define PCMBUF_H
|
||||||
|
|
||||||
#if MEM > 1
|
|
||||||
#define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks
|
#define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks
|
||||||
on the pcm buffer */
|
on the pcm buffer */
|
||||||
#define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of
|
#define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of
|
||||||
chunks on the pcm buffer (or we run out
|
chunks on the pcm buffer (or we run out
|
||||||
of buffer descriptors, which is
|
of buffer descriptors, which is
|
||||||
non-fatal) */
|
non-fatal) */
|
||||||
#else
|
|
||||||
#define PCMBUF_TARGET_CHUNK 16384
|
|
||||||
#define PCMBUF_MINAVG_CHUNK 12288
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PCMBUF_MIN_CHUNK 4096 /* We try to never feed a chunk smaller than
|
#define PCMBUF_MIN_CHUNK 4096 /* We try to never feed a chunk smaller than
|
||||||
this to the DMA */
|
this to the DMA */
|
||||||
#define PCMBUF_MIX_CHUNK 8192 /* This is the maximum size of one packet
|
#define PCMBUF_MIX_CHUNK 8192 /* This is the maximum size of one packet
|
||||||
|
|
|
@ -88,8 +88,6 @@
|
||||||
|
|
||||||
#define PLAYBACK_VOICE
|
#define PLAYBACK_VOICE
|
||||||
|
|
||||||
/* default point to start buffer refill */
|
|
||||||
#define AUDIO_DEFAULT_WATERMARK (1024*512)
|
|
||||||
/* amount of guess-space to allow for codecs that must hunt and peck
|
/* amount of guess-space to allow for codecs that must hunt and peck
|
||||||
* for their correct seeek target, 32k seems a good size */
|
* for their correct seeek target, 32k seems a good size */
|
||||||
#define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
|
#define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
|
||||||
|
@ -162,20 +160,12 @@ enum filling_state {
|
||||||
STATE_FINISHED, /* all remaining tracks are fully buffered */
|
STATE_FINISHED, /* all remaining tracks are fully buffered */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if MEM > 1
|
|
||||||
#define MAX_TRACK 128
|
#define MAX_TRACK 128
|
||||||
#else
|
|
||||||
#define MAX_TRACK 32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_TRACK_MASK (MAX_TRACK-1)
|
#define MAX_TRACK_MASK (MAX_TRACK-1)
|
||||||
|
|
||||||
/* As defined in plugins/lib/xxx2wav.h */
|
/* As defined in plugins/lib/xxx2wav.h */
|
||||||
#if MEM > 1
|
|
||||||
#define GUARD_BUFSIZE (32*1024)
|
#define GUARD_BUFSIZE (32*1024)
|
||||||
#else
|
|
||||||
#define GUARD_BUFSIZE (8*1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* As defined in plugin.lds */
|
/* As defined in plugin.lds */
|
||||||
#if defined(CPU_PP)
|
#if defined(CPU_PP)
|
||||||
|
@ -277,11 +267,13 @@ static bool track_load_started = false;
|
||||||
*/
|
*/
|
||||||
static bool codec_requested_stop = false;
|
static bool codec_requested_stop = false;
|
||||||
|
|
||||||
|
#ifdef HAVE_DISK_STORAGE
|
||||||
static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */
|
static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Multiple threads */
|
/* Multiple threads */
|
||||||
/* Set the watermark to trigger buffer fill (A/C) FIXME */
|
/* Set the watermark to trigger buffer fill (A/C) */
|
||||||
static void set_filebuf_watermark(int seconds, size_t max);
|
static void set_filebuf_watermark(void);
|
||||||
|
|
||||||
/* Audio thread */
|
/* Audio thread */
|
||||||
static struct event_queue audio_queue SHAREDBSS_ATTR;
|
static struct event_queue audio_queue SHAREDBSS_ATTR;
|
||||||
|
@ -797,7 +789,7 @@ void audio_set_buffer_margin(int setting)
|
||||||
static const int lookup[] = {5, 15, 30, 60, 120, 180, 300, 600};
|
static const int lookup[] = {5, 15, 30, 60, 120, 180, 300, 600};
|
||||||
buffer_margin = lookup[setting];
|
buffer_margin = lookup[setting];
|
||||||
logf("buffer margin: %ld", (long)buffer_margin);
|
logf("buffer margin: %ld", (long)buffer_margin);
|
||||||
set_filebuf_watermark(buffer_margin, 0);
|
set_filebuf_watermark();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -843,16 +835,35 @@ void audio_set_crossfade(int enable)
|
||||||
|
|
||||||
/* --- Routines called from multiple threads --- */
|
/* --- Routines called from multiple threads --- */
|
||||||
|
|
||||||
static void set_filebuf_watermark(int seconds, size_t max)
|
static void set_filebuf_watermark(void)
|
||||||
{
|
{
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
return; /* Audio buffers not yet set up */
|
return; /* Audio buffers not yet set up */
|
||||||
|
|
||||||
bytes = seconds?MAX(curtrack_id3.bitrate * seconds * (1000/8), max):max;
|
#ifdef HAVE_FLASH_STORAGE
|
||||||
bytes = MIN(bytes, filebuflen / 2);
|
int seconds = 1;
|
||||||
|
#else
|
||||||
|
int seconds;
|
||||||
|
int spinup = ata_spinup_time();
|
||||||
|
if (spinup)
|
||||||
|
seconds = (spinup / HZ) + 1;
|
||||||
|
else
|
||||||
|
seconds = 3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bitrate of last track in buffer dictates watermark */
|
||||||
|
struct mp3entry* id3 = NULL;
|
||||||
|
if (tracks[track_widx].taginfo_ready)
|
||||||
|
id3 = bufgetid3(tracks[track_widx].id3_hid);
|
||||||
|
else
|
||||||
|
id3 = bufgetid3(tracks[track_widx-1].id3_hid);
|
||||||
|
if (!id3) {
|
||||||
|
logf("fwmark: No id3 for last track (r%d/w%d), aborting!", track_ridx, track_widx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t bytes = id3->bitrate * (1000/8) * seconds;
|
||||||
buf_set_watermark(bytes);
|
buf_set_watermark(bytes);
|
||||||
|
logf("fwmark: %d", bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_codec_filename(int cod_spec)
|
const char *get_codec_filename(int cod_spec)
|
||||||
|
@ -1106,10 +1117,6 @@ static bool codec_seek_buffer_callback(size_t newpos)
|
||||||
static void codec_configure_callback(int setting, intptr_t value)
|
static void codec_configure_callback(int setting, intptr_t value)
|
||||||
{
|
{
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case CODEC_SET_FILEBUF_WATERMARK:
|
|
||||||
set_filebuf_watermark(buffer_margin, value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!dsp_configure(ci.dsp, setting, value))
|
if (!dsp_configure(ci.dsp, setting, value))
|
||||||
{ logf("Illegal key:%d", setting); }
|
{ logf("Illegal key:%d", setting); }
|
||||||
|
@ -1709,7 +1716,7 @@ static bool audio_load_track(size_t offset, bool start_play)
|
||||||
/* Set default values */
|
/* Set default values */
|
||||||
if (start_play)
|
if (start_play)
|
||||||
{
|
{
|
||||||
buf_set_watermark(AUDIO_DEFAULT_WATERMARK);
|
buf_set_watermark(filebuflen/2);
|
||||||
dsp_configure(ci.dsp, DSP_RESET, 0);
|
dsp_configure(ci.dsp, DSP_RESET, 0);
|
||||||
track_changed = true;
|
track_changed = true;
|
||||||
playlist_update_resume_info(audio_current_track());
|
playlist_update_resume_info(audio_current_track());
|
||||||
|
@ -2223,10 +2230,6 @@ static void audio_play_start(size_t offset)
|
||||||
/* Officially playing */
|
/* Officially playing */
|
||||||
queue_reply(&audio_queue, 1);
|
queue_reply(&audio_queue, 1);
|
||||||
|
|
||||||
#ifdef HAVE_DISK_STORAGE
|
|
||||||
set_filebuf_watermark(buffer_margin, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
audio_fill_file_buffer(true, offset);
|
audio_fill_file_buffer(true, offset);
|
||||||
|
|
||||||
add_event(BUFFER_EVENT_BUFFER_LOW, false, buffering_low_buffer_callback);
|
add_event(BUFFER_EVENT_BUFFER_LOW, false, buffering_low_buffer_callback);
|
||||||
|
@ -2358,11 +2361,13 @@ static void audio_reset_buffer(void)
|
||||||
|
|
||||||
/* Subtract whatever the pcm buffer says it used plus the guard buffer */
|
/* Subtract whatever the pcm buffer says it used plus the guard buffer */
|
||||||
const size_t pcmbuf_size = pcmbuf_init(filebuf + filebuflen) +GUARD_BUFSIZE;
|
const size_t pcmbuf_size = pcmbuf_init(filebuf + filebuflen) +GUARD_BUFSIZE;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if(pcmbuf_size > filebuflen)
|
if(pcmbuf_size > filebuflen)
|
||||||
panicf("Not enough memory for pcmbuf_init() : %d > %d",
|
panicf("Not enough memory for pcmbuf_init() : %d > %d",
|
||||||
(int)pcmbuf_size, (int)filebuflen);
|
(int)pcmbuf_size, (int)filebuflen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
filebuflen -= pcmbuf_size;
|
filebuflen -= pcmbuf_size;
|
||||||
|
|
||||||
/* Make sure filebuflen is a longword multiple after adjustment - filebuf
|
/* Make sure filebuflen is a longword multiple after adjustment - filebuf
|
||||||
|
@ -2414,6 +2419,7 @@ static void audio_thread(void)
|
||||||
case Q_AUDIO_FILL_BUFFER:
|
case Q_AUDIO_FILL_BUFFER:
|
||||||
LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER %d", (int)ev.data);
|
LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER %d", (int)ev.data);
|
||||||
audio_fill_file_buffer((bool)ev.data, 0);
|
audio_fill_file_buffer((bool)ev.data, 0);
|
||||||
|
set_filebuf_watermark();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_AUDIO_FINISH_LOAD:
|
case Q_AUDIO_FINISH_LOAD:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue