blob: b0cf1870976e74ae330be6942857d2648ecb9e96 [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 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _CODECS_H_
22#define _CODECS_H_
23
24/* instruct simulator code to not redefine any symbols when compiling codecs.
25 (the CODEC macro is defined in apps/codecs/Makefile) */
26#ifdef CODEC
27#define NO_REDEFINES_PLEASE
28#endif
29
30#ifndef MEM
31#define MEM 2
32#endif
33
34#include <stdbool.h>
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000035#include <stdlib.h>
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000036#include "config.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000037#include "kernel.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000038#include "system.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000039#include "id3.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000040#include "audio.h"
Brandon Low05dccc32006-01-18 20:54:13 +000041#ifdef RB_PROFILE
42#include "profile.h"
Dave Chapman1feb8bd2007-05-07 13:32:56 +000043#include "thread.h"
Brandon Low05dccc32006-01-18 20:54:13 +000044#endif
Thom Johansen6dfe98e2005-10-10 15:54:36 +000045#if (CONFIG_CODEC == SWCODEC)
Michael Sevakis0f5cb942006-11-06 18:07:30 +000046#if !defined(SIMULATOR) && defined(HAVE_RECORDING)
Michael Sevakis4fc717a2006-08-28 22:38:41 +000047#include "pcm_record.h"
48#endif
Thom Johansen6dfe98e2005-10-10 15:54:36 +000049#include "dsp.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000050#endif
51#include "settings.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000052
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000053#ifdef CODEC
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000054#if defined(DEBUG) || defined(SIMULATOR)
55#undef DEBUGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000056#define DEBUGF ci->debugf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000057#undef LDEBUGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000058#define LDEBUGF ci->debugf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000059#else
60#define DEBUGF(...)
61#define LDEBUGF(...)
62#endif
63
64#ifdef ROCKBOX_HAS_LOGF
65#undef LOGF
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000066#define LOGF ci->logf
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000067#else
68#define LOGF(...)
69#endif
70
71#endif
72
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000073#ifdef SIMULATOR
74#define PREFIX(_x_) sim_ ## _x_
75#else
76#define PREFIX(_x_) _x_
77#endif
78
Michael Sevakis0f5cb942006-11-06 18:07:30 +000079/* magic for normal codecs */
Jens Arnoldb8749fd2006-01-18 00:05:14 +000080#define CODEC_MAGIC 0x52434F44 /* RCOD */
Michael Sevakis0f5cb942006-11-06 18:07:30 +000081/* magic for encoder codecs */
82#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +000083
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000084/* increase this every time the api struct changes */
Michael Sevakis4855e732008-03-29 06:36:53 +000085#define CODEC_API_VERSION 24
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000086
87/* update this to latest version if a change to the api struct breaks
Jens Arnold99a05982005-08-29 20:07:17 +000088 backwards compatibility (and please take the opportunity to sort in any
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000089 new function which are "waiting" at the end of the function table) */
Michael Sevakis4855e732008-03-29 06:36:53 +000090#define CODEC_MIN_API_VERSION 24
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000091
92/* codec return codes */
93enum codec_status {
94 CODEC_OK = 0,
95 CODEC_USB_CONNECTED,
Jens Arnoldb8749fd2006-01-18 00:05:14 +000096 CODEC_ERROR = -1,
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000097};
98
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000099/* NOTE: To support backwards compatibility, only add new functions at
100 the end of the structure. Every time you add a new function,
101 remember to increase CODEC_API_VERSION. If you make changes to the
102 existing APIs then also update CODEC_MIN_API_VERSION to current
103 version
104 */
105struct codec_api {
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000106
107 off_t filesize; /* Total file length */
108 off_t curpos; /* Current buffer position */
109
110 /* For gapless mp3 */
111 struct mp3entry *id3; /* TAG metadata pointer */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000112 bool *taginfo_ready; /* Is metadata read */
113
114 /* Codec should periodically check if stop_codec is set to true.
Brandon Lowebadcc62006-04-15 02:03:11 +0000115 In case it is, codec must return immediately */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000116 bool stop_codec;
Brandon Lowebadcc62006-04-15 02:03:11 +0000117 /* Codec should periodically check if new_track is non zero.
118 When it is, the codec should request a new track. */
119 int new_track;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000120 /* If seek_time != 0, codec should seek to that song position (in ms)
121 if codec supports seeking. */
Jens Arnold8ac3ae72006-03-03 02:09:58 +0000122 long seek_time;
Michael Sevakis27cf6772008-03-25 02:34:12 +0000123
124 /* The dsp instance to be used for audio output */
125 struct dsp_config *dsp;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000126
127 /* Returns buffer to malloc array. Only codeclib should need this. */
Brandon Low86f1e2e2006-03-24 13:43:15 +0000128 void* (*get_codec_memory)(size_t *size);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000129 /* Insert PCM data into audio buffer for playback. Playback will start
130 automatically. */
Steve Bavin135cc752008-03-28 12:51:33 +0000131 bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000132 /* Set song position in WPS (value in ms). */
Steve Bavin135cc752008-03-28 12:51:33 +0000133 void (*set_elapsed)(unsigned int value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000134
135 /* Read next <size> amount bytes from file buffer to <ptr>.
136 Will return number of bytes read or 0 if end of file. */
Steve Bavin135cc752008-03-28 12:51:33 +0000137 size_t (*read_filebuf)(void *ptr, size_t size);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000138 /* Request pointer to file buffer which can be used to read
139 <realsize> amount of data. <reqsize> tells the buffer system
140 how much data it should try to allocate. If <realsize> is 0,
141 end of file is reached. */
Steve Bavin135cc752008-03-28 12:51:33 +0000142 void* (*request_buffer)(size_t *realsize, size_t reqsize);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000143 /* Advance file buffer position by <amount> amount of bytes. */
Steve Bavin135cc752008-03-28 12:51:33 +0000144 void (*advance_buffer)(size_t amount);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000145 /* Advance file buffer to a pointer location inside file buffer. */
146 void (*advance_buffer_loc)(void *ptr);
147 /* Seek file buffer to position <newpos> beginning of file. */
Steve Bavin135cc752008-03-28 12:51:33 +0000148 bool (*seek_buffer)(size_t newpos);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000149 /* Codec should call this function when it has done the seeking. */
150 void (*seek_complete)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000151 /* Request file change from file buffer. Returns true is next
152 track is available and changed. If return value is false,
153 codec should exit immediately with PLUGIN_OK status. */
154 bool (*request_next_track)(void);
Brandon Lowebadcc62006-04-15 02:03:11 +0000155 /* Free the buffer area of the current codec after its loaded */
156 void (*discard_codec)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000157
Steve Bavin135cc752008-03-28 12:51:33 +0000158 void (*set_offset)(size_t value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000159 /* Configure different codec buffer parameters. */
Steve Bavin135cc752008-03-28 12:51:33 +0000160 void (*configure)(int setting, intptr_t value);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000161
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000162 /* kernel/ system */
Steve Bavin135cc752008-03-28 12:51:33 +0000163 void (*PREFIX(sleep))(int ticks);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000164 void (*yield)(void);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000165
Michael Sevakis27cf6772008-03-25 02:34:12 +0000166#if NUM_CORES > 1
167 struct thread_entry *
168 (*create_thread)(void (*function)(void), void* stack,
169 size_t stack_size, unsigned flags, const char *name
170 IF_PRIO(, int priority)
171 IF_COP(, unsigned int core));
172
173 void (*thread_thaw)(struct thread_entry *thread);
174 void (*thread_wait)(struct thread_entry *thread);
175 void (*semaphore_init)(struct semaphore *s, int max, int start);
176 void (*semaphore_wait)(struct semaphore *s);
177 void (*semaphore_release)(struct semaphore *s);
178 void (*event_init)(struct event *e, unsigned int flags);
179 void (*event_wait)(struct event *e, unsigned int for_state);
180 void (*event_set_state)(struct event *e, unsigned int state);
181#endif /* NUM_CORES */
182
183#ifdef CACHE_FUNCTIONS_AS_CALL
184 void (*flush_icache)(void);
185 void (*invalidate_icache)(void);
186#endif
187
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000188 /* strings and memory */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000189 char* (*strcpy)(char *dst, const char *src);
190 char* (*strncpy)(char *dst, const char *src, size_t length);
191 size_t (*strlen)(const char *str);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000192 int (*strcmp)(const char *, const char *);
Dave Chapman9a011f32007-05-07 11:09:45 +0000193 char *(*strcat)(char *s1, const char *s2);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000194 void* (*memset)(void *dst, int c, size_t length);
195 void* (*memcpy)(void *out, const void *in, size_t n);
Brandon Low86f1e2e2006-03-24 13:43:15 +0000196 void* (*memmove)(void *out, const void *in, size_t n);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000197 int (*memcmp)(const void *s1, const void *s2, size_t n);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000198 void *(*memchr)(const void *s1, int c, size_t n);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000199
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000200#if defined(DEBUG) || defined(SIMULATOR)
Jens Arnold79c8a8c2007-03-17 09:02:53 +0000201 void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000202#endif
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000203#ifdef ROCKBOX_HAS_LOGF
Jens Arnold79c8a8c2007-03-17 09:02:53 +0000204 void (*logf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000205#endif
Dave Chapman9a011f32007-05-07 11:09:45 +0000206
207 /* Tremor requires qsort */
208 void (*qsort)(void *base, size_t nmemb, size_t size,
209 int(*compar)(const void *, const void *));
210
211 /* The ADX codec accesses global_settings to test for REPEAT_ONE mode */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000212 struct user_settings* global_settings;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000213
Brandon Low05dccc32006-01-18 20:54:13 +0000214#ifdef RB_PROFILE
215 void (*profile_thread)(void);
216 void (*profstop)(void);
217 void (*profile_func_enter)(void *this_fn, void *call_site);
218 void (*profile_func_exit)(void *this_fn, void *call_site);
219#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000220
221#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
Michael Sevakis598629c2007-03-04 04:16:53 +0000222 volatile bool stop_encoder;
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000223 volatile int enc_codec_loaded; /* <0=error, 0=pending, >0=ok */
224 void (*enc_get_inputs)(struct enc_inputs *inputs);
225 void (*enc_set_parameters)(struct enc_parameters *params);
226 struct enc_chunk_hdr * (*enc_get_chunk)(void);
227 void (*enc_finish_chunk)(void);
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000228 unsigned char * (*enc_get_pcm_data)(size_t size);
229 size_t (*enc_unget_pcm_data)(size_t size);
Dave Chapman9a011f32007-05-07 11:09:45 +0000230
231 /* file */
232 int (*PREFIX(open))(const char* pathname, int flags);
233 int (*close)(int fd);
234 ssize_t (*read)(int fd, void* buf, size_t count);
235 off_t (*PREFIX(lseek))(int fd, off_t offset, int whence);
236 ssize_t (*write)(int fd, const void* buf, size_t count);
Dave Chapman9a011f32007-05-07 11:09:45 +0000237 int (*round_value_to_list32)(unsigned long value,
238 const unsigned long list[],
239 int count,
240 bool signd);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000241#endif
Linus Nielsen Feltzingeaf8b2d2005-07-05 08:43:36 +0000242
Brandon Lowd2e75bf2006-02-03 00:12:11 +0000243 /* new stuff at the end, sort into place next time
244 the API gets incompatible */
245
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000246};
247
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000248/* codec header */
249struct codec_header {
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000250 unsigned long magic; /* RCOD or RENC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000251 unsigned short target_id;
252 unsigned short api_version;
253 unsigned char *load_addr;
254 unsigned char *end_addr;
255 enum codec_status(*entry_point)(struct codec_api*);
256};
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000257
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000258#ifdef CODEC
259#ifndef SIMULATOR
260/* plugin_* is correct, codecs use the plugin linker script */
261extern unsigned char plugin_start_addr[];
262extern unsigned char plugin_end_addr[];
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000263/* decoders */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000264#define CODEC_HEADER \
265 const struct codec_header __header \
266 __attribute__ ((section (".header")))= { \
267 CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
268 plugin_start_addr, plugin_end_addr, codec_start };
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000269/* encoders */
270#define CODEC_ENC_HEADER \
271 const struct codec_header __header \
272 __attribute__ ((section (".header")))= { \
273 CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
274 plugin_start_addr, plugin_end_addr, codec_start };
275
276#else /* def SIMULATOR */
277/* decoders */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000278#define CODEC_HEADER \
Nils Wallménius605949d2007-10-02 09:08:08 +0000279 const struct codec_header __header \
280 __attribute__((visibility("default"))) = { \
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000281 CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
282 NULL, NULL, codec_start };
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000283/* encoders */
284#define CODEC_ENC_HEADER \
285 const struct codec_header __header = { \
286 CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
287 NULL, NULL, codec_start };
288#endif /* SIMULATOR */
289#endif /* CODEC */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000290
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000291/* create full codec path from root filenames in audio_formats[]
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000292 assumes buffer size is MAX_PATH */
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000293void codec_get_full_path(char *path, const char *codec_root_fn);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000294
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000295/* defined by the codec loader (codec.c) */
Brandon Low86919f42007-11-03 17:55:29 +0000296int codec_load_buf(unsigned int hid, struct codec_api *api);
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000297int codec_load_file(const char* codec, struct codec_api *api);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000298
299/* defined by the codec */
Jens Arnoldb8749fd2006-01-18 00:05:14 +0000300enum codec_status codec_start(struct codec_api* rockbox);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000301
Michael Sevakis7914e902007-09-28 10:20:02 +0000302#ifndef CACHE_FUNCTION_WRAPPERS
303
304#ifdef CACHE_FUNCTIONS_AS_CALL
305#define CACHE_FUNCTION_WRAPPERS(api) \
306 void flush_icache(void) \
307 { \
308 (api)->flush_icache(); \
309 } \
310 void invalidate_icache(void) \
311 { \
312 (api)->invalidate_icache(); \
313 }
314#else
315#define CACHE_FUNCTION_WRAPPERS(api)
316#endif /* CACHE_FUNCTIONS_AS_CALL */
317
318#endif /* CACHE_FUNCTION_WRAPPERS */
319
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000320#endif