diff options
Diffstat (limited to 'lib/rbcodec/codecs/asap.c')
-rw-r--r-- | lib/rbcodec/codecs/asap.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/asap.c b/lib/rbcodec/codecs/asap.c new file mode 100644 index 0000000000..19b39a44c4 --- /dev/null +++ b/lib/rbcodec/codecs/asap.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 Dominik Wenger | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "codeclib.h" | ||
23 | #include "libasap/asap.h" | ||
24 | |||
25 | CODEC_HEADER | ||
26 | |||
27 | #define CHUNK_SIZE (1024*2) | ||
28 | |||
29 | static byte samples[CHUNK_SIZE] IBSS_ATTR; /* The sample buffer */ | ||
30 | static ASAP_State asap IBSS_ATTR; /* asap codec state */ | ||
31 | |||
32 | /* this is the codec entry point */ | ||
33 | enum codec_status codec_main(enum codec_entry_call_reason reason) | ||
34 | { | ||
35 | /* Nothing to do */ | ||
36 | return CODEC_OK; | ||
37 | (void)reason; | ||
38 | } | ||
39 | |||
40 | /* this is called for each file to process */ | ||
41 | enum codec_status codec_run(void) | ||
42 | { | ||
43 | int n_bytes; | ||
44 | int song; | ||
45 | int duration; | ||
46 | char* module; | ||
47 | int bytesPerSample =2; | ||
48 | intptr_t param; | ||
49 | |||
50 | if (codec_init()) { | ||
51 | DEBUGF("codec init failed\n"); | ||
52 | return CODEC_ERROR; | ||
53 | } | ||
54 | |||
55 | codec_set_replaygain(ci->id3); | ||
56 | |||
57 | int bytes_done =0; | ||
58 | size_t filesize; | ||
59 | ci->seek_buffer(0); | ||
60 | module = ci->request_buffer(&filesize, ci->filesize); | ||
61 | if (!module || (size_t)filesize < (size_t)ci->filesize) | ||
62 | { | ||
63 | DEBUGF("loading error\n"); | ||
64 | return CODEC_ERROR; | ||
65 | } | ||
66 | |||
67 | /*Init ASAP */ | ||
68 | if (!ASAP_Load(&asap, ci->id3->path, module, filesize)) | ||
69 | { | ||
70 | DEBUGF("%s: format not supported",ci->id3->path); | ||
71 | return CODEC_ERROR; | ||
72 | } | ||
73 | |||
74 | /* Make use of 44.1khz */ | ||
75 | ci->configure(DSP_SET_FREQUENCY, 44100); | ||
76 | /* Sample depth is 16 bit little endian */ | ||
77 | ci->configure(DSP_SET_SAMPLE_DEPTH, 16); | ||
78 | /* Stereo or Mono output ? */ | ||
79 | if(asap.module_info->channels ==1) | ||
80 | { | ||
81 | ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); | ||
82 | bytesPerSample = 2; | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); | ||
87 | bytesPerSample = 4; | ||
88 | } | ||
89 | /* reset eleapsed */ | ||
90 | ci->set_elapsed(0); | ||
91 | |||
92 | song = asap.module_info->default_song; | ||
93 | duration = asap.module_info->durations[song]; | ||
94 | if (duration < 0) | ||
95 | duration = 180 * 1000; | ||
96 | |||
97 | /* set id3 length, because metadata parse might not have done it */ | ||
98 | ci->id3->length = duration; | ||
99 | |||
100 | ASAP_PlaySong(&asap, song, duration); | ||
101 | ASAP_MutePokeyChannels(&asap, 0); | ||
102 | |||
103 | /* The main decoder loop */ | ||
104 | while (1) { | ||
105 | enum codec_command_action action = ci->get_command(¶m); | ||
106 | |||
107 | if (action == CODEC_ACTION_HALT) | ||
108 | break; | ||
109 | |||
110 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
111 | /* New time is ready in param */ | ||
112 | |||
113 | /* seek to pos */ | ||
114 | ASAP_Seek(&asap,param); | ||
115 | /* update bytes_done */ | ||
116 | bytes_done = param*44.1*2; | ||
117 | /* update elapsed */ | ||
118 | ci->set_elapsed((bytes_done / 2) / 44.1); | ||
119 | /* seek ready */ | ||
120 | ci->seek_complete(); | ||
121 | } | ||
122 | |||
123 | /* Generate a buffer full of Audio */ | ||
124 | #ifdef ROCKBOX_LITTLE_ENDIAN | ||
125 | n_bytes = ASAP_Generate(&asap, samples, sizeof(samples), ASAP_FORMAT_S16_LE); | ||
126 | #else | ||
127 | n_bytes = ASAP_Generate(&asap, samples, sizeof(samples), ASAP_FORMAT_S16_BE); | ||
128 | #endif | ||
129 | |||
130 | ci->pcmbuf_insert(samples, NULL, n_bytes /bytesPerSample); | ||
131 | |||
132 | bytes_done += n_bytes; | ||
133 | ci->set_elapsed((bytes_done / 2) / 44.1); | ||
134 | |||
135 | if(n_bytes != sizeof(samples)) | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | return CODEC_OK; | ||
140 | } | ||