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"
|
||||
#endif
|
||||
|
||||
#if MEM > 1
|
||||
#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*/
|
||||
|
@ -88,11 +84,9 @@
|
|||
#endif
|
||||
|
||||
/* 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 */
|
||||
#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
|
||||
|
||||
|
@ -173,7 +167,6 @@ enum {
|
|||
Q_BASE_HANDLE, /* Set the reference handle for buf_useful_data */
|
||||
|
||||
/* Configuration: */
|
||||
Q_SET_WATERMARK,
|
||||
Q_START_FILL, /* Request that the buffering thread initiate a buffer
|
||||
fill at its earliest convenience */
|
||||
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)
|
||||
{
|
||||
update_data_counters();
|
||||
return data_counters.useful < BUFFERING_CRITICAL_LEVEL;
|
||||
return data_counters.useful < (conf_watermark / 2);
|
||||
}
|
||||
|
||||
/* Buffer data for the given handle.
|
||||
|
@ -1313,8 +1306,7 @@ size_t buf_used(void)
|
|||
|
||||
void buf_set_watermark(size_t bytes)
|
||||
{
|
||||
LOGFQUEUE("buffering > Q_SET_WATERMARK %ld", (long)bytes);
|
||||
queue_post(&buffering_queue, Q_SET_WATERMARK, bytes);
|
||||
conf_watermark = bytes;
|
||||
}
|
||||
|
||||
static void shrink_buffer_inner(struct memory_handle *h)
|
||||
|
@ -1386,17 +1378,6 @@ void buffering_thread(void)
|
|||
base_handle_id = (int)ev.data;
|
||||
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
|
||||
case SYS_USB_CONNECTED:
|
||||
LOGFQUEUE("buffering < SYS_USB_CONNECTED");
|
||||
|
|
|
@ -55,8 +55,6 @@ enum codec_status codec_main(void)
|
|||
unsigned char c = 0;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ enum codec_status codec_main(void)
|
|||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
next_track:
|
||||
if (codec_init()) {
|
||||
|
|
|
@ -44,8 +44,6 @@ enum codec_status codec_main(void)
|
|||
int retval;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
|
||||
|
||||
|
|
|
@ -147,8 +147,6 @@ enum codec_status codec_main(void)
|
|||
size_t resume_offset;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
|
||||
|
||||
next_track:
|
||||
|
|
|
@ -38,9 +38,6 @@ enum codec_status codec_main(void)
|
|||
char* module;
|
||||
int bytesPerSample =2;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
next_track:
|
||||
if (codec_init()) {
|
||||
DEBUGF("codec init failed\n");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
demac - A Monkey's Audio decoder
|
||||
|
||||
$Id:$
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
|
|
|
@ -423,8 +423,6 @@ enum codec_status codec_main(void)
|
|||
int retval;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, FLAC_OUTPUT_DEPTH-1);
|
||||
|
||||
next_track:
|
||||
|
|
|
@ -1229,9 +1229,6 @@ enum codec_status codec_main(void)
|
|||
|
||||
int bytesdone;
|
||||
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
|
||||
next_track:
|
||||
if (codec_init()) {
|
||||
return CODEC_ERROR;
|
||||
|
|
|
@ -47,8 +47,6 @@ enum codec_status codec_main(void)
|
|||
size_t bytesleft;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
|
||||
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 nSamplesToRender = 0;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
next_track:
|
||||
if (codec_init()) {
|
||||
return CODEC_ERROR;
|
||||
|
|
|
@ -559,8 +559,6 @@ enum codec_status codec_main(void)
|
|||
|
||||
/* Read the entire file */
|
||||
DEBUGF("SPC: request initial buffer\n");
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, ci->filesize);
|
||||
|
||||
ci->seek_buffer(0);
|
||||
size_t buffersize;
|
||||
uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize);
|
||||
|
|
|
@ -228,7 +228,6 @@ enum codec_status codec_main(void)
|
|||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
next_track:
|
||||
if (codec_init()) {
|
||||
|
|
|
@ -44,8 +44,6 @@ enum codec_status codec_main(void)
|
|||
int retval;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
|
||||
|
||||
next_track:
|
||||
|
|
|
@ -468,8 +468,6 @@ enum codec_status codec_main(void)
|
|||
int errcount = 0;
|
||||
|
||||
/* Generic codec initialisation */
|
||||
ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
|
||||
|
||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
|
||||
|
||||
next_track:
|
||||
|
|
|
@ -329,14 +329,14 @@ static bool dbg_buffering_thread(void)
|
|||
|
||||
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);
|
||||
|
||||
gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
|
||||
bufsize, 0, bufused, HORIZONTAL);
|
||||
line++;
|
||||
|
||||
snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
|
||||
snprintf(buf, sizeof(buf), "alloc: %6ld/%ld", audio_filebufused(),
|
||||
(long) filebuflen);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
@ -345,7 +345,7 @@ static bool dbg_buffering_thread(void)
|
|||
filebuflen, 0, audio_filebufused(), HORIZONTAL);
|
||||
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);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
@ -354,7 +354,7 @@ static bool dbg_buffering_thread(void)
|
|||
line++;
|
||||
#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);
|
||||
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 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);
|
||||
lcd_puts(0, line++, buf);
|
||||
}
|
||||
|
|
|
@ -42,8 +42,7 @@ enum
|
|||
|
||||
enum
|
||||
{
|
||||
CODEC_SET_FILEBUF_WATERMARK = 1,
|
||||
DSP_MYDSP,
|
||||
DSP_MYDSP = 1,
|
||||
DSP_SET_FREQUENCY,
|
||||
DSP_SWITCH_FREQUENCY,
|
||||
DSP_SET_SAMPLE_DEPTH,
|
||||
|
|
|
@ -48,8 +48,12 @@ static inline int32_t clip_sample_16(int32_t sample)
|
|||
return sample;
|
||||
}
|
||||
|
||||
#if MEMORYSIZE > 2
|
||||
/* Keep watermark high for iPods at least (2s) */
|
||||
#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
|
||||
* by the driver code. */
|
||||
|
@ -125,7 +129,7 @@ extern unsigned int codec_thread_id;
|
|||
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
||||
|
||||
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);
|
||||
|
||||
#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) ?
|
||||
/* If crossfading, try to keep the buffer full other than 1 second */
|
||||
(pcmbuf_size - (NATIVE_FREQUENCY * 4 * 1)) :
|
||||
/* Otherwise, just keep it above 2 second */
|
||||
/* Otherwise, just use the default */
|
||||
PCMBUF_WATERMARK;
|
||||
}
|
||||
|
||||
|
@ -271,7 +275,7 @@ static void boost_codec_thread(bool boost)
|
|||
}
|
||||
#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
|
||||
a clip */
|
||||
|
@ -279,6 +283,8 @@ static void pcmbuf_under_watermark(void)
|
|||
if (thread_get_current() == codec_thread_id)
|
||||
#endif /* SIMULATOR */
|
||||
{
|
||||
if (under)
|
||||
{
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
/* If buffer is critically low, override UI priority, else
|
||||
set back to the original priority. */
|
||||
|
@ -287,6 +293,12 @@ static void pcmbuf_under_watermark(void)
|
|||
/* Fill audio buffer by boosting cpu */
|
||||
trigger_cpu_boost();
|
||||
}
|
||||
else
|
||||
{
|
||||
boost_codec_thread(false);
|
||||
cancel_cpu_boost();
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable crossfade if < .5s of audio */
|
||||
if (LOW_DATA(2))
|
||||
|
@ -318,8 +330,13 @@ bool pcmbuf_is_lowdata(void)
|
|||
crossfade_init || crossfade_active)
|
||||
return false;
|
||||
|
||||
#if MEMORYSIZE > 2
|
||||
/* 1 seconds of buffer is low data */
|
||||
return LOW_DATA(4);
|
||||
#else
|
||||
/* under watermark is low data */
|
||||
return (pcmbuf_unplayed_bytes < pcmbuf_watermark);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
#if MEM > 1
|
||||
size_t seconds = 1;
|
||||
|
||||
if (crossfade_enabled_pending)
|
||||
seconds += global_settings.crossfade_fade_out_delay
|
||||
+ global_settings.crossfade_fade_out_duration;
|
||||
|
||||
#if MEMORYSIZE > 2
|
||||
/* Buffer has to be at least 2s long. */
|
||||
seconds += 2;
|
||||
logf("pcmbuf len: %ld", seconds);
|
||||
return seconds * (NATIVE_FREQUENCY*4);
|
||||
#else
|
||||
return NATIVE_FREQUENCY*2;
|
||||
#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)
|
||||
|
@ -817,8 +832,7 @@ static bool prepare_insert(size_t length)
|
|||
if (low_latency_mode)
|
||||
{
|
||||
/* 1/4s latency. */
|
||||
if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 2
|
||||
&& pcm_is_playing())
|
||||
if (!LOW_DATA(1) && pcm_is_playing())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -830,11 +844,11 @@ static bool prepare_insert(size_t length)
|
|||
{
|
||||
trigger_cpu_boost();
|
||||
|
||||
/* Pre-buffer 1s. */
|
||||
#if MEM <= 1
|
||||
if (!LOW_DATA(1))
|
||||
#else
|
||||
/* Pre-buffer up to watermark */
|
||||
#if MEMORYSIZE > 2
|
||||
if (!LOW_DATA(4))
|
||||
#else
|
||||
if (pcmbuf_unplayed_bytes > pcmbuf_watermark)
|
||||
#endif
|
||||
{
|
||||
logf("pcm starting");
|
||||
|
@ -842,8 +856,8 @@ static bool prepare_insert(size_t length)
|
|||
pcmbuf_play_start();
|
||||
}
|
||||
}
|
||||
else if (pcmbuf_unplayed_bytes <= pcmbuf_watermark)
|
||||
pcmbuf_under_watermark();
|
||||
else
|
||||
pcmbuf_under_watermark(pcmbuf_unplayed_bytes <= pcmbuf_watermark);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1119,11 +1133,8 @@ void pcmbuf_write_voice_complete(int count)
|
|||
|
||||
void pcmbuf_crossfade_enable(bool on_off)
|
||||
{
|
||||
#if MEM > 1
|
||||
/* Next setting to be used, not applied now */
|
||||
crossfade_enabled_pending = on_off;
|
||||
#endif
|
||||
(void)on_off;
|
||||
}
|
||||
|
||||
void pcmbuf_crossfade_enable_finished(void)
|
||||
|
|
|
@ -21,18 +21,12 @@
|
|||
#ifndef PCMBUF_H
|
||||
#define PCMBUF_H
|
||||
|
||||
#if MEM > 1
|
||||
#define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks
|
||||
on the pcm buffer */
|
||||
#define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of
|
||||
chunks on the pcm buffer (or we run out
|
||||
of buffer descriptors, which is
|
||||
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
|
||||
this to the DMA */
|
||||
#define PCMBUF_MIX_CHUNK 8192 /* This is the maximum size of one packet
|
||||
|
|
|
@ -88,8 +88,6 @@
|
|||
|
||||
#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
|
||||
* for their correct seeek target, 32k seems a good size */
|
||||
#define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
|
||||
|
@ -162,20 +160,12 @@ enum filling_state {
|
|||
STATE_FINISHED, /* all remaining tracks are fully buffered */
|
||||
};
|
||||
|
||||
#if MEM > 1
|
||||
#define MAX_TRACK 128
|
||||
#else
|
||||
#define MAX_TRACK 32
|
||||
#endif
|
||||
|
||||
#define MAX_TRACK_MASK (MAX_TRACK-1)
|
||||
|
||||
/* As defined in plugins/lib/xxx2wav.h */
|
||||
#if MEM > 1
|
||||
#define GUARD_BUFSIZE (32*1024)
|
||||
#else
|
||||
#define GUARD_BUFSIZE (8*1024)
|
||||
#endif
|
||||
|
||||
/* As defined in plugin.lds */
|
||||
#if defined(CPU_PP)
|
||||
|
@ -277,11 +267,13 @@ static bool track_load_started = 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-) */
|
||||
#endif
|
||||
|
||||
/* Multiple threads */
|
||||
/* Set the watermark to trigger buffer fill (A/C) FIXME */
|
||||
static void set_filebuf_watermark(int seconds, size_t max);
|
||||
/* Set the watermark to trigger buffer fill (A/C) */
|
||||
static void set_filebuf_watermark(void);
|
||||
|
||||
/* Audio thread */
|
||||
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};
|
||||
buffer_margin = lookup[setting];
|
||||
logf("buffer margin: %ld", (long)buffer_margin);
|
||||
set_filebuf_watermark(buffer_margin, 0);
|
||||
set_filebuf_watermark();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -843,16 +835,35 @@ void audio_set_crossfade(int enable)
|
|||
|
||||
/* --- 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)
|
||||
return; /* Audio buffers not yet set up */
|
||||
|
||||
bytes = seconds?MAX(curtrack_id3.bitrate * seconds * (1000/8), max):max;
|
||||
bytes = MIN(bytes, filebuflen / 2);
|
||||
#ifdef HAVE_FLASH_STORAGE
|
||||
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);
|
||||
logf("fwmark: %d", bytes);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (setting) {
|
||||
case CODEC_SET_FILEBUF_WATERMARK:
|
||||
set_filebuf_watermark(buffer_margin, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!dsp_configure(ci.dsp, setting, value))
|
||||
{ logf("Illegal key:%d", setting); }
|
||||
|
@ -1709,7 +1716,7 @@ static bool audio_load_track(size_t offset, bool start_play)
|
|||
/* Set default values */
|
||||
if (start_play)
|
||||
{
|
||||
buf_set_watermark(AUDIO_DEFAULT_WATERMARK);
|
||||
buf_set_watermark(filebuflen/2);
|
||||
dsp_configure(ci.dsp, DSP_RESET, 0);
|
||||
track_changed = true;
|
||||
playlist_update_resume_info(audio_current_track());
|
||||
|
@ -2223,10 +2230,6 @@ static void audio_play_start(size_t offset)
|
|||
/* Officially playing */
|
||||
queue_reply(&audio_queue, 1);
|
||||
|
||||
#ifdef HAVE_DISK_STORAGE
|
||||
set_filebuf_watermark(buffer_margin, 0);
|
||||
#endif
|
||||
|
||||
audio_fill_file_buffer(true, offset);
|
||||
|
||||
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 */
|
||||
const size_t pcmbuf_size = pcmbuf_init(filebuf + filebuflen) +GUARD_BUFSIZE;
|
||||
|
||||
#ifdef DEBUG
|
||||
if(pcmbuf_size > filebuflen)
|
||||
panicf("Not enough memory for pcmbuf_init() : %d > %d",
|
||||
(int)pcmbuf_size, (int)filebuflen);
|
||||
#endif
|
||||
|
||||
filebuflen -= pcmbuf_size;
|
||||
|
||||
/* Make sure filebuflen is a longword multiple after adjustment - filebuf
|
||||
|
@ -2414,6 +2419,7 @@ static void audio_thread(void)
|
|||
case Q_AUDIO_FILL_BUFFER:
|
||||
LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER %d", (int)ev.data);
|
||||
audio_fill_file_buffer((bool)ev.data, 0);
|
||||
set_filebuf_watermark();
|
||||
break;
|
||||
|
||||
case Q_AUDIO_FINISH_LOAD:
|
||||
|
|
Loading…
Reference in a new issue