From 6427d127aaedcf7f68f7ad7438c5ffb284b8c9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Sat, 10 Jan 2009 21:10:56 +0000 Subject: [PATCH] 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 --- apps/buffering.c | 25 ++------- apps/codecs/aac.c | 2 - apps/codecs/aiff.c | 1 - apps/codecs/alac.c | 2 - apps/codecs/ape.c | 2 - apps/codecs/asap.c | 3 -- apps/codecs/demac/libdemac/decoder.h | 2 +- apps/codecs/demac/libdemac/demac.h | 2 +- apps/codecs/demac/libdemac/filter_1280_15.c | 2 +- apps/codecs/demac/libdemac/filter_16_11.c | 2 +- apps/codecs/demac/libdemac/filter_256_13.c | 2 +- apps/codecs/demac/libdemac/filter_32_10.c | 2 +- apps/codecs/demac/libdemac/filter_64_11.c | 2 +- apps/codecs/demac/wavwrite.h | 2 +- apps/codecs/flac.c | 2 - apps/codecs/mod.c | 3 -- apps/codecs/shorten.c | 2 - apps/codecs/sid.c | 3 -- apps/codecs/spc.c | 2 - apps/codecs/wav.c | 1 - apps/codecs/wavpack.c | 2 - apps/codecs/wma.c | 2 - apps/debug_menu.c | 10 ++-- apps/dsp.h | 3 +- apps/pcmbuf.c | 59 +++++++++++--------- apps/pcmbuf.h | 6 --- apps/playback.c | 60 +++++++++++---------- 27 files changed, 85 insertions(+), 121 deletions(-) diff --git a/apps/buffering.c b/apps/buffering.c index 1e643c5771..d715456efb 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -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("wmarkconfigure(CODEC_SET_FILEBUF_WATERMARK, 1024*512); - ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); ci->configure(DSP_SET_SAMPLE_DEPTH, 29); diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c index 53593fcaa8..9a675415e2 100644 --- a/apps/codecs/aiff.c +++ b/apps/codecs/aiff.c @@ -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()) { diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c index 367be14824..fdc6748a95 100644 --- a/apps/codecs/alac.c +++ b/apps/codecs/alac.c @@ -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); diff --git a/apps/codecs/ape.c b/apps/codecs/ape.c index dbe6e0fc9e..6c829c3863 100644 --- a/apps/codecs/ape.c +++ b/apps/codecs/ape.c @@ -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: diff --git a/apps/codecs/asap.c b/apps/codecs/asap.c index 9e2228bf84..bb627ad06c 100644 --- a/apps/codecs/asap.c +++ b/apps/codecs/asap.c @@ -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"); diff --git a/apps/codecs/demac/libdemac/decoder.h b/apps/codecs/demac/libdemac/decoder.h index 0c3bd15b37..aeac569509 100644 --- a/apps/codecs/demac/libdemac/decoder.h +++ b/apps/codecs/demac/libdemac/decoder.h @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/demac.h b/apps/codecs/demac/libdemac/demac.h index d1bb361574..696b2aba73 100644 --- a/apps/codecs/demac/libdemac/demac.h +++ b/apps/codecs/demac/libdemac/demac.h @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/filter_1280_15.c b/apps/codecs/demac/libdemac/filter_1280_15.c index edf1ce1bb1..7077e0ee8e 100644 --- a/apps/codecs/demac/libdemac/filter_1280_15.c +++ b/apps/codecs/demac/libdemac/filter_1280_15.c @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/filter_16_11.c b/apps/codecs/demac/libdemac/filter_16_11.c index 07e4b96dc2..94c56e247f 100644 --- a/apps/codecs/demac/libdemac/filter_16_11.c +++ b/apps/codecs/demac/libdemac/filter_16_11.c @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/filter_256_13.c b/apps/codecs/demac/libdemac/filter_256_13.c index 370dec1d5a..69cf638903 100644 --- a/apps/codecs/demac/libdemac/filter_256_13.c +++ b/apps/codecs/demac/libdemac/filter_256_13.c @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/filter_32_10.c b/apps/codecs/demac/libdemac/filter_32_10.c index b585de98a4..5ec85089db 100644 --- a/apps/codecs/demac/libdemac/filter_32_10.c +++ b/apps/codecs/demac/libdemac/filter_32_10.c @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/libdemac/filter_64_11.c b/apps/codecs/demac/libdemac/filter_64_11.c index 8b8d326d1d..cd74fa5f6b 100644 --- a/apps/codecs/demac/libdemac/filter_64_11.c +++ b/apps/codecs/demac/libdemac/filter_64_11.c @@ -2,7 +2,7 @@ libdemac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/demac/wavwrite.h b/apps/codecs/demac/wavwrite.h index eba8ac7e31..a124353229 100644 --- a/apps/codecs/demac/wavwrite.h +++ b/apps/codecs/demac/wavwrite.h @@ -2,7 +2,7 @@ demac - A Monkey's Audio decoder -$Id:$ +$Id$ Copyright (C) Dave Chapman 2007 diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c index 3a23d0b951..00d2c16993 100644 --- a/apps/codecs/flac.c +++ b/apps/codecs/flac.c @@ -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: diff --git a/apps/codecs/mod.c b/apps/codecs/mod.c index 91b5955b40..523e1c7d0b 100644 --- a/apps/codecs/mod.c +++ b/apps/codecs/mod.c @@ -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; diff --git a/apps/codecs/shorten.c b/apps/codecs/shorten.c index 4e00b9a579..9b5c2e2f17 100644 --- a/apps/codecs/shorten.c +++ b/apps/codecs/shorten.c @@ -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); diff --git a/apps/codecs/sid.c b/apps/codecs/sid.c index 087ad754fb..c00aa22142 100644 --- a/apps/codecs/sid.c +++ b/apps/codecs/sid.c @@ -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; diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 14d28dfca8..5ac594431a 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c @@ -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); diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index 4657891595..b3efbc10ce 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c @@ -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()) { diff --git a/apps/codecs/wavpack.c b/apps/codecs/wavpack.c index c93e2e0dcd..c85c254580 100644 --- a/apps/codecs/wavpack.c +++ b/apps/codecs/wavpack.c @@ -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: diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c index 93f4e27136..b5dfa4cb00 100644 --- a/apps/codecs/wma.c +++ b/apps/codecs/wma.c @@ -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: diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 7567c64a21..10d69b018c 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -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); } diff --git a/apps/dsp.h b/apps/dsp.h index 1746a5cccc..c3239360b0 100644 --- a/apps/dsp.h +++ b/apps/dsp.h @@ -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, diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 095b5209eb..c8ed91e21a 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c @@ -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,13 +283,21 @@ 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. */ - boost_codec_thread(LOW_DATA(2) && pcm_is_playing()); + /* If buffer is critically low, override UI priority, else + set back to the original priority. */ + boost_codec_thread(LOW_DATA(2) && pcm_is_playing()); #endif - /* Fill audio buffer by boosting cpu */ - trigger_cpu_boost(); + /* Fill audio buffer by boosting cpu */ + trigger_cpu_boost(); + } + else + { + boost_codec_thread(false); + cancel_cpu_boost(); + } } /* Disable crossfade if < .5s of audio */ @@ -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) diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h index 8c448884f9..b4e551f74d 100644 --- a/apps/pcmbuf.h +++ b/apps/pcmbuf.h @@ -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 diff --git a/apps/playback.c b/apps/playback.c index e81b32dbf9..c98455ccb0 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -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: