From 645a2e16ed645c30858e3b494ba2ff7d00b7a09b Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Sun, 10 Jul 2005 16:33:03 +0000 Subject: Fixed a simulator crash while trying to play a song. Fixed crossfade when selecting a new track to play. Most likely fixed a bug which caused playback to stop on track change. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7094 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs.c | 23 ++++++++++++---- apps/codecs.h | 2 +- apps/playback.c | 27 ++++++++++++++----- uisimulator/common/io.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 12 deletions(-) diff --git a/apps/codecs.c b/apps/codecs.c index 400e7fbfcf..dd87ddf0ed 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -56,8 +56,9 @@ #if CONFIG_HWCODEC == MASNONE static unsigned char codecbuf[CODEC_SIZE]; #endif -void *sim_codec_load(char *plugin, int *fd); -void sim_codec_close(int fd); +void *sim_codec_load_ram(char* codecptr, int size, + void* ptr2, int bufwrap, int *pd); +void sim_codec_close(int pd); #else #define sim_codec_close(x) extern unsigned char codecbuf[]; @@ -245,11 +246,12 @@ struct codec_api ci = { memchr, }; -int codec_load_ram(char* codecptr, size_t size, void* ptr2, size_t bufwrap) +int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap) { enum codec_status (*codec_start)(const struct codec_api* api); - int copy_n; int status; +#ifndef SIMULATOR + int copy_n; if ((char *)&codecbuf[0] != codecptr) { /* zero out codec buffer to ensure a properly zeroed bss area */ @@ -265,8 +267,19 @@ int codec_load_ram(char* codecptr, size_t size, void* ptr2, size_t bufwrap) } codec_start = (void*)&codecbuf; +#else /* SIMULATOR */ + int pd; + + codec_start = sim_codec_load_ram(codecptr, size, ptr2, bufwrap, &pd); + if (pd < 0) + return CODEC_ERROR; +#endif /* SIMULATOR */ + invalidate_icache(); status = codec_start(&ci); +#ifdef SIMULATOR + sim_codec_close(pd); +#endif return status; } @@ -294,7 +307,7 @@ int codec_load_file(const char *plugin) logf("Codec read error"); return CODEC_ERROR; } - + return codec_load_ram(codecbuf, (size_t)rc, NULL, 0); } diff --git a/apps/codecs.h b/apps/codecs.h index ea5972968f..73a5709328 100644 --- a/apps/codecs.h +++ b/apps/codecs.h @@ -331,7 +331,7 @@ struct codec_api { /* defined by the codec loader (codec.c) */ #if CONFIG_HWCODEC == MASNONE -int codec_load_ram(char* codecptr, size_t size, void* ptr2, size_t bufwrap); +int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap); int codec_load_file(const char* codec); #endif diff --git a/apps/playback.c b/apps/playback.c index a1f098b148..e7c1040378 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -191,15 +191,16 @@ void pcm_flush_buffer(long length) void* pcm_request_buffer(long length, long *realsize) { - (void)length; - (void)realsize; + static char temp_audiobuffer[32768]; + + *realsize = MIN((int)sizeof(temp_audiobuffer), length); - return NULL; + return temp_audiobuffer; } void audiobuffer_add_event(void (*event_handler)(void)) { - (void)event_handler; + event_handler(); } unsigned int audiobuffer_get_latency() @@ -1287,6 +1288,18 @@ void audio_change_track(void) queue_post(&codec_queue, CODEC_LOAD, 0); } +static int get_codec_base_type(int type) +{ + switch (type) { + case AFMT_MPA_L1: + case AFMT_MPA_L2: + case AFMT_MPA_L3: + return AFMT_MPA_L3; + } + + return type; +} + bool codec_request_next_track_callback(void) { if (ci.stop_codec || !playing) @@ -1361,7 +1374,9 @@ bool codec_request_next_track_callback(void) ci.reload_codec = false; - if (cur_ti->id3.codectype != tracks[track_ridx].id3.codectype) { + /* Check if the next codec is the same file. */ + if (get_codec_base_type(cur_ti->id3.codectype) != + get_codec_base_type(tracks[track_ridx].id3.codectype)) { logf("New codec:%d/%d", cur_ti->id3.codectype, tracks[track_ridx].id3.codectype); if (--track_ridx < 0) @@ -1436,7 +1451,7 @@ void audio_thread(void) ci.stop_codec = true; ci.reload_codec = false; ci.seek_time = 0; - if (!pcm_crossfade_init()) + if (!pcm_crossfade_init() && !pcm_is_crossfade_active()) pcm_flush_audio(); audio_play_start((int)ev.data); playlist_update_resume_info(audio_current_track()); diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index 78fb835785..7ea2d6878f 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -307,6 +307,78 @@ int sim_fsync(int fd) #include #endif +void *sim_codec_load_ram(char* codecptr, int size, + void* ptr2, int bufwrap, int *pd_fd) +{ + void *pd; + char *path = "archos/_temp_codec.dll"; + int (*codec_start)(void * api); + int fd; + int copy_n; +#ifdef WIN32 + char buf[256]; +#endif + + /* We have to create the dynamic link library file from ram + * so we could simulate the codec loading. + */ + *pd_fd = -1; + fd = open(path, O_WRONLY | O_CREAT, S_IRWXU); + if (fd < 0) { + DEBUGF("failed to open for write: %s\n", path); + return NULL; + } + + if (bufwrap == 0) + bufwrap = size; + + copy_n = bufwrap < size ? bufwrap : size; + if (write(fd, codecptr, copy_n) != copy_n) { + DEBUGF("write failed"); + return NULL; + } + size -= copy_n; + if (size > 0) { + if (write(fd, ptr2, size) != size) { + DEBUGF("write failed [2]"); + return NULL; + } + } + close(fd); + + /* Now load the library. */ + pd = dlopen(path, RTLD_NOW); + if (!pd) { + DEBUGF("failed to load %s\n", path); +#ifdef WIN32 + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, + buf, sizeof buf, NULL); + DEBUGF("dlopen(%s): %s\n", path, buf); +#else + DEBUGF("dlopen(%s): %s\n", path, dlerror()); +#endif + dlclose(pd); + return NULL; + } + + codec_start = dlsym(pd, "codec_start"); + if (!codec_start) { + codec_start = dlsym(pd, "_codec_start"); + if (!codec_start) { + dlclose(pd); + return NULL; + } + } + + *pd_fd = (int)pd; + return codec_start; +} + +void sim_codec_close(int pd) +{ + dlclose((void *)pd); +} + void *sim_plugin_load(char *plugin, int *fd) { void* pd; -- cgit v1.2.3