summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-07-10 16:33:03 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-07-10 16:33:03 +0000
commit645a2e16ed645c30858e3b494ba2ff7d00b7a09b (patch)
treebe5da24477ae465c77342947de6ef73c57505e0d
parenta9203b4d8352d9de761c5baf95314ff189242ec0 (diff)
downloadrockbox-645a2e16ed645c30858e3b494ba2ff7d00b7a09b.tar.gz
rockbox-645a2e16ed645c30858e3b494ba2ff7d00b7a09b.zip
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
-rw-r--r--apps/codecs.c23
-rw-r--r--apps/codecs.h2
-rw-r--r--apps/playback.c27
-rw-r--r--uisimulator/common/io.c72
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 <dlfcn.h>
#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;