blob: 06016567be8c0708797bfdc231952452cd6fb057 [file] [log] [blame]
Daniel Stenberg1dd672f2005-06-22 19:41:30 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Nicolas Pennequin357ffb32008-05-05 10:32:46 +000010 * Copyright (C) 2002 Björn Stenberg
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000011 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef _CODECS_H_
20#define _CODECS_H_
21
22/* instruct simulator code to not redefine any symbols when compiling codecs.
23 (the CODEC macro is defined in apps/codecs/Makefile) */
24#ifdef CODEC
25#define NO_REDEFINES_PLEASE
26#endif
27
28#ifndef MEM
29#define MEM 2
30#endif
31
32#include <stdbool.h>
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000033#include <stdlib.h>
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000034#include "config.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000035#include "kernel.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000036#include "system.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000037#include "id3.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000038#include "audio.h"
Brandon Low05dccc32006-01-18 20:54:13 +000039#ifdef RB_PROFILE
40#include "profile.h"
Dave Chapman1feb8bd2007-05-07 13:32:56 +000041#include "thread.h"
Brandon Low05dccc32006-01-18 20:54:13 +000042#endif
Thom Johansen6dfe98e2005-10-10 15:54:36 +000043#if (CONFIG_CODEC == SWCODEC)
Michael Sevakis0f5cb942006-11-06 18:07:30 +000044#if !defined(SIMULATOR) && defined(HAVE_RECORDING)
Michael Sevakis4fc717a2006-08-28 22:38:41 +000045#include "pcm_record.h"
46#endif
Thom Johansen6dfe98e2005-10-10 15:54:36 +000047#include "dsp.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000048#endif
49#include "settings.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000050
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000051#ifdef CODEC
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000052#if defined(DEBUG) || defined(SIMULATOR)
53#undef DEBUGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000054#define DEBUGF ci->debugf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000055#undef LDEBUGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000056#define LDEBUGF ci->debugf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000057#else
58#define DEBUGF(...)
59#define LDEBUGF(...)
60#endif
61
62#ifdef ROCKBOX_HAS_LOGF
63#undef LOGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000064#define LOGF ci->logf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000065#else
66#define LOGF(...)
67#endif
68
69#endif
70
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000071#ifdef SIMULATOR
72#define PREFIX(_x_) sim_ ## _x_
73#else
74#define PREFIX(_x_) _x_
75#endif
76
Michael Sevakis0f5cb942006-11-06 18:07:30 +000077/* magic for normal codecs */
Jens Arnoldb8749fd2006-01-18 00:05:14 +000078#define CODEC_MAGIC 0x52434F44 /* RCOD */
Michael Sevakis0f5cb942006-11-06 18:07:30 +000079/* magic for encoder codecs */
80#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +000081
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000082/* increase this every time the api struct changes */
Michael Sevakis4855e732008-03-29 06:36:53 +000083#define CODEC_API_VERSION 24
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000084
85/* update this to latest version if a change to the api struct breaks
Jens Arnold99a05982005-08-29 20:07:17 +000086 backwards compatibility (and please take the opportunity to sort in any
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000087 new function which are "waiting" at the end of the function table) */
Michael Sevakis4855e732008-03-29 06:36:53 +000088#define CODEC_MIN_API_VERSION 24
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000089
90/* codec return codes */
91enum codec_status {
92 CODEC_OK = 0,
93 CODEC_USB_CONNECTED,
Jens Arnoldb8749fd2006-01-18 00:05:14 +000094 CODEC_ERROR = -1,
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000095};
96
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000097/* NOTE: To support backwards compatibility, only add new functions at
98 the end of the structure. Every time you add a new function,
99 remember to increase CODEC_API_VERSION. If you make changes to the
100 existing APIs then also update CODEC_MIN_API_VERSION to current
101 version
102 */
103struct codec_api {
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000104
105 off_t filesize; /* Total file length */
106 off_t curpos; /* Current buffer position */
107
108 /* For gapless mp3 */
109 struct mp3entry *id3; /* TAG metadata pointer */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000110 bool *taginfo_ready; /* Is metadata read */
111
112 /* Codec should periodically check if stop_codec is set to true.
Brandon Lowebadcc62006-04-15 02:03:11 +0000113 In case it is, codec must return immediately */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000114 bool stop_codec;
Brandon Lowebadcc62006-04-15 02:03:11 +0000115 /* Codec should periodically check if new_track is non zero.
116 When it is, the codec should request a new track. */
117 int new_track;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000118 /* If seek_time != 0, codec should seek to that song position (in ms)
119 if codec supports seeking. */
Jens Arnold8ac3ae72006-03-03 02:09:58 +0000120 long seek_time;
Michael Sevakis27cf6772008-03-25 02:34:12 +0000121
122 /* The dsp instance to be used for audio output */
123 struct dsp_config *dsp;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000124
125 /* Returns buffer to malloc array. Only codeclib should need this. */
Brandon Low86f1e2e2006-03-24 13:43:15 +0000126 void* (*get_codec_memory)(size_t *size);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000127 /* Insert PCM data into audio buffer for playback. Playback will start
128 automatically. */
Steve Bavin135cc752008-03-28 12:51:33 +0000129 bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000130 /* Set song position in WPS (value in ms). */
Steve Bavin135cc752008-03-28 12:51:33 +0000131 void (*set_elapsed)(unsigned int value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000132
133 /* Read next <size> amount bytes from file buffer to <ptr>.
134 Will return number of bytes read or 0 if end of file. */
Steve Bavin135cc752008-03-28 12:51:33 +0000135 size_t (*read_filebuf)(void *ptr, size_t size);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000136 /* Request pointer to file buffer which can be used to read
137 <realsize> amount of data. <reqsize> tells the buffer system
138 how much data it should try to allocate. If <realsize> is 0,
139 end of file is reached. */
Steve Bavin135cc752008-03-28 12:51:33 +0000140 void* (*request_buffer)(size_t *realsize, size_t reqsize);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000141 /* Advance file buffer position by <amount> amount of bytes. */
Steve Bavin135cc752008-03-28 12:51:33 +0000142 void (*advance_buffer)(size_t amount);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000143 /* Advance file buffer to a pointer location inside file buffer. */
144 void (*advance_buffer_loc)(void *ptr);
145 /* Seek file buffer to position <newpos> beginning of file. */
Steve Bavin135cc752008-03-28 12:51:33 +0000146 bool (*seek_buffer)(size_t newpos);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000147 /* Codec should call this function when it has done the seeking. */
148 void (*seek_complete)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000149 /* Request file change from file buffer. Returns true is next
150 track is available and changed. If return value is false,
151 codec should exit immediately with PLUGIN_OK status. */
152 bool (*request_next_track)(void);
Brandon Lowebadcc62006-04-15 02:03:11 +0000153 /* Free the buffer area of the current codec after its loaded */
154 void (*discard_codec)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000155
Steve Bavin135cc752008-03-28 12:51:33 +0000156 void (*set_offset)(size_t value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000157 /* Configure different codec buffer parameters. */
Steve Bavin135cc752008-03-28 12:51:33 +0000158 void (*configure)(int setting, intptr_t value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000159
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000160 /* kernel/ system */
Steve Bavin135cc752008-03-28 12:51:33 +0000161 void (*PREFIX(sleep))(int ticks);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000162 void (*yield)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000163
Michael Sevakis27cf6772008-03-25 02:34:12 +0000164#if NUM_CORES > 1
165 struct thread_entry *
166 (*create_thread)(void (*function)(void), void* stack,
167 size_t stack_size, unsigned flags, const char *name
168 IF_PRIO(, int priority)
169 IF_COP(, unsigned int core));
170
171 void (*thread_thaw)(struct thread_entry *thread);
172 void (*thread_wait)(struct thread_entry *thread);
173 void (*semaphore_init)(struct semaphore *s, int max, int start);
174 void (*semaphore_wait)(struct semaphore *s);
175 void (*semaphore_release)(struct semaphore *s);
176 void (*event_init)(struct event *e, unsigned int flags);
177 void (*event_wait)(struct event *e, unsigned int for_state);
178 void (*event_set_state)(struct event *e, unsigned int state);
179#endif /* NUM_CORES */
180
181#ifdef CACHE_FUNCTIONS_AS_CALL
182 void (*flush_icache)(void);
183 void (*invalidate_icache)(void);
184#endif
185
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000186 /* strings and memory */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000187 char* (*strcpy)(char *dst, const char *src);
188 char* (*strncpy)(char *dst, const char *src, size_t length);
189 size_t (*strlen)(const char *str);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000190 int (*strcmp)(const char *, const char *);
Dave Chapman9a011f32007-05-07 11:09:45 +0000191 char *(*strcat)(char *s1, const char *s2);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000192 void* (*memset)(void *dst, int c, size_t length);
193 void* (*memcpy)(void *out, const void *in, size_t n);
Brandon Low86f1e2e2006-03-24 13:43:15 +0000194 void* (*memmove)(void *out, const void *in, size_t n);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000195 int (*memcmp)(const void *s1, const void *s2, size_t n);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000196 void *(*memchr)(const void *s1, int c, size_t n);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000197
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000198#if defined(DEBUG) || defined(SIMULATOR)
Jens Arnold79c8a8c2007-03-17 09:02:53 +0000199 void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000200#endif
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000201#ifdef ROCKBOX_HAS_LOGF
Jens Arnold79c8a8c2007-03-17 09:02:53 +0000202 void (*logf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000203#endif
Dave Chapman9a011f32007-05-07 11:09:45 +0000204
205 /* Tremor requires qsort */
206 void (*qsort)(void *base, size_t nmemb, size_t size,
207 int(*compar)(const void *, const void *));
208
209 /* The ADX codec accesses global_settings to test for REPEAT_ONE mode */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000210 struct user_settings* global_settings;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000211
Brandon Low05dccc32006-01-18 20:54:13 +0000212#ifdef RB_PROFILE
213 void (*profile_thread)(void);
214 void (*profstop)(void);
215 void (*profile_func_enter)(void *this_fn, void *call_site);
216 void (*profile_func_exit)(void *this_fn, void *call_site);
217#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000218
219#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
Michael Sevakis598629c2007-03-04 04:16:53 +0000220 volatile bool stop_encoder;
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000221 volatile int enc_codec_loaded; /* <0=error, 0=pending, >0=ok */
222 void (*enc_get_inputs)(struct enc_inputs *inputs);
223 void (*enc_set_parameters)(struct enc_parameters *params);
224 struct enc_chunk_hdr * (*enc_get_chunk)(void);
225 void (*enc_finish_chunk)(void);
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000226 unsigned char * (*enc_get_pcm_data)(size_t size);
227 size_t (*enc_unget_pcm_data)(size_t size);
Dave Chapman9a011f32007-05-07 11:09:45 +0000228
229 /* file */
230 int (*PREFIX(open))(const char* pathname, int flags);
231 int (*close)(int fd);
232 ssize_t (*read)(int fd, void* buf, size_t count);
233 off_t (*PREFIX(lseek))(int fd, off_t offset, int whence);
234 ssize_t (*write)(int fd, const void* buf, size_t count);
Dave Chapman9a011f32007-05-07 11:09:45 +0000235 int (*round_value_to_list32)(unsigned long value,
236 const unsigned long list[],
237 int count,
238 bool signd);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000239#endif
Linus Nielsen Feltzingeaf8b2d2005-07-05 08:43:36 +0000240
Brandon Lowd2e75bf2006-02-03 00:12:11 +0000241 /* new stuff at the end, sort into place next time
242 the API gets incompatible */
243
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000244};
245
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000246/* codec header */
247struct codec_header {
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000248 unsigned long magic; /* RCOD or RENC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000249 unsigned short target_id;
250 unsigned short api_version;
251 unsigned char *load_addr;
252 unsigned char *end_addr;
253 enum codec_status(*entry_point)(struct codec_api*);
254};
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000255
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000256#ifdef CODEC
257#ifndef SIMULATOR
258/* plugin_* is correct, codecs use the plugin linker script */
259extern unsigned char plugin_start_addr[];
260extern unsigned char plugin_end_addr[];
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000261/* decoders */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000262#define CODEC_HEADER \
263 const struct codec_header __header \
264 __attribute__ ((section (".header")))= { \
265 CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
266 plugin_start_addr, plugin_end_addr, codec_start };
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000267/* encoders */
268#define CODEC_ENC_HEADER \
269 const struct codec_header __header \
270 __attribute__ ((section (".header")))= { \
271 CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
272 plugin_start_addr, plugin_end_addr, codec_start };
273
274#else /* def SIMULATOR */
275/* decoders */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000276#define CODEC_HEADER \
Nils Wallménius605949d2007-10-02 09:08:08 +0000277 const struct codec_header __header \
278 __attribute__((visibility("default"))) = { \
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000279 CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
280 NULL, NULL, codec_start };
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000281/* encoders */
282#define CODEC_ENC_HEADER \
283 const struct codec_header __header = { \
284 CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
285 NULL, NULL, codec_start };
286#endif /* SIMULATOR */
287#endif /* CODEC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000288
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000289/* create full codec path from root filenames in audio_formats[]
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000290 assumes buffer size is MAX_PATH */
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000291void codec_get_full_path(char *path, const char *codec_root_fn);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000292
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000293/* defined by the codec loader (codec.c) */
Brandon Low86919f42007-11-03 17:55:29 +0000294int codec_load_buf(unsigned int hid, struct codec_api *api);
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000295int codec_load_file(const char* codec, struct codec_api *api);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000296
297/* defined by the codec */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000298enum codec_status codec_start(struct codec_api* rockbox);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000299
Michael Sevakis7914e902007-09-28 10:20:02 +0000300#ifndef CACHE_FUNCTION_WRAPPERS
301
302#ifdef CACHE_FUNCTIONS_AS_CALL
303#define CACHE_FUNCTION_WRAPPERS(api) \
304 void flush_icache(void) \
305 { \
306 (api)->flush_icache(); \
307 } \
308 void invalidate_icache(void) \
309 { \
310 (api)->invalidate_icache(); \
311 }
312#else
313#define CACHE_FUNCTION_WRAPPERS(api)
314#endif /* CACHE_FUNCTIONS_AS_CALL */
315
316#endif /* CACHE_FUNCTION_WRAPPERS */
317
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000318#endif