From fcd7527fba942f7550a1a08cf1d4497cc42806cd Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Mon, 11 Jul 2011 02:35:21 -0400 Subject: [PATCH] Simplify the codec API and don't always loop MODs. The unused strcasestr callback is removed. Several codecs were using the global_settings pointer to check whether REPEAT_ONE mode was on; this has been replaced with a should_loop callback. The MOD codec has been modified not to restart the file when it reaches the end. This does not affect MOD files that use "position jump" to create a loop of part of the song. Ideally the MOD codec would only follow such loops if should_loop() returns 1, but detecting loops is nontrivial. --- apps/codec_thread.c | 7 +++++++ apps/codecs.c | 4 ++-- apps/codecs.h | 11 ++++------- apps/codecs/adx.c | 2 +- apps/codecs/mod.c | 9 +++++---- apps/codecs/nsf.c | 13 +++++-------- apps/codecs/spc.c | 10 +++++----- apps/plugins/test_codec.c | 9 +++++++-- 8 files changed, 36 insertions(+), 29 deletions(-) diff --git a/apps/codec_thread.c b/apps/codec_thread.c index a7bff74..3e18ce4 100644 --- a/apps/codec_thread.c +++ b/apps/codec_thread.c @@ -30,6 +30,7 @@ #include "buffering.h" #include "dsp.h" #include "metadata.h" +#include "settings.h" /* Define LOGF_ENABLE to enable logf output in this file */ /*#define LOGF_ENABLE*/ @@ -402,6 +403,11 @@ static enum codec_command_action } } +static bool codec_should_loop_callback(void) +{ + return global_settings.repeat_mode == REPEAT_ONE; +} + /* Initialize codec API */ void codec_init_codec_api(void) { @@ -418,6 +424,7 @@ void codec_init_codec_api(void) ci.set_offset = audio_codec_update_offset; ci.configure = codec_configure_callback; ci.get_command = codec_get_command_callback; + ci.should_loop = codec_should_loop_callback; } diff --git a/apps/codecs.c b/apps/codecs.c index cd4a9d5..c2efbaa 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -50,6 +50,7 @@ #include "sound.h" #include "splash.h" #include "general.h" +#include "rbpaths.h" #define LOGF_ENABLE #include "logf.h" @@ -97,6 +98,7 @@ struct codec_api ci = { NULL, /* set_offset */ NULL, /* configure */ NULL, /* get_command */ + NULL, /* should_loop */ /* kernel/ system */ #if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE @@ -127,7 +129,6 @@ struct codec_api ci = { memmove, memcmp, memchr, - strcasestr, #if defined(DEBUG) || defined(SIMULATOR) debugf, #endif @@ -136,7 +137,6 @@ struct codec_api ci = { #endif (qsort_func)qsort, - &global_settings, #ifdef RB_PROFILE profile_thread, diff --git a/apps/codecs.h b/apps/codecs.h index e240811..a699711 100644 --- a/apps/codecs.h +++ b/apps/codecs.h @@ -44,7 +44,6 @@ #endif #include "dsp.h" #endif -#include "settings.h" #include "gcc_extensions.h" #include "load_code.h" @@ -75,12 +74,12 @@ #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ /* increase this every time the api struct changes */ -#define CODEC_API_VERSION 42 +#define CODEC_API_VERSION 43 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define CODEC_MIN_API_VERSION 42 +#define CODEC_MIN_API_VERSION 43 /* reasons for calling codec main entrypoint */ enum codec_entry_call_reason { @@ -145,6 +144,8 @@ struct codec_api { void (*configure)(int setting, intptr_t value); /* Obtain command action on what to do next */ enum codec_command_action (*get_command)(intptr_t *param); + /* Determine whether the loop should be used, if applicable. */ + bool (*should_loop)(void); /* kernel/ system */ #if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE @@ -180,7 +181,6 @@ struct codec_api { void* (*memmove)(void *out, const void *in, size_t n); int (*memcmp)(const void *s1, const void *s2, size_t n); void *(*memchr)(const void *s1, int c, size_t n); - char *(*strcasestr) (const char* phaystack, const char* pneedle); #if defined(DEBUG) || defined(SIMULATOR) void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2); @@ -193,9 +193,6 @@ struct codec_api { void (*qsort)(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); - /* The ADX codec accesses global_settings to test for REPEAT_ONE mode */ - struct user_settings* global_settings; - #ifdef RB_PROFILE void (*profile_thread)(void); void (*profstop)(void); diff --git a/apps/codecs/adx.c b/apps/codecs/adx.c index e75e7dc..1318aff 100644 --- a/apps/codecs/adx.c +++ b/apps/codecs/adx.c @@ -239,7 +239,7 @@ enum codec_status codec_run(void) if (bufoff > end_adr-18*channels && looping) { DEBUGF("ADX: loop!\n"); /* check for endless looping */ - if (ci->global_settings->repeat_mode==REPEAT_ONE) { + if (ci->should_loop()) { loop_count=0; fade_count = -1; /* disable fade */ } else { diff --git a/apps/codecs/mod.c b/apps/codecs/mod.c index 3703ecd..36c6cbd 100644 --- a/apps/codecs/mod.c +++ b/apps/codecs/mod.c @@ -1192,12 +1192,13 @@ void synthrender(int32_t *renderbuffer, int samplecount) if (modplayer.currentline == 64) { modplayer.patterntableposition++; - if (modplayer.patterntableposition >= modsong.songlength) - /* This is for Noise Tracker + if (modplayer.patterntableposition >= modsong.songlength) { + /* For Noise Tracker: * modplayer.patterntableposition = * modsong.songendjumpposition; - * More compatible approach is restart from 0 */ - modplayer.patterntableposition=0; + * However, it's more compatible not to loop. */ + break; + } modplayer.currentline = 0; } } diff --git a/apps/codecs/nsf.c b/apps/codecs/nsf.c index d626d52..334934f 100644 --- a/apps/codecs/nsf.c +++ b/apps/codecs/nsf.c @@ -4324,14 +4324,13 @@ jammed: static int track = 0; static char last_path[MAX_PATH]; static int dontresettrack = 0; -static bool repeat_one = false; static void set_codec_track(int t, int d) { int track,fade,def=0; SetTrack(t); - /* for REPEAT_ONE we disable track limits */ - if (!repeat_one) { + /* for loop mode we disable track limits */ + if (!ci->should_loop()) { if (!bIsExtended || nTrackTime[t]==-1) {track=60*2*1000; def=1;} else track=nTrackTime[t]; if (!bIsExtended || nTrackFade[t]==-1) fade=5*1000; @@ -4384,8 +4383,6 @@ enum codec_status codec_run(void) return CODEC_ERROR; } - repeat_one = ci->global_settings->repeat_mode == REPEAT_ONE; - init_nsf: if(!NSFCore_Initialize()) { DEBUGF("NSF: NSFCore_Initialize failed\n"); return CODEC_ERROR;} @@ -4401,7 +4398,7 @@ init_nsf: /* if this is the first time we're seeing this file, or if we haven't been asked to preserve the track number, default to the proper initial track */ - if (bIsExtended && !repeat_one && nPlaylistSize>0) { + if (bIsExtended && !ci->should_loop() && nPlaylistSize>0) { /* decide to use the playlist */ usingplaylist=1; track=0; @@ -4466,8 +4463,8 @@ init_nsf: print_timers(last_path,track); - if (repeat_one) { - /* in repeat one mode just advance to the next track */ + if (ci->should_loop()) { + /* in loop mode just advance to the next track */ track++; if (track>=nTrackCount) track=0; dontresettrack=1; diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 6b21f9a..8974b8b 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c @@ -477,7 +477,7 @@ static int play_track( void ) sampleswritten += WAV_CHUNK_SIZE; /* is track timed? */ - if (ci->global_settings->repeat_mode!=REPEAT_ONE && ci->id3->length) { + if (!ci->should_loop() && ci->id3->length) { unsigned long curtime = sampleswritten*1000LL/SAMPLE_RATE; unsigned long lasttimesample = (sampleswritten-WAV_CHUNK_SIZE); @@ -513,10 +513,10 @@ static int play_track( void ) spc_play_send_samples(samples); - if (ci->global_settings->repeat_mode!=REPEAT_ONE) - ci->set_elapsed(sampleswritten*1000LL/SAMPLE_RATE); - else + if (ci->should_loop()) ci->set_elapsed(0); + else + ci->set_elapsed(sampleswritten*1000LL/SAMPLE_RATE); } EXIT_TIMER(total); @@ -569,7 +569,7 @@ enum codec_status codec_run(void) LoadID666(buffer+0x2e); - if (ci->global_settings->repeat_mode!=REPEAT_ONE && ID666.length==0) { + if (!ci->should_loop() && ID666.length==0) { ID666.length=3*60*1000; /* 3 minutes */ ID666.fade=5*1000; /* 5 seconds */ } diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index 5c98201..9309f22 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -509,6 +509,12 @@ static enum codec_command_action get_command(intptr_t *param) (void)param; } +/* Some codecs call this to determine whether they should loop. */ +static bool should_loop(void) +{ + return false; +} + static void set_offset(size_t value) { ci.id3->offset = value; @@ -565,6 +571,7 @@ static void init_ci(void) ci.set_offset = set_offset; ci.configure = configure; ci.get_command = get_command; + ci.should_loop = should_loop; /* --- "Core" functions --- */ @@ -582,7 +589,6 @@ static void init_ci(void) ci.memmove = rb->memmove; ci.memcmp = rb->memcmp; ci.memchr = rb->memchr; - ci.strcasestr = rb->strcasestr; #if defined(DEBUG) || defined(SIMULATOR) ci.debugf = rb->debugf; #endif @@ -591,7 +597,6 @@ static void init_ci(void) #endif ci.qsort = rb->qsort; - ci.global_settings = rb->global_settings; #ifdef RB_PROFILE ci.profile_thread = rb->profile_thread; -- 1.7.6