1
0
Fork 0
forked from len0rd/rockbox

Hooked up the runtime database on archos.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7376 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2005-08-21 21:15:32 +00:00
parent c9caf9781b
commit dece414749
3 changed files with 132 additions and 17 deletions

View file

@ -43,7 +43,13 @@
#include "keyboard.h"
#include "database.h"
#include "autoconf.h"
#if CONFIG_HWCODEC == MASNONE
#include "playback.h"
#else
#include "mpeg.h"
#endif
#include "logf.h"
/* internal functions */
@ -328,9 +334,6 @@ void rundb_buffer_track(struct mp3entry *id, bool last_track) {
int rundb_init(void)
{
#if CONFIG_HWCODEC != MASNONE
return -1;
#else
unsigned char* ptr = (char*)&rundbheader.version;
#ifdef ROCKBOX_LITTLE_ENDIAN
int i, *p;
@ -376,17 +379,13 @@ int rundb_init(void)
}
rundb_initialized = 1;
/* hooks disabled for archos, rendering the runtime database not working,
* re enable when these callbacks are implemented in mpeg.c */
#if CONFIG_HWCODEC == MASNONE
audio_set_track_buffer_event(&rundb_buffer_track);
audio_set_track_changed_event(&rundb_track_change);
audio_set_track_unbuffer_event(&rundb_unbuffer_track);
logf("rundb inited.");
#endif
rundbsize=lseek(rundb_fd,0,SEEK_END);
return 0;
#endif
}
void rundb_shutdown(void)
@ -394,11 +393,9 @@ void rundb_shutdown(void)
if (rundb_fd >= 0)
close(rundb_fd);
rundb_initialized = 0;
#if CONFIG_HWCODEC == MASNONE
audio_set_track_buffer_event(NULL);
audio_set_track_unbuffer_event(NULL);
audio_set_track_changed_event(NULL);
#endif
}
void writerundbheader(void)

View file

@ -20,6 +20,7 @@
#define _MPEG_H_
#include <stdbool.h>
#include "id3.h"
#define MPEG_SWAP_CHUNKSIZE 0x2000
#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
@ -65,4 +66,10 @@ void rec_tick(void);
void playback_tick(void); /* FixMe: get rid of this, use mp3_get_playtime() */
void mpeg_id3_options(bool _v1first);
void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3));
void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
bool last_track));
void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
bool last_track));
#endif

View file

@ -84,6 +84,9 @@ extern int playlist_update_resume_info(const struct mp3entry* id3);
#define MPEG_SAVE_DATA 102
#define MPEG_STOP_DONE 103
/* indicator for MPEG_NEED_DATA */
#define GENERATE_UNBUFFER_EVENTS ((void*)1)
/* list of tracks in memory */
#define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
#define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
@ -93,6 +96,7 @@ struct trackdata
struct mp3entry id3;
int mempos;
int load_ahead_index;
bool event_sent;
};
static struct trackdata trackdata[MAX_TRACK_ENTRIES];
@ -105,6 +109,11 @@ static int track_read_idx = 0;
static int track_write_idx = 0;
#endif /* !SIMULATOR */
/* Callback function to call when current track has really changed. */
void (*track_changed_callback)(struct mp3entry *id3);
void (*track_buffer_callback)(struct mp3entry *id3, bool last_track);
void (*track_unbuffer_callback)(struct mp3entry *id3, bool last_track);
static const char mpeg_thread_name[] = "mpeg";
static unsigned int mpeg_errno;
@ -400,8 +409,89 @@ unsigned long mpeg_get_last_header(void)
#endif /* !SIMULATOR */
}
void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
bool last_track))
{
track_buffer_callback = handler;
}
void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
bool last_track))
{
track_unbuffer_callback = handler;
}
void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
{
track_changed_callback = handler;
}
#ifndef SIMULATOR
/* Send callback events to notify about removing old tracks. */
static void generate_unbuffer_events(void)
{
int i;
int event_count = 0;
int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
int cur_idx = track_write_idx;
for (i = 0; i < numentries; i++)
{
if (trackdata[cur_idx].event_sent)
event_count++;
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
cur_idx = track_write_idx;
for (i = 0; i < numentries; i++)
{
/* Send an event to notify that track has finished. */
if (trackdata[cur_idx].event_sent)
{
event_count--;
if (track_unbuffer_callback)
track_unbuffer_callback(&trackdata[cur_idx].id3,
event_count == 0);
trackdata[cur_idx].event_sent = false;
}
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
}
/* Send callback events to notify about new tracks. */
static void generate_postbuffer_events(void)
{
int i;
int event_count = 0;
int numentries = num_tracks_in_memory();
int cur_idx = track_read_idx;
for (i = 0; i < numentries; i++)
{
if (!trackdata[cur_idx].event_sent)
event_count++;
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
cur_idx = track_read_idx;
for (i = 0; i < numentries; i++)
{
if (!trackdata[cur_idx].event_sent)
{
event_count--;
if (track_buffer_callback)
track_buffer_callback(&trackdata[cur_idx].id3,
event_count == 0);
trackdata[cur_idx].event_sent = true;
}
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
}
static void recalculate_watermark(int bitrate)
{
int bytes_per_sec;
@ -684,7 +774,7 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
if(!filling && unplayed_space_left < low_watermark)
{
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
}
if(unplayed_space_left)
@ -862,6 +952,7 @@ static void stop_playing(void)
close(mpeg_file);
mpeg_file = -1;
remove_all_tags();
generate_unbuffer_events();
reset_mp3_buffer();
}
@ -894,6 +985,8 @@ static void track_change(void)
if (num_tracks_in_memory() > 0)
{
remove_current_tag();
if (track_changed_callback)
track_changed_callback(audio_current_track());
update_playlist();
}
@ -935,9 +1028,15 @@ static void start_playback_if_ready(void)
!filling || dma_underrun)
{
DEBUGF("P\n");
play_pending = false;
if (play_pending) /* don't do this when recovering from DMA underrun */
{
generate_postbuffer_events(); /* signal first track as buffered */
if (track_changed_callback)
track_changed_callback(audio_current_track());
play_pending = false;
}
playing = true;
last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
dma_underrun = false;
@ -1066,6 +1165,7 @@ static void mpeg_thread(void)
reset_mp3_buffer();
remove_all_tags();
generate_unbuffer_events();
if(mpeg_file >= 0)
close(mpeg_file);
@ -1170,7 +1270,7 @@ static void mpeg_thread(void)
/* should we start reading more data? */
if(!filling && (unplayed_space_left < low_watermark)) {
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
play_pending = true;
} else if(unswapped_space_left &&
unswapped_space_left > unplayed_space_left) {
@ -1194,6 +1294,7 @@ static void mpeg_thread(void)
reset_mp3_buffer();
remove_all_tags();
generate_unbuffer_events();
/* Open the next file */
if (mpeg_file >= 0)
@ -1233,6 +1334,7 @@ static void mpeg_thread(void)
reset_mp3_buffer();
remove_all_tags();
generate_unbuffer_events();
/* Open the next file */
if (mpeg_file >= 0)
@ -1324,7 +1426,7 @@ static void mpeg_thread(void)
{
/* We need to load more data before starting */
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
play_pending = true;
}
else
@ -1348,6 +1450,7 @@ static void mpeg_thread(void)
/* We have to reload the current track */
close(mpeg_file);
remove_all_non_current_tags();
generate_unbuffer_events();
mpeg_file = -1;
}
@ -1396,6 +1499,7 @@ static void mpeg_thread(void)
close(mpeg_file);
remove_all_non_current_tags();
generate_unbuffer_events();
mpeg_file = -1;
reload_track = true;
}
@ -1407,8 +1511,8 @@ static void mpeg_thread(void)
if(reload_track && new_file(1) >= 0)
{
/* Tell ourselves that we want more data */
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
filling = true;
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
}
break;
@ -1425,12 +1529,16 @@ static void mpeg_thread(void)
/* Make sure that we don't fill the entire buffer */
free_space_left -= MPEG_HIGH_WATER;
if (ev.data == GENERATE_UNBUFFER_EVENTS)
generate_unbuffer_events();
/* do we have any more buffer space to fill? */
if(free_space_left <= 0)
{
DEBUGF("0\n");
filling = false;
generate_postbuffer_events();
ata_sleep();
break;
}
@ -1575,7 +1683,7 @@ static void mpeg_thread(void)
if (playing)
playlist_update_resume_info(audio_current_track());
break;
}
}
#if CONFIG_HWCODEC == MAS3587F
}
else
@ -2673,6 +2781,9 @@ static void mpeg_thread(void)
void audio_init(void)
{
mpeg_errno = 0;
track_buffer_callback = NULL;
track_unbuffer_callback = NULL;
track_changed_callback = NULL;
#ifndef SIMULATOR
audiobuflen = audiobufend - audiobuf;