some tags need special handling when they are in the wrong branch of a conditional...
[kugel-rb.git] / apps / codecs.h
blob27c9caba138e051b3981d1d804183df058753071
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * 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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #ifndef _CODECS_H_
22 #define _CODECS_H_
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
30 #ifndef MEM
31 #define MEM 2
32 #endif
34 #include <_ansi.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 #include "strlcpy.h"
38 #include "config.h"
39 #include "system.h"
40 #include "metadata.h"
41 #include "audio.h"
42 #ifdef RB_PROFILE
43 #include "profile.h"
44 #include "thread.h"
45 #endif
46 #if (CONFIG_CODEC == SWCODEC)
47 #if !defined(SIMULATOR) && defined(HAVE_RECORDING)
48 #include "pcm_record.h"
49 #endif
50 #include "dsp.h"
51 #endif
52 #include "settings.h"
54 #ifdef CODEC
55 #if defined(DEBUG) || defined(SIMULATOR)
56 #undef DEBUGF
57 #define DEBUGF ci->debugf
58 #undef LDEBUGF
59 #define LDEBUGF ci->debugf
60 #else
61 #define DEBUGF(...)
62 #define LDEBUGF(...)
63 #endif
65 #ifdef ROCKBOX_HAS_LOGF
66 #undef LOGF
67 #define LOGF ci->logf
68 #else
69 #define LOGF(...)
70 #endif
72 #endif
74 /* magic for normal codecs */
75 #define CODEC_MAGIC 0x52434F44 /* RCOD */
76 /* magic for encoder codecs */
77 #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
79 /* increase this every time the api struct changes */
80 #define CODEC_API_VERSION 34
82 /* update this to latest version if a change to the api struct breaks
83 backwards compatibility (and please take the opportunity to sort in any
84 new function which are "waiting" at the end of the function table) */
85 #define CODEC_MIN_API_VERSION 34
87 /* codec return codes */
88 enum codec_status {
89 CODEC_OK = 0,
90 CODEC_USB_CONNECTED,
91 CODEC_ERROR = -1,
94 /* NOTE: To support backwards compatibility, only add new functions at
95 the end of the structure. Every time you add a new function,
96 remember to increase CODEC_API_VERSION. If you make changes to the
97 existing APIs then also update CODEC_MIN_API_VERSION to current
98 version
100 struct codec_api {
102 off_t filesize; /* Total file length */
103 off_t curpos; /* Current buffer position */
105 /* For gapless mp3 */
106 struct mp3entry *id3; /* TAG metadata pointer */
107 bool *taginfo_ready; /* Is metadata read */
109 /* Codec should periodically check if stop_codec is set to true.
110 In case it is, codec must return immediately */
111 bool stop_codec;
112 /* Codec should periodically check if new_track is non zero.
113 When it is, the codec should request a new track. */
114 int new_track;
115 /* If seek_time != 0, codec should seek to that song position (in ms)
116 if codec supports seeking. */
117 long seek_time;
119 /* The dsp instance to be used for audio output */
120 struct dsp_config *dsp;
122 /* Returns buffer to malloc array. Only codeclib should need this. */
123 void* (*codec_get_buffer)(size_t *size);
124 /* Insert PCM data into audio buffer for playback. Playback will start
125 automatically. */
126 void (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
127 /* Set song position in WPS (value in ms). */
128 void (*set_elapsed)(unsigned long value);
130 /* Read next <size> amount bytes from file buffer to <ptr>.
131 Will return number of bytes read or 0 if end of file. */
132 size_t (*read_filebuf)(void *ptr, size_t size);
133 /* Request pointer to file buffer which can be used to read
134 <realsize> amount of data. <reqsize> tells the buffer system
135 how much data it should try to allocate. If <realsize> is 0,
136 end of file is reached. */
137 void* (*request_buffer)(size_t *realsize, size_t reqsize);
138 /* Advance file buffer position by <amount> amount of bytes. */
139 void (*advance_buffer)(size_t amount);
140 /* Advance file buffer to a pointer location inside file buffer. */
141 void (*advance_buffer_loc)(void *ptr);
142 /* Seek file buffer to position <newpos> beginning of file. */
143 bool (*seek_buffer)(size_t newpos);
144 /* Codec should call this function when it has done the seeking. */
145 void (*seek_complete)(void);
146 /* Request file change from file buffer. Returns true is next
147 track is available and changed. If return value is false,
148 codec should exit immediately with PLUGIN_OK status. */
149 bool (*request_next_track)(void);
150 /* Free the buffer area of the current codec after its loaded */
151 void (*discard_codec)(void);
153 void (*set_offset)(size_t value);
154 /* Configure different codec buffer parameters. */
155 void (*configure)(int setting, intptr_t value);
157 /* kernel/ system */
158 #ifdef CPU_ARM
159 void (*__div0)(void);
160 #endif
161 void (*sleep)(int ticks);
162 void (*yield)(void);
164 #if NUM_CORES > 1
165 unsigned int
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));
171 void (*thread_thaw)(unsigned int thread_id);
172 void (*thread_wait)(unsigned int thread_id);
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 #endif /* NUM_CORES */
178 #if NUM_CORES > 1
179 void (*cpucache_flush)(void);
180 void (*cpucache_invalidate)(void);
181 #endif
183 /* strings and memory */
184 char* (*strcpy)(char *dst, const char *src);
185 size_t (*strlen)(const char *str);
186 int (*strcmp)(const char *, const char *);
187 char *(*strcat)(char *s1, const char *s2);
188 void* (*memset)(void *dst, int c, size_t length);
189 void* (*memcpy)(void *out, const void *in, size_t n);
190 void* (*memmove)(void *out, const void *in, size_t n);
191 int (*memcmp)(const void *s1, const void *s2, size_t n);
192 void *(*memchr)(const void *s1, int c, size_t n);
193 char *(*strcasestr) (const char* phaystack, const char* pneedle);
195 #if defined(DEBUG) || defined(SIMULATOR)
196 void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
197 #endif
198 #ifdef ROCKBOX_HAS_LOGF
199 void (*logf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
200 #endif
202 /* Tremor requires qsort */
203 void (*qsort)(void *base, size_t nmemb, size_t size,
204 int(*compar)(const void *, const void *));
206 /* The ADX codec accesses global_settings to test for REPEAT_ONE mode */
207 struct user_settings* global_settings;
209 #ifdef RB_PROFILE
210 void (*profile_thread)(void);
211 void (*profstop)(void);
212 void (*profile_func_enter)(void *this_fn, void *call_site);
213 void (*profile_func_exit)(void *this_fn, void *call_site);
214 #endif
216 #if defined(HAVE_RECORDING) && !defined(SIMULATOR)
217 volatile bool stop_encoder;
218 volatile int enc_codec_loaded; /* <0=error, 0=pending, >0=ok */
219 void (*enc_get_inputs)(struct enc_inputs *inputs);
220 void (*enc_set_parameters)(struct enc_parameters *params);
221 struct enc_chunk_hdr * (*enc_get_chunk)(void);
222 void (*enc_finish_chunk)(void);
223 unsigned char * (*enc_get_pcm_data)(size_t size);
224 size_t (*enc_unget_pcm_data)(size_t size);
226 /* file */
227 int (*open)(const char* pathname, int flags, ...);
228 int (*close)(int fd);
229 ssize_t (*read)(int fd, void* buf, size_t count);
230 off_t (*lseek)(int fd, off_t offset, int whence);
231 ssize_t (*write)(int fd, const void* buf, size_t count);
232 int (*round_value_to_list32)(unsigned long value,
233 const unsigned long list[],
234 int count,
235 bool signd);
236 #endif
238 /* new stuff at the end, sort into place next time
239 the API gets incompatible */
242 /* codec header */
243 struct codec_header {
244 unsigned long magic; /* RCOD or RENC */
245 unsigned short target_id;
246 unsigned short api_version;
247 unsigned char *load_addr;
248 unsigned char *end_addr;
249 enum codec_status(*entry_point)(void);
250 struct codec_api **api;
253 extern unsigned char codecbuf[];
254 extern size_t codec_size;
256 #ifdef CODEC
257 #ifndef SIMULATOR
258 /* plugin_* is correct, codecs use the plugin linker script */
259 extern unsigned char plugin_start_addr[];
260 extern unsigned char plugin_end_addr[];
261 /* decoders */
262 #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, &ci };
267 /* 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, &ci };
274 #else /* def SIMULATOR */
275 /* decoders */
276 #define CODEC_HEADER \
277 const struct codec_header __header \
278 __attribute__((visibility("default"))) = { \
279 CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
280 NULL, NULL, codec_start, &ci };
281 /* 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, &ci };
286 #endif /* SIMULATOR */
287 #endif /* CODEC */
289 /* create full codec path from root filenames in audio_formats[]
290 assumes buffer size is MAX_PATH */
291 void codec_get_full_path(char *path, const char *codec_root_fn);
293 /* defined by the codec loader (codec.c) */
294 int codec_load_buf(unsigned int hid, struct codec_api *api);
295 int codec_load_file(const char* codec, struct codec_api *api);
297 /* defined by the codec */
298 enum codec_status codec_start(void);
299 enum codec_status codec_main(void);
301 #endif