summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-12-05 12:18:22 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-12-05 12:18:22 +0000
commit2df262c23d0aab2bbaa221190e05824fc06d0810 (patch)
tree731f26c75e9d54f1496ae26dae402ac34cd332f3
parent8344437de0064c69c06fb3c4948fd92a28aeb3b7 (diff)
downloadrockbox-2df262c23d0aab2bbaa221190e05824fc06d0810.zip
rockbox-2df262c23d0aab2bbaa221190e05824fc06d0810.tar.gz
rockbox-2df262c23d0aab2bbaa221190e05824fc06d0810.tar.bz2
rockbox-2df262c23d0aab2bbaa221190e05824fc06d0810.tar.xz
The low watermark level is now dynamically calculated
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2937 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/mpeg.c41
-rw-r--r--firmware/mpeg.h3
2 files changed, 37 insertions, 7 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 6aad963..e2a2a38 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -207,6 +207,7 @@ static unsigned int last_track_counter = 0;
#ifndef SIMULATOR
static bool mpeg_is_initialized = false;
+
static int tag_read_idx = 0;
static int tag_write_idx = 0;
@@ -468,6 +469,7 @@ static bool is_playing; /* We are (attempting to) playing MP3 files */
static bool filling; /* We are filling the buffer with data from disk */
static bool dma_underrun; /* True when the DMA has stopped because of
slow disk reading (read error, shaking) */
+static int low_watermark; /* Dynamic low watermark level */
static int lowest_watermark_level; /* Debug value to observe the buffer
usage */
#ifdef HAVE_MAS3587F
@@ -486,6 +488,18 @@ static bool init_recording_done;
static bool init_playback_done;
#endif
+static void recalculate_watermark(int bitrate)
+{
+ if(ata_spinup_time)
+ {
+ low_watermark = ata_spinup_time * 3 / HZ * bitrate*1000 / 8;
+ }
+ else
+ {
+ low_watermark = MPEG_LOW_WATER;
+ }
+}
+
void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
{
dbgdata->mp3buflen = mp3buflen;
@@ -505,6 +519,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
dbgdata->unplayed_space = get_unplayed_space();
dbgdata->unswapped_space = get_unswapped_space();
+ dbgdata->low_watermark_level = low_watermark;
dbgdata->lowest_watermark_level = lowest_watermark_level;
}
@@ -768,7 +783,7 @@ static void dma_tick(void)
if(num_bytes < 0)
num_bytes += mp3buflen;
- if(mp3buflen - num_bytes < MPEG_LOW_WATER && !saving)
+ if(mp3buflen - num_bytes < low_watermark && !saving)
queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
}
}
@@ -810,7 +825,7 @@ void DEI3(void)
space_until_end_of_buffer = mp3buflen - mp3buf_read;
- if(!filling && unplayed_space_left < MPEG_LOW_WATER)
+ if(!filling && unplayed_space_left < low_watermark)
{
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
@@ -1067,13 +1082,19 @@ void hexdump(unsigned char *buf, int len)
static void start_playback_if_ready(void)
{
+ int playable_space;
+
+ playable_space = mp3buf_swapwrite - mp3buf_read;
+ if(playable_space < 0)
+ playable_space += mp3buflen;
+
/* See if we have started playing yet. If not, do it. */
if(play_pending || dma_underrun)
{
/* If the filling has stopped, and we still haven't reached
the watermark, the file must be smaller than the
watermark. We must still play it. */
- if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) ||
+ if((playable_space >= low_watermark) ||
!filling || dma_underrun)
{
DEBUGF("P\n");
@@ -1278,7 +1299,7 @@ static void mpeg_thread(void)
unswapped_space_left = get_unswapped_space();
/* should we start reading more data? */
- if(!filling && (unplayed_space_left < MPEG_LOW_WATER)) {
+ if(!filling && (unplayed_space_left < low_watermark)) {
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
play_pending = true;
@@ -1464,7 +1485,7 @@ static void mpeg_thread(void)
unplayed_space_left = get_unplayed_space();
unswapped_space_left = get_unswapped_space();
- if (mpeg_file>=0 && unplayed_space_left < MPEG_LOW_WATER)
+ if (mpeg_file>=0 && unplayed_space_left < low_watermark)
{
/* We need to load more data before starting */
filling = true;
@@ -1579,7 +1600,7 @@ static void mpeg_thread(void)
}
/* Read small chunks while we are below the low water mark */
- if(unplayed_space_left < MPEG_LOW_WATER)
+ if(unplayed_space_left < low_watermark)
amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
free_space_left);
else
@@ -1595,6 +1616,12 @@ static void mpeg_thread(void)
t1 = current_tick;
len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
+ if(id3tags[tag_read_idx]->id3.vbr)
+ recalculate_watermark(320);
+ else
+ recalculate_watermark(
+ id3tags[tag_read_idx]->id3.bitrate);
+
if(len > 0)
{
t2 = current_tick;
@@ -2794,6 +2821,8 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness, int
dbg_timer_start();
dbg_cnt2us(0);
#endif
+
+ recalculate_watermark(320); /* Maximum bitrate for safety's sake */
}
/* -----------------------------------------------------------------
diff --git a/firmware/mpeg.h b/firmware/mpeg.h
index cba5299..3e81349 100644
--- a/firmware/mpeg.h
+++ b/firmware/mpeg.h
@@ -25,7 +25,7 @@
#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
wouldn't be able to see the difference between
an empty buffer and a full one. */
-#define MPEG_LOW_WATER 0x40000
+#define MPEG_LOW_WATER 0x60000
#define MPEG_LOW_WATER_CHUNKSIZE 0x40000
struct mpeg_debug
@@ -47,6 +47,7 @@ struct mpeg_debug
int unplayed_space;
int unswapped_space;
+ int low_watermark_level;
int lowest_watermark_level;
};