2005-06-22 19:41:30 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
2008-05-05 10:32:46 +00:00
|
|
|
* Copyright (C) 2002 Björn Stenberg
|
2005-06-22 19:41:30 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* 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.
|
2005-06-22 19:41:30 +00:00
|
|
|
*
|
|
|
|
* 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.
|
2011-06-26 01:32:25 +00:00
|
|
|
(the CODEC macro is defined in codecs.make) */
|
2005-06-22 19:41:30 +00:00
|
|
|
#ifdef CODEC
|
|
|
|
#define NO_REDEFINES_PLEASE
|
|
|
|
#endif
|
|
|
|
|
2011-10-30 16:05:04 +00:00
|
|
|
#include "rbcodecconfig.h"
|
2008-10-15 06:38:51 +00:00
|
|
|
#include "metadata.h"
|
2005-06-22 19:41:30 +00:00
|
|
|
#include "audio.h"
|
2006-01-18 20:54:13 +00:00
|
|
|
#ifdef RB_PROFILE
|
|
|
|
#include "profile.h"
|
2007-05-07 13:32:56 +00:00
|
|
|
#include "thread.h"
|
2006-01-18 20:54:13 +00:00
|
|
|
#endif
|
2005-10-10 15:54:36 +00:00
|
|
|
#if (CONFIG_CODEC == SWCODEC)
|
2010-07-04 13:37:52 +00:00
|
|
|
#ifdef HAVE_RECORDING
|
2006-08-28 22:38:41 +00:00
|
|
|
#include "pcm_record.h"
|
|
|
|
#endif
|
2012-04-29 21:31:30 +00:00
|
|
|
#include "dsp_core.h"
|
|
|
|
#include "dsp_misc.h"
|
2011-12-04 18:19:39 +00:00
|
|
|
#include "dsp-util.h"
|
2005-06-22 19:41:30 +00:00
|
|
|
#endif
|
|
|
|
|
2010-07-25 14:44:29 +00:00
|
|
|
#include "gcc_extensions.h"
|
2010-09-09 16:17:21 +00:00
|
|
|
#include "load_code.h"
|
2010-07-25 14:44:29 +00:00
|
|
|
|
2005-06-22 19:41:30 +00:00
|
|
|
#ifdef CODEC
|
|
|
|
#if defined(DEBUG) || defined(SIMULATOR)
|
|
|
|
#undef DEBUGF
|
2006-11-26 18:31:41 +00:00
|
|
|
#define DEBUGF ci->debugf
|
2005-06-22 19:41:30 +00:00
|
|
|
#undef LDEBUGF
|
2006-11-26 18:31:41 +00:00
|
|
|
#define LDEBUGF ci->debugf
|
2005-06-22 19:41:30 +00:00
|
|
|
#else
|
|
|
|
#define DEBUGF(...)
|
|
|
|
#define LDEBUGF(...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ROCKBOX_HAS_LOGF
|
|
|
|
#undef LOGF
|
2006-11-26 18:31:41 +00:00
|
|
|
#define LOGF ci->logf
|
2005-06-22 19:41:30 +00:00
|
|
|
#else
|
|
|
|
#define LOGF(...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2006-11-06 18:07:30 +00:00
|
|
|
/* magic for normal codecs */
|
2006-01-18 00:05:14 +00:00
|
|
|
#define CODEC_MAGIC 0x52434F44 /* RCOD */
|
2006-11-06 18:07:30 +00:00
|
|
|
/* magic for encoder codecs */
|
|
|
|
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
|
2006-01-18 00:05:14 +00:00
|
|
|
|
2005-06-22 19:41:30 +00:00
|
|
|
/* increase this every time the api struct changes */
|
2012-03-27 23:52:15 +00:00
|
|
|
#define CODEC_API_VERSION 45
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* update this to latest version if a change to the api struct breaks
|
2005-08-29 20:07:17 +00:00
|
|
|
backwards compatibility (and please take the opportunity to sort in any
|
2005-06-22 19:41:30 +00:00
|
|
|
new function which are "waiting" at the end of the function table) */
|
2012-03-27 23:52:15 +00:00
|
|
|
#define CODEC_MIN_API_VERSION 45
|
2011-04-27 03:08:23 +00:00
|
|
|
|
|
|
|
/* reasons for calling codec main entrypoint */
|
|
|
|
enum codec_entry_call_reason {
|
|
|
|
CODEC_LOAD = 0,
|
|
|
|
CODEC_UNLOAD
|
|
|
|
};
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* codec return codes */
|
|
|
|
enum codec_status {
|
|
|
|
CODEC_OK = 0,
|
2006-01-18 00:05:14 +00:00
|
|
|
CODEC_ERROR = -1,
|
2005-06-22 19:41:30 +00:00
|
|
|
};
|
|
|
|
|
2011-04-27 03:08:23 +00:00
|
|
|
/* codec command action codes */
|
|
|
|
enum codec_command_action {
|
|
|
|
CODEC_ACTION_HALT = -1,
|
|
|
|
CODEC_ACTION_NULL = 0,
|
|
|
|
CODEC_ACTION_SEEK_TIME = 1,
|
|
|
|
};
|
|
|
|
|
2005-06-22 19:41:30 +00:00
|
|
|
/* 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 {
|
|
|
|
off_t filesize; /* Total file length */
|
|
|
|
off_t curpos; /* Current buffer position */
|
|
|
|
|
|
|
|
struct mp3entry *id3; /* TAG metadata pointer */
|
2011-04-27 03:08:23 +00:00
|
|
|
int audio_hid; /* Current audio handle */
|
2005-06-22 19:41:30 +00:00
|
|
|
|
2008-03-25 02:34:12 +00:00
|
|
|
/* The dsp instance to be used for audio output */
|
|
|
|
struct dsp_config *dsp;
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* Returns buffer to malloc array. Only codeclib should need this. */
|
2008-10-19 12:35:53 +00:00
|
|
|
void* (*codec_get_buffer)(size_t *size);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* Insert PCM data into audio buffer for playback. Playback will start
|
|
|
|
automatically. */
|
2009-11-11 07:02:18 +00:00
|
|
|
void (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* Set song position in WPS (value in ms). */
|
2009-11-05 17:32:32 +00:00
|
|
|
void (*set_elapsed)(unsigned long value);
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* Read next <size> amount bytes from file buffer to <ptr>.
|
|
|
|
Will return number of bytes read or 0 if end of file. */
|
2008-03-28 12:51:33 +00:00
|
|
|
size_t (*read_filebuf)(void *ptr, size_t size);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* 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. */
|
2008-03-28 12:51:33 +00:00
|
|
|
void* (*request_buffer)(size_t *realsize, size_t reqsize);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* Advance file buffer position by <amount> amount of bytes. */
|
2008-03-28 12:51:33 +00:00
|
|
|
void (*advance_buffer)(size_t amount);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* Seek file buffer to position <newpos> beginning of file. */
|
2008-03-28 12:51:33 +00:00
|
|
|
bool (*seek_buffer)(size_t newpos);
|
2006-01-18 00:05:14 +00:00
|
|
|
/* Codec should call this function when it has done the seeking. */
|
|
|
|
void (*seek_complete)(void);
|
2011-04-27 03:08:23 +00:00
|
|
|
/* Update the current position */
|
2008-03-28 12:51:33 +00:00
|
|
|
void (*set_offset)(size_t value);
|
2005-06-22 19:41:30 +00:00
|
|
|
/* Configure different codec buffer parameters. */
|
2008-03-28 12:51:33 +00:00
|
|
|
void (*configure)(int setting, intptr_t value);
|
2011-04-27 03:08:23 +00:00
|
|
|
/* Obtain command action on what to do next */
|
|
|
|
enum codec_command_action (*get_command)(intptr_t *param);
|
2011-08-30 19:40:09 +00:00
|
|
|
/* Determine whether the track should be looped, if applicable. */
|
|
|
|
bool (*loop_track)(void);
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* kernel/ system */
|
2010-08-03 19:00:29 +00:00
|
|
|
#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE
|
2009-02-11 16:37:12 +00:00
|
|
|
void (*__div0)(void);
|
|
|
|
#endif
|
2010-09-01 21:29:34 +00:00
|
|
|
unsigned (*sleep)(unsigned ticks);
|
2005-06-22 19:41:30 +00:00
|
|
|
void (*yield)(void);
|
|
|
|
|
2008-03-25 02:34:12 +00:00
|
|
|
#if NUM_CORES > 1
|
2008-12-10 08:57:10 +00:00
|
|
|
unsigned int
|
2008-03-25 02:34:12 +00:00
|
|
|
(*create_thread)(void (*function)(void), void* stack,
|
|
|
|
size_t stack_size, unsigned flags, const char *name
|
|
|
|
IF_PRIO(, int priority)
|
|
|
|
IF_COP(, unsigned int core));
|
|
|
|
|
2008-12-10 08:57:10 +00:00
|
|
|
void (*thread_thaw)(unsigned int thread_id);
|
|
|
|
void (*thread_wait)(unsigned int thread_id);
|
2008-03-25 02:34:12 +00:00
|
|
|
void (*semaphore_init)(struct semaphore *s, int max, int start);
|
2011-03-02 08:49:38 +00:00
|
|
|
int (*semaphore_wait)(struct semaphore *s, int timeout);
|
2008-03-25 02:34:12 +00:00
|
|
|
void (*semaphore_release)(struct semaphore *s);
|
|
|
|
#endif /* NUM_CORES */
|
|
|
|
|
2011-12-17 07:27:24 +00:00
|
|
|
void (*commit_dcache)(void);
|
|
|
|
void (*commit_discard_dcache)(void);
|
2012-03-27 23:52:15 +00:00
|
|
|
void (*commit_discard_idcache)(void);
|
2008-03-25 02:34:12 +00:00
|
|
|
|
2005-06-22 19:41:30 +00:00
|
|
|
/* strings and memory */
|
|
|
|
char* (*strcpy)(char *dst, const char *src);
|
|
|
|
size_t (*strlen)(const char *str);
|
|
|
|
int (*strcmp)(const char *, const char *);
|
2007-05-07 11:09:45 +00:00
|
|
|
char *(*strcat)(char *s1, const char *s2);
|
2005-06-22 19:41:30 +00:00
|
|
|
void* (*memset)(void *dst, int c, size_t length);
|
|
|
|
void* (*memcpy)(void *out, const void *in, size_t n);
|
2006-03-24 13:43:15 +00:00
|
|
|
void* (*memmove)(void *out, const void *in, size_t n);
|
2005-06-22 19:41:30 +00:00
|
|
|
int (*memcmp)(const void *s1, const void *s2, size_t n);
|
2006-01-18 00:05:14 +00:00
|
|
|
void *(*memchr)(const void *s1, int c, size_t n);
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
#if defined(DEBUG) || defined(SIMULATOR)
|
2007-03-17 09:02:53 +00:00
|
|
|
void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
|
2006-01-18 00:05:14 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ROCKBOX_HAS_LOGF
|
2007-03-17 09:02:53 +00:00
|
|
|
void (*logf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
|
2005-06-22 19:41:30 +00:00
|
|
|
#endif
|
2007-05-07 11:09:45 +00:00
|
|
|
|
|
|
|
/* Tremor requires qsort */
|
|
|
|
void (*qsort)(void *base, size_t nmemb, size_t size,
|
|
|
|
int(*compar)(const void *, const void *));
|
|
|
|
|
2006-01-18 20:54:13 +00:00
|
|
|
#ifdef RB_PROFILE
|
|
|
|
void (*profile_thread)(void);
|
|
|
|
void (*profstop)(void);
|
|
|
|
void (*profile_func_enter)(void *this_fn, void *call_site);
|
|
|
|
void (*profile_func_exit)(void *this_fn, void *call_site);
|
|
|
|
#endif
|
2006-08-28 22:38:41 +00:00
|
|
|
|
2010-07-04 13:37:52 +00:00
|
|
|
#ifdef HAVE_RECORDING
|
2006-11-06 18:07:30 +00:00
|
|
|
void (*enc_get_inputs)(struct enc_inputs *inputs);
|
|
|
|
void (*enc_set_parameters)(struct enc_parameters *params);
|
|
|
|
struct enc_chunk_hdr * (*enc_get_chunk)(void);
|
|
|
|
void (*enc_finish_chunk)(void);
|
|
|
|
unsigned char * (*enc_get_pcm_data)(size_t size);
|
|
|
|
size_t (*enc_unget_pcm_data)(size_t size);
|
2007-05-07 11:09:45 +00:00
|
|
|
|
|
|
|
/* file */
|
2010-05-06 17:35:13 +00:00
|
|
|
int (*open)(const char* pathname, int flags, ...);
|
2007-05-07 11:09:45 +00:00
|
|
|
int (*close)(int fd);
|
|
|
|
ssize_t (*read)(int fd, void* buf, size_t count);
|
2009-01-07 09:53:46 +00:00
|
|
|
off_t (*lseek)(int fd, off_t offset, int whence);
|
2007-05-07 11:09:45 +00:00
|
|
|
ssize_t (*write)(int fd, const void* buf, size_t count);
|
|
|
|
int (*round_value_to_list32)(unsigned long value,
|
|
|
|
const unsigned long list[],
|
|
|
|
int count,
|
|
|
|
bool signd);
|
2006-08-28 22:38:41 +00:00
|
|
|
#endif
|
2005-07-05 08:43:36 +00:00
|
|
|
|
2006-02-03 00:12:11 +00:00
|
|
|
/* new stuff at the end, sort into place next time
|
2009-01-24 03:47:09 +00:00
|
|
|
the API gets incompatible */
|
2005-06-22 19:41:30 +00:00
|
|
|
};
|
|
|
|
|
2006-01-18 00:05:14 +00:00
|
|
|
/* codec header */
|
|
|
|
struct codec_header {
|
2010-09-09 16:17:21 +00:00
|
|
|
struct lc_header lc_hdr; /* must be first */
|
2011-04-27 03:08:23 +00:00
|
|
|
enum codec_status(*entry_point)(enum codec_entry_call_reason reason);
|
|
|
|
enum codec_status(*run_proc)(void);
|
2009-01-23 09:51:26 +00:00
|
|
|
struct codec_api **api;
|
2006-01-18 00:05:14 +00:00
|
|
|
};
|
2006-11-06 18:07:30 +00:00
|
|
|
|
2006-01-18 00:05:14 +00:00
|
|
|
#ifdef CODEC
|
2010-06-21 16:53:00 +00:00
|
|
|
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
2006-01-18 00:05:14 +00:00
|
|
|
/* plugin_* is correct, codecs use the plugin linker script */
|
|
|
|
extern unsigned char plugin_start_addr[];
|
|
|
|
extern unsigned char plugin_end_addr[];
|
2006-11-06 18:07:30 +00:00
|
|
|
/* decoders */
|
2006-01-18 00:05:14 +00:00
|
|
|
#define CODEC_HEADER \
|
|
|
|
const struct codec_header __header \
|
|
|
|
__attribute__ ((section (".header")))= { \
|
2010-09-09 16:17:21 +00:00
|
|
|
{ CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
|
2011-04-27 03:08:23 +00:00
|
|
|
plugin_start_addr, plugin_end_addr }, codec_start, \
|
|
|
|
codec_run, &ci };
|
2006-11-06 18:07:30 +00:00
|
|
|
/* encoders */
|
|
|
|
#define CODEC_ENC_HEADER \
|
|
|
|
const struct codec_header __header \
|
|
|
|
__attribute__ ((section (".header")))= { \
|
2010-09-09 16:17:21 +00:00
|
|
|
{ CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
|
2011-04-27 03:08:23 +00:00
|
|
|
plugin_start_addr, plugin_end_addr }, codec_start, \
|
|
|
|
codec_run, &ci };
|
2006-11-06 18:07:30 +00:00
|
|
|
|
|
|
|
#else /* def SIMULATOR */
|
|
|
|
/* decoders */
|
2006-01-18 00:05:14 +00:00
|
|
|
#define CODEC_HEADER \
|
2007-10-02 09:08:08 +00:00
|
|
|
const struct codec_header __header \
|
|
|
|
__attribute__((visibility("default"))) = { \
|
2010-09-09 16:17:21 +00:00
|
|
|
{ CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \
|
2011-04-27 03:08:23 +00:00
|
|
|
codec_start, codec_run, &ci };
|
2006-11-06 18:07:30 +00:00
|
|
|
/* encoders */
|
|
|
|
#define CODEC_ENC_HEADER \
|
|
|
|
const struct codec_header __header = { \
|
2010-09-09 16:17:21 +00:00
|
|
|
{ CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \
|
2011-04-27 03:08:23 +00:00
|
|
|
codec_start, codec_run, &ci };
|
2006-11-06 18:07:30 +00:00
|
|
|
#endif /* SIMULATOR */
|
|
|
|
#endif /* CODEC */
|
2006-01-18 00:05:14 +00:00
|
|
|
|
2006-11-06 18:07:30 +00:00
|
|
|
/* create full codec path from root filenames in audio_formats[]
|
2006-08-28 22:38:41 +00:00
|
|
|
assumes buffer size is MAX_PATH */
|
2006-11-06 18:07:30 +00:00
|
|
|
void codec_get_full_path(char *path, const char *codec_root_fn);
|
2006-08-28 22:38:41 +00:00
|
|
|
|
2011-05-08 20:18:35 +00:00
|
|
|
/* Returns pointer to and size of free codec RAM */
|
2011-05-09 19:34:45 +00:00
|
|
|
void *codec_get_buffer_callback(size_t *size);
|
2011-05-08 20:18:35 +00:00
|
|
|
|
2005-06-22 19:41:30 +00:00
|
|
|
/* defined by the codec loader (codec.c) */
|
2011-04-27 03:08:23 +00:00
|
|
|
int codec_load_buf(int hid, struct codec_api *api);
|
|
|
|
int codec_load_file(const char* codec, struct codec_api *api);
|
|
|
|
int codec_run_proc(void);
|
|
|
|
int codec_halt(void);
|
|
|
|
int codec_close(void);
|
2005-06-22 19:41:30 +00:00
|
|
|
|
|
|
|
/* defined by the codec */
|
2011-04-27 03:08:23 +00:00
|
|
|
enum codec_status codec_start(enum codec_entry_call_reason reason);
|
2011-08-25 20:52:50 +00:00
|
|
|
enum codec_status codec_main(enum codec_entry_call_reason reason);
|
2011-04-27 03:08:23 +00:00
|
|
|
enum codec_status codec_run(void);
|
2005-06-22 19:41:30 +00:00
|
|
|
|
2011-04-27 03:08:23 +00:00
|
|
|
#endif /* _CODECS_H_ */
|