blob: 004d4681f776869881db0ec8511e319fb9cc6777 [file] [log] [blame]
Daniel Stenberg1dd672f2005-06-22 19:41:30 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Björn Stenberg
11 *
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 ****************************************************************************/
Daniel Stenberga24017f42005-06-27 21:23:03 +000019#include "config.h"
20
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000021#include <stdbool.h>
22#include <string.h>
23#include <stdio.h>
24#include <atoi.h>
25#include <timefuncs.h>
26#include <ctype.h>
27#include "debug.h"
28#include "button.h"
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000029#include "dir.h"
30#include "file.h"
31#include "kernel.h"
32#include "sprintf.h"
33#include "logf.h"
34#include "screens.h"
35#include "misc.h"
36#include "mas.h"
37#include "codecs.h"
38#include "lang.h"
39#include "keyboard.h"
40#include "mpeg.h"
41#include "buffer.h"
42#include "mp3_playback.h"
43#include "backlight.h"
44#include "ata.h"
45#include "talk.h"
46#include "mp3data.h"
47#include "powermgmt.h"
48#include "system.h"
49#include "sound.h"
50#include "database.h"
51#if (CONFIG_HWCODEC == MASNONE)
52#include "pcm_playback.h"
53#endif
54
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000055#ifdef SIMULATOR
56#if CONFIG_HWCODEC == MASNONE
Miika Pekkarinen159c52d2005-08-20 11:13:19 +000057unsigned char codecbuf[CODEC_SIZE];
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000058#endif
Miika Pekkarinen645a2e12005-07-10 16:33:03 +000059void *sim_codec_load_ram(char* codecptr, int size,
60 void* ptr2, int bufwrap, int *pd);
61void sim_codec_close(int pd);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000062#else
63#define sim_codec_close(x)
64extern unsigned char codecbuf[];
65#endif
66
67extern void* plugin_get_audio_buffer(int *buffer_size);
68
69static int codec_test(int api_version, int model, int memsize);
70
Miika Pekkarinen159c52d2005-08-20 11:13:19 +000071struct codec_api ci_voice;
72
Daniel Stenberg54c1c662005-06-22 21:16:28 +000073struct codec_api ci = {
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000074 CODEC_API_VERSION,
75 codec_test,
76
77 0, /* filesize */
78 0, /* curpos */
79 NULL, /* id3 */
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000080 NULL, /* taginfo_ready */
81 false, /* stop_codec */
82 false, /* reload_codec */
83 0, /* seek_time */
84 NULL,
85 NULL,
86 NULL,
87 NULL,
88 NULL,
89 NULL,
90 NULL,
91 NULL,
92 NULL,
93 NULL,
94 NULL,
Miika Pekkarinend8cb7032005-06-26 19:41:29 +000095 NULL,
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000096
Daniel Stenberg1dd672f2005-06-22 19:41:30 +000097 splash,
98
99 /* file */
100 (open_func)PREFIX(open),
101 close,
102 (read_func)read,
103 PREFIX(lseek),
104 (creat_func)PREFIX(creat),
105 (write_func)write,
106 PREFIX(remove),
107 PREFIX(rename),
108 PREFIX(ftruncate),
109 fdprintf,
110 read_line,
111 settings_parseline,
112#ifndef SIMULATOR
113 ata_sleep,
114#endif
115
116 /* dir */
117 PREFIX(opendir),
118 PREFIX(closedir),
119 PREFIX(readdir),
120 PREFIX(mkdir),
121
122 /* kernel/ system */
123 PREFIX(sleep),
124 yield,
125 &current_tick,
126 default_event_handler,
127 default_event_handler_ex,
128 create_thread,
129 remove_thread,
130 reset_poweroff_timer,
131#ifndef SIMULATOR
132 system_memory_guard,
133 &cpu_frequency,
134#ifdef HAVE_ADJUSTABLE_CPU_FREQ
135 cpu_boost,
136#endif
137#endif
138
139 /* strings and memory */
140 snprintf,
141 strcpy,
142 strncpy,
143 strlen,
144 strrchr,
145 strcmp,
146 strcasecmp,
147 strncasecmp,
148 memset,
149 memcpy,
150 _ctype_,
151 atoi,
152 strchr,
153 strcat,
154 memcmp,
155 strcasestr,
156
157 /* sound */
158 sound_set,
159#ifndef SIMULATOR
160 mp3_play_data,
161 mp3_play_pause,
162 mp3_play_stop,
163 mp3_is_playing,
164#if CONFIG_HWCODEC != MASNONE
165 bitswap,
166#endif
167#if CONFIG_HWCODEC == MASNONE
168 pcm_play_data,
169 pcm_play_stop,
170 pcm_set_frequency,
171 pcm_is_playing,
172 pcm_play_pause,
173#endif
174#endif
175
176 /* playback control */
177 PREFIX(audio_play),
178 audio_stop,
179 audio_pause,
180 audio_resume,
181 audio_next,
182 audio_prev,
183 audio_ff_rewind,
184 audio_next_track,
185 playlist_amount,
186 audio_status,
187 audio_has_changed_track,
188 audio_current_track,
189 audio_flush_and_reload_tracks,
190 audio_get_file_pos,
191#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
192 mpeg_get_last_header,
193#endif
194#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
195 sound_set_pitch,
196#endif
197
198#if !defined(SIMULATOR) && (CONFIG_HWCODEC != MASNONE)
199 /* MAS communication */
200 mas_readmem,
201 mas_writemem,
202 mas_readreg,
203 mas_writereg,
204#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
205 mas_codec_writereg,
206 mas_codec_readreg,
207#endif
208#endif /* !simulator and HWCODEC != MASNONE */
209
210 /* tag database */
211 &tagdbheader,
212 &tagdb_fd,
213 &tagdb_initialized,
214 tagdb_init,
215
216 /* misc */
217 srand,
218 rand,
219 (qsort_func)qsort,
220 kbd_input,
221 get_time,
222 set_time,
223 plugin_get_audio_buffer,
224
225#if defined(DEBUG) || defined(SIMULATOR)
226 debugf,
227#endif
228 &global_settings,
229 mp3info,
230 count_mp3_frames,
231 create_xing_header,
232 find_next_frame,
233 battery_level,
234 battery_level_safe,
235#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
236 peak_meter_scale_value,
237 peak_meter_set_use_dbfs,
238 peak_meter_get_use_dbfs,
239#endif
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000240
241 /* new stuff at the end, sort into place next time
242 the API gets incompatible */
243
244#ifdef ROCKBOX_HAS_LOGF
245 logf,
246#endif
247
Linus Nielsen Feltzingeaf8b2d2005-07-05 08:43:36 +0000248 memchr,
Ryan Jacksond1917562005-07-12 16:45:38 +0000249 NULL,
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000250};
251
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000252int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
253 struct codec_api *api)
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000254{
Daniel Stenberg31efab42005-06-22 19:55:09 +0000255 enum codec_status (*codec_start)(const struct codec_api* api);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000256 int status;
Miika Pekkarinen645a2e12005-07-10 16:33:03 +0000257#ifndef SIMULATOR
258 int copy_n;
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000259
260 if ((char *)&codecbuf[0] != codecptr) {
261 /* zero out codec buffer to ensure a properly zeroed bss area */
Daniel Stenberga24017f42005-06-27 21:23:03 +0000262 memset(codecbuf, 0, CODEC_SIZE);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000263
Daniel Stenberga24017f42005-06-27 21:23:03 +0000264 size = MIN(size, CODEC_SIZE);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000265 copy_n = MIN(size, bufwrap);
266 memcpy(codecbuf, codecptr, copy_n);
267 size -= copy_n;
268 if (size > 0) {
269 memcpy(&codecbuf[copy_n], ptr2, size);
270 }
271 }
272 codec_start = (void*)&codecbuf;
273
Miika Pekkarinen645a2e12005-07-10 16:33:03 +0000274#else /* SIMULATOR */
275 int pd;
276
277 codec_start = sim_codec_load_ram(codecptr, size, ptr2, bufwrap, &pd);
278 if (pd < 0)
279 return CODEC_ERROR;
280#endif /* SIMULATOR */
281
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000282 invalidate_icache();
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000283 status = codec_start(api);
Miika Pekkarinen645a2e12005-07-10 16:33:03 +0000284#ifdef SIMULATOR
285 sim_codec_close(pd);
286#endif
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000287
288 return status;
289}
290
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000291int codec_load_file(const char *plugin, struct codec_api *api)
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000292{
293 char msgbuf[80];
294 int fd;
295 int rc;
296
Miika Pekkarinen3eb962d2005-07-07 07:15:05 +0000297 /* zero out codec buffer to ensure a properly zeroed bss area */
298 memset(codecbuf, 0, CODEC_SIZE);
Ryan Jacksond1917562005-07-12 16:45:38 +0000299
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000300 fd = open(plugin, O_RDONLY);
301 if (fd < 0) {
302 snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
303 logf("Codec load error:%d", fd);
304 splash(HZ*2, true, msgbuf);
305 return fd;
306 }
307
Daniel Stenberga24017f42005-06-27 21:23:03 +0000308 rc = read(fd, &codecbuf[0], CODEC_SIZE);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000309 close(fd);
310 if (rc <= 0) {
311 logf("Codec read error");
312 return CODEC_ERROR;
313 }
Miika Pekkarinen645a2e12005-07-10 16:33:03 +0000314
Miika Pekkarinen159c52d2005-08-20 11:13:19 +0000315 return codec_load_ram(codecbuf, (size_t)rc, NULL, 0, api);
Daniel Stenberg1dd672f2005-06-22 19:41:30 +0000316}
317
318static int codec_test(int api_version, int model, int memsize)
319{
320 if (api_version < CODEC_MIN_API_VERSION ||
321 api_version > CODEC_API_VERSION)
322 return CODEC_WRONG_API_VERSION;
323
324 (void)model;
325#if 0
326 if (model != MODEL)
327 return CODEC_WRONG_MODEL;
328#endif
329
330 if (memsize != MEM)
331 return CODEC_WRONG_MODEL;
332
333 return CODEC_OK;
334}