1
0
Fork 0
forked from len0rd/rockbox

At last, really short load times

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1385 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Linus Nielsen Feltzing 2002-07-18 21:02:55 +00:00
parent f952ba7548
commit 4e46ac78ae

View file

@ -34,13 +34,12 @@
#include "file.h"
#endif
#define MPEG_CHUNKSIZE 0x20000
#ifdef ARCHOS_RECORDER
/* recorder is slower and needs more load time */
#define MPEG_LOW_WATER 0x40000
#else
#define MPEG_FIRST_CHUNKSIZE 0x20000
#define MPEG_CHUNKSIZE 0x180000
#define MPEG_FIRST_SWAP_CHUNKSIZE 0x20000
#define MPEG_SWAP_CHUNKSIZE 0x8000
#define MPEG_HIGHWATER 0x10000
#define MPEG_LOW_WATER 0x30000
#endif
#define MPEG_PLAY 1
#define MPEG_STOP 2
@ -49,6 +48,7 @@
#define MPEG_NEXT 5
#define MPEG_PREV 6
#define MPEG_NEED_DATA 100
#define MPEG_SWAP_DATA 101
extern char* peek_next_track(int type);
extern char* peek_prev_track(int type);
@ -274,6 +274,7 @@ extern unsigned char mp3end[];
static int mp3buflen;
static int mp3buf_write;
static int mp3buf_swapwrite;
static int mp3buf_read;
static int last_dma_chunk_size;
@ -379,6 +380,7 @@ static void reset_mp3_buffer(void)
{
mp3buf_read = 0;
mp3buf_write = 0;
mp3buf_swapwrite = 0;
}
#pragma interrupt
@ -497,6 +499,7 @@ static void mpeg_thread(void)
int len;
int free_space_left;
int amount_to_read;
int amount_to_swap;
play_pending = false;
playing = false;
@ -505,6 +508,7 @@ static void mpeg_thread(void)
while(1)
{
DEBUGF("S\n");
yield();
queue_wait(&mpeg_queue, &ev);
switch(ev.id)
{
@ -614,49 +618,36 @@ static void mpeg_thread(void)
}
break;
case MPEG_NEED_DATA:
free_space_left = mp3buf_read - mp3buf_write;
case MPEG_SWAP_DATA:
free_space_left = mp3buf_write - mp3buf_swapwrite;
/* We interpret 0 as "empty buffer" */
if(free_space_left <= 0)
if(free_space_left == 0)
break;
if(free_space_left < 0)
free_space_left = mp3buflen + free_space_left;
/* do we have any more buffer space to fill? */
if(free_space_left <= MPEG_CHUNKSIZE)
if(play_pending)
amount_to_swap = MIN(MPEG_FIRST_SWAP_CHUNKSIZE,
free_space_left);
else
amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
amount_to_swap);
DEBUGF("B %x\n", amount_to_swap);
bitswap((unsigned short *)(mp3buf + mp3buf_swapwrite),
(amount_to_swap+1)/2);
mp3buf_swapwrite += amount_to_swap;
if(mp3buf_swapwrite >= mp3buflen)
{
DEBUGF("0\n");
filling = false;
ata_sleep();
break;
mp3buf_swapwrite = 0;
DEBUGF("BW\n");
}
amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
/* Read in a few seconds worth of MP3 data. We don't want to
read too large chunks because the bitswapping will take
too much time. We must keep the DMA happy and also give
the other threads a chance to run. */
if(mpeg_file >= 0)
{
DEBUGF("R\n");
len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
if(len > 0)
{
DEBUGF("B\n");
bitswap((unsigned short *)(mp3buf + mp3buf_write),
(len+1)/2);
mp3buf_write += len;
if(mp3buf_write >= mp3buflen)
{
mp3buf_write = 0;
DEBUGF("W\n");
}
/* Tell ourselves that we want more data */
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
/* Tell ourselves that we must swap more data */
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
/* And while we're at it, see if we have started
playing yet. If not, do it. */
@ -669,6 +660,59 @@ static void mpeg_thread(void)
init_dma();
start_dma();
}
break;
case MPEG_NEED_DATA:
free_space_left = mp3buf_read - mp3buf_write;
/* We interpret 0 as "empty buffer" */
if(free_space_left <= 0)
free_space_left = mp3buflen + free_space_left;
/* Make sure that we don't fill the entire buffer */
free_space_left -= 2;
/* do we have any more buffer space to fill? */
if(free_space_left <= MPEG_HIGHWATER)
{
DEBUGF("0\n");
filling = false;
ata_sleep();
break;
}
if(play_pending)
{
amount_to_read = MIN(MPEG_FIRST_CHUNKSIZE, free_space_left);
}
else
{
amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
}
amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
/* Read in a few seconds worth of MP3 data. We don't want to
read too large chunks because the bitswapping will take
too much time. We must keep the DMA happy and also give
the other threads a chance to run. */
if(mpeg_file >= 0)
{
DEBUGF("R\n");
len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
if(len > 0)
{
/* Tell ourselves that we need to swap some data */
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
mp3buf_write += len;
if(mp3buf_write >= mp3buflen)
{
mp3buf_write = 0;
DEBUGF("W\n");
}
/* Tell ourselves that we want more data */
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
}
else
{
@ -696,7 +740,6 @@ static void mpeg_thread(void)
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
}
}
yield(); /* To be safe */
}
break;