From c537d5958e8b421ac4f9bef6c8b9e7425a6cf167 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 27 Apr 2011 03:08:23 +0000 Subject: Commit FS#12069 - Playback rework - first stages. Gives as thorough as possible a treatment of codec management, track change and metadata logic as possible while maintaining fairly narrow focus and not rewriting everything all at once. Please see the rockbox-dev mail archive on 2011-04-25 (Playback engine rework) for a more thorough manifest of what was addressed. Plugins and codecs become incompatible. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29785 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/atrac3_oma.c | 136 ++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 67 deletions(-) (limited to 'apps/codecs/atrac3_oma.c') diff --git a/apps/codecs/atrac3_oma.c b/apps/codecs/atrac3_oma.c index 73f3ad29fd..ab24783368 100644 --- a/apps/codecs/atrac3_oma.c +++ b/apps/codecs/atrac3_oma.c @@ -33,24 +33,22 @@ CODEC_HEADER static ATRAC3Context q IBSS_ATTR; -/* this is the codec entry point */ -enum codec_status codec_main(void) -{ +/* this is called for each file to process */ +enum codec_status codec_run(void) +{ static size_t buff_size; int datasize, res, frame_counter, total_frames, seek_frame_offset; uint8_t *bit_buffer; int elapsed = 0; size_t resume_offset; + intptr_t param; + enum codec_command_action action = CODEC_ACTION_NULL; -next_track: if (codec_init()) { DEBUGF("codec init failed\n"); return CODEC_ERROR; } - if (codec_wait_taginfo() != 0) - goto done; - resume_offset = ci->id3->offset; codec_set_replaygain(ci->id3); @@ -60,84 +58,88 @@ next_track: ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */ ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ? STEREO_MONO : STEREO_NONINTERLEAVED); - - res =atrac3_decode_init(&q, ci->id3); + + ci->seek_buffer(0); + + res = atrac3_decode_init(&q, ci->id3); if(res < 0) { DEBUGF("failed to initialize OMA atrac decoder\n"); return CODEC_ERROR; } + total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE; + frame_counter = 0; + /* check for a mid-track resume and force a seek time accordingly */ if(resume_offset > ci->id3->first_frame_offset) { resume_offset -= ci->id3->first_frame_offset; /* calculate resume_offset in frames */ resume_offset = (int)resume_offset / FRAMESIZE; - ci->seek_time = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); + param = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); + action = CODEC_ACTION_SEEK_TIME; + } + else { + ci->set_elapsed(0); + ci->seek_buffer(ci->id3->first_frame_offset); } - total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE; - frame_counter = 0; - - ci->set_elapsed(0); - ci->seek_buffer(0); - ci->advance_buffer(ci->id3->first_frame_offset); /* The main decoder loop */ -seek_start : while(frame_counter < total_frames) - { + { + if (action == CODEC_ACTION_NULL) + action = ci->get_command(¶m); + + if (action == CODEC_ACTION_HALT) + break; + bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); - ci->yield(); - if (ci->stop_codec || ci->new_track) - goto done; - - if (ci->seek_time) { - ci->set_elapsed(ci->seek_time); - - /* Do not allow seeking beyond the file's length */ - if ((unsigned) ci->seek_time > ci->id3->length) { - ci->seek_complete(); - goto done; - } - - /* Seek to the start of the track */ - if (ci->seek_time == 1) { - ci->set_elapsed(0); - ci->seek_complete(); - ci->seek_buffer(ci->id3->first_frame_offset); - elapsed = 0; - goto seek_start; - } - seek_frame_offset = (ci->seek_time * BITRATE) / (8 * FRAMESIZE); - frame_counter = seek_frame_offset; - ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); - bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); - elapsed = ci->seek_time; - - ci->set_elapsed(elapsed); - ci->seek_complete(); - } - - res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); - - if(res != (int)FRAMESIZE) { - DEBUGF("codec error\n"); - return CODEC_ERROR; - } - - if(datasize) - ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / ci->id3->channels); - - elapsed += (FRAMESIZE * 8) / BITRATE; + if (action == CODEC_ACTION_SEEK_TIME) { + /* Do not allow seeking beyond the file's length */ + if ((unsigned) param > ci->id3->length) { + ci->set_elapsed(ci->id3->length); + ci->seek_complete(); + break; + } + + /* Seek to the start of the track */ + if (param == 0) { + elapsed = 0; + ci->set_elapsed(0); + ci->seek_buffer(ci->id3->first_frame_offset); + ci->seek_complete(); + action = CODEC_ACTION_NULL; + continue; + } + + seek_frame_offset = (param * BITRATE) / (8 * FRAMESIZE); + frame_counter = seek_frame_offset; + ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); + bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); + elapsed = param; ci->set_elapsed(elapsed); - - ci->advance_buffer(FRAMESIZE); - frame_counter++; - } + ci->seek_complete(); + } + + action = CODEC_ACTION_NULL; - done: - if (ci->request_next_track()) - goto next_track; + res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); + + if(res != (int)FRAMESIZE) { + DEBUGF("codec error\n"); + return CODEC_ERROR; + } + + if(datasize) + ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, + q.samples_per_frame / ci->id3->channels); + + elapsed += (FRAMESIZE * 8) / BITRATE; + ci->set_elapsed(elapsed); + + ci->advance_buffer(FRAMESIZE); + frame_counter++; + } return CODEC_OK; } -- cgit v1.2.3