summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-06-22 19:41:30 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-06-22 19:41:30 +0000
commit1dd672fe3226fa77113f35e4d72f50b863484c63 (patch)
tree67b424ab990f160dbc8fb238b9fa3390ceba10ed
parentb7aaa641b864628d76103b8c9d57c15747560ca7 (diff)
downloadrockbox-1dd672fe3226fa77113f35e4d72f50b863484c63.zip
rockbox-1dd672fe3226fa77113f35e4d72f50b863484c63.tar.gz
rockbox-1dd672fe3226fa77113f35e4d72f50b863484c63.tar.bz2
rockbox-1dd672fe3226fa77113f35e4d72f50b863484c63.tar.xz
moved and renamed the codecs, gave the codecs a new extension (.codec),
unified to a single codec-only API, made a new codeclib, disabled the building of the *2wav plugins git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6812 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/FILES3
-rw-r--r--apps/Makefile1
-rw-r--r--apps/SOURCES3
-rw-r--r--apps/codecs.c364
-rw-r--r--apps/codecs.h403
-rw-r--r--apps/codecs/Makefile81
-rw-r--r--apps/codecs/a52.c (renamed from apps/plugins/codeca52.c)20
-rw-r--r--apps/codecs/flac.c (renamed from apps/plugins/codecflac.c)24
-rw-r--r--apps/codecs/lib/Makefile46
-rw-r--r--apps/codecs/lib/codeclib.c (renamed from apps/plugins/lib/codeclib.c)9
-rw-r--r--apps/codecs/lib/codeclib.h (renamed from apps/plugins/lib/codeclib.h)7
-rw-r--r--apps/codecs/lib/xxx2wav.c (renamed from apps/plugins/lib/xxx2wav.c)53
-rw-r--r--apps/codecs/lib/xxx2wav.h (renamed from apps/plugins/lib/xxx2wav.h)6
-rw-r--r--apps/codecs/mpa.c521
-rw-r--r--apps/codecs/mpc.c (renamed from apps/plugins/codecmpc.c)26
-rw-r--r--apps/codecs/vorbis.c168
-rw-r--r--apps/codecs/wav.c (renamed from apps/plugins/codecwav.c)26
-rw-r--r--apps/codecs/wavpack.c (renamed from apps/plugins/codecwavpack.c)22
-rw-r--r--apps/playback.c24
-rw-r--r--apps/playback.h54
-rw-r--r--apps/plugin.c54
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/CODECS7
-rw-r--r--apps/plugins/Makefile15
-rw-r--r--apps/plugins/SOURCES11
-rw-r--r--apps/plugins/codecmpa.c520
-rw-r--r--apps/plugins/codecvorbis.c166
-rw-r--r--apps/plugins/lib/SOURCES3
-rwxr-xr-xtools/buildzip.pl2
29 files changed, 1709 insertions, 937 deletions
diff --git a/apps/FILES b/apps/FILES
index daa1856..2a25386 100644
--- a/apps/FILES
+++ b/apps/FILES
@@ -16,7 +16,6 @@ plugins/viewers.config
plugins/snake2.levels
SOURCES
plugins/SOURCES
-plugins/CODECS
plugins/lib/SOURCES
plugins/rockboy/*.[ch]
plugins/rockboy/Makefile
@@ -53,3 +52,5 @@ codecs/dumb/src/core/*
codecs/dumb/src/helpers/*
codecs/dumb/src/it/*
codecs/libmusepack/*
+codecs/lib/*.[ch]
+codecs/lib/Makefile
diff --git a/apps/Makefile b/apps/Makefile
index 6287f49..ec97a66 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -57,6 +57,7 @@ endif
dep: $(DEPFILE)
build-codecs:
+ @$(MAKE) -C codecs/lib OBJDIR=$(OBJDIR)/codecs/lib
@$(MAKE) -C codecs OBJDIR=$(OBJDIR)/codecs
rocks:
diff --git a/apps/SOURCES b/apps/SOURCES
index fb8acd7..7385331 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -48,9 +48,10 @@ recorder/radio.c
#ifdef HAVE_RECORDING
recorder/recording.c
#endif
-#ifdef IRIVER_H100
+#if CONFIG_HWCODEC == MASNONE
playback.c
metadata.c
+codecs.c
#ifndef SIMULATOR
pcm_recording.c
#endif
diff --git a/apps/codecs.c b/apps/codecs.c
new file mode 100644
index 0000000..d366c93
--- /dev/null
+++ b/apps/codecs.c
@@ -0,0 +1,364 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Björn Stenberg
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <atoi.h>
+#include <timefuncs.h>
+#include <ctype.h>
+#include "debug.h"
+#include "button.h"
+#include "lcd.h"
+#include "dir.h"
+#include "file.h"
+#include "kernel.h"
+#include "sprintf.h"
+#include "logf.h"
+#include "screens.h"
+#include "misc.h"
+#include "mas.h"
+#include "codecs.h"
+#include "lang.h"
+#include "keyboard.h"
+#include "mpeg.h"
+#include "buffer.h"
+#include "mp3_playback.h"
+#include "backlight.h"
+#include "ata.h"
+#include "talk.h"
+#include "mp3data.h"
+#include "powermgmt.h"
+#include "system.h"
+#include "sound.h"
+#include "database.h"
+#if (CONFIG_HWCODEC == MASNONE)
+#include "pcm_playback.h"
+#endif
+
+#ifdef HAVE_LCD_BITMAP
+#include "peakmeter.h"
+#include "widgets.h"
+#include "bmp.h"
+#endif
+
+#ifdef SIMULATOR
+#if CONFIG_HWCODEC == MASNONE
+static unsigned char codecbuf[CODEC_BUFFER_SIZE];
+#endif
+void *sim_codec_load(char *plugin, int *fd);
+void sim_codec_close(int fd);
+#else
+#define sim_codec_close(x)
+extern unsigned char codecbuf[];
+#endif
+
+extern void* plugin_get_audio_buffer(int *buffer_size);
+
+static int codec_test(int api_version, int model, int memsize);
+
+const struct codec_api ci = {
+ CODEC_API_VERSION,
+ codec_test,
+
+ 0, /* filesize */
+ 0, /* curpos */
+ NULL, /* id3 */
+ NULL, /* mp3data */
+ NULL, /* taginfo_ready */
+ false, /* stop_codec */
+ false, /* reload_codec */
+ 0, /* seek_time */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ /* lcd */
+ lcd_clear_display,
+ lcd_puts,
+ lcd_puts_scroll,
+ lcd_stop_scroll,
+ lcd_set_contrast,
+#ifdef HAVE_LCD_CHARCELLS
+ lcd_define_pattern,
+ lcd_get_locked_pattern,
+ lcd_unlock_pattern,
+ lcd_putc,
+ lcd_put_cursor,
+ lcd_remove_cursor,
+ PREFIX(lcd_icon),
+#else
+ lcd_putsxy,
+ lcd_puts_style,
+ lcd_puts_scroll_style,
+ lcd_bitmap,
+ lcd_drawline,
+ lcd_clearline,
+ lcd_drawpixel,
+ lcd_clearpixel,
+ lcd_setfont,
+ font_get,
+ lcd_clearrect,
+ lcd_fillrect,
+ lcd_drawrect,
+ lcd_invertrect,
+ lcd_getstringsize,
+ lcd_update,
+ lcd_update_rect,
+ scrollbar,
+ checkbox,
+ &lcd_framebuffer[0][0],
+ lcd_blit,
+#ifndef SIMULATOR
+ lcd_roll,
+#endif
+#endif
+ backlight_on,
+ backlight_off,
+ backlight_set_timeout,
+ splash,
+
+ /* file */
+ (open_func)PREFIX(open),
+ close,
+ (read_func)read,
+ PREFIX(lseek),
+ (creat_func)PREFIX(creat),
+ (write_func)write,
+ PREFIX(remove),
+ PREFIX(rename),
+ PREFIX(ftruncate),
+ fdprintf,
+ read_line,
+ settings_parseline,
+#ifndef SIMULATOR
+ ata_sleep,
+#endif
+
+ /* dir */
+ PREFIX(opendir),
+ PREFIX(closedir),
+ PREFIX(readdir),
+ PREFIX(mkdir),
+
+ /* kernel/ system */
+ PREFIX(sleep),
+ yield,
+ &current_tick,
+ default_event_handler,
+ default_event_handler_ex,
+ create_thread,
+ remove_thread,
+ reset_poweroff_timer,
+#ifndef SIMULATOR
+ system_memory_guard,
+ &cpu_frequency,
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ cpu_boost,
+#endif
+#endif
+
+ /* strings and memory */
+ snprintf,
+ strcpy,
+ strncpy,
+ strlen,
+ strrchr,
+ strcmp,
+ strcasecmp,
+ strncasecmp,
+ memset,
+ memcpy,
+ _ctype_,
+ atoi,
+ strchr,
+ strcat,
+ memcmp,
+ strcasestr,
+
+ /* sound */
+ sound_set,
+#ifndef SIMULATOR
+ mp3_play_data,
+ mp3_play_pause,
+ mp3_play_stop,
+ mp3_is_playing,
+#if CONFIG_HWCODEC != MASNONE
+ bitswap,
+#endif
+#if CONFIG_HWCODEC == MASNONE
+ pcm_play_data,
+ pcm_play_stop,
+ pcm_set_frequency,
+ pcm_is_playing,
+ pcm_play_pause,
+#endif
+#endif
+
+ /* playback control */
+ PREFIX(audio_play),
+ audio_stop,
+ audio_pause,
+ audio_resume,
+ audio_next,
+ audio_prev,
+ audio_ff_rewind,
+ audio_next_track,
+ playlist_amount,
+ audio_status,
+ audio_has_changed_track,
+ audio_current_track,
+ audio_flush_and_reload_tracks,
+ audio_get_file_pos,
+#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
+ mpeg_get_last_header,
+#endif
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ sound_set_pitch,
+#endif
+
+#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
+ /* MAS communication */
+ mas_readmem,
+ mas_writemem,
+ mas_readreg,
+ mas_writereg,
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ mas_codec_writereg,
+ mas_codec_readreg,
+#endif
+#endif /* !simulator and HWCODEC != MASNONE */
+
+ /* tag database */
+ &tagdbheader,
+ &tagdb_fd,
+ &tagdb_initialized,
+ tagdb_init,
+
+ /* misc */
+ srand,
+ rand,
+ (qsort_func)qsort,
+ kbd_input,
+ get_time,
+ set_time,
+ plugin_get_audio_buffer,
+
+#if defined(DEBUG) || defined(SIMULATOR)
+ debugf,
+#endif
+ &global_settings,
+ mp3info,
+ count_mp3_frames,
+ create_xing_header,
+ find_next_frame,
+ battery_level,
+ battery_level_safe,
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ peak_meter_scale_value,
+ peak_meter_set_use_dbfs,
+ peak_meter_get_use_dbfs,
+#endif
+#ifdef HAVE_LCD_BITMAP
+ read_bmp_file,
+#endif
+
+ /* new stuff at the end, sort into place next time
+ the API gets incompatible */
+
+#ifdef ROCKBOX_HAS_LOGF
+ logf,
+#endif
+
+};
+
+int codec_load_ram(char* codecptr, size_t size, void* ptr2, size_t bufwrap)
+{
+ enum codec_status (*codec_start)(const struct codec_api* api, void* param);
+ int copy_n;
+ int status;
+
+ if ((char *)&codecbuf[0] != codecptr) {
+ /* zero out codec buffer to ensure a properly zeroed bss area */
+ memset(codecbuf, 0, CODEC_BUFFER_SIZE);
+
+ size = MIN(size, CODEC_BUFFER_SIZE);
+ copy_n = MIN(size, bufwrap);
+ memcpy(codecbuf, codecptr, copy_n);
+ size -= copy_n;
+ if (size > 0) {
+ memcpy(&codecbuf[copy_n], ptr2, size);
+ }
+ }
+ codec_start = (void*)&codecbuf;
+
+ invalidate_icache();
+ status = codec_start(&ci, NULL);
+
+ return status;
+}
+
+int codec_load_file(const char *plugin)
+{
+ char msgbuf[80];
+ int fd;
+ int rc;
+
+ fd = open(plugin, O_RDONLY);
+ if (fd < 0) {
+ snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
+ logf("Codec load error:%d", fd);
+ splash(HZ*2, true, msgbuf);
+ return fd;
+ }
+
+ rc = read(fd, &codecbuf[0], CODEC_BUFFER_SIZE);
+ close(fd);
+ if (rc <= 0) {
+ logf("Codec read error");
+ return CODEC_ERROR;
+ }
+
+ return codec_load_ram(codecbuf, (size_t)rc, NULL, 0);
+}
+
+static int codec_test(int api_version, int model, int memsize)
+{
+ if (api_version < CODEC_MIN_API_VERSION ||
+ api_version > CODEC_API_VERSION)
+ return CODEC_WRONG_API_VERSION;
+
+ (void)model;
+#if 0
+ if (model != MODEL)
+ return CODEC_WRONG_MODEL;
+#endif
+
+ if (memsize != MEM)
+ return CODEC_WRONG_MODEL;
+
+ return CODEC_OK;
+}
diff --git a/apps/codecs.h b/apps/codecs.h
new file mode 100644
index 0000000..2c2a4cf
--- /dev/null
+++ b/apps/codecs.h
@@ -0,0 +1,403 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Björn Stenberg
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _CODECS_H_
+#define _CODECS_H_
+
+/* instruct simulator code to not redefine any symbols when compiling codecs.
+ (the CODEC macro is defined in apps/codecs/Makefile) */
+#ifdef CODEC
+#define NO_REDEFINES_PLEASE
+#endif
+
+#ifndef MEM
+#define MEM 2
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "config.h"
+#include "dir.h"
+#include "kernel.h"
+#include "button.h"
+#include "font.h"
+#include "system.h"
+#include "lcd.h"
+#include "id3.h"
+#include "mpeg.h"
+#include "audio.h"
+#include "mp3_playback.h"
+#if (HWCODEC == MASNONE)
+#include "pcm_playback.h"
+#endif
+#include "settings.h"
+#include "thread.h"
+#include "playlist.h"
+#ifdef HAVE_LCD_BITMAP
+#include "widgets.h"
+#endif
+#include "sound.h"
+
+#ifdef HAVE_REMOTE_LCD
+#include "lcd-remote.h"
+#endif
+
+#ifdef CODEC
+
+#if defined(DEBUG) || defined(SIMULATOR)
+#undef DEBUGF
+#define DEBUGF rb->debugf
+#undef LDEBUGF
+#define LDEBUGF rb->debugf
+#else
+#define DEBUGF(...)
+#define LDEBUGF(...)
+#endif
+
+#ifdef ROCKBOX_HAS_LOGF
+#undef LOGF
+#define LOGF rb->logf
+#else
+#define LOGF(...)
+#endif
+
+#endif
+
+/* This size must match the one set in ../plugins/plugin.lds */
+#define CODEC_BUFFER_SIZE 0x3C000
+
+#ifdef SIMULATOR
+#define PREFIX(_x_) sim_ ## _x_
+#else
+#define PREFIX(_x_) _x_
+#endif
+
+/* increase this every time the api struct changes */
+#define CODEC_API_VERSION 40
+
+/* 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 40
+
+/* codec return codes */
+enum codec_status {
+ CODEC_OK = 0,
+ CODEC_USB_CONNECTED,
+
+ CODEC_WRONG_API_VERSION = -1,
+ CODEC_WRONG_MODEL = -2,
+ CODEC_ERROR = -3,
+};
+
+/* compatibility test macro */
+#define TEST_CODEC_API(_api_) \
+do { \
+ int _rc_ = _api_->codec_test(CODEC_API_VERSION, 1, MEM); \
+ if (_rc_<0) \
+ return _rc_; \
+} while(0)
+
+/* NOTE: To support backwards compatibility, only add new functions at
+ the end of the structure. Every time you add a new function,
+ remember to increase CODEC_API_VERSION. If you make changes to the
+ existing APIs then also update CODEC_MIN_API_VERSION to current
+ version
+ */
+struct codec_api {
+ /* these two fields must always be first, to ensure
+ TEST_CODEC_API will always work */
+ int version;
+ int (*codec_test)(int api_version, int model, int memsize);
+
+ off_t filesize; /* Total file length */
+ off_t curpos; /* Current buffer position */
+
+ /* For gapless mp3 */
+ struct mp3entry *id3; /* TAG metadata pointer */
+ struct mp3info *mp3data; /* MP3 metadata pointer */
+ bool *taginfo_ready; /* Is metadata read */
+
+ /* Codec should periodically check if stop_codec is set to true.
+ In case it's, codec must return with PLUGIN_OK status immediately. */
+ bool stop_codec;
+ /* Codec should periodically check if reload_codec is set to true.
+ In case it's, codec should reload itself without exiting. */
+ bool reload_codec;
+ /* If seek_time != 0, codec should seek to that song position (in ms)
+ if codec supports seeking. */
+ int seek_time;
+
+ /* Returns buffer to malloc array. Only codeclib should need this. */
+ void* (*get_codec_memory)(size_t *size);
+ /* Insert PCM data into audio buffer for playback. Playback will start
+ automatically. */
+ bool (*audiobuffer_insert)(char *data, size_t length);
+ /* Set song position in WPS (value in ms). */
+ void (*set_elapsed)(unsigned int value);
+
+ /* Read next <size> amount bytes from file buffer to <ptr>.
+ Will return number of bytes read or 0 if end of file. */
+ size_t (*read_filebuf)(void *ptr, size_t size);
+ /* Request pointer to file buffer which can be used to read
+ <realsize> amount of data. <reqsize> tells the buffer system
+ how much data it should try to allocate. If <realsize> is 0,
+ end of file is reached. */
+ void* (*request_buffer)(size_t *realsize, size_t reqsize);
+ /* Advance file buffer position by <amount> amount of bytes. */
+ void (*advance_buffer)(size_t amount);
+ /* Advance file buffer to a pointer location inside file buffer. */
+ void (*advance_buffer_loc)(void *ptr);
+ /* Seek file buffer to position <newpos> beginning of file. */
+ bool (*seek_buffer)(off_t newpos);
+ /* Calculate mp3 seek position from given time data in ms. */
+ off_t (*mp3_get_filepos)(int newtime);
+ /* Request file change from file buffer. Returns true is next
+ track is available and changed. If return value is false,
+ codec should exit immediately with PLUGIN_OK status. */
+ bool (*request_next_track)(void);
+
+ /* Configure different codec buffer parameters. */
+ void (*configure)(int setting, void *value);
+
+
+ /* lcd */
+ void (*lcd_clear_display)(void);
+ void (*lcd_puts)(int x, int y, const unsigned char *string);
+ void (*lcd_puts_scroll)(int x, int y, const unsigned char* string);
+ void (*lcd_stop_scroll)(void);
+ void (*lcd_set_contrast)(int x);
+#ifdef HAVE_LCD_CHARCELLS
+ void (*lcd_define_pattern)(int which,const char *pattern);
+ unsigned char (*lcd_get_locked_pattern)(void);
+ void (*lcd_unlock_pattern)(unsigned char pat);
+ void (*lcd_putc)(int x, int y, unsigned short ch);
+ void (*lcd_put_cursor)(int x, int y, char cursor_char);
+ void (*lcd_remove_cursor)(void);
+ void (*PREFIX(lcd_icon))(int icon, bool enable);
+#else
+ void (*lcd_putsxy)(int x, int y, const unsigned char *string);
+ void (*lcd_puts_style)(int x, int y, const unsigned char *str, int style);
+ void (*lcd_puts_scroll_style)(int x, int y, const unsigned char* string,
+ int style);
+ void (*lcd_bitmap)(const unsigned char *src, int x, int y,
+ int nx, int ny, bool clear);
+ void (*lcd_drawline)(int x1, int y1, int x2, int y2);
+ void (*lcd_clearline)(int x1, int y1, int x2, int y2);
+ void (*lcd_drawpixel)(int x, int y);
+ void (*lcd_clearpixel)(int x, int y);
+ void (*lcd_setfont)(int font);
+ struct font* (*font_get)(int font);
+ void (*lcd_clearrect)(int x, int y, int nx, int ny);
+ void (*lcd_fillrect)(int x, int y, int nx, int ny);
+ void (*lcd_drawrect)(int x, int y, int nx, int ny);
+ void (*lcd_invertrect)(int x, int y, int nx, int ny);
+ int (*lcd_getstringsize)(const unsigned char *str, int *w, int *h);
+ void (*lcd_update)(void);
+ void (*lcd_update_rect)(int x, int y, int width, int height);
+ void (*scrollbar)(int x, int y, int width, int height, int items,
+ int min_shown, int max_shown, int orientation);
+ void (*checkbox)(int x, int y, int width, int height, bool checked);
+ unsigned char* lcd_framebuffer;
+ void (*lcd_blit) (const unsigned char* p_data, int x, int y, int width,
+ int height, int stride);
+#ifndef SIMULATOR
+ void (*lcd_roll)(int pixels);
+#endif
+#endif
+ void (*backlight_on)(void);
+ void (*backlight_off)(void);
+ void (*backlight_set_timeout)(int index);
+ void (*splash)(int ticks, bool center, const char *fmt, ...);
+
+ /* file */
+ int (*PREFIX(open))(const char* pathname, int flags);
+ int (*close)(int fd);
+ ssize_t (*read)(int fd, void* buf, size_t count);
+ off_t (*PREFIX(lseek))(int fd, off_t offset, int whence);
+ int (*PREFIX(creat))(const char *pathname, mode_t mode);
+ ssize_t (*write)(int fd, const void* buf, size_t count);
+ int (*PREFIX(remove))(const char* pathname);
+ int (*PREFIX(rename))(const char* path, const char* newname);
+ int (*PREFIX(ftruncate))(int fd, off_t length);
+
+ int (*fdprintf)(int fd, const char *fmt, ...);
+ int (*read_line)(int fd, char* buffer, int buffer_size);
+ bool (*settings_parseline)(char* line, char** name, char** value);
+#ifndef SIMULATOR
+ int (*ata_sleep)(void);
+#endif
+
+ /* dir */
+ DIR* (*PREFIX(opendir))(const char* name);
+ int (*PREFIX(closedir))(DIR* dir);
+ struct dirent* (*PREFIX(readdir))(DIR* dir);
+ int (*PREFIX(mkdir))(const char *name, int mode);
+
+ /* kernel/ system */
+ void (*PREFIX(sleep))(int ticks);
+ void (*yield)(void);
+ long* current_tick;
+ long (*default_event_handler)(long event);
+ long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
+ int (*create_thread)(void* function, void* stack, int stack_size, const char *name);
+ void (*remove_thread)(int threadnum);
+ void (*reset_poweroff_timer)(void);
+#ifndef SIMULATOR
+ int (*system_memory_guard)(int newmode);
+ long *cpu_frequency;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ void (*cpu_boost)(bool on_off);
+#endif
+#endif
+
+ /* strings and memory */
+ int (*snprintf)(char *buf, size_t size, const char *fmt, ...);
+ char* (*strcpy)(char *dst, const char *src);
+ char* (*strncpy)(char *dst, const char *src, size_t length);
+ size_t (*strlen)(const char *str);
+ char * (*strrchr)(const char *s, int c);
+ int (*strcmp)(const char *, const char *);
+ int (*strcasecmp)(const char *, const char *);
+ int (*strncasecmp)(const char *s1, const char *s2, size_t n);
+ void* (*memset)(void *dst, int c, size_t length);
+ void* (*memcpy)(void *out, const void *in, size_t n);
+ const char *_ctype_;
+ int (*atoi)(const char *str);
+ char *(*strchr)(const char *s, int c);
+ char *(*strcat)(char *s1, const char *s2);
+ int (*memcmp)(const void *s1, const void *s2, size_t n);
+ char *(*strcasestr) (const char* phaystack, const char* pneedle);
+
+ /* sound */
+ void (*sound_set)(int setting, int value);
+#ifndef SIMULATOR
+ void (*mp3_play_data)(const unsigned char* start, int size, void (*get_more)(unsigned char** start, int* size));
+ void (*mp3_play_pause)(bool play);
+ void (*mp3_play_stop)(void);
+ bool (*mp3_is_playing)(void);
+#if CONFIG_HWCODEC != MASNONE
+ void (*bitswap)(unsigned char *data, int length);
+#endif
+#if CONFIG_HWCODEC == MASNONE
+ void (*pcm_play_data)(const unsigned char *start, int size,
+ void (*get_more)(unsigned char** start, long*size));
+ void (*pcm_play_stop)(void);
+ void (*pcm_set_frequency)(unsigned int frequency);
+ bool (*pcm_is_playing)(void);
+ void (*pcm_play_pause)(bool play);
+#endif
+#endif /* !SIMULATOR */
+
+ /* playback control */
+ void (*PREFIX(audio_play))(int offset);
+ void (*audio_stop)(void);
+ void (*audio_pause)(void);
+ void (*audio_resume)(void);
+ void (*audio_next)(void);
+ void (*audio_prev)(void);
+ void (*audio_ff_rewind)(int newtime);
+ struct mp3entry* (*audio_next_track)(void);
+ int (*playlist_amount)(void);
+ int (*audio_status)(void);
+ bool (*audio_has_changed_track)(void);
+ struct mp3entry* (*audio_current_track)(void);
+ void (*audio_flush_and_reload_tracks)(void);
+ int (*audio_get_file_pos)(void);
+#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
+ unsigned long (*mpeg_get_last_header)(void);
+#endif
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ void (*sound_set_pitch)(int pitch);
+#endif
+
+ /* MAS communication */
+#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
+ int (*mas_readmem)(int bank, int addr, unsigned long* dest, int len);
+ int (*mas_writemem)(int bank, int addr, const unsigned long* src, int len);
+ int (*mas_readreg)(int reg);
+ int (*mas_writereg)(int reg, unsigned int val);
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ int (*mas_codec_writereg)(int reg, unsigned int val);
+ int (*mas_codec_readreg)(int reg);
+#endif
+#endif
+
+ /* tag database */
+ struct tagdb_header *tagdbheader;
+ int *tagdb_fd;
+ int *tagdb_initialized;
+ int (*tagdb_init) (void);
+
+ /* misc */
+ void (*srand)(unsigned int seed);
+ int (*rand)(void);
+ void (*qsort)(void *base, size_t nmemb, size_t size,
+ int(*compar)(const void *, const void *));
+ int (*kbd_input)(char* buffer, int buflen);
+ struct tm* (*get_time)(void);
+ int (*set_time)(const struct tm *tm);
+ void* (*plugin_get_audio_buffer)(int* buffer_size);
+
+#if defined(DEBUG) || defined(SIMULATOR)
+ void (*debugf)(const char *fmt, ...);
+#endif
+ struct user_settings* global_settings;
+ bool (*mp3info)(struct mp3entry *entry, const char *filename, bool v1first);
+ int (*count_mp3_frames)(int fd, int startpos, int filesize,
+ void (*progressfunc)(int));
+ int (*create_xing_header)(int fd, int startpos, int filesize,
+ unsigned char *buf, int num_frames,
+ unsigned long header_template,
+ void (*progressfunc)(int), bool generate_toc);
+ unsigned long (*find_next_frame)(int fd, long *offset,
+ long max_offset, unsigned long last_header);
+ int (*battery_level)(void);
+ bool (*battery_level_safe)(void);
+#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
+ unsigned short (*peak_meter_scale_value)(unsigned short val,
+ int meterwidth);
+ void (*peak_meter_set_use_dbfs)(int use);
+ int (*peak_meter_get_use_dbfs)(void);
+#endif
+#ifdef HAVE_LCD_BITMAP
+ int (*read_bmp_file)(char* filename, int *get_width, int *get_height,
+ char *bitmap, int maxsize);
+#endif
+
+ /* new stuff at the end, sort into place next time
+ the API gets incompatible */
+
+#ifdef ROCKBOX_HAS_LOGF
+ void (*logf)(const char *fmt, ...);
+#endif
+};
+
+/* 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_file(const char* codec);
+#endif
+
+/* defined by the codec */
+enum codec_status codec_start(struct codec_api* rockbox, void* parameter)
+ __attribute__ ((section (".entry")));
+
+#endif
diff --git a/apps/codecs/Makefile b/apps/codecs/Makefile
index ffd8eab..970048e 100644
--- a/apps/codecs/Makefile
+++ b/apps/codecs/Makefile
@@ -10,20 +10,97 @@
INCLUDES = -I$(FIRMDIR)/include -I$(FIRMDIR)/export -I$(FIRMDIR)/common \
-I$(FIRMDIR)/drivers -I$(APPSDIR) -Ilib -I$(BUILDDIR)
CFLAGS = $(GCCOPTS) $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \
- -DMEM=${MEMORYSIZE}
+ -DMEM=${MEMORYSIZE} -DCODEC
ifdef APPEXTRA
INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
endif
+ifdef SOFTWARECODECS
+ CODECLIBS = -lmad -la52 -lFLAC -lTremor -lwavpack -lmusepack
+endif
+
+# we "borrow" the plugin LDS file
+LDS := $(APPSDIR)/plugins/plugin.lds
+
+LINKCODEC := $(OBJDIR)/codeclink.lds
+DEPFILE = $(OBJDIR)/dep-codecs
+
+# This sets up 'SRC' based on the files mentioned in SOURCES
+include $(TOOLSDIR)/makesrc.inc
+
+ROCKS := $(SRC:%.c=$(OBJDIR)/%.codec)
+SOURCES = $(SRC)
+ELFS := $(SRC:%.c=$(OBJDIR)/%.elf)
+OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
+# as created by the cross-compiler for win32:
+DEFS := $(SRC:%.c=$(OBJDIR)/%.def)
+DIRS = .
+
.PHONY: libmad liba52 libFLAC libTremor libwavpack dumb libmusepack
OUTPUT = $(SOFTWARECODECS)
-all: $(OUTPUT)
+all: $(OUTPUT) $(ROCKS) $(DEPFILE)
+
+ifndef SIMVER
+$(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKCODEC)
+ $(SILENT)(file=`basename $@`; \
+ echo "LD $$file"; \
+ $(CC) $(GCCOPTS) -O -nostdlib -o $@ $< -L$(BUILDDIR) $(CODECLIBS) -lcodec -lgcc -T$(LINKCODEC) -Wl,-Map,$(OBJDIR)/$*.map)
+
+$(OBJDIR)/%.codec : $(OBJDIR)/%.elf
+ @echo "OBJCOPY "`basename $@`
+ @$(OC) -O binary $< $@
+else
+
+ifeq ($(SIMVER), x11)
+###################################################
+# This is the X11 simulator version
+
+$(OBJDIR)/%.codec : $(OBJDIR)/%.o $(BUILDDIR)/libplugin.a
+ @echo "LD "`basename $@`
+ @$(CC) $(CFLAGS) -shared $< -L$(BUILDDIR) $(CODECLIBS) -lplugin -o $@
+ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
+# 'x' must be kept or you'll have "Win32 error 5"
+# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
+# #define ERROR_ACCESS_DENIED 5L
+else
+ @chmod -x $@
+endif
+
+else # end of x11-simulator
+###################################################
+# This is the win32 simulator version
+DLLTOOLFLAGS = --export-all
+DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
+
+$(OBJDIR)/%.codec : $(OBJDIR)/%.o $(BUILDDIR)/libplugin.a
+ @echo "DLL "`basename $@`
+ @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $<
+ @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $< $(BUILDDIR)/libplugin.a \
+ $(patsubst -l%,$(BUILDDIR)/lib%.a,$(CODECLIBS)) -o $@
+ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
+# 'x' must be kept or you'll have "Win32 error 5"
+# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
+# #define ERROR_ACCESS_DENIED 5L
+else
+ @chmod -x $@
+endif
+endif # end of win32-simulator
+
+endif # end of simulator section
include $(TOOLSDIR)/make.inc
+$(BUILDDIR)/libcodec.a:
+ @echo "MAKE in codecs/lib"
+ @mkdir -p $(OBJDIR)/lib
+ @$(MAKE) -C lib OBJDIR=$(OBJDIR)/lib
+
+$(LINKCODEC): $(LDS)
+ @echo "build $@"
+ @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) -DCODEC $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@
libmad:
@echo "MAKE in libmad"
diff --git a/apps/plugins/codeca52.c b/apps/codecs/a52.c
index ced5ced..d35854e 100644
--- a/apps/plugins/codeca52.c
+++ b/apps/codecs/a52.c
@@ -17,7 +17,7 @@
*
****************************************************************************/
-#include "plugin.h"
+#include "codec.h"
#include <inttypes.h> /* Needed by a52.h */
#include <codecs/liba52/config-a52.h>
@@ -28,7 +28,7 @@
#define BUFFER_SIZE 4096
-struct plugin_api* rb;
+struct codec_api* rb;
struct codec_api* ci;
static float gain = 1;
@@ -154,17 +154,17 @@ extern char iramstart[];
extern char iramend[];
#endif
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
{
size_t n;
unsigned char* filebuf;
- /* Generic plugin initialisation */
- TEST_PLUGIN_API(api);
+ /* Generic codec initialisation */
+ TEST_CODEC_API(api);
rb = api;
- ci = (struct codec_api*)parm;
+ ci = (struct codec_api*)api;
#ifndef SIMULATOR
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
@@ -175,8 +175,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
next_track:
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
+ if (codec_init(api)) {
+ return CODEC_ERROR;
}
/* Intialise the A52 decoder and check for success */
@@ -206,5 +206,5 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
//NOT NEEDED??: a52_free (state);
- return PLUGIN_OK;
+ return CODEC_OK;
}
diff --git a/apps/plugins/codecflac.c b/apps/codecs/flac.c
index 1cc95b3..93134bb 100644
--- a/apps/plugins/codecflac.c
+++ b/apps/codecs/flac.c
@@ -17,7 +17,7 @@
*
****************************************************************************/
-#include "plugin.h"
+#include "codec.h"
#include <codecs/libFLAC/include/FLAC/seekable_stream_decoder.h>
#include "playback.h"
@@ -26,7 +26,7 @@
#define FLAC_MAX_SUPPORTED_BLOCKSIZE 4608
#define FLAC_MAX_SUPPORTED_CHANNELS 2
-static struct plugin_api* rb;
+static struct codec_api* rb;
static uint32_t samplesdone;
/* Called when the FLAC decoder needs some FLAC data to decode */
@@ -159,14 +159,14 @@ extern char iramstart[];
extern char iramend[];
#endif
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
{
- struct codec_api* ci = (struct codec_api*)parm;
- FLAC__SeekableStreamDecoder* flacDecoder;
+ struct codec_api* ci = api;
+ FLAC__SeekableStreamDecoder* flacDecoder;
- /* Generic plugin initialisation */
- TEST_PLUGIN_API(api);
+ /* Generic codec initialisation */
+ TEST_CODEC_API(api);
/* if you are using a global api pointer, don't forget to copy it!
otherwise you will get lovely "I04: IllInstr" errors... :-) */
@@ -182,8 +182,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
next_track:
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
+ if (codec_init(api)) {
+ return CODEC_ERROR;
}
/* Create a decoder instance */
@@ -209,7 +209,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
/* QUESTION: What do we do when the init fails? */
if (FLAC__seekable_stream_decoder_init(flacDecoder)) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
/* The first thing to do is to parse the metadata */
@@ -244,5 +244,5 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
if (ci->request_next_track())
goto next_track;
- return PLUGIN_OK;
+ return CODEC_OK;
}
diff --git a/apps/codecs/lib/Makefile b/apps/codecs/lib/Makefile
new file mode 100644
index 0000000..08dcd2a
--- /dev/null
+++ b/apps/codecs/lib/Makefile
@@ -0,0 +1,46 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+# ../.. for the codec.h in the apps dir
+# .. for stuff in the codecs dir
+# . for stuff in the codeclib dir
+INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
+ -I$(FIRMDIR)/common -I$(BUILDDIR)
+
+ifdef APPEXTRA
+INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
+endif
+
+CFLAGS = $(GCCOPTS) \
+$(INCLUDES) $(TARGET) $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} -DCODEC
+
+# This sets up 'SRC' based on the files mentioned in SOURCES
+include $(TOOLSDIR)/makesrc.inc
+
+SOURCES = $(SRC)
+OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
+DEPFILE = $(OBJDIR)/dep-codeclib
+DIRS = .
+
+OUTPUT = $(BUILDDIR)/libcodec.a
+
+all: $(OUTPUT)
+
+$(OUTPUT): $(OBJS)
+ @echo "AR+RANLIB $@"
+ @$(AR) ruv $@ $+ >/dev/null 2>&1
+ @$(RANLIB) $@
+
+include $(TOOLSDIR)/make.inc
+
+clean:
+ @echo "cleaning lib"
+ @rm -f $(OBJS) $(OUTPUT) $(DEPFILE)
+
+-include $(DEPFILE)
diff --git a/apps/plugins/lib/codeclib.c b/apps/codecs/lib/codeclib.c
index 9d9cc0b..3aa6216 100644
--- a/apps/plugins/lib/codeclib.c
+++ b/apps/codecs/lib/codeclib.c
@@ -17,21 +17,22 @@
*
****************************************************************************/
-/* Various "helper functions" common to all the xxx2wav decoder plugins */
+/* "helper functions" common to all codecs */
#include "plugin.h"
#include "playback.h"
#include "codeclib.h"
#include "xxx2wav.h"
-struct plugin_api* local_rb;
+struct codec_api *local_rb;
-int codec_init(struct plugin_api* rb, struct codec_api* ci) {
+int codec_init(struct codec_api* rb)
+{
local_rb = rb;
xxx2wav_set_api(rb);
mem_ptr = 0;
- mallocbuf = (unsigned char *)ci->get_codec_memory((size_t *)&bufsize);
+ mallocbuf = (unsigned char *)rb->get_codec_memory((size_t *)&bufsize);
return 0;
}
diff --git a/apps/plugins/lib/codeclib.h b/apps/codecs/lib/codeclib.h
index 876e69b..116f210 100644
--- a/apps/plugins/lib/codeclib.h
+++ b/apps/codecs/lib/codeclib.h
@@ -17,7 +17,10 @@
*
****************************************************************************/
-/* Various "helper functions" common to all the xxx2wav decoder plugins */
+#include "config.h"
+#include "codecs.h"
+
+/* Various codec "helper functions" */
#if CONFIG_CPU == MCF5249 && !defined(SIMULATOR)
#define ICODE_ATTR __attribute__ ((section(".icode")))
@@ -42,5 +45,5 @@ void *memset(void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void* memmove(const void *s1, const void *s2, size_t n);
-int codec_init(struct plugin_api* rb, struct codec_api* ci);
+int codec_init(struct codec_api* rb);
diff --git a/apps/plugins/lib/xxx2wav.c b/apps/codecs/lib/xxx2wav.c
index 8eadfb8..1bc1837 100644
--- a/apps/plugins/lib/xxx2wav.c
+++ b/apps/codecs/lib/xxx2wav.c
@@ -22,10 +22,10 @@
#if (CONFIG_HWCODEC == MASNONE)
/* software codec platforms, not for simulator */
-#include "plugin.h"
+#include "codecs.h"
#include "xxx2wav.h"
-static struct plugin_api* local_rb;
+static struct codec_api* local_rb;
int mem_ptr;
int bufsize;
@@ -33,11 +33,12 @@ unsigned char* audiobuf; // The actual audio buffer from Rockbox
unsigned char* mallocbuf; // 512K from the start of audio buffer
unsigned char* filebuf; // The rest of the audio buffer
-void* codec_malloc(size_t size) {
- void* x;
+void* codec_malloc(size_t size)
+{
+ void* x;
- x=&mallocbuf[mem_ptr];
- mem_ptr+=(size+3)&~3; // Keep memory 32-bit aligned (if it was already?)
+ x=&mallocbuf[mem_ptr];
+ mem_ptr+=(size+3)&~3; // Keep memory 32-bit aligned (if it was already?)
/*
if(TIME_AFTER(*(local_rb->current_tick), last_tick + HZ)) {
char s[32];
@@ -48,24 +49,26 @@ void* codec_malloc(size_t size) {
last_tick = *(local_rb->current_tick);
local_rb->lcd_update();
}*/
- return(x);
+ return(x);
}
-void* codec_calloc(size_t nmemb, size_t size) {
- void* x;
- x = codec_malloc(nmemb*size);
- local_rb->memset(x,0,nmemb*size);
- return(x);
+void* codec_calloc(size_t nmemb, size_t size)
+{
+ void* x;
+ x = codec_malloc(nmemb*size);
+ local_rb->memset(x,0,nmemb*size);
+ return(x);
}
-void* codec_alloca(size_t size) {
- void* x;
- x = codec_malloc(size);
- return(x);
+void* codec_alloca(size_t size)
+{
+ void* x;
+ x = codec_malloc(size);
+ return(x);
}
void codec_free(void* ptr) {
- (void)ptr;
+ (void)ptr;
}
void* codec_realloc(void* ptr, size_t size) {
@@ -146,6 +149,7 @@ void display_status(file_info_struct* file_info) {
}
}
+#if 0
static unsigned char wav_header[44]={'R','I','F','F', // 0 - ChunkID
0,0,0,0, // 4 - ChunkSize (filesize-8)
'W','A','V','E', // 8 - Format
@@ -160,14 +164,18 @@ static unsigned char wav_header[44]={'R','I','F','F', // 0 - ChunkID
'd','a','t','a', // 36 - Subchunk2ID
0,0,0,0 // 40 - Subchunk2Size
};
+#endif
-
-void xxx2wav_set_api(struct plugin_api* rb)
+void xxx2wav_set_api(struct codec_api* rb)
{
local_rb = rb;
}
-int local_init(char* infilename, char* outfilename, file_info_struct* file_info, struct plugin_api* rb) {
+#if 0
+int local_init(char* infilename, char* outfilename,
+ file_info_struct* file_info,
+ struct codec_api* rb)
+{
char s[32];
int i,n,bytesleft;
@@ -218,7 +226,8 @@ int local_init(char* infilename, char* outfilename, file_info_struct* file_info,
return(0);
}
-void close_wav(file_info_struct* file_info) {
+void close_wav(file_info_struct* file_info)
+{
int x;
int filesize=local_rb->filesize(file_info->outfile);
@@ -256,4 +265,6 @@ void close_wav(file_info_struct* file_info) {
local_rb->write(file_info->outfile,wav_header,sizeof(wav_header));
local_rb->close(file_info->outfile);
}
+#endif /* 0 */
+
#endif /* CONFIG_HWCODEC == MASNONE */
diff --git a/apps/plugins/lib/xxx2wav.h b/apps/codecs/lib/xxx2wav.h
index 7e1b942..1fa7dc9 100644
--- a/apps/plugins/lib/xxx2wav.h
+++ b/apps/codecs/lib/xxx2wav.h
@@ -62,6 +62,8 @@ int memcmp(const void *s1, const void *s2, size_t n);
void* memmove(const void *s1, const void *s2, size_t n);
void display_status(file_info_struct* file_info);
-int local_init(char* infilename, char* outfilename, file_info_struct* file_info, struct plugin_api* rb);
+int local_init(char* infilename, char* outfilename,
+ file_info_struct* file_info,
+ struct codec_api* rb);
void close_wav(file_info_struct* file_info);
-void xxx2wav_set_api(struct plugin_api* rb);
+void xxx2wav_set_api(struct codec_api* rb);
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
new file mode 100644
index 0000000..beb71d7
--- /dev/null
+++ b/apps/codecs/mpa.c
@@ -0,0 +1,521 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 Dave Chapman
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "codec.h"
+
+#include <codecs/libmad/mad.h>
+
+#include "playback.h"
+#include "mp3data.h"
+#include "lib/codeclib.h"
+
+static struct codec_api* rb;
+
+struct mad_stream Stream IDATA_ATTR;
+struct mad_frame Frame IDATA_ATTR;
+struct mad_synth Synth IDATA_ATTR;
+mad_timer_t Timer;
+struct dither d0, d1;
+
+/* The following function is used inside libmad - let's hope it's never
+ called.
+*/
+
+void abort(void) {
+}
+
+/* The "dither" code to convert the 24-bit samples produced by libmad was
+ taken from the coolplayer project - coolplayer.sourceforge.net */
+
+struct dither {
+ mad_fixed_t error[3];
+ mad_fixed_t random;
+};
+
+# define SAMPLE_DEPTH 16
+# define scale(x, y) dither((x), (y))
+
+/*
+ * NAME: prng()
+ * DESCRIPTION: 32-bit pseudo-random number generator
+ */
+static __inline
+unsigned long prng(unsigned long state)
+{
+ return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
+}
+
+/*
+ * NAME: dither()
+ * DESCRIPTION: dither and scale sample
+ */
+static __inline
+signed int dither(mad_fixed_t sample, struct dither *dither)
+{
+ unsigned int scalebits;
+ mad_fixed_t output, mask, random;
+
+ enum {
+ MIN = -MAD_F_ONE,
+ MAX = MAD_F_ONE - 1
+ };
+
+ /* noise shape */
+ sample += dither->error[0] - dither->error[1] + dither->error[2];
+
+ dither->error[2] = dither->error[1];
+ dither->error[1] = dither->error[0] / 2;
+
+ /* bias */
+ output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1));
+
+ scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH;
+ mask = (1L << scalebits) - 1;
+
+ /* dither */
+ random = prng(dither->random);
+ output += (random & mask) - (dither->random & mask);
+
+ //dither->random = random;
+
+ /* clip */
+ if (output > MAX) {
+ output = MAX;
+
+ if (sample > MAX)
+ sample = MAX;
+ }
+ else if (output < MIN) {
+ output = MIN;
+
+ if (sample < MIN)
+ sample = MIN;
+ }
+
+ /* quantize */
+ output &= ~mask;
+
+ /* error feedback */
+ dither->error[0] = sample - output;
+
+ /* scale */
+ return output >> scalebits;
+}
+
+static __inline
+signed int detect_silence(mad_fixed_t sample)
+{
+ unsigned int scalebits;
+ mad_fixed_t output, mask;
+
+ enum {
+ MIN = -MAD_F_ONE,
+ MAX = MAD_F_ONE - 1
+ };
+
+ /* bias */
+ output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1));
+
+ scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH;
+ mask = (1L << scalebits) - 1;
+
+ /* clip */
+ if (output > MAX) {
+ output = MAX;
+
+ if (sample > MAX)
+ sample = MAX;
+ }
+ else if (output < MIN) {
+ output = MIN;
+
+ if (sample < MIN)
+ sample = MIN;
+ }
+
+ /* quantize */
+ output &= ~mask;
+
+ /* scale */
+ output >>= scalebits + 4;
+
+ if (output == 0x00 || output == 0xff)
+ return 1;
+
+ return 0;
+}
+#define SHRT_MAX 32767
+
+#define INPUT_CHUNK_SIZE 8192
+#define OUTPUT_BUFFER_SIZE 65536 /* Must be an integer multiple of 4. */
+
+unsigned char OutputBuffer[OUTPUT_BUFFER_SIZE];
+unsigned char *OutputPtr;
+unsigned char *GuardPtr=NULL;
+const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
+long resampled_data[2][5000]; /* enough to cope with 11khz upsampling */
+
+mad_fixed_t mad_frame_overlap[2][32][18] IDATA_ATTR;
+unsigned char mad_main_data[MAD_BUFFER_MDLEN] IDATA_ATTR;
+/* TODO: what latency does layer 1 have? */
+int mpeg_latency[3] = { 0, 481, 529 };
+#ifdef USE_IRAM
+extern char iramcopy[];
+extern char iramstart[];
+extern char iramend[];
+#endif
+
+#undef DEBUG_GAPLESS
+
+struct resampler {
+ long last_sample, phase, delta;
+};
+
+#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR)
+
+#define INIT() asm volatile ("move.l #0xb0, %macsr") /* frac, round, clip */
+#define FRACMUL(x, y) \
+({ \
+ long t; \
+ asm volatile ("mac.l %[a], %[b], %%acc0\n\t" \
+ "movclr.l %%acc0, %[t]\n\t" \
+ : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \
+ t; \
+})
+
+#else
+
+#define INIT()
+#define FRACMUL(x, y) (long)(((long long)(x)*(long long)(y)) << 1)
+#endif
+
+/* linear resampling, introduces one sample delay, because of our inability to
+ look into the future at the end of a frame */
+long downsample(long *in, long *out, int num, struct resampler *s)
+{
+ long i = 1, pos;
+ long last = s->last_sample;
+
+ INIT();
+ pos = s->phase >> 16;
+ /* check if we need last sample of previous frame for interpolation */
+ if (pos > 0)
+ last = in[pos - 1];
+ out[0] = last + FRACMUL((s->phase & 0xffff) << 15, in[pos] - last);
+ s->phase += s->delta;
+ while ((pos = s->phase >> 16) < num) {
+ out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]);
+ s->phase += s->delta;
+ }
+ /* wrap phase accumulator back to start of next frame */
+ s->phase -= num << 16;
+ s->last_sample = in[num - 1];
+ return i;
+}
+
+long upsample(long *in, long *out, int num, struct resampler *s)
+{
+ long i = 0, pos;
+
+ INIT();
+ while ((pos = s->phase >> 16) == 0) {
+ out[i++] = s->last_sample + FRACMUL((s->phase & 0xffff) << 15, in[pos] - s->last_sample);
+ s->phase += s->delta;
+ }
+ while ((pos = s->phase >> 16) < num) {
+ out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]);
+ s->phase += s->delta;
+ }
+ /* wrap phase accumulator back to start of next frame */
+ s->phase -= num << 16;
+ s->last_sample = in[num - 1];
+ return i;
+}
+
+long resample(long *in, long *out, int num, struct resampler *s)
+{
+ if (s->delta >= (1 << 16))
+ return downsample(in, out, num, s);
+ else
+ return upsample(in, out, num, s);
+}
+
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
+{
+ struct codec_api *ci = api;
+ struct mp3info *info;
+ int Status=0;
+ size_t size;
+ int file_end;
+ unsigned short Sample;
+ char *InputBuffer;
+ unsigned int samplecount;
+ unsigned int samplesdone;
+ bool first_frame;
+#ifdef DEBUG_GAPLESS
+ bool first = true;
+ int fd;
+#endif
+ int i;
+ int yieldcounter = 0;
+ int stop_skip, start_skip;
+ struct resampler lr = { 0, 0, 0 }, rr = { 0, 0, 0 };
+ long length;
+ /* Generic codec inititialisation */
+ (void)parm;
+
+ TEST_CODEC_API(api);
+ rb = api;
+
+#ifdef USE_IRAM
+ rb->memcpy(iramstart, iramcopy, iramend-iramstart);
+#endif
+
+ /* This function sets up the buffers and reads the file into RAM */
+
+ if (codec_init(api)) {
+ return CODEC_ERROR;
+ }
+
+ /* Create a decoder instance */
+
+ ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
+ ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16));
+
+ memset(&Stream, 0, sizeof(struct mad_stream));
+ memset(&Frame, 0, sizeof(struct mad_frame));
+ memset(&Synth, 0, sizeof(struct mad_synth));
+ memset(&Timer, 0, sizeof(mad_timer_t));
+
+ mad_stream_init(&Stream);
+ mad_frame_init(&Frame);
+ mad_synth_init(&Synth);
+ mad_timer_reset(&Timer);
+
+ /* We do this so libmad doesn't try to call codec_calloc() */
+ memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
+ Frame.overlap = &mad_frame_overlap;
+ Stream.main_data = &mad_main_data;
+ /* This label might need to be moved above all the init code, but I don't
+ think reiniting the codec is necessary for MPEG. It might even be unwanted
+ for gapless playback */
+ next_track:
+
+#ifdef DEBUG_GAPLESS
+ if (first)
+ fd = rb->open("/first.pcm", O_WRONLY | O_CREAT);
+ else
+ fd = rb->open("/second.pcm", O_WRONLY | O_CREAT);
+ first = false;
+#endif
+
+ info = ci->mp3data;
+ first_frame = false;
+ file_end = 0;
+ OutputPtr = OutputBuffer;
+
+ while (!*ci->taginfo_ready)
+ rb->yield();
+
+ ci->request_buffer(&size, ci->id3->first_frame_offset);
+ ci->advance_buffer(size);
+
+ if (info->enc_delay >= 0 && info->enc_padding >= 0) {
+ stop_skip = info->enc_padding - mpeg_latency[info->layer];
+ if (stop_skip < 0) stop_skip = 0;
+ start_skip = info->enc_delay + mpeg_latency[info->layer];
+ } else {
+ stop_skip = 0;
+ /* We want to skip this amount anyway */
+ start_skip = mpeg_latency[info->layer];
+ }
+
+ /* NOTE: currently this doesn't work, the below calculated samples_count
+ seems to be right, but sometimes libmad just can't supply us with
+ all the data we need... */
+ if (info->frame_count) {
+ /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3,
+ it's probably not correct at all for MPEG2 and layer 1 */
+ samplecount = info->frame_count*1152 - (start_skip + stop_skip);
+ samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10;
+ } else {
+ samplecount = ci->id3->length * (ci->id3->frequency / 100) / 10;
+ samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10;
+ }
+ /* rb->snprintf(buf2, sizeof(buf2), "sc: %d", samplecount);
+ rb->splash(0, true, buf2);
+ rb->snprintf(buf2, sizeof(buf2), "length: %d", ci->id3->length);
+ rb->splash(HZ*5, true, buf2);
+ rb->snprintf(buf2, sizeof(buf2), "frequency: %d", ci->id3->frequency);
+ rb->splash(HZ*5, true, buf2); */
+ lr.delta = rr.delta = ci->id3->frequency*65536/44100;
+ /* This is the decoding loop. */
+ while (1) {
+ rb->yield();
+ if (ci->stop_codec || ci->reload_codec) {
+ break ;
+ }
+
+ if (ci->seek_time) {
+ unsigned int sample_loc;
+ int newpos;
+
+ sample_loc = ci->seek_time/1000 * ci->id3->frequency;
+ newpos = ci->mp3_get_filepos(ci->seek_time-1);
+ if (ci->seek_buffer(newpos)) {
+ if (sample_loc >= samplecount + samplesdone)
+ break ;
+ samplecount += samplesdone - sample_loc;
+ samplesdone = sample_loc;
+ }
+ ci->seek_time = 0;
+ }
+
+ /* Lock buffers */
+ if (Stream.error == 0) {
+ InputBuffer = ci->request_buffer(&size, INPUT_CHUNK_SIZE);
+ if (size == 0 || InputBuffer == NULL)
+ break ;
+ mad_stream_buffer(&Stream, InputBuffer, size);
+ }
+
+ //if ((int)ci->curpos >= ci->id3->first_frame_offset)
+ //first_frame = true;
+
+ if(mad_frame_decode(&Frame,&Stream))
+ {
+ if (Stream.error == MAD_FLAG_INCOMPLETE || Stream.error == MAD_ERROR_BUFLEN) {
+ // rb->splash(HZ*1, true, "Incomplete");
+ /* This makes the codec to support partially corrupted files too. */
+ if (file_end == 30)
+ break ;
+
+ /* Fill the buffer */
+ Stream.error = 0;
+ file_end++;
+ continue ;
+ }
+ else if(MAD_RECOVERABLE(Stream.error))
+ {
+ if(Stream.error!=MAD_ERROR_LOSTSYNC || Stream.this_frame!=GuardPtr)
+ {
+ // rb->splash(HZ*1, true, "Recoverable...!");
+ }
+ continue;
+ }
+ else if(Stream.error==MAD_ERROR_BUFLEN) {
+ //rb->splash(HZ*1, true, "Buflen error");
+ break ;
+ } else {
+ //rb->splash(HZ*1, true, "Unrecoverable error");
+ Status=1;
+ break;
+ }
+ }
+ if (Stream.next_frame)
+ ci->advance_buffer_loc((void *)Stream.next_frame);
+ file_end = false;
+ /* ?? Do we need the timer module? */
+ // mad_timer_add(&Timer,Frame.header.duration);
+
+/* DAVE: This can be used to attenuate the audio */
+// if(DoFilter)
+// ApplyFilter(&Frame);
+
+ mad_synth_frame(&Synth,&Frame);
+
+ //if (!first_frame) {
+ //samplecount -= Synth.pcm.length;
+ //continue ;
+ //}
+
+ /* Convert MAD's numbers to an array of 16-bit LE signed integers */
+ /* We skip start_skip number of samples here, this should only happen for
+ very first frame in the stream. */
+ /* TODO: possible for start_skip to exceed one frames worth of samples? */
+ length = resample((long *)&Synth.pcm.samples[0][start_skip], resampled_data[0], Synth.pcm.length, &lr);
+ if (MAD_NCHANNELS(&Frame.header) == 2)
+ resample((long *)&Synth.pcm.samples[1][start_skip], resampled_data[1], Synth.pcm.length, &rr);
+ for (i = 0;i<length;i++)
+ {
+ start_skip = 0; /* not very elegant, and might want to keep this value */
+ samplesdone++;
+ //if (ci->mp3data->padding > 0) {
+ // ci->mp3data->padding--;
+ // continue ;
+ //}
+ /*if (!first_frame) {
+ if (detect_silence(Synth.pcm.samples[0][i]))
+ continue ;
+ first_frame = true;
+ }*/
+
+ /* Left channel */
+ Sample=scale(resampled_data[0][i],&d0);
+ *(OutputPtr++)=Sample>>8;
+ *(OutputPtr++)=Sample&0xff;
+
+ /* Right channel. If the decoded stream is monophonic then
+ * the right output channel is the same as the left one.
+ */
+ if(MAD_NCHANNELS(&Frame.header)==2)
+ Sample=scale(resampled_data[1][i],&d1);
+ *(OutputPtr++)=Sample>>8;
+ *(OutputPtr++)=Sample&0xff;
+
+ samplecount--;
+ if (samplecount == 0) {
+#ifdef DEBUG_GAPLESS
+ rb->write(fd, OutputBuffer, (int)OutputPtr-(int)OutputBuffer);
+#endif
+ while (!ci->audiobuffer_insert(OutputBuffer, (int)OutputPtr-(int)OutputBuffer))
+ rb->yield();
+ goto song_end;
+ }
+
+ if (yieldcounter++ == 200) {
+ rb->yield();
+ yieldcounter = 0;
+ }
+
+ /* Flush the buffer if it is full. */
+ if(OutputPtr==OutputBufferEnd)
+ {
+#ifdef DEBUG_GAPLESS
+ rb->write(fd, OutputBuffer, OUTPUT_BUFFER_SIZE);
+#endif
+ while (!ci->audiobuffer_insert(OutputBuffer, OUTPUT_BUFFER_SIZE))
+ rb->yield();
+ OutputPtr=OutputBuffer;
+ }
+ }
+ ci->set_elapsed(samplesdone / (ci->id3->frequency/1000));
+ }
+
+ song_end:
+#ifdef DEBUG_GAPLESS
+ rb->close(fd);
+#endif
+ Stream.error = 0;
+
+ if (ci->request_next_track())
+ goto next_track;
+ return CODEC_OK;
+}
diff --git a/apps/plugins/codecmpc.c b/apps/codecs/mpc.c
index 19eb518..9b4a616 100644
--- a/apps/plugins/codecmpc.c
+++ b/apps/codecs/mpc.c
@@ -17,12 +17,12 @@
*
****************************************************************************/
-#include "plugin.h"
+#include "codec.h"
#include "playback.h"
#include "lib/codeclib.h"
#include <codecs/libmusepack/musepack.h>
-static struct plugin_api* rb;
+static struct codec_api* rb;
mpc_decoder decoder;
/*
@@ -92,10 +92,10 @@ extern char iramstart[];
extern char iramend[];
#endif
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
{
- struct codec_api* ci = (struct codec_api*)parm;
+ struct codec_api* ci = api;
unsigned short Sample;
unsigned long samplesdone;
unsigned long frequency;
@@ -103,9 +103,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
unsigned int i;
mpc_reader reader;
- /* Generic plugin inititialisation */
+ /* Generic codec inititialisation */
- TEST_PLUGIN_API(api);
+ TEST_CODEC_API(api);
rb = api;
#ifndef SIMULATOR
@@ -117,8 +117,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
next_track:
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
+ if (codec_init(api)) {
+ return CODEC_ERROR;
}
/* Create a decoder instance */
@@ -134,14 +134,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
mpc_streaminfo info;
mpc_streaminfo_init(&info);
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
frequency=info.sample_freq;
/* instantiate a decoder with our file reader */
mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info)) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
/* Initialise the output buffer. */
@@ -158,7 +158,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
status = mpc_decoder_decode(&decoder, sample_buffer, 0, 0);
if (status == (unsigned)(-1)) {
//decode error
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
else //status>0
{
@@ -209,6 +209,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
if (ci->request_next_track())
goto next_track;
- return PLUGIN_OK;
+ return CODEC_OK;
}
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c
new file mode 100644
index 0000000..969fdf3
--- /dev/null
+++ b/apps/codecs/vorbis.c
@@ -0,0 +1,168 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 Björn Stenberg
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "kernel.h"
+#include "codecs.h"
+
+#include "Tremor/ivorbisfile.h"
+#include "playback.h"
+#include "lib/codeclib.h"
+
+static struct codec_api* rb;
+
+/* Some standard functions and variables needed by Tremor */
+
+int errno;
+
+size_t strlen(const char *s)
+{
+ return(rb->strlen(s));
+}
+
+char *strcpy(char *dest, const char *src)
+{
+ return(rb->strcpy(dest,src));
+}
+
+char *strcat(char *dest, const char *src)
+{
+ return(rb->strcat(dest,src));
+}
+
+size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource)
+{
+ return rb->read_filebuf(ptr, nmemb*size);
+}
+
+int seek_handler(void *datasource, ogg_int64_t offset, int whence)
+{
+ /* We are not seekable at the moment */
+ (void)datasource;
+ (void)offset;
+ (void)whence;
+ return -1;
+}
+
+int close_handler(void *datasource)
+{
+ (void)datasource;
+ return 0;
+}
+
+long tell_handler(void *datasource)
+{
+ return rb->curpos;
+}
+
+#ifdef USE_IRAM
+extern char iramcopy[];
+extern char iramstart[];
+extern char iramend[];
+#endif
+
+
+/* reserve the PCM buffer in the IRAM area */
+static char pcmbuf[4096] IDATA_ATTR;
+
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
+{
+ ov_callbacks callbacks;
+ OggVorbis_File vf;
+ vorbis_info* vi;
+
+ int error;
+ long n;
+ int current_section;
+ int eof;
+#if BYTE_ORDER == BIG_ENDIAN
+ int i;
+ char x;
+#endif
+
+ TEST_CODEC_API(api);
+
+ /* if you are using a global api pointer, don't forget to copy it!
+ otherwise you will get lovely "I04: IllInstr" errors... :-) */
+ rb = api;
+
+#ifdef USE_IRAM
+ rb->memcpy(iramstart, iramcopy, iramend-iramstart);
+#endif
+
+ rb->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
+ rb->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*64));
+
+ /* We need to flush reserver memory every track load. */
+ next_track:
+ if (codec_init(rb)) {
+ return CODEC_ERROR;
+ }
+
+
+ /* Create a decoder instance */
+
+ callbacks.read_func=read_handler;
+ callbacks.seek_func=seek_handler;
+ callbacks.tell_func=tell_handler;
+ callbacks.close_func=close_handler;
+
+ error=ov_open_callbacks(rb,&vf,NULL,0,callbacks);
+
+ vi=ov_info(&vf,-1);
+
+ if (vi==NULL) {
+ // rb->splash(HZ*2, true, "Vorbis Error");
+ return CODEC_ERROR;
+ }
+
+ eof=0;
+ while (!eof) {
+ /* Read host-endian signed 16 bit PCM samples */
+ n=ov_read(&vf,pcmbuf,sizeof(pcmbuf),&current_section);
+
+ if (n==0) {
+ eof=1;
+ }
+ else if (n < 0) {
+ DEBUGF("Error decoding frame\n");
+ } else {
+ rb->yield();
+ if (rb->stop_codec || rb->reload_codec)
+ break ;
+
+ rb->yield();
+ while (!rb->audiobuffer_insert(pcmbuf, n))
+ rb->yield();
+
+ rb->set_elapsed(ov_time_tell(&vf));
+
+#if BYTE_ORDER == BIG_ENDIAN
+ for (i=0;i<n;i+=2) {
+ x=pcmbuf[i]; pcmbuf[i]=pcmbuf[i+1]; pcmbuf[i+1]=x;
+ }
+#endif
+ }
+ }
+
+ if (rb->request_next_track())
+ goto next_track;
+
+ return CODEC_OK;
+}
+
diff --git a/apps/plugins/codecwav.c b/apps/codecs/wav.c
index 230b316..d750b64 100644
--- a/apps/plugins/codecwav.c
+++ b/apps/codecs/wav.c
@@ -17,7 +17,7 @@
*
****************************************************************************/
-#include "plugin.h"
+#include "codec.h"
#include "playback.h"
#include "lib/codeclib.h"
@@ -32,11 +32,11 @@ extern char iramstart[];
extern char iramend[];
#endif
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
{
- struct plugin_api* rb = (struct plugin_api*)api;
- struct codec_api* ci = (struct codec_api*)parm;
+ struct codec_api* rb = api;
+ struct codec_api* ci = api;
unsigned long samplerate,numbytes,totalsamples,samplesdone,nsamples;
int channels,bytespersample,bitspersample;
unsigned int i;
@@ -45,8 +45,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
unsigned char* header;
unsigned short* wavbuf;
- /* Generic plugin initialisation */
- TEST_PLUGIN_API(api);
+ /* Generic codec initialisation */
+ TEST_CODEC_API(api);
/* if you are using a global api pointer, don't forget to copy it!
otherwise you will get lovely "I04: IllInstr" errors... :-) */
@@ -62,18 +62,18 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
next_track:
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
+ if (codec_init(api)) {
+ return CODEC_ERROR;
}
/* FIX: Correctly parse WAV header - we assume canonical 44-byte header */
header=ci->request_buffer(&n,44);
if (n!=44) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
if ((memcmp(header,"RIFF",4)!=0) || (memcmp(&header[8],"WAVEfmt",7)!=0)) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
samplerate=header[24]|(header[25]<<8)|(header[26]<<16)|(header[27]<<24);
@@ -84,7 +84,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
totalsamples=numbytes/bytespersample;
if ((bitspersample!=16) || (channels != 2)) {
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
}
ci->advance_buffer(44);
@@ -132,5 +132,5 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
if (ci->request_next_track())
goto next_track;
- return PLUGIN_OK;
+ return CODEC_OK;
}
diff --git a/apps/plugins/codecwavpack.c b/apps/codecs/wavpack.c
index 1e56dbd..e18dac6 100644
--- a/apps/plugins/codecwavpack.c
+++ b/apps/codecs/wavpack.c
@@ -17,13 +17,13 @@
*
****************************************************************************/
-#include "plugin.h"
+#include "codec.h"
#include <codecs/libwavpack/wavpack.h>
#include "playback.h"
#include "lib/codeclib.h"
-static struct plugin_api *rb;
+static struct codec_api *rb;
static struct codec_api *ci;
#define BUFFER_SIZE 4096
@@ -41,18 +41,18 @@ extern char iramstart[];
extern char iramend[];
#endif
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api, void* parm)
{
WavpackContext *wpc;
char error [80];
int bps, nchans;
- /* Generic plugin initialisation */
- TEST_PLUGIN_API(api);
+ /* Generic codec initialisation */
+ TEST_CODEC_API(api);
rb = api;
- ci = (struct codec_api*) parm;
+ ci = api;
#ifndef SIMULATOR
rb->memcpy(iramstart, iramcopy, iramend-iramstart);
@@ -64,15 +64,15 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
next_track:
- if (codec_init(api, ci))
- return PLUGIN_ERROR;
+ if (codec_init(api))
+ return CODEC_ERROR;
/* Create a decoder instance */
wpc = WavpackOpenFileInput (read_callback, error);
if (!wpc)
- return PLUGIN_ERROR;
+ return CODEC_ERROR;
bps = WavpackGetBytesPerSample (wpc);
nchans = WavpackGetReducedChannels (wpc);
@@ -181,5 +181,5 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
if (ci->request_next_track())
goto next_track;
- return PLUGIN_OK;
+ return CODEC_OK;
}
diff --git a/apps/playback.c b/apps/playback.c
index 0881d6e..3bd4ff6 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -33,7 +33,7 @@
#include "debug.h"
#include "sprintf.h"
#include "settings.h"
-#include "plugin.h"
+#include "codecs.h"
#include "wps.h"
#include "wps-display.h"
#include "audio.h"
@@ -63,13 +63,13 @@
static volatile bool playing;
static volatile bool paused;
-#define CODEC_VORBIS "/.rockbox/codecs/codecvorbis.rock";
-#define CODEC_MPA_L3 "/.rockbox/codecs/codecmpa.rock";
-#define CODEC_FLAC "/.rockbox/codecs/codecflac.rock";
-#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
-#define CODEC_A52 "/.rockbox/codecs/codeca52.rock";
-#define CODEC_MPC "/.rockbox/codecs/codecmpc.rock";
-#define CODEC_WAVPACK "/.rockbox/codecs/codecwavpack.rock";
+#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec";
+#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec";
+#define CODEC_FLAC "/.rockbox/codecs/flac.codec";
+#define CODEC_WAV "/.rockbox/codecs/wav.codec";
+#define CODEC_A52 "/.rockbox/codecs/a52.codec";
+#define CODEC_MPC "/.rockbox/codecs/mpc.codec";
+#define CODEC_WAVPACK "/.rockbox/codecs/wavpack.codec";
#define AUDIO_FILL_CYCLE (1024*256)
#define AUDIO_DEFAULT_WATERMARK (1024*256)
@@ -153,7 +153,7 @@ static struct track_info tracks[MAX_TRACK];
static volatile struct track_info *cur_ti;
/* Codec API including function callbacks. */
-static struct codec_api ci;
+extern struct codec_api ci;
/* When we change a song and buffer is not in filling state, this
variable keeps information about whether to go a next/previous track. */
@@ -1074,7 +1074,7 @@ void codec_thread(void)
switch (ev.id) {
case CODEC_LOAD_DISK:
ci.stop_codec = false;
- status = codec_load_file((char *)ev.data, &ci);
+ status = codec_load_file((char *)ev.data);
break ;
case CODEC_LOAD:
@@ -1089,7 +1089,7 @@ void codec_thread(void)
ci.stop_codec = false;
wrap = (int)&codecbuf[codecbuflen] - (int)cur_ti->codecbuf;
status = codec_load_ram(cur_ti->codecbuf, codecsize,
- &ci, &codecbuf[0], wrap);
+ &codecbuf[0], wrap);
break ;
#ifndef SIMULATOR
@@ -1103,7 +1103,7 @@ void codec_thread(void)
switch (ev.id) {
case CODEC_LOAD_DISK:
case CODEC_LOAD:
- if (status != PLUGIN_OK) {
+ if (status != CODEC_OK) {
logf("Codec failure");
splash(HZ*2, true, "Codec failure");
playing = false;
diff --git a/apps/playback.h b/apps/playback.h
index 06b82b4..24fc857 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -51,60 +51,6 @@ struct track_info {
int playlist_offset; /* File location in playlist */
};
-
-/* Codec Interface */
-struct codec_api {
- off_t filesize; /* Total file length */
- off_t curpos; /* Current buffer position */
-
- /* For gapless mp3 */
- struct mp3entry *id3; /* TAG metadata pointer */
- struct mp3info *mp3data; /* MP3 metadata pointer */
- bool *taginfo_ready; /* Is metadata read */
-
- /* Codec should periodically check if stop_codec is set to true.
- In case it's, codec must return with PLUGIN_OK status immediately. */
- bool stop_codec;
- /* Codec should periodically check if reload_codec is set to true.
- In case it's, codec should reload itself without exiting. */
- bool reload_codec;
- /* If seek_time != 0, codec should seek to that song position (in ms)
- if codec supports seeking. */
- int seek_time;
-
- /* Returns buffer to malloc array. Only codeclib should need this. */
- void* (*get_codec_memory)(size_t *size);
- /* Insert PCM data into audio buffer for playback. Playback will start
- automatically. */
- bool (*audiobuffer_insert)(char *data, size_t length);
- /* Set song position in WPS (value in ms). */
- void (*set_elapsed)(unsigned int value);
-
- /* Read next <size> amount bytes from file buffer to <ptr>.
- Will return number of bytes read or 0 if end of file. */
- size_t (*read_filebuf)(void *ptr, size_t size);
- /* Request pointer to file buffer which can be used to read
- <realsize> amount of data. <reqsize> tells the buffer system
- how much data it should try to allocate. If <realsize> is 0,
- end of file is reached. */
- void* (*request_buffer)(size_t *realsize, size_t reqsize);
- /* Advance file buffer position by <amount> amount of bytes. */
- void (*advance_buffer)(size_t amount);
- /* Advance file buffer to a pointer location inside file buffer. */
- void (*advance_buffer_loc)(void *ptr);
- /* Seek file buffer to position <newpos> beginning of file. */
- bool (*seek_buffer)(off_t newpos);
- /* Calculate mp3 seek position from given time data in ms. */
- off_t (*mp3_get_filepos)(int newtime);
- /* Request file change from file buffer. Returns true is next
- track is available and changed. If return value is false,
- codec should exit immediately with PLUGIN_OK status. */
- bool (*request_next_track)(void);
-
- /* Configure different codec buffer parameters. */
- void (*configure)(int setting, void *value);
-};
-
#endif
diff --git a/apps/plugin.c b/apps/plugin.c
index a1a0b06..97f811e 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -332,60 +332,6 @@ static const struct plugin_api rockbox_api = {
};
-#if CONFIG_HWCODEC == MASNONE
-int codec_load_ram(char* codecptr, size_t size, void *parameter, void* ptr2,
- size_t bufwrap)
-{
- enum plugin_status (*plugin_start)(struct plugin_api* api, void* param);
- int copy_n;
- int status;
-
- if ((char *)&codecbuf[0] != codecptr) {
- /* zero out codec buffer to ensure a properly zeroed bss area */
- memset(codecbuf, 0, CODEC_BUFFER_SIZE);
-
- size = MIN(size, CODEC_BUFFER_SIZE);
- copy_n = MIN(size, bufwrap);
- memcpy(codecbuf, codecptr, copy_n);
- size -= copy_n;
- if (size > 0) {
- memcpy(&codecbuf[copy_n], ptr2, size);
- }
- }
- plugin_start = (void*)&codecbuf;
-
- invalidate_icache();
- status = plugin_start((struct plugin_api*) &rockbox_api, parameter);
-
- return status;
-}
-
-int codec_load_file(const char *plugin, void *parameter)
-{
- char msgbuf[80];
- int fd;
- int rc;
-
- fd = open(plugin, O_RDONLY);
- if (fd < 0) {
- snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
- logf("Codec load error:%d", fd);
- splash(HZ*2, true, msgbuf);
- return fd;
- }
-
- rc = read(fd, &codecbuf[0], CODEC_BUFFER_SIZE);
- close(fd);
- if (rc <= 0) {
- logf("Codec read error");
- return PLUGIN_ERROR;
- }
-
- return codec_load_ram(codecbuf, (size_t)rc, parameter, NULL, 0);
-}
-
-#endif
-
int plugin_load(const char* plugin, void* parameter)
{
enum plugin_status (*plugin_start)(struct plugin_api* api, void* param);
diff --git a/apps/plugin.h b/apps/plugin.h
index 94967c7..6bd4ed7 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -403,13 +403,6 @@ struct plugin_api {
#endif
};
-/* defined by the plugin loader (plugin.c) */
-#if CONFIG_HWCODEC == MASNONE
-int codec_load_ram(char* pluginptr, size_t size, void *parameter, void* ptr2,
- size_t bufwrap);
-int codec_load_file(const char* plugin, void* parameter);
-#endif
-
int plugin_load(const char* plugin, void* parameter);
void* plugin_get_buffer(int *buffer_size);
void* plugin_get_audio_buffer(int *buffer_size);
diff --git a/apps/plugins/CODECS b/apps/plugins/CODECS
deleted file mode 100644
index ea921a6..0000000
--- a/apps/plugins/CODECS
+++ /dev/null
@@ -1,7 +0,0 @@
-codecvorbis.elf
-codecmpa.elf
-codecflac.elf
-codecwav.elf
-codeca52.elf
-codecmpc.elf
-codecwavpack.elf
diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile
index 44e055d..fbae027 100644
--- a/apps/plugins/Makefile
+++ b/apps/plugins/Makefile
@@ -22,7 +22,6 @@ endif
LDS := plugin.lds
LINKFILE := $(OBJDIR)/pluginlink.lds
-LINKCODEC := $(OBJDIR)/codeclink.lds
DEPFILE = $(OBJDIR)/dep-plugins
# This sets up 'SRC' based on the files mentioned in SOURCES
@@ -55,13 +54,7 @@ ifndef SIMVER
$(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKFILE) $(LINKCODEC) $(BUILDDIR)/libplugin.a
$(SILENT)(file=`basename $@`; \
echo "LD $$file"; \
- match=`grep $$file CODECS`; \
- if test -z "$$match"; then \
- LINKWITH=$(LINKFILE); \
- else \
- LINKWITH=$(LINKCODEC); \
- fi; \
- $(CC) $(GCCOPTS) -O -nostdlib -o $@ $< -L$(BUILDDIR) $(CODECLIBS) -lplugin -lgcc -T$$LINKWITH -Wl,-Map,$(OBJDIR)/$*.map)
+ $(CC) $(GCCOPTS) -O -nostdlib -o $@ $< -L$(BUILDDIR) $(CODECLIBS) -lplugin -lgcc -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/$*.map)
$(OBJDIR)/%.rock : $(OBJDIR)/%.elf
@echo "OBJCOPY "`basename $@`
@@ -108,7 +101,7 @@ endif # end of simulator section
include $(TOOLSDIR)/make.inc
$(BUILDDIR)/libplugin.a:
- @echo "MAKE in lib"
+ @echo "MAKE in plugin/lib"
@mkdir -p $(OBJDIR)/lib
@$(MAKE) -C lib OBJDIR=$(OBJDIR)/lib
@@ -116,10 +109,6 @@ $(LINKFILE): $(LDS)
@echo "build $@"
@cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@
-$(LINKCODEC): $(LDS)
- @echo "build $@"
- @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) -DCODEC $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@
-
$(SUBDIRS):
@echo "MAKE in $@"
@mkdir -p $(OBJDIR)/$@
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 34f014d..933625a 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -67,22 +67,15 @@ alpine_cdc.c
#endif
#if CONFIG_HWCODEC == MASNONE /* software codec platforms */
+#if 0
mpa2wav.c
a52towav.c
flac2wav.c
vorbis2wav.c
-#ifdef IRIVER_H100
-codecvorbis.c
-codecmpa.c
-codecflac.c
-codecwav.c
-codeca52.c
-codecmpc.c
-codecwavpack.c
-#endif
wv2wav.c
mpc2wav.c
midi2wav.c
+#endif
iriverify.c
#else
splitedit.c
diff --git a/apps/plugins/codecmpa.c b/apps/plugins/codecmpa.c
deleted file mode 100644
index 768c3fe..0000000
--- a/apps/plugins/codecmpa.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2005 Dave Chapman
- *
- * All files in this archive are subject to the GNU General Public License.
- * See the file COPYING in the source tree root for full license agreement.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "plugin.h"
-
-#include <codecs/libmad/mad.h>
-
-#include "playback.h"
-#include "mp3data.h"
-#include "lib/codeclib.h"
-
-static struct plugin_api* rb;
-
-struct mad_stream Stream IDATA_ATTR;
-struct mad_frame Frame IDATA_ATTR;
-struct mad_synth Synth IDATA_ATTR;
-mad_timer_t Timer;
-struct dither d0, d1;
-
-/* The following function is used inside libmad - let's hope it's never
- called.
-*/
-
-void abort(void) {
-}
-
-/* The "dither" code to convert the 24-bit samples produced by libmad was
- taken from the coolplayer project - coolplayer.sourceforge.net */
-
-struct dither {
- mad_fixed_t error[3];
- mad_fixed_t random;
-};
-
-# define SAMPLE_DEPTH 16
-# define scale(x, y) dither((x), (y))
-
-/*
- * NAME: prng()
- * DESCRIPTION: 32-bit pseudo-random number generator
- */
-static __inline
-unsigned long prng(unsigned long state)
-{
- return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
-}
-
-/*
- * NAME: dither()
- * DESCRIPTION: dither and scale sample
- */
-static __inline
-signed int dither(mad_fixed_t sample, struct dither *dither)
-{
- unsigned int scalebits;
- mad_fixed_t output, mask, random;
-
- enum {
- MIN = -MAD_F_ONE,
- MAX = MAD_F_ONE - 1
- };
-
- /* noise shape */
- sample += dither->error[0] - dither->error[1] + dither->error[2];
-
- dither->error[2] = dither->error[1];
- dither->error[1] = dither->error[0] / 2;
-
- /* bias */
- output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1));
-
- scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH;
- mask = (1L << scalebits) - 1;
-
- /* dither */
- random = prng(dither->random);
- output += (random & mask) - (dither->random & mask);
-
- //dither->random = random;
-
- /* clip */
- if (output > MAX) {
- output = MAX;
-
- if (sample > MAX)
- sample = MAX;
- }
- else if (output < MIN) {
- output = MIN;
-
- if (sample < MIN)
- sample = MIN;
- }
-
- /* quantize */
- output &= ~mask;
-
- /* error feedback */
- dither->error[0] = sample - output;
-
- /* scale */
- return output >> scalebits;
-}
-
-static __inline
-signed int detect_silence(mad_fixed_t sample)
-{
- unsigned int scalebits;
- mad_fixed_t output, mask;
-
- enum {
- MIN = -MAD_F_ONE,
- MAX = MAD_F_ONE - 1
- };
-
- /* bias */
- output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1));
-
- scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH;
- mask = (1L << scalebits) - 1;
-
- /* clip */
- if (output > MAX) {
- output = MAX;
-
- if (sample > MAX)
- sample = MAX;
- }
- else if (output < MIN) {
- output = MIN;
-
- if (sample < MIN)
- sample = MIN;
- }
-
- /* quantize */
- output &= ~mask;
-
- /* scale */
- output >>= scalebits + 4;
-
- if (output == 0x00 || output == 0xff)
- return 1;
-
- return 0;
-}
-#define SHRT_MAX 32767
-
-#define INPUT_CHUNK_SIZE 8192
-#define OUTPUT_BUFFER_SIZE 65536 /* Must be an integer multiple of 4. */
-
-unsigned char OutputBuffer[OUTPUT_BUFFER_SIZE];
-unsigned char *OutputPtr;
-unsigned char *GuardPtr=NULL;
-const unsigned char *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
-long resampled_data[2][5000]; /* enough to cope with 11khz upsampling */
-
-mad_fixed_t mad_frame_overlap[2][32][18] IDATA_ATTR;
-unsigned char mad_main_data[MAD_BUFFER_MDLEN] IDATA_ATTR;
-/* TODO: what latency does layer 1 have? */
-int mpeg_latency[3] = { 0, 481, 529 };
-#ifdef USE_IRAM
-extern char iramcopy[];
-extern char iramstart[];
-extern char iramend[];
-#endif
-
-#undef DEBUG_GAPLESS
-
-struct resampler {
- long last_sample, phase, delta;
-};
-
-#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR)
-
-#define INIT() asm volatile ("move.l #0xb0, %macsr") /* frac, round, clip */
-#define FRACMUL(x, y) \
-({ \
- long t; \
- asm volatile ("mac.l %[a], %[b], %%acc0\n\t" \
- "movclr.l %%acc0, %[t]\n\t" \
- : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \
- t; \
-})
-
-#else
-
-#define INIT()
-#define FRACMUL(x, y) (long)(((long long)(x)*(long long)(y)) << 1)
-#endif
-
-/* linear resampling, introduces one sample delay, because of our inability to
- look into the future at the end of a frame */
-long downsample(long *in, long *out, int num, struct resampler *s)
-{
- long i = 1, pos;
- long last = s->last_sample;
-
- INIT();
- pos = s->phase >> 16;
- /* check if we need last sample of previous frame for interpolation */
- if (pos > 0)
- last = in[pos - 1];
- out[0] = last + FRACMUL((s->phase & 0xffff) << 15, in[pos] - last);
- s->phase += s->delta;
- while ((pos = s->phase >> 16) < num) {
- out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]);
- s->phase += s->delta;
- }
- /* wrap phase accumulator back to start of next frame */
- s->phase -= num << 16;
- s->last_sample = in[num - 1];
- return i;
-}
-
-long upsample(long *in, long *out, int num, struct resampler *s)
-{
- long i = 0, pos;
-
- INIT();
- while ((pos = s->phase >> 16) == 0) {
- out[i++] = s->last_sample + FRACMUL((s->phase & 0xffff) << 15, in[pos] - s->last_sample);
- s->phase += s->delta;
- }
- while ((pos = s->phase >> 16) < num) {
- out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]);
- s->phase += s->delta;
- }
- /* wrap phase accumulator back to start of next frame */
- s->phase -= num << 16;
- s->last_sample = in[num - 1];
- return i;
-}
-
-long resample(long *in, long *out, int num, struct resampler *s)
-{
- if (s->delta >= (1 << 16))
- return downsample(in, out, num, s);
- else
- return upsample(in, out, num, s);
-}
-
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
-{
- struct codec_api *ci = (struct codec_api *)parm;
- struct mp3info *info;
- int Status=0;
- size_t size;
- int file_end;
- unsigned short Sample;
- char *InputBuffer;
- unsigned int samplecount;
- unsigned int samplesdone;
- bool first_frame;
-#ifdef DEBUG_GAPLESS
- bool first = true;
- int fd;
-#endif
- int i;
- int yieldcounter = 0;
- int stop_skip, start_skip;
- struct resampler lr = { 0, 0, 0 }, rr = { 0, 0, 0 };
- long length;
- /* Generic plugin inititialisation */
-
- TEST_PLUGIN_API(api);
- rb = api;
-
-#ifdef USE_IRAM
- rb->memcpy(iramstart, iramcopy, iramend-iramstart);
-#endif
-
- /* This function sets up the buffers and reads the file into RAM */
-
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
- }
-
- /* Create a decoder instance */
-
- ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
- ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16));
-
- memset(&Stream, 0, sizeof(struct mad_stream));
- memset(&Frame, 0, sizeof(struct mad_frame));
- memset(&Synth, 0, sizeof(struct mad_synth));
- memset(&Timer, 0, sizeof(mad_timer_t));
-
- mad_stream_init(&Stream);
- mad_frame_init(&Frame);
- mad_synth_init(&Synth);
- mad_timer_reset(&Timer);
-
- /* We do this so libmad doesn't try to call codec_calloc() */
- memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
- Frame.overlap = &mad_frame_overlap;
- Stream.main_data = &mad_main_data;
- /* This label might need to be moved above all the init code, but I don't
- think reiniting the codec is necessary for MPEG. It might even be unwanted
- for gapless playback */
- next_track:
-
-#ifdef DEBUG_GAPLESS
- if (first)
- fd = rb->open("/first.pcm", O_WRONLY | O_CREAT);
- else
- fd = rb->open("/second.pcm", O_WRONLY | O_CREAT);
- first = false;
-#endif
-
- info = ci->mp3data;
- first_frame = false;
- file_end = 0;
- OutputPtr = OutputBuffer;
-
- while (!*ci->taginfo_ready)
- rb->yield();
-
- ci->request_buffer(&size, ci->id3->first_frame_offset);
- ci->advance_buffer(size);
-
- if (info->enc_delay >= 0 && info->enc_padding >= 0) {
- stop_skip = info->enc_padding - mpeg_latency[info->layer];
- if (stop_skip < 0) stop_skip = 0;
- start_skip = info->enc_delay + mpeg_latency[info->layer];
- } else {
- stop_skip = 0;
- /* We want to skip this amount anyway */
- start_skip = mpeg_latency[info->layer];
- }
-
- /* NOTE: currently this doesn't work, the below calculated samples_count
- seems to be right, but sometimes libmad just can't supply us with
- all the data we need... */
- if (info->frame_count) {
- /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3,
- it's probably not correct at all for MPEG2 and layer 1 */
- samplecount = info->frame_count*1152 - (start_skip + stop_skip);
- samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10;
- } else {
- samplecount = ci->id3->length * (ci->id3->frequency / 100) / 10;
- samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10;
- }
- /* rb->snprintf(buf2, sizeof(buf2), "sc: %d", samplecount);
- rb->splash(0, true, buf2);
- rb->snprintf(buf2, sizeof(buf2), "length: %d", ci->id3->length);
- rb->splash(HZ*5, true, buf2);
- rb->snprintf(buf2, sizeof(buf2), "frequency: %d", ci->id3->frequency);
- rb->splash(HZ*5, true, buf2); */
- lr.delta = rr.delta = ci->id3->frequency*65536/44100;
- /* This is the decoding loop. */
- while (1) {
- rb->yield();
- if (ci->stop_codec || ci->reload_codec) {
- break ;
- }
-
- if (ci->seek_time) {
- unsigned int sample_loc;
- int newpos;
-
- sample_loc = ci->seek_time/1000 * ci->id3->frequency;
- newpos = ci->mp3_get_filepos(ci->seek_time-1);
- if (ci->seek_buffer(newpos)) {
- if (sample_loc >= samplecount + samplesdone)
- break ;
- samplecount += samplesdone - sample_loc;
- samplesdone = sample_loc;
- }
- ci->seek_time = 0;
- }
-
- /* Lock buffers */
- if (Stream.error == 0) {
- InputBuffer = ci->request_buffer(&size, INPUT_CHUNK_SIZE);
- if (size == 0 || InputBuffer == NULL)
- break ;
- mad_stream_buffer(&Stream, InputBuffer, size);
- }
-
- //if ((int)ci->curpos >= ci->id3->first_frame_offset)
- //first_frame = true;
-
- if(mad_frame_decode(&Frame,&Stream))
- {
- if (Stream.error == MAD_FLAG_INCOMPLETE || Stream.error == MAD_ERROR_BUFLEN) {
- // rb->splash(HZ*1, true, "Incomplete");
- /* This makes the codec to support partially corrupted files too. */
- if (file_end == 30)
- break ;
-
- /* Fill the buffer */
- Stream.error = 0;
- file_end++;
- continue ;
- }
- else if(MAD_RECOVERABLE(Stream.error))
- {
- if(Stream.error!=MAD_ERROR_LOSTSYNC || Stream.this_frame!=GuardPtr)
- {
- // rb->splash(HZ*1, true, "Recoverable...!");
- }
- continue;
- }
- else if(Stream.error==MAD_ERROR_BUFLEN) {
- //rb->splash(HZ*1, true, "Buflen error");
- break ;
- } else {
- //rb->splash(HZ*1, true, "Unrecoverable error");
- Status=1;
- break;
- }
- }
- if (Stream.next_frame)
- ci->advance_buffer_loc((void *)Stream.next_frame);
- file_end = false;
- /* ?? Do we need the timer module? */
- // mad_timer_add(&Timer,Frame.header.duration);
-
-/* DAVE: This can be used to attenuate the audio */
-// if(DoFilter)
-// ApplyFilter(&Frame);
-
- mad_synth_frame(&Synth,&Frame);
-
- //if (!first_frame) {
- //samplecount -= Synth.pcm.length;
- //continue ;
- //}
-
- /* Convert MAD's numbers to an array of 16-bit LE signed integers */
- /* We skip start_skip number of samples here, this should only happen for
- very first frame in the stream. */
- /* TODO: possible for start_skip to exceed one frames worth of samples? */
- length = resample((long *)&Synth.pcm.samples[0][start_skip], resampled_data[0], Synth.pcm.length, &lr);
- if (MAD_NCHANNELS(&Frame.header) == 2)
- resample((long *)&Synth.pcm.samples[1][start_skip], resampled_data[1], Synth.pcm.length, &rr);
- for (i = 0;i<length;i++)
- {
- start_skip = 0; /* not very elegant, and might want to keep this value */
- samplesdone++;
- //if (ci->mp3data->padding > 0) {
- // ci->mp3data->padding--;
- // continue ;
- //}
- /*if (!first_frame) {
- if (detect_silence(Synth.pcm.samples[0][i]))
- continue ;
- first_frame = true;
- }*/
-
- /* Left channel */
- Sample=scale(resampled_data[0][i],&d0);
- *(OutputPtr++)=Sample>>8;
- *(OutputPtr++)=Sample&0xff;
-
- /* Right channel. If the decoded stream is monophonic then
- * the right output channel is the same as the left one.
- */
- if(MAD_NCHANNELS(&Frame.header)==2)
- Sample=scale(resampled_data[1][i],&d1);
- *(OutputPtr++)=Sample>>8;
- *(OutputPtr++)=Sample&0xff;
-
- samplecount--;
- if (samplecount == 0) {
-#ifdef DEBUG_GAPLESS
- rb->write(fd, OutputBuffer, (int)OutputPtr-(int)OutputBuffer);
-#endif
- while (!ci->audiobuffer_insert(OutputBuffer, (int)OutputPtr-(int)OutputBuffer))
- rb->yield();
- goto song_end;
- }
-
- if (yieldcounter++ == 200) {
- rb->yield();
- yieldcounter = 0;
- }
-
- /* Flush the buffer if it is full. */
- if(OutputPtr==OutputBufferEnd)
- {
-#ifdef DEBUG_GAPLESS
- rb->write(fd, OutputBuffer, OUTPUT_BUFFER_SIZE);
-#endif
- while (!ci->audiobuffer_insert(OutputBuffer, OUTPUT_BUFFER_SIZE))
- rb->yield();
- OutputPtr=OutputBuffer;
- }
- }
- ci->set_elapsed(samplesdone / (ci->id3->frequency/1000));
- }
-
- song_end:
-#ifdef DEBUG_GAPLESS
- rb->close(fd);
-#endif
- Stream.error = 0;
-
- if (ci->request_next_track())
- goto next_track;
- return PLUGIN_OK;
-}
diff --git a/apps/plugins/codecvorbis.c b/apps/plugins/codecvorbis.c
deleted file mode 100644
index 8e88471..0000000
--- a/apps/plugins/codecvorbis.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2002 Björn Stenberg
- *
- * All files in this archive are subject to the GNU General Public License.
- * See the file COPYING in the source tree root for full license agreement.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "kernel.h"
-#include "plugin.h"
-
-#include <codecs/Tremor/ivorbisfile.h>
-
-#include "playback.h"
-#include "lib/codeclib.h"
-
-static struct plugin_api* rb;
-
-/* Some standard functions and variables needed by Tremor */
-
-
-int errno;
-
-size_t strlen(const char *s) {
- return(rb->strlen(s));
-}
-
-char *strcpy(char *dest, const char *src) {
- return(rb->strcpy(dest,src));
-}
-
-char *strcat(char *dest, const char *src) {
- return(rb->strcat(dest,src));
-}
-
-size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) {
- struct codec_api *p = (struct codec_api *) datasource;
-
- return p->read_filebuf(ptr, nmemb*size);
-}
-
-int seek_handler(void *datasource, ogg_int64_t offset, int whence) {
- /* We are not seekable at the moment */
- (void)datasource;
- (void)offset;
- (void)whence;
- return -1;
-}
-
-int close_handler(void *datasource) {
- (void)datasource;
- return 0;
-}
-
-long tell_handler(void *datasource) {
- struct codec_api *p = (struct codec_api *) datasource;
- return p->curpos;
-}
-
-#ifdef USE_IRAM
-extern char iramcopy[];
-extern char iramstart[];
-extern char iramend[];
-#endif
-
-
-/* reserve the PCM buffer in the IRAM area */
-static char pcmbuf[4096] IDATA_ATTR;
-
-/* this is the plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parm)
-{
- struct codec_api *ci = (struct codec_api *)parm;
- ov_callbacks callbacks;
- OggVorbis_File vf;
- vorbis_info* vi;
-
- int error;
- long n;
- int current_section;
- int eof;
-#if BYTE_ORDER == BIG_ENDIAN
- int i;
- char x;
-#endif
-
- TEST_PLUGIN_API(api);
-
- /* if you are using a global api pointer, don't forget to copy it!
- otherwise you will get lovely "I04: IllInstr" errors... :-) */
- rb = api;
-
- #ifdef USE_IRAM
- rb->memcpy(iramstart, iramcopy, iramend-iramstart);
- #endif
-
- ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
- ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*64));
-
- /* We need to flush reserver memory every track load. */
- next_track:
- if (codec_init(api, ci)) {
- return PLUGIN_ERROR;
- }
-
-
- /* Create a decoder instance */
-
- callbacks.read_func=read_handler;
- callbacks.seek_func=seek_handler;
- callbacks.tell_func=tell_handler;
- callbacks.close_func=close_handler;
-
- error=ov_open_callbacks(ci,&vf,NULL,0,callbacks);
-
- vi=ov_info(&vf,-1);
-
- if (vi==NULL) {
- // rb->splash(HZ*2, true, "Vorbis Error");
- return PLUGIN_ERROR;
- }
-
- eof=0;
- while (!eof) {
- /* Read host-endian signed 16 bit PCM samples */
- n=ov_read(&vf,pcmbuf,sizeof(pcmbuf),&current_section);
-
- if (n==0) {
- eof=1;
- } else if (n < 0) {
- DEBUGF("Error decoding frame\n");
- } else {
- rb->yield();
- if (ci->stop_codec || ci->reload_codec)
- break ;
-
- rb->yield();
- while (!ci->audiobuffer_insert(pcmbuf, n))
- rb->yield();
-
- ci->set_elapsed(ov_time_tell(&vf));
-
-#if BYTE_ORDER == BIG_ENDIAN
- for (i=0;i<n;i+=2) {
- x=pcmbuf[i]; pcmbuf[i]=pcmbuf[i+1]; pcmbuf[i+1]=x;
- }
-#endif
- }
- }
-
- if (ci->request_next_track())
- goto next_track;
-
- return PLUGIN_OK;
-}
-
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index f8ed798..0914f10 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -34,9 +34,8 @@ gray_verline.c
#ifdef HAVE_LCD_CHARCELLS
playergfx.c
#endif
+#if 0
#if CONFIG_HWCODEC == MASNONE /* software codec platforms */
xxx2wav.c
-#ifdef IRIVER_H100
-codeclib.c
#endif
#endif
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index b5ff864..3da8753 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -48,7 +48,7 @@ sub buildzip {
mkdir ".rockbox/langs", 0777;
mkdir ".rockbox/rocks", 0777;
mkdir ".rockbox/codecs", 0777;
- `find apps -name "codec*.rock" ! -empty | xargs --replace=foo cp foo .rockbox/codecs/`;
+ `find apps -name "*.codec" ! -empty | xargs --replace=foo cp foo .rockbox/codecs/`;
`find apps -name "*.rock" -o -name "*.ovl" ! -empty ! -name "codec*.rock" | xargs --replace=foo cp foo .rockbox/rocks/`;
open VIEWERS, "$ROOT/apps/plugins/viewers.config" or