summaryrefslogtreecommitdiff
path: root/apps/codecs/ape.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/ape.c')
-rw-r--r--apps/codecs/ape.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/apps/codecs/ape.c b/apps/codecs/ape.c
index 11d973ab26..8f95a01ec7 100644
--- a/apps/codecs/ape.c
+++ b/apps/codecs/ape.c
@@ -127,13 +127,23 @@ static void ape_resume(struct ape_ctx_t* ape_ctx, size_t resume_offset,
127} 127}
128 128
129/* this is the codec entry point */ 129/* this is the codec entry point */
130enum codec_status codec_main(void) 130enum codec_status codec_main(enum codec_entry_call_reason reason)
131{
132 if (reason == CODEC_LOAD) {
133 /* Generic codec initialisation */
134 ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
135 }
136
137 return CODEC_OK;
138}
139
140/* this is called for each file to process */
141enum codec_status codec_run(void)
131{ 142{
132 struct ape_ctx_t ape_ctx; 143 struct ape_ctx_t ape_ctx;
133 uint32_t samplesdone; 144 uint32_t samplesdone;
134 uint32_t elapsedtime; 145 uint32_t elapsedtime;
135 size_t bytesleft; 146 size_t bytesleft;
136 int retval;
137 147
138 uint32_t currentframe; 148 uint32_t currentframe;
139 uint32_t newfilepos; 149 uint32_t newfilepos;
@@ -145,33 +155,24 @@ enum codec_status codec_main(void)
145 int res; 155 int res;
146 int firstbyte; 156 int firstbyte;
147 size_t resume_offset; 157 size_t resume_offset;
148 158 intptr_t param;
149 /* Generic codec initialisation */
150 ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
151
152next_track:
153 retval = CODEC_OK;
154 159
155 if (codec_init()) { 160 if (codec_init()) {
156 LOGF("APE: Error initialising codec\n"); 161 LOGF("APE: Error initialising codec\n");
157 retval = CODEC_ERROR; 162 return CODEC_ERROR;
158 goto exit;
159 } 163 }
160 164
161 if (codec_wait_taginfo() != 0)
162 goto done;
163
164 /* Remember the resume position - when the codec is opened, the 165 /* Remember the resume position - when the codec is opened, the
165 playback engine will reset it. */ 166 playback engine will reset it. */
166 resume_offset = ci->id3->offset; 167 resume_offset = ci->id3->offset;
167 168
169 ci->seek_buffer(0);
168 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); 170 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
169 171
170 /* Read the file headers to populate the ape_ctx struct */ 172 /* Read the file headers to populate the ape_ctx struct */
171 if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) { 173 if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) {
172 LOGF("APE: Error reading header\n"); 174 LOGF("APE: Error reading header\n");
173 retval = CODEC_ERROR; 175 return CODEC_ERROR;
174 goto exit;
175 } 176 }
176 177
177 /* Initialise the seektable for this file */ 178 /* Initialise the seektable for this file */
@@ -243,16 +244,16 @@ frame_start:
243 /* Decode the frame a chunk at a time */ 244 /* Decode the frame a chunk at a time */
244 while (nblocks > 0) 245 while (nblocks > 0)
245 { 246 {
246 ci->yield(); 247 enum codec_command_action action = ci->get_command(&param);
247 if (ci->stop_codec || ci->new_track) { 248
249 if (action == CODEC_ACTION_HALT)
248 goto done; 250 goto done;
249 }
250 251
251 /* Deal with any pending seek requests */ 252 /* Deal with any pending seek requests */
252 if (ci->seek_time) 253 if (action == CODEC_ACTION_SEEK_TIME)
253 { 254 {
254 if (ape_calc_seekpos(&ape_ctx, 255 if (ape_calc_seekpos(&ape_ctx,
255 ((ci->seek_time-1)/10) * (ci->id3->frequency/100), 256 (param/10) * (ci->id3->frequency/100),
256 &currentframe, 257 &currentframe,
257 &newfilepos, 258 &newfilepos,
258 &samplestoskip)) 259 &samplestoskip))
@@ -266,9 +267,12 @@ frame_start:
266 ci->seek_buffer(newfilepos); 267 ci->seek_buffer(newfilepos);
267 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); 268 inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
268 269
270 elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100);
271 ci->set_elapsed(elapsedtime);
269 ci->seek_complete(); 272 ci->seek_complete();
270 goto frame_start; /* Sorry... */ 273 goto frame_start; /* Sorry... */
271 } 274 }
275
272 ci->seek_complete(); 276 ci->seek_complete();
273 } 277 }
274 278
@@ -281,8 +285,7 @@ frame_start:
281 { 285 {
282 /* Frame decoding error, abort */ 286 /* Frame decoding error, abort */
283 LOGF("APE: Frame %lu, error %d\n",(unsigned long)currentframe,res); 287 LOGF("APE: Frame %lu, error %d\n",(unsigned long)currentframe,res);
284 retval = CODEC_ERROR; 288 return CODEC_ERROR;
285 goto done;
286 } 289 }
287 290
288 ci->yield(); 291 ci->yield();
@@ -320,10 +323,5 @@ frame_start:
320 323
321done: 324done:
322 LOGF("APE: Decoded %lu samples\n",(unsigned long)samplesdone); 325 LOGF("APE: Decoded %lu samples\n",(unsigned long)samplesdone);
323 326 return CODEC_OK;
324 if (ci->request_next_track())
325 goto next_track;
326
327exit:
328 return retval;
329} 327}