Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- apps/codec_thread.c | 7 +
- apps/codecs.c | 4 +-
- apps/codecs.h | 11 +-
- apps/codecs/adx.c | 2 +-
- apps/codecs/libtremor/SOURCES | 1 -
- apps/codecs/libtremor/ctype.c | 4 -
- apps/codecs/libtremor/info.c | 1 -
- apps/codecs/libtremor/vorbisfile.c | 1 -
- apps/codecs/mod.c | 11 +-
- apps/codecs/nsf.c | 13 +-
- apps/codecs/spc.c | 10 +-
- apps/codecs/wav.c | 4 +-
- apps/main.c | 6 +-
- apps/metadata.c | 8 +-
- apps/metadata.h | 2 +-
- apps/metadata/adx.c | 1 -
- apps/metadata/aiff.c | 1 -
- apps/metadata/ape.c | 1 -
- apps/metadata/asap.c | 1 -
- apps/metadata/asf.c | 1 -
- apps/metadata/flac.c | 1 -
- apps/metadata/metadata_common.c | 11 +-
- apps/metadata/monkeys.c | 1 -
- apps/metadata/mp4.c | 1 -
- apps/metadata/nsf.c | 1 -
- apps/metadata/ogg.c | 1 -
- apps/metadata/rm.c | 1 -
- apps/metadata/sid.c | 1 -
- apps/metadata/spc.c | 1 -
- apps/metadata/tta.c | 1 -
- apps/metadata/vorbis.c | 2 -
- apps/metadata/vox.c | 1 -
- apps/metadata/wavpack.c | 1 -
- apps/playback.c | 3 +-
- apps/plugins/test_codec.c | 9 +-
- apps/screen_access.c | 1 +
- apps/settings.h | 3 +-
- apps/tdspeed.c | 22 +-
- warble/Makefile | 63 +++
- warble/autoconf.h | 16 +
- warble/warble.c | 824 ++++++++++++++++++++++++++++++++++++
- 41 files changed, 974 insertions(+), 81 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/libtremor/SOURCES b/apps/codecs/libtremor/SOURCES
- index c622699..4076694 100644
- --- a/apps/codecs/libtremor/SOURCES
- +++ b/apps/codecs/libtremor/SOURCES
- @@ -12,5 +12,4 @@ sharedbook.c
- synthesis.c
- vorbisfile.c
- window.c
- -ctype.c
- oggmalloc.c
- diff --git a/apps/codecs/libtremor/ctype.c b/apps/codecs/libtremor/ctype.c
- deleted file mode 100644
- index 9f22047..0000000
- --- a/apps/codecs/libtremor/ctype.c
- +++ /dev/null
- @@ -1,4 +0,0 @@
- -#include "config.h"
- -#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
- -#include "libc/ctype.c"
- -#endif
- diff --git a/apps/codecs/libtremor/info.c b/apps/codecs/libtremor/info.c
- index b21d08d..b3451d3 100644
- --- a/apps/codecs/libtremor/info.c
- +++ b/apps/codecs/libtremor/info.c
- @@ -20,7 +20,6 @@
- #include "config-tremor.h"
- #include <string.h>
- -#include <ctype.h>
- #include "ogg.h"
- #include "ivorbiscodec.h"
- #include "codec_internal.h"
- diff --git a/apps/codecs/libtremor/vorbisfile.c b/apps/codecs/libtremor/vorbisfile.c
- index 5721178..cdc1853 100644
- --- a/apps/codecs/libtremor/vorbisfile.c
- +++ b/apps/codecs/libtremor/vorbisfile.c
- @@ -21,7 +21,6 @@
- #include <errno.h>
- #include <string.h>
- #include <math.h>
- -#include "system.h"
- #include "ivorbiscodec.h"
- #include "ivorbisfile.h"
- diff --git a/apps/codecs/mod.c b/apps/codecs/mod.c
- index 3dfaac6..862dd86 100644
- --- a/apps/codecs/mod.c
- +++ b/apps/codecs/mod.c
- @@ -37,7 +37,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- CODEC_HEADER
- @@ -1132,12 +1131,16 @@ void synthrender(int32_t *renderbuffer, int samplecount)
- if (modplayer.currentline == 64)
- {
- modplayer.patterntableposition++;
- - if (modplayer.patterntableposition >= modsong.songlength)
- + if (modplayer.patterntableposition >= modsong.songlength) {
- /* This is for Noise Tracker
- * modplayer.patterntableposition =
- * modsong.songendjumpposition;
- * More compatible approach is restart from 0 */
- - modplayer.patterntableposition=0;
- + if (ci->should_loop())
- + modplayer.patterntableposition = 0;
- + else
- + modplayer.patterntableposition = 127;
- + }
- modplayer.currentline = 0;
- }
- }
- @@ -1278,6 +1281,8 @@ enum codec_status codec_run(void)
- }
- if(old_patterntableposition != modplayer.patterntableposition) {
- + if (modplayer.patterntableposition == 127)
- + break;
- ci->set_elapsed(modplayer.patterntableposition*1000+500);
- old_patterntableposition=modplayer.patterntableposition;
- }
- 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/codecs/wav.c b/apps/codecs/wav.c
- index f6f83b1..d43961a 100644
- --- a/apps/codecs/wav.c
- +++ b/apps/codecs/wav.c
- @@ -28,12 +28,12 @@ CODEC_HEADER
- /* WAVE (RIFF) codec:
- *
- * For a good documentation on WAVE files, see:
- - * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/WAVE.html
- + * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
- * and
- * http://www.sonicspot.com/guide/wavefiles.html
- *
- * For sample WAV files, see:
- - * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/WAVE/Samples.html
- + * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html
- *
- */
- diff --git a/apps/main.c b/apps/main.c
- index 0b566b5..26c5bfa 100644
- --- a/apps/main.c
- +++ b/apps/main.c
- @@ -407,7 +407,8 @@ static void init(void)
- scrobbler_init();
- #if CONFIG_CODEC == SWCODEC && defined (HAVE_PITCHSCREEN)
- - tdspeed_init();
- + if (global_settings.timestretch_enabled)
- + tdspeed_init();
- #endif /* CONFIG_CODEC == SWCODEC */
- audio_init();
- @@ -670,7 +671,8 @@ static void init(void)
- filetype_init();
- scrobbler_init();
- #if CONFIG_CODEC == SWCODEC && defined (HAVE_PITCHSCREEN)
- - tdspeed_init();
- + if (global_settings.timestretch_enabled)
- + tdspeed_init();
- #endif /* CONFIG_CODEC == SWCODEC */
- theme_init_buffer();
- diff --git a/apps/metadata.c b/apps/metadata.c
- index cbb5b42..4649324 100644
- --- a/apps/metadata.c
- +++ b/apps/metadata.c
- @@ -20,12 +20,10 @@
- ****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include "string-extra.h"
- #include "debug.h"
- #include "logf.h"
- -#include "settings.h"
- #include "cuesheet.h"
- #include "metadata.h"
- @@ -552,9 +550,9 @@ void fill_metadata_from_path(struct mp3entry *id3, const char *trackname)
- enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE };
- -bool autoresumable(struct mp3entry *id3)
- +bool autoresumable(struct mp3entry *id3, const char *autoresume_paths)
- {
- - char *endp, *path;
- + const char *endp, *path;
- size_t len;
- bool is_resumable;
- @@ -565,7 +563,7 @@ bool autoresumable(struct mp3entry *id3)
- if (id3->path)
- {
- - for (path = global_settings.autoresume_paths;
- + for (path = autoresume_paths;
- *path; /* search terms left? */
- path++)
- {
- diff --git a/apps/metadata.h b/apps/metadata.h
- index a191e43..e5cbf37 100644
- --- a/apps/metadata.h
- +++ b/apps/metadata.h
- @@ -324,7 +324,7 @@ bool format_buffers_with_offset(int afmt);
- #endif
- #ifdef HAVE_TAGCACHE
- -bool autoresumable(struct mp3entry *id3);
- +bool autoresumable(struct mp3entry *id3, const char *autoresume_paths);
- #endif
- #endif
- diff --git a/apps/metadata/adx.c b/apps/metadata/adx.c
- index 4e18254..e427f66 100644
- --- a/apps/metadata/adx.c
- +++ b/apps/metadata/adx.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/aiff.c b/apps/metadata/aiff.c
- index 654f37c..52582d7 100644
- --- a/apps/metadata/aiff.c
- +++ b/apps/metadata/aiff.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/ape.c b/apps/metadata/ape.c
- index 44fc69a..4ddb9b0 100644
- --- a/apps/metadata/ape.c
- +++ b/apps/metadata/ape.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/asap.c b/apps/metadata/asap.c
- index 9e7f227..27c848b 100644
- --- a/apps/metadata/asap.c
- +++ b/apps/metadata/asap.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/asf.c b/apps/metadata/asf.c
- index 56d5c87..a758852 100644
- --- a/apps/metadata/asf.c
- +++ b/apps/metadata/asf.c
- @@ -22,7 +22,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "metadata.h"
- diff --git a/apps/metadata/flac.c b/apps/metadata/flac.c
- index 2993717..33a6bf3 100644
- --- a/apps/metadata/flac.c
- +++ b/apps/metadata/flac.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
- index e620514..f3602d7 100644
- --- a/apps/metadata/metadata_common.c
- +++ b/apps/metadata/metadata_common.c
- @@ -29,7 +29,6 @@
- #include "metadata_common.h"
- #include "metadata_parsers.h"
- #include "replaygain.h"
- -#include "misc.h"
- /* Read a string from the file. Read up to size bytes, or, if eos != -1,
- * until the eos character is found (eos is not stored in buf, unless it is
- @@ -194,7 +193,10 @@ uint32_t get_itunes_int32(char* value, int count)
- while (count-- > 0)
- {
- - value = skip_whitespace(value);
- + while (isspace(*value))
- + {
- + value++;
- + }
- while (*value && !isspace(*value))
- {
- @@ -202,7 +204,10 @@ uint32_t get_itunes_int32(char* value, int count)
- }
- }
- - value = skip_whitespace(value);
- + while (isspace(*value))
- + {
- + value++;
- + }
- while (*value && ((c = strchr(hexdigits, toupper(*value))) != NULL))
- {
- diff --git a/apps/metadata/monkeys.c b/apps/metadata/monkeys.c
- index 4aff141..c049d26 100644
- --- a/apps/metadata/monkeys.c
- +++ b/apps/metadata/monkeys.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
- index 4feb56c..025ffd1 100644
- --- a/apps/metadata/mp4.c
- +++ b/apps/metadata/mp4.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/nsf.c b/apps/metadata/nsf.c
- index 29fd847..b9c8266 100644
- --- a/apps/metadata/nsf.c
- +++ b/apps/metadata/nsf.c
- @@ -1,7 +1,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/ogg.c b/apps/metadata/ogg.c
- index 3a3cb29..2657fe4 100644
- --- a/apps/metadata/ogg.c
- +++ b/apps/metadata/ogg.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/rm.c b/apps/metadata/rm.c
- index 27f541c..7ffd1aa 100644
- --- a/apps/metadata/rm.c
- +++ b/apps/metadata/rm.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include <codecs/librm/rm.h>
- diff --git a/apps/metadata/sid.c b/apps/metadata/sid.c
- index 50b879b..51ba380 100644
- --- a/apps/metadata/sid.c
- +++ b/apps/metadata/sid.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/spc.c b/apps/metadata/spc.c
- index 1c02062..50ea751 100644
- --- a/apps/metadata/spc.c
- +++ b/apps/metadata/spc.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/tta.c b/apps/metadata/tta.c
- index 1d3d95f..8ef3754 100644
- --- a/apps/metadata/tta.c
- +++ b/apps/metadata/tta.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/vorbis.c b/apps/metadata/vorbis.c
- index f6d3af1..60b1523 100644
- --- a/apps/metadata/vorbis.c
- +++ b/apps/metadata/vorbis.c
- @@ -21,14 +21,12 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- #include "metadata.h"
- #include "metadata_common.h"
- #include "metadata_parsers.h"
- -#include "structec.h"
- /* Define LOGF_ENABLE to enable logf output in this file */
- /*#define LOGF_ENABLE*/
- diff --git a/apps/metadata/vox.c b/apps/metadata/vox.c
- index f6bc849..64ccfea 100644
- --- a/apps/metadata/vox.c
- +++ b/apps/metadata/vox.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/metadata/wavpack.c b/apps/metadata/wavpack.c
- index f2811df..bfb92b7 100644
- --- a/apps/metadata/wavpack.c
- +++ b/apps/metadata/wavpack.c
- @@ -21,7 +21,6 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- -#include <ctype.h>
- #include <inttypes.h>
- #include "system.h"
- diff --git a/apps/playback.c b/apps/playback.c
- index 2775e8a..29f3db8 100644
- --- a/apps/playback.c
- +++ b/apps/playback.c
- @@ -1291,7 +1291,8 @@ static bool audio_start_codec(bool auto_skip)
- break;
- default:
- /* Not "never resume" - pass resume filter? */
- - resume = autoresumable(cur_id3);
- + resume = autoresumable(cur_id3,
- + global_settings.autoresume_paths);
- }
- }
- 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;
- diff --git a/apps/screen_access.c b/apps/screen_access.c
- index b83e842..1b466ea 100644
- --- a/apps/screen_access.c
- +++ b/apps/screen_access.c
- @@ -33,6 +33,7 @@
- #include "backlight.h"
- #include "screen_access.h"
- #include "backdrop.h"
- +#include "statusbar.h"
- /* some helper functions to calculate metrics on the fly */
- static int screen_helper_getcharwidth(void)
- diff --git a/apps/settings.h b/apps/settings.h
- index 05965b3..9678bef 100644
- --- a/apps/settings.h
- +++ b/apps/settings.h
- @@ -27,8 +27,9 @@
- #include "inttypes.h"
- #include "config.h"
- #include "audiohw.h" /* for the AUDIOHW_* defines */
- -#include "statusbar.h" /* for the statusbar values */
- +#ifdef HAVE_QUICKSCREEN
- #include "quickscreen.h"
- +#endif
- #include "button.h"
- #if CONFIG_CODEC == SWCODEC
- #include "audio.h"
- diff --git a/apps/tdspeed.c b/apps/tdspeed.c
- index 61f47f9..04f1210 100644
- --- a/apps/tdspeed.c
- +++ b/apps/tdspeed.c
- @@ -28,7 +28,6 @@
- #include "buffer.h"
- #include "system.h"
- #include "tdspeed.h"
- -#include "settings.h"
- #define assert(cond)
- @@ -57,18 +56,15 @@ static int32_t *outbuf[2] = { NULL, NULL };
- void tdspeed_init()
- {
- - if (global_settings.timestretch_enabled)
- - {
- - /* Allocate buffers */
- - if (overlap_buffer[0] == NULL)
- - overlap_buffer[0] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
- - if (overlap_buffer[1] == NULL)
- - overlap_buffer[1] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
- - if (outbuf[0] == NULL)
- - outbuf[0] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
- - if (outbuf[1] == NULL)
- - outbuf[1] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
- - }
- + /* Allocate buffers */
- + if (overlap_buffer[0] == NULL)
- + overlap_buffer[0] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
- + if (overlap_buffer[1] == NULL)
- + overlap_buffer[1] = (int32_t *) buffer_alloc(FIXED_BUFSIZE * sizeof(int32_t));
- + if (outbuf[0] == NULL)
- + outbuf[0] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
- + if (outbuf[1] == NULL)
- + outbuf[1] = (int32_t *) buffer_alloc(TDSPEED_OUTBUFSIZE * sizeof(int32_t));
- }
- diff --git a/warble/Makefile b/warble/Makefile
- new file mode 100644
- index 0000000..472067d
- --- /dev/null
- +++ b/warble/Makefile
- @@ -0,0 +1,63 @@
- +default: all
- +
- +ROOTDIR = $(shell readlink -e ..)
- +BUILDDIR = $(shell pwd)/build
- +APPSDIR = $(ROOTDIR)/apps
- +TOOLSDIR = $(ROOTDIR)/tools
- +CODECDIR = $(BUILDDIR)/apps/codecs
- +DEPFILE = $(BUILDDIR)/make.dep
- +APP_TYPE = sdl-app
- +
- +INCLUDES = -I$(shell pwd)
- +INCLUDES += -I$(APPSDIR) -I$(APPSDIR)/codecs -I$(APPSDIR)/codecs/lib -I$(APPSDIR)/gui -I$(APPSDIR)/metadata -I$(APPSDIR)/recorder
- +INCLUDES += -I$(ROOTDIR)/firmware/export -I$(ROOTDIR)/firmware/include -I$(ROOTDIR)/firmware/target/hosted/sdl
- +
- +CFLAGS = -D__PCTOOL__ -DSIMULATOR=1 -D"IBSS_ATTR=" -DROCKBOX_LITTLE_ENDIAN=1 -D"ICODE_ATTR=" -D"ICONST_ATTR=" -DROCKBOX $(INCLUDES)
- +CFLAGS += -O0 -ggdb -DDEBUG -DDEBUGF=debugf -DLOGF_ENABLE
- +PPCFLAGS = $(CFLAGS)
- +
- +SHARED_CFLAGS = -fPIC -fvisibility=hidden
- +SHARED_LDFLAG = -shared
- +
- +WARBLE_OBJS = $(BUILDDIR)/warble.o
- +WARBLE_CFLAGS = '-DCODECDIR="$(CODECDIR)"' $(shell sdl-config --cflags)
- +WARBLE_LDFLAGS = -lm -ldl $(shell sdl-config --libs)
- +
- +include $(ROOTDIR)/tools/functions.make
- +include $(APPSDIR)/codecs/codecs.make
- +CODECFLAGS += -ffreestanding -nostdlib
- +
- +SRC = $(ROOTDIR)/apps/metadata.c $(ROOTDIR)/apps/replaygain.c $(ROOTDIR)/firmware/common/strlcpy.c $(ROOTDIR)/firmware/common/unicode.c $(ROOTDIR)/firmware/common/structec.c $(ROOTDIR)/apps/mp3data.c $(ROOTDIR)/apps/fixedpoint.c $(ROOTDIR)/uisimulator/common/io.c
- +SRC += $(ROOTDIR)/apps/dsp.c $(ROOTDIR)/apps/eq.c $(ROOTDIR)/apps/tdspeed.c
- +SRC += $(patsubst %,$(ROOTDIR)/apps/metadata/%.c,a52 adx aiff ape asap asf au flac id3tags metadata_common mod monkeys mp3 mp4 mpc nsf ogg oma rm sid smaf spc tta vorbis vox wave wavpack)
- +
- +OBJ := $(SRC:.c=.o)
- +OBJ := $(OBJ:.S=.o)
- +OBJ := $(subst $(ROOTDIR),$(BUILDDIR),$(OBJ))
- +
- +all: $(DEPFILE) warble $(CODECS)
- +
- +dep $(DEPFILE):
- + $(SILENT)mkdir -p $(dir $(DEPFILE))
- + $(call PRINTS,Generating dependencies)
- + $(call mkdepfile,$(DEPFILE)_,$(SRC))
- + $(call mkdepfile,$(DEPFILE)_,$(OTHER_SRC))
- + $(call mkdepfile,$(DEPFILE)_,$(ASMDEFS_SRC))
- + @mv $(DEPFILE)_ $(DEPFILE)
- +
- +-include $(DEPFILE)
- +
- +warble: $(WARBLE_OBJS) $(OBJ)
- + $(call PRINTS,LD $@)$(CC) $(LDFLAGS) $^ -o $@ $(WARBLE_LDFLAGS)
- +
- +$(BUILDDIR)/%.o: %.c
- + $(SILENT)mkdir -p $(dir $@)
- + $(call PRINTS,CC $<)$(CC) $(CFLAGS) -c $< -o $@ $(WARBLE_CFLAGS)
- +
- +$(BUILDDIR)/%.o: $(ROOTDIR)/%.c
- + $(SILENT)mkdir -p $(dir $@)
- + $(call PRINTS,CC $<)$(CC) $(CFLAGS) -c $< -o $@
- +
- +clean:
- + $(SILENT)echo Cleaning build directory
- + $(SILENT)rm -rf warble $(BUILDDIR)/*
- diff --git a/warble/autoconf.h b/warble/autoconf.h
- new file mode 100644
- index 0000000..d79a720
- --- /dev/null
- +++ b/warble/autoconf.h
- @@ -0,0 +1,16 @@
- +#ifndef __BUILD_AUTOCONF_H
- +#define __BUILD_AUTOCONF_H
- +
- +#define CONFIG_CODEC SWCODEC
- +#define TARGET_ID 73 /* sdlapp */
- +#define MEMORYSIZE 64
- +#define ROCKBOX_LITTLE_ENDIAN 1
- +#define HAVE_PITCHSCREEN
- +#define HAVE_SW_TONE_CONTROLS
- +#define HAVE_SW_VOLUME_CONTROL
- +#define VOLUME_MIN -100
- +#define VOLUME_MAX 100
- +#define SW_VOLUME_MIN -100
- +#define SW_VOLUME_MAX 100
- +
- +#endif /* __BUILD_AUTOCONF_H */
- diff --git a/warble/warble.c b/warble/warble.c
- new file mode 100644
- index 0000000..08a8982
- --- /dev/null
- +++ b/warble/warble.c
- @@ -0,0 +1,824 @@
- +/***************************************************************************
- + * __________ __ ___.
- + * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- + * \/ \/ \/ \/ \/
- + *
- + * Copyright (C) 2011 Sean Bartell
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License
- + * as published by the Free Software Foundation; either version 2
- + * of the License, or (at your option) any later version.
- + *
- + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- + * KIND, either express or implied.
- + *
- + ****************************************************************************/
- +
- +#define _BSD_SOURCE /* htole64 from endian.h */
- +#include <sys/types.h>
- +#include <SDL.h>
- +#include <dlfcn.h>
- +#include <endian.h>
- +#include <fcntl.h>
- +#include <math.h>
- +#include <stdarg.h>
- +#include <stdio.h>
- +#include <stdlib.h>
- +#include <string.h>
- +#include <sys/stat.h>
- +#include <unistd.h>
- +#include "buffering.h" /* TYPE_PACKET_AUDIO */
- +#include "codecs.h"
- +#include "debug.h"
- +#include "dsp.h"
- +#include "metadata.h"
- +#include "settings.h"
- +#include "sound.h"
- +
- +/***************** EXPORTED *****************/
- +
- +struct user_settings global_settings;
- +volatile long current_tick = 0;
- +
- +void yield()
- +{
- +}
- +
- +void *buffer_alloc(size_t size)
- +{
- + return malloc(size);
- +}
- +
- +void mutex_init(struct mutex *m)
- +{
- +}
- +
- +void mutex_lock(struct mutex *m)
- +{
- +}
- +
- +void mutex_unlock(struct mutex *m)
- +{
- +}
- +
- +/***************** INTERNAL *****************/
- +
- +static enum { MODE_PLAY, MODE_WRITE } mode;
- +static bool use_dsp = true;
- +static bool enable_loop = false;
- +static bool verbose = false;
- +static const char *config = "";
- +
- +static int input_fd;
- +static enum codec_command_action codec_action;
- +static intptr_t codec_action_param = 0;
- +static unsigned long num_output_samples = 0;
- +static struct codec_api ci;
- +
- +static struct {
- + intptr_t freq;
- + intptr_t stereo_mode;
- + intptr_t depth;
- + int channels;
- +} format;
- +
- +/***** MODE_WRITE *****/
- +
- +#define WAVE_HEADER_SIZE 0x2e
- +#define WAVE_FORMAT_PCM 1
- +#define WAVE_FORMAT_IEEE_FLOAT 3
- +static int output_fd;
- +static bool write_raw = false;
- +static bool write_header_written = false;
- +
- +static void write_init(const char *output_fn)
- +{
- + mode = MODE_WRITE;
- + if (!strcmp(output_fn, "-")) {
- + output_fd = STDOUT_FILENO;
- + } else {
- + output_fd = creat(output_fn, 0666);
- + if (output_fd == -1) {
- + perror(output_fn);
- + exit(1);
- + }
- + }
- +}
- +
- +static void set_le16(char *buf, uint16_t val)
- +{
- + buf[0] = val;
- + buf[1] = val >> 8;
- +}
- +
- +static void set_le32(char *buf, uint32_t val)
- +{
- + buf[0] = val;
- + buf[1] = val >> 8;
- + buf[2] = val >> 16;
- + buf[3] = val >> 24;
- +}
- +
- +static void write_wav_header()
- +{
- + int channels, sample_size, freq, type;
- + if (use_dsp) {
- + channels = 2;
- + sample_size = 16;
- + freq = NATIVE_FREQUENCY;
- + type = WAVE_FORMAT_PCM;
- + } else {
- + channels = format.channels;
- + sample_size = 64;
- + freq = format.freq;
- + type = WAVE_FORMAT_IEEE_FLOAT;
- + }
- +
- + /* The size fields are normally overwritten by write_quit(). If that fails,
- + * this fake size ensures the file can still be played. */
- + off_t total_size = 0x7fffff00 + WAVE_HEADER_SIZE;
- + char header[WAVE_HEADER_SIZE] = {"RIFF____WAVEfmt \x12\0\0\0"
- + "________________\0\0data____"};
- + set_le32(header + 0x04, total_size - 8);
- + set_le16(header + 0x14, type);
- + set_le16(header + 0x16, channels);
- + set_le32(header + 0x18, freq);
- + set_le32(header + 0x1c, freq * channels * sample_size / 8);
- + set_le16(header + 0x20, channels * sample_size / 8);
- + set_le16(header + 0x22, sample_size);
- + set_le32(header + 0x2a, total_size - WAVE_HEADER_SIZE);
- + write(output_fd, header, sizeof(header));
- + write_header_written = true;
- +}
- +
- +static void write_quit()
- +{
- + if (!write_raw) {
- + /* Write the correct size fields in the header. If lseek fails (e.g.
- + * for a pipe) nothing is written. */
- + off_t total_size = lseek(output_fd, 0, SEEK_CUR);
- + if (total_size != (off_t)-1) {
- + char buf[4];
- + set_le32(buf, total_size - 8);
- + lseek(output_fd, 4, SEEK_SET);
- + write(output_fd, buf, 4);
- + set_le32(buf, total_size - WAVE_HEADER_SIZE);
- + lseek(output_fd, 0x2a, SEEK_SET);
- + write(output_fd, buf, 4);
- + }
- + }
- + if (output_fd != STDOUT_FILENO)
- + close(output_fd);
- +}
- +
- +static uint64_t make_float64(int32_t sample, int shift)
- +{
- + /* TODO: be more portable */
- + double val = ldexp(sample, -shift);
- + return *(uint64_t*)&val;
- +}
- +
- +static void write_pcm(int16_t *pcm, int count)
- +{
- + if (!write_header_written)
- + write_wav_header();
- + int i;
- + for (i = 0; i < 2 * count; i++)
- + pcm[i] = htole16(pcm[i]);
- + write(output_fd, pcm, 4 * count);
- +}
- +
- +static void write_pcm_raw(int32_t *pcm, int count)
- +{
- + if (write_raw) {
- + write(output_fd, pcm, count * sizeof(*pcm));
- + } else {
- + if (!write_header_written)
- + write_wav_header();
- + int i;
- + uint64_t buf[count];
- +
- + for (i = 0; i < count; i++)
- + buf[i] = htole64(make_float64(pcm[i], format.depth));
- + write(output_fd, buf, count * sizeof(*buf));
- + }
- +}
- +
- +/***** MODE_PLAY *****/
- +
- +/* MODE_PLAY uses a double buffer: one half is read by the playback thread and
- + * the other half is written to by the main thread. When a thread is done with
- + * its current half, it waits for the other thread and then switches. The main
- + * advantage of this method is its simplicity; the main disadvantage is that it
- + * has long latency. ALSA buffer underruns still occur sometimes, but this is
- + * SDL's fault. */
- +
- +#define PLAYBACK_BUFFER_SIZE 0x10000
- +static bool playback_running = false;
- +static char playback_buffer[2][PLAYBACK_BUFFER_SIZE];
- +static int playback_play_ind, playback_decode_ind;
- +static int playback_play_pos, playback_decode_pos;
- +static SDL_sem *playback_play_sema, *playback_decode_sema;
- +
- +static void playback_init()
- +{
- + mode = MODE_PLAY;
- + if (SDL_Init(SDL_INIT_AUDIO)) {
- + fprintf(stderr, "error: Can't initialize SDL: %s\n", SDL_GetError());
- + exit(1);
- + }
- + playback_play_ind = 1;
- + playback_play_pos = PLAYBACK_BUFFER_SIZE;
- + playback_decode_ind = 0;
- + playback_decode_pos = 0;
- + playback_play_sema = SDL_CreateSemaphore(0);
- + playback_decode_sema = SDL_CreateSemaphore(0);
- +}
- +
- +static void playback_callback(void *userdata, Uint8 *stream, int len)
- +{
- + while (len > 0) {
- + if (!playback_running && playback_play_ind == playback_decode_ind
- + && playback_play_pos >= playback_decode_pos) {
- + /* end of data */
- + memset(stream, 0, len);
- + SDL_SemPost(playback_play_sema);
- + return;
- + }
- + if (playback_play_pos >= PLAYBACK_BUFFER_SIZE) {
- + SDL_SemPost(playback_play_sema);
- + SDL_SemWait(playback_decode_sema);
- + playback_play_ind = !playback_play_ind;
- + playback_play_pos = 0;
- + }
- + char *play_buffer = playback_buffer[playback_play_ind];
- + int copy_len = MIN(len, PLAYBACK_BUFFER_SIZE - playback_play_pos);
- + memcpy(stream, play_buffer + playback_play_pos, copy_len);
- + len -= copy_len;
- + stream += copy_len;
- + playback_play_pos += copy_len;
- + }
- +}
- +
- +static void playback_start()
- +{
- + playback_running = true;
- + SDL_AudioSpec spec = {0};
- + spec.freq = NATIVE_FREQUENCY;
- + spec.format = AUDIO_S16SYS;
- + spec.channels = 2;
- + spec.samples = 0x400;
- + spec.callback = playback_callback;
- + spec.userdata = NULL;
- + if (SDL_OpenAudio(&spec, NULL)) {
- + fprintf(stderr, "error: Can't open SDL audio: %s\n", SDL_GetError());
- + exit(1);
- + }
- + SDL_PauseAudio(0);
- +}
- +
- +static void playback_quit()
- +{
- + if (!playback_running)
- + playback_start();
- + memset(playback_buffer[playback_decode_ind] + playback_decode_pos, 0,
- + PLAYBACK_BUFFER_SIZE - playback_decode_pos);
- + playback_running = false;
- + SDL_SemPost(playback_decode_sema);
- + SDL_SemWait(playback_play_sema);
- + SDL_SemWait(playback_play_sema);
- + SDL_Quit();
- +}
- +
- +static void playback_pcm(int16_t *pcm, int count)
- +{
- + const char *stream = (const char *)pcm;
- + count *= 4;
- +
- + while (count > 0) {
- + if (playback_decode_pos >= PLAYBACK_BUFFER_SIZE) {
- + if (!playback_running)
- + playback_start();
- + SDL_SemPost(playback_decode_sema);
- + SDL_SemWait(playback_play_sema);
- + playback_decode_ind = !playback_decode_ind;
- + playback_decode_pos = 0;
- + }
- + char *decode_buffer = playback_buffer[playback_decode_ind];
- + int copy_len = MIN(count, PLAYBACK_BUFFER_SIZE - playback_decode_pos);
- + memcpy(decode_buffer + playback_decode_pos, stream, copy_len);
- + stream += copy_len;
- + count -= copy_len;
- + playback_decode_pos += copy_len;
- + }
- +}
- +
- +/***** ALL MODES *****/
- +
- +static void perform_config()
- +{
- + while (config) {
- + const char *name = config;
- + const char *eq = strchr(config, '=');
- + if (!eq)
- + break;
- + const char *val = eq + 1;
- + const char *end = val + strcspn(val, ": \t\n");
- +
- + if (!strncmp(name, "wait=", 5)) {
- + if (atoi(val) > num_output_samples)
- + return;
- + } else if (!strncmp(name, "dither=", 7)) {
- + dsp_dither_enable(atoi(val) ? true : false);
- + } else if (!strncmp(name, "halt=", 5)) {
- + if (atoi(val))
- + codec_action = CODEC_ACTION_HALT;
- + } else if (!strncmp(name, "loop=", 5)) {
- + enable_loop = atoi(val) != 0;
- + } else if (!strncmp(name, "offset=", 7)) {
- + ci.id3->offset = atoi(val);
- + } else if (!strncmp(name, "rate=", 5)) {
- + sound_set_pitch(atof(val) * PITCH_SPEED_100);
- + } else if (!strncmp(name, "seek=", 5)) {
- + codec_action = CODEC_ACTION_SEEK_TIME;
- + codec_action_param = atoi(val);
- + } else if (!strncmp(name, "tempo=", 6)) {
- + dsp_set_timestretch(atof(val) * PITCH_SPEED_100);
- + } else if (!strncmp(name, "vol=", 4)) {
- + global_settings.volume = atoi(val);
- + dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0);
- + } else {
- + fprintf(stderr, "error: unrecognized config \"%.*s\"\n", eq - name, name);
- + exit(1);
- + }
- +
- + if (*end)
- + config = end + 1;
- + else
- + config = NULL;
- + }
- +}
- +
- +static void *ci_codec_get_buffer(size_t *size)
- +{
- + static char buffer[64 * 1024 * 1024];
- + char *ptr = buffer;
- + *size = sizeof(buffer);
- + ALIGN_BUFFER(ptr, *size, CACHEALIGN_SIZE);
- + return ptr;
- +}
- +
- +static void ci_pcmbuf_insert(const void *ch1, const void *ch2, int count)
- +{
- + num_output_samples += count;
- +
- + if (use_dsp) {
- + const char *src[2] = {ch1, ch2};
- + while (count > 0) {
- + int out_count = dsp_output_count(ci.dsp, count);
- + int in_count = MIN(dsp_input_count(ci.dsp, out_count), count);
- + int16_t buf[2 * out_count];
- + out_count = dsp_process(ci.dsp, (char *)buf, src, in_count);
- + if (mode == MODE_WRITE)
- + write_pcm(buf, out_count);
- + else if (mode == MODE_PLAY)
- + playback_pcm(buf, out_count);
- + count -= in_count;
- + }
- + } else {
- + /* Convert to 32-bit interleaved. */
- + count *= format.channels;
- + int i;
- + int32_t buf[count];
- + if (format.depth > 16) {
- + if (format.stereo_mode == STEREO_NONINTERLEAVED) {
- + for (i = 0; i < count; i += 2) {
- + buf[i+0] = ((int32_t*)ch1)[i/2];
- + buf[i+1] = ((int32_t*)ch2)[i/2];
- + }
- + } else {
- + memcpy(buf, ch1, sizeof(buf));
- + }
- + } else {
- + if (format.stereo_mode == STEREO_NONINTERLEAVED) {
- + for (i = 0; i < count; i += 2) {
- + buf[i+0] = ((int16_t*)ch1)[i/2];
- + buf[i+1] = ((int16_t*)ch2)[i/2];
- + }
- + } else {
- + for (i = 0; i < count; i++) {
- + buf[i] = ((int16_t*)ch1)[i];
- + }
- + }
- + }
- +
- + if (mode == MODE_WRITE)
- + write_pcm_raw(buf, count);
- + }
- +
- + perform_config();
- +}
- +
- +static void ci_set_elapsed(unsigned long value)
- +{
- + //debugf("Time elapsed: %lu\n", value);
- +}
- +
- +static char *input_buffer = 0;
- +
- +/*
- + * Read part of the input file into a provided buffer.
- + *
- + * The entire size requested will be provided except at the end of the file.
- + * The current file position will be moved, just like with advance_buffer, but
- + * the offset is not updated. This invalidates buffers returned by
- + * request_buffer.
- + */
- +static size_t ci_read_filebuf(void *ptr, size_t size)
- +{
- + free(input_buffer);
- + input_buffer = NULL;
- +
- + ssize_t actual = read(input_fd, ptr, size);
- + if (actual < 0)
- + actual = 0;
- + ci.curpos += actual;
- + return actual;
- +}
- +
- +/*
- + * Request a buffer containing part of the input file.
- + *
- + * The size provided will be the requested size, or the remaining size of the
- + * file, whichever is smaller. Packet audio has an additional maximum of 32
- + * KiB. The returned buffer remains valid until the next time read_filebuf,
- + * request_buffer, advance_buffer, or seek_buffer is called.
- + */
- +static void *ci_request_buffer(size_t *realsize, size_t reqsize)
- +{
- + free(input_buffer);
- + if (get_audio_base_data_type(ci.id3->codectype) == TYPE_PACKET_AUDIO)
- + reqsize = MIN(reqsize, 32 * 1024);
- + input_buffer = malloc(reqsize);
- + *realsize = read(input_fd, input_buffer, reqsize);
- + if (*realsize < 0)
- + *realsize = 0;
- + lseek(input_fd, -*realsize, SEEK_CUR);
- + return input_buffer;
- +}
- +
- +/*
- + * Advance the current position in the input file.
- + *
- + * This automatically updates the current offset. This invalidates buffers
- + * returned by request_buffer.
- + */
- +static void ci_advance_buffer(size_t amount)
- +{
- + free(input_buffer);
- + input_buffer = NULL;
- +
- + lseek(input_fd, amount, SEEK_CUR);
- + ci.curpos += amount;
- + ci.id3->offset = ci.curpos;
- +}
- +
- +/*
- + * Seek to a position in the input file.
- + *
- + * This invalidates buffers returned by request_buffer.
- + */
- +static bool ci_seek_buffer(size_t newpos)
- +{
- + free(input_buffer);
- + input_buffer = NULL;
- +
- + off_t actual = lseek(input_fd, newpos, SEEK_SET);
- + if (actual >= 0)
- + ci.curpos = actual;
- + return actual != -1;
- +}
- +
- +static void ci_seek_complete()
- +{
- +}
- +
- +static void ci_set_offset(size_t value)
- +{
- + ci.id3->offset = value;
- +}
- +
- +static void ci_configure(int setting, intptr_t value)
- +{
- + if (use_dsp) {
- + dsp_configure(ci.dsp, setting, value);
- + } else {
- + if (setting == DSP_SET_FREQUENCY
- + || setting == DSP_SWITCH_FREQUENCY)
- + format.freq = value;
- + else if (setting == DSP_SET_SAMPLE_DEPTH)
- + format.depth = value;
- + else if (setting == DSP_SET_STEREO_MODE) {
- + format.stereo_mode = value;
- + format.channels = (value == STEREO_MONO) ? 1 : 2;
- + }
- + }
- +}
- +
- +static enum codec_command_action ci_get_command(intptr_t *param)
- +{
- + enum codec_command_action ret = codec_action;
- + *param = codec_action_param;
- + codec_action = CODEC_ACTION_NULL;
- + return ret;
- +}
- +
- +static bool ci_should_loop()
- +{
- + return enable_loop;
- +}
- +
- +static unsigned ci_sleep(unsigned ticks)
- +{
- + return 0;
- +}
- +
- +static void ci_cpucache_flush()
- +{
- +}
- +
- +static void ci_cpucache_invalidate()
- +{
- +}
- +
- +static struct codec_api ci = {
- +
- + 0, /* filesize */
- + 0, /* curpos */
- + NULL, /* id3 */
- + -1, /* audio_hid */
- + NULL, /* struct dsp_config *dsp */
- + ci_codec_get_buffer, /* codec_get_buffer */
- + ci_pcmbuf_insert, /* pcmbuf_insert */
- + ci_set_elapsed, /* set_elapsed */
- + ci_read_filebuf, /* read_filebuf */
- + ci_request_buffer, /* request_buffer */
- + ci_advance_buffer, /* advance_buffer */
- + ci_seek_buffer, /* seek_buffer */
- + ci_seek_complete, /* seek_complete */
- + ci_set_offset, /* set_offset */
- + ci_configure, /* configure */
- + ci_get_command, /* get_command */
- + ci_should_loop, /* should_loop */
- +
- + ci_sleep,
- + yield,
- +
- +#if NUM_CORES > 1
- + ci_create_thread,
- + ci_thread_thaw,
- + ci_thread_wait,
- + ci_semaphore_init,
- + ci_semaphore_wait,
- + ci_semaphore_release,
- +#endif
- +
- + ci_cpucache_flush,
- + ci_cpucache_invalidate,
- +
- + /* strings and memory */
- + strcpy,
- + strlen,
- + strcmp,
- + strcat,
- + memset,
- + memcpy,
- + memmove,
- + memcmp,
- + memchr,
- +#if defined(DEBUG) || defined(SIMULATOR)
- + debugf,
- +#endif
- +#ifdef ROCKBOX_HAS_LOGF
- + debugf, /* logf */
- +#endif
- +
- + qsort,
- +
- +#ifdef HAVE_RECORDING
- + ci_enc_get_inputs,
- + ci_enc_set_parameters,
- + ci_enc_get_chunk,
- + ci_enc_finish_chunk,
- + ci_enc_get_pcm_data,
- + ci_enc_unget_pcm_data,
- +
- + /* file */
- + open,
- + close,
- + read,
- + lseek,
- + write,
- + ci_round_value_to_list32,
- +
- +#endif /* HAVE_RECORDING */
- +};
- +
- +static void print_mp3entry(const struct mp3entry *id3, FILE *f)
- +{
- + fprintf(f, "Path: %s\n", id3->path);
- + if (id3->title) fprintf(f, "Title: %s\n", id3->title);
- + if (id3->artist) fprintf(f, "Artist: %s\n", id3->artist);
- + if (id3->album) fprintf(f, "Album: %s\n", id3->album);
- + if (id3->genre_string) fprintf(f, "Genre: %s\n", id3->genre_string);
- + if (id3->disc_string || id3->discnum) fprintf(f, "Disc: %s (%d)\n", id3->disc_string, id3->discnum);
- + if (id3->track_string || id3->tracknum) fprintf(f, "Track: %s (%d)\n", id3->track_string, id3->tracknum);
- + if (id3->year_string || id3->year) fprintf(f, "Year: %s (%d)\n", id3->year_string, id3->year);
- + if (id3->composer) fprintf(f, "Composer: %s\n", id3->composer);
- + if (id3->comment) fprintf(f, "Comment: %s\n", id3->comment);
- + if (id3->albumartist) fprintf(f, "Album artist: %s\n", id3->albumartist);
- + if (id3->grouping) fprintf(f, "Grouping: %s\n", id3->grouping);
- + if (id3->layer) fprintf(f, "Layer: %d\n", id3->layer);
- + if (id3->id3version) fprintf(f, "ID3 version: %u\n", (int)id3->id3version);
- + fprintf(f, "Codec: %s\n", audio_formats[id3->codectype].label);
- + fprintf(f, "Bitrate: %d kb/s\n", id3->bitrate);
- + fprintf(f, "Frequency: %lu Hz\n", id3->frequency);
- + if (id3->id3v2len) fprintf(f, "ID3v2 length: %lu\n", id3->id3v2len);
- + if (id3->id3v1len) fprintf(f, "ID3v1 length: %lu\n", id3->id3v1len);
- + if (id3->first_frame_offset) fprintf(f, "First frame offset: %lu\n", id3->first_frame_offset);
- + fprintf(f, "File size without headers: %lu\n", id3->filesize);
- + fprintf(f, "Song length: %lu ms\n", id3->length);
- + if (id3->lead_trim || id3->tail_trim) fprintf(f, "Trim: %d/%d\n", id3->lead_trim, id3->tail_trim);
- + if (id3->samples) fprintf(f, "Number of samples: %lu\n", id3->samples);
- + if (id3->frame_count) fprintf(f, "Number of frames: %lu\n", id3->frame_count);
- + if (id3->bytesperframe) fprintf(f, "Bytes per frame: %lu\n", id3->bytesperframe);
- + if (id3->vbr) fprintf(f, "VBR: true\n");
- + if (id3->has_toc) fprintf(f, "Has TOC: true\n");
- + if (id3->channels) fprintf(f, "Number of channels: %u\n", id3->channels);
- + if (id3->extradata_size) fprintf(f, "Size of extra data: %u\n", id3->extradata_size);
- + if (id3->needs_upsampling_correction) fprintf(f, "Needs upsampling correction: true\n");
- + /* TODO: replaygain; albumart; cuesheet */
- + if (id3->mb_track_id) fprintf(f, "Musicbrainz track ID: %s\n", id3->mb_track_id);
- +}
- +
- +static void decode_file(const char *input_fn)
- +{
- + /* Set up global settings */
- + memset(&global_settings, 0, sizeof(global_settings));
- + global_settings.timestretch_enabled = true;
- + dsp_timestretch_enable(true);
- + tdspeed_init();
- +
- + /* Open file */
- + if (!strcmp(input_fn, "-")) {
- + input_fd = STDIN_FILENO;
- + } else {
- + input_fd = open(input_fn, O_RDONLY);
- + if (input_fd == -1) {
- + perror(input_fn);
- + exit(1);
- + }
- + }
- +
- + /* Set up ci */
- + struct mp3entry id3;
- + if (!get_metadata(&id3, input_fd, input_fn)) {
- + fprintf(stderr, "error: metadata parsing failed\n");
- + exit(1);
- + }
- + print_mp3entry(&id3, stderr);
- + ci.filesize = filesize(input_fd);
- + ci.id3 = &id3;
- + if (use_dsp) {
- + ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP, CODEC_IDX_AUDIO);
- + dsp_configure(ci.dsp, DSP_RESET, 0);
- + dsp_dither_enable(false);
- + }
- + perform_config();
- +
- + /* Load codec */
- + char str[MAX_PATH];
- + snprintf(str, sizeof(str), CODECDIR"/%s.codec", audio_formats[id3.codectype].codec_root_fn);
- + debugf("Loading %s\n", str);
- + void *dlcodec = dlopen(str, RTLD_NOW);
- + if (!dlcodec) {
- + fprintf(stderr, "error: dlopen failed: %s\n", dlerror());
- + exit(1);
- + }
- + struct codec_header *c_hdr = NULL;
- + c_hdr = dlsym(dlcodec, "__header");
- + if (c_hdr->lc_hdr.magic != CODEC_MAGIC) {
- + fprintf(stderr, "error: %s invalid: incorrect magic\n", str);
- + exit(1);
- + }
- + if (c_hdr->lc_hdr.target_id != TARGET_ID) {
- + fprintf(stderr, "error: %s invalid: incorrect target id\n", str);
- + exit(1);
- + }
- + if (c_hdr->lc_hdr.api_version != CODEC_API_VERSION) {
- + fprintf(stderr, "error: %s invalid: incorrect API version\n", str);
- + exit(1);
- + }
- +
- + /* Run the codec */
- + *c_hdr->api = &ci;
- + if (c_hdr->entry_point(CODEC_LOAD) != CODEC_OK) {
- + fprintf(stderr, "error: codec returned error from codec_main\n");
- + exit(1);
- + }
- + if (c_hdr->run_proc() != CODEC_OK) {
- + fprintf(stderr, "error: codec error\n");
- + }
- + c_hdr->entry_point(CODEC_UNLOAD);
- +
- + /* Close */
- + dlclose(dlcodec);
- + if (input_fd != STDIN_FILENO)
- + close(input_fd);
- +}
- +
- +static void print_help(const char *progname)
- +{
- + fprintf(stderr, "Usage:\n"
- + " Play: %s [options] INPUTFILE\n"
- + "Write to WAV: %s [options] INPUTFILE OUTPUTFILE\n"
- + "\n"
- + "general options:\n"
- + " -c a=1:b=2 Configuration (see below)\n"
- + " -h Show this help\n"
- + "\n"
- + "write to WAV options:\n"
- + " -f Write raw codec output converted to 64-bit float\n"
- + " -r Write raw 32-bit codec output without WAV header\n"
- + "\n"
- + "configuration:\n"
- + " dither=<0|1> Enable/disable dithering [0]\n"
- + " halt=<0|1> Stop decoding if 1 [0]\n"
- + " loop=<0|1> Enable/disable looping [0]\n"
- + " offset=<n> Start at byte offset within the file [0]\n"
- + " rate=<n> Multiply rate by <n> [1.0]\n"
- + " seek=<n> Seek <n> ms into the file\n"
- + " tempo=<n> Timestretch by <n> [1.0]\n"
- + " vol=<n> Set volume to <n> dB [0]\n"
- + " wait=<n> Don't apply remaining configuration until\n"
- + " <n> total samples have output\n"
- + "\n"
- + "examples:\n"
- + " # Play while looping; stop after 44100 output samples\n"
- + " %s in.adx -c loop=1:wait=44100:halt=1\n"
- + " # Lower pitch 1 octave and write to out.wav\n"
- + " %s in.ogg -c rate=0.5:tempo=2 out.wav\n"
- + , progname, progname, progname, progname);
- +}
- +
- +int main(int argc, char **argv)
- +{
- + int opt;
- + while ((opt = getopt(argc, argv, "c:fhr")) != -1) {
- + switch (opt) {
- + case 'c':
- + config = optarg;
- + break;
- + case 'f':
- + use_dsp = false;
- + break;
- + case 'r':
- + use_dsp = false;
- + write_raw = true;
- + break;
- + case 'h': /* fallthrough */
- + default:
- + print_help(argv[0]);
- + exit(1);
- + }
- + }
- +
- + if (argc == optind + 2) {
- + write_init(argv[optind + 1]);
- + } else if (argc == optind + 1) {
- + if (!use_dsp) {
- + fprintf(stderr, "error: -r can't be used for playback\n");
- + print_help(argv[0]);
- + exit(1);
- + }
- + playback_init();
- + } else {
- + if (argc > 1)
- + fprintf(stderr, "error: wrong number of arguments\n");
- + print_help(argv[0]);
- + exit(1);
- + }
- +
- + decode_file(argv[optind]);
- +
- + if (mode == MODE_WRITE)
- + write_quit();
- + else if (mode == MODE_PLAY)
- + playback_quit();
- +
- + return 0;
- +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement