summaryrefslogtreecommitdiffstats
path: root/apps/codecs
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-04-27 03:08:23 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-04-27 03:08:23 +0000
commitc537d5958e8b421ac4f9bef6c8b9e7425a6cf167 (patch)
tree7ed36518fb6524da7bbd913ba7619b85b5d15d23 /apps/codecs
parentdcf0f8de4a37ff1d2ea510aef75fa67977a8bdcc (diff)
downloadrockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.tar.gz
rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.zip
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
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/a52.c53
-rw-r--r--apps/codecs/a52_rm.c77
-rw-r--r--apps/codecs/aac.c62
-rw-r--r--apps/codecs/adx.c40
-rw-r--r--apps/codecs/aiff.c108
-rw-r--r--apps/codecs/aiff_enc.c54
-rw-r--r--apps/codecs/alac.c188
-rw-r--r--apps/codecs/ape.c54
-rw-r--r--apps/codecs/asap.c32
-rw-r--r--apps/codecs/atrac3_oma.c136
-rw-r--r--apps/codecs/atrac3_rm.c67
-rw-r--r--apps/codecs/au.c80
-rw-r--r--apps/codecs/codec_crt0.c50
-rw-r--r--apps/codecs/cook.c63
-rw-r--r--apps/codecs/flac.c62
-rw-r--r--apps/codecs/lib/codeclib.c25
-rw-r--r--apps/codecs/lib/codeclib.h3
-rw-r--r--apps/codecs/mod.c67
-rw-r--r--apps/codecs/mp3_enc.c59
-rw-r--r--apps/codecs/mpa.c76
-rw-r--r--apps/codecs/mpc.c76
-rw-r--r--apps/codecs/nsf.c82
-rw-r--r--apps/codecs/raac.c98
-rw-r--r--apps/codecs/shorten.c40
-rw-r--r--apps/codecs/sid.c72
-rw-r--r--apps/codecs/smaf.c82
-rw-r--r--apps/codecs/spc.c128
-rw-r--r--apps/codecs/speex.c61
-rw-r--r--apps/codecs/tta.c61
-rw-r--r--apps/codecs/vorbis.c74
-rw-r--r--apps/codecs/vox.c78
-rw-r--r--apps/codecs/wav.c106
-rw-r--r--apps/codecs/wav64.c113
-rw-r--r--apps/codecs/wav_enc.c54
-rw-r--r--apps/codecs/wavpack.c78
-rw-r--r--apps/codecs/wavpack_enc.c112
-rw-r--r--apps/codecs/wma.c77
-rw-r--r--apps/codecs/wmapro.c68
-rw-r--r--apps/codecs/wmavoice.c68
39 files changed, 1384 insertions, 1500 deletions
diff --git a/apps/codecs/a52.c b/apps/codecs/a52.c
index 00fdeea309..4cd293e37f 100644
--- a/apps/codecs/a52.c
+++ b/apps/codecs/a52.c
@@ -116,27 +116,31 @@ static void a52_decode_data(uint8_t *start, uint8_t *end)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ }
+ else if (reason == CODEC_UNLOAD) {
+ if (state)
+ a52_free(state);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
size_t n;
unsigned char *filebuf;
int sample_loc;
- int retval;
+ intptr_t param;
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
-
-next_track:
- retval = CODEC_OK;
-
- if (codec_init()) {
- retval = CODEC_ERROR;
- goto exit;
- }
-
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
+ if (codec_init())
+ return CODEC_ERROR;
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
codec_set_replaygain(ci->id3);
@@ -153,15 +157,18 @@ next_track:
}
}
else {
+ ci->seek_buffer(ci->id3->first_frame_offset);
samplesdone = 0;
}
while (1) {
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- sample_loc = (ci->seek_time - 1)/1000 * ci->id3->frequency;
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ sample_loc = param/1000 * ci->id3->frequency;
if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) {
samplesdone = sample_loc;
@@ -179,11 +186,5 @@ next_track:
ci->advance_buffer(n);
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- a52_free(state);
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/a52_rm.c b/apps/codecs/a52_rm.c
index f5e4923292..c1930aa7b4 100644
--- a/apps/codecs/a52_rm.c
+++ b/apps/codecs/a52_rm.c
@@ -124,36 +124,44 @@ static void a52_decode_data(uint8_t *start, uint8_t *end)
}
}
-
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ }
+ else if (reason == CODEC_UNLOAD) {
+ if (state)
+ a52_free(state);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
size_t n;
uint8_t *filebuf;
- int retval, consumed, packet_offset;
+ int consumed, packet_offset;
int playback_on = -1;
size_t resume_offset;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
-
-next_track:
- retval = CODEC_OK;
+ intptr_t param;
+ enum codec_command_action action = CODEC_ACTION_NULL;
if (codec_init()) {
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
resume_offset = ci->id3->offset;
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
codec_set_replaygain(ci->id3);
+ ci->seek_buffer(ci->id3->first_frame_offset);
+
/* Intializations */
state = a52_init(0);
ci->memset(&rmctx,0,sizeof(RMContext));
@@ -165,26 +173,34 @@ next_track:
resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
/* put number of subpackets to skip in resume_offset */
resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE);
- ci->seek_time = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
+ param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
+ action = CODEC_ACTION_SEEK_TIME;
+ }
+ else {
+ /* Seek to the first packet */
+ ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE );
}
-
- /* Seek to the first packet */
- ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE );
/* The main decoding loop */
while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ if (action == CODEC_ACTION_NULL)
+ action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- packet_offset = ci->seek_time / ((rmctx.block_align*8*1000)/rmctx.bit_rate);
- ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE));
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ packet_offset = param / ((rmctx.block_align*8*1000)/rmctx.bit_rate);
+ ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE +
+ packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE));
rmctx.audio_pkt_cnt = packet_offset;
- samplesdone = (rmctx.sample_rate/1000 * ci->seek_time);
+ samplesdone = (rmctx.sample_rate/1000 * param);
+ ci->set_elapsed(samplesdone/(frequency/1000));
ci->seek_complete();
}
+ action = CODEC_ACTION_NULL;
+
filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE);
consumed = rm_get_packet(&filebuf, &rmctx, &pkt);
@@ -195,8 +211,7 @@ next_track:
return CODEC_ERROR;
}
else {
- retval = CODEC_OK;
- goto exit;
+ break;
}
}
@@ -205,11 +220,5 @@ next_track:
ci->advance_buffer(pkt.length);
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- a52_free(state);
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 5638dc49a9..90cf0438ce 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -33,7 +33,19 @@ CODEC_HEADER
#define FAAD_BYTE_BUFFER_SIZE (2048-12)
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
/* Note that when dealing with QuickTime/MPEG4 files, terminology is
* a bit confusing. Files with sound are split up in chunks, where
@@ -59,25 +71,15 @@ enum codec_status codec_main(void)
uint32_t sbr_fac = 1;
unsigned char c = 0;
void *ret;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
-
-next_track:
- err = CODEC_OK;
+ intptr_t param;
/* Clean and initialize decoder structures */
memset(&demux_res , 0, sizeof(demux_res));
if (codec_init()) {
LOGF("FAAD: Codec init error\n");
- err = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
file_offset = ci->id3->offset;
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -85,12 +87,13 @@ next_track:
stream_create(&input_stream,ci);
+ ci->seek_buffer(ci->id3->first_frame_offset);
+
/* if qtmovie_read returns successfully, the stream is up to
* the movie data, which can be used directly by the decoder */
if (!qtmovie_read(&input_stream, &demux_res)) {
LOGF("FAAD: File init error\n");
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* initialise the sound converter */
@@ -98,8 +101,7 @@ next_track:
if (!decoder) {
LOGF("FAAD: Decode open error\n");
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
@@ -109,8 +111,7 @@ next_track:
err = NeAACDecInit2(decoder, demux_res.codecdata, demux_res.codecdata_len, &s, &c);
if (err) {
LOGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type);
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
#ifdef SBR_DEC
@@ -150,20 +151,19 @@ next_track:
/* The main decoding loop */
while (i < demux_res.num_sample_byte_sizes) {
- ci->yield();
+ enum codec_command_action action = ci->get_command(&param);
- if (ci->stop_codec || ci->new_track) {
+ if (action == CODEC_ACTION_HALT)
break;
- }
/* Deal with any pending seek requests */
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* Seek to the desired time position. Important: When seeking in SBR
* upsampling files the seek_time must be divided by 2 when calling
* m4a_seek and the resulting sound_samples_done must be expanded
* by a factor 2. This is done via using sbr_fac. */
if (m4a_seek(&demux_res, &input_stream,
- ((ci->seek_time-1)/10/sbr_fac)*(ci->id3->frequency/100),
+ (param/10/sbr_fac)*(ci->id3->frequency/100),
&sound_samples_done, (int*) &i)) {
sound_samples_done *= sbr_fac;
elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
@@ -194,8 +194,7 @@ next_track:
else if (file_offset == 0)
{
LOGF("AAC: get_sample_offset error\n");
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Request the required number of bytes from the input buffer */
@@ -207,8 +206,7 @@ next_track:
/* NeAACDecDecode may sometimes return NULL without setting error. */
if (ret == NULL || frame_info.error > 0) {
LOGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error));
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Advance codec buffer (no need to call set_offset because of this) */
@@ -251,12 +249,6 @@ next_track:
i++;
}
-done:
LOGF("AAC: Decoded %lu samples\n", (unsigned long)sound_samples_done);
-
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return err;
+ return CODEC_OK;
}
diff --git a/apps/codecs/adx.c b/apps/codecs/adx.c
index 832b94797b..a1b57fce58 100644
--- a/apps/codecs/adx.c
+++ b/apps/codecs/adx.c
@@ -45,7 +45,19 @@ static const long cutoff = 500;
static int16_t samples[WAV_CHUNK_SIZE] IBSS_ATTR;
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ /* we only render 16 bits */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
int channels;
int sampleswritten, i;
@@ -62,12 +74,8 @@ enum codec_status codec_main(void)
off_t chanstart, bufoff;
/*long coef1=0x7298L,coef2=-0x3350L;*/
long coef1, coef2;
+ intptr_t param;
- /* Generic codec initialisation */
- /* we only render 16 bits */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
-
-next_track:
DEBUGF("ADX: next_track\n");
if (codec_init()) {
return CODEC_ERROR;
@@ -77,10 +85,6 @@ next_track:
/* init history */
ch1_1=ch1_2=ch2_1=ch2_2=0;
- /* wait for track info to load */
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
/* Get header */
@@ -226,10 +230,10 @@ next_track:
/* The main decoder loop */
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
/* do we need to loop? */
if (bufoff > end_adr-18*channels && looping) {
@@ -254,17 +258,17 @@ next_track:
}
/* do we need to seek? */
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
uint32_t newpos;
- DEBUGF("ADX: seek to %ldms\n",ci->seek_time);
+ DEBUGF("ADX: seek to %ldms\n", (long)param);
endofstream = 0;
loop_count = 0;
fade_count = -1; /* disable fade */
fade_frames = 1;
- newpos = (((uint64_t)avgbytespersec*(ci->seek_time - 1))
+ newpos = (((uint64_t)avgbytespersec*param)
/ (1000LL*18*channels))*(18*channels);
bufoff = chanstart + newpos;
while (bufoff > end_adr-18*channels) {
@@ -385,9 +389,5 @@ next_track:
1000LL/avgbytespersec);
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
return CODEC_OK;
}
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c
index d4cf8660dd..3fc137eaeb 100644
--- a/apps/codecs/aiff.c
+++ b/apps/codecs/aiff.c
@@ -61,9 +61,20 @@ static const struct pcm_codec *get_codec(uint32_t formattag)
return NULL;
}
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
struct pcm_format format;
uint32_t bytesdone, decodedsamples;
uint32_t num_sample_frames = 0;
@@ -77,38 +88,28 @@ enum codec_status codec_main(void)
bool is_aifc = false;
const struct pcm_codec *codec;
uint32_t size;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
-
-next_track:
- status = CODEC_OK;
+ intptr_t param;
if (codec_init()) {
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
codec_set_replaygain(ci->id3);
/* Need to save offset for later use (cleared indirectly by advance_buffer) */
bytesdone = ci->id3->offset;
/* assume the AIFF header is less than 1024 bytes */
+ ci->seek_buffer(0);
buf = ci->request_buffer(&n, 1024);
if (n < 54) {
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (memcmp(buf, "FORM", 4) != 0)
{
DEBUGF("CODEC_ERROR: does not aiff format %4.4s\n", (char*)&buf[0]);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (memcmp(&buf[8], "AIFF", 4) == 0)
is_aifc = false;
@@ -117,8 +118,7 @@ next_track:
else
{
DEBUGF("CODEC_ERROR: does not aiff format %4.4s\n", (char*)&buf[8]);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
buf += 12;
@@ -141,8 +141,7 @@ next_track:
{
DEBUGF("CODEC_ERROR: 'COMM' chunk size=%lu < %d\n",
(unsigned long)size, (is_aifc)?22:18);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* num_channels */
format.channels = ((buf[8]<<8)|buf[9]);
@@ -154,8 +153,7 @@ next_track:
/* sample_rate (don't use last 4 bytes, only integer fs) */
if (buf[16] != 0x40) {
DEBUGF("CODEC_ERROR: weird sampling rate (no @)\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
format.samplespersec = ((buf[18]<<24)|(buf[19]<<16)|(buf[20]<<8)|buf[21])+1;
format.samplespersec >>= (16 + 14 - buf[17]);
@@ -181,8 +179,7 @@ next_track:
} else if (memcmp(buf, "SSND", 4)==0) {
if (format.bitspersample == 0) {
DEBUGF("CODEC_ERROR: unsupported chunk order\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* offset2snd */
offset2snd = (buf[8]<<24)|(buf[9]<<16)|(buf[10]<<8)|buf[11];
@@ -205,21 +202,18 @@ next_track:
buf += size;
if (n < size) {
DEBUGF("CODEC_ERROR: AIFF header size > 1024\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
n -= size;
} /* while 'SSND' */
if (format.channels == 0) {
DEBUGF("CODEC_ERROR: 'COMM' chunk not found or 0-channels file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.numbytes == 0) {
DEBUGF("CODEC_ERROR: 'SSND' chunk not found or has zero length\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
codec = get_codec(format.formattag);
@@ -227,14 +221,12 @@ next_track:
{
DEBUGF("CODEC_ERROR: AIFC does not support compressionType: 0x%x\n",
(unsigned int)format.formattag);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (!codec->set_format(&format))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -245,21 +237,18 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels unsupported\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.samplesperblock == 0)
{
DEBUGF("CODEC_ERROR: samplesperblock is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.blockalign == 0)
{
DEBUGF("CODEC_ERROR: blockalign is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -269,8 +258,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
firstblockposn = 1024 - n;
@@ -283,13 +271,13 @@ next_track:
PCM_SEEK_POS, NULL);
if (newpos->pos > format.numbytes)
- goto done;
+ return CODEC_OK;
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
} else {
/* already where we need to be */
bytesdone = 0;
@@ -299,21 +287,29 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* 3rd args(read_buffer) is unnecessary in the format which AIFF supports. */
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME, NULL);
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME, NULL);
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
aifbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize);
@@ -326,11 +322,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(aifbuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(aifbuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -343,13 +338,6 @@ next_track:
ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
}
- status = CODEC_OK;
-
-done:
- if (ci->request_next_track())
- goto next_track;
-exit:
- return status;
+ return CODEC_OK;
}
-
diff --git a/apps/codecs/aiff_enc.c b/apps/codecs/aiff_enc.c
index 69496f70ac..fc44196eb0 100644
--- a/apps/codecs/aiff_enc.c
+++ b/apps/codecs/aiff_enc.c
@@ -359,40 +359,42 @@ static bool init_encoder(void)
return true;
} /* init_encoder */
-/* main codec entry point */
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- if (!init_encoder())
- return CODEC_ERROR;
+ if (reason == CODEC_LOAD) {
+ if (!init_encoder())
+ return CODEC_ERROR;
+ }
+ else if (reason == CODEC_UNLOAD) {
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(NULL);
+ }
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
/* main encoding loop */
- while(!ci->stop_codec)
+ while (ci->get_command(NULL) != CODEC_ACTION_HALT)
{
- uint32_t *src;
+ uint32_t *src = (uint32_t *)ci->enc_get_pcm_data(PCM_CHUNK_SIZE);
+ struct enc_chunk_hdr *chunk;
- while ((src = (uint32_t *)ci->enc_get_pcm_data(PCM_CHUNK_SIZE)) != NULL)
- {
- struct enc_chunk_hdr *chunk;
-
- if (ci->stop_codec)
- break;
+ if (src == NULL)
+ continue;
- chunk = ci->enc_get_chunk();
- chunk->enc_size = enc_size;
- chunk->num_pcm = PCM_SAMP_PER_CHUNK;
- chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
+ chunk = ci->enc_get_chunk();
+ chunk->enc_size = enc_size;
+ chunk->num_pcm = PCM_SAMP_PER_CHUNK;
+ chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
- chunk_to_aiff_format(src, (uint32_t *)chunk->enc_data);
-
- ci->enc_finish_chunk();
- ci->yield();
- }
+ chunk_to_aiff_format(src, (uint32_t *)chunk->enc_data);
- ci->yield();
+ ci->enc_finish_chunk();
}
- /* reset parameters to initial state */
- ci->enc_set_parameters(NULL);
-
return CODEC_OK;
-} /* codec_start */
+}
diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c
index cd9129a278..82bda264c3 100644
--- a/apps/codecs/alac.c
+++ b/apps/codecs/alac.c
@@ -32,116 +32,114 @@ CODEC_HEADER
static int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR;
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- size_t n;
- demux_res_t demux_res;
- stream_t input_stream;
- uint32_t samplesdone;
- uint32_t elapsedtime;
- int samplesdecoded;
- unsigned int i;
- unsigned char* buffer;
- alac_file alac;
- int retval;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
-
- next_track:
- retval = CODEC_OK;
-
- /* Clean and initialize decoder structures */
- memset(&demux_res , 0, sizeof(demux_res));
- if (codec_init()) {
- LOGF("ALAC: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto exit;
- }
-
- if (codec_wait_taginfo() != 0)
- goto done;
-
- ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
- codec_set_replaygain(ci->id3);
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
+ }
- stream_create(&input_stream,ci);
+ return CODEC_OK;
+}
- /* Read from ci->id3->offset before calling qtmovie_read. */
- samplesdone = (uint32_t)(((uint64_t)(ci->id3->offset) * ci->id3->frequency) /
- (ci->id3->bitrate*128));
-
- /* if qtmovie_read returns successfully, the stream is up to
- * the movie data, which can be used directly by the decoder */
- if (!qtmovie_read(&input_stream, &demux_res)) {
- LOGF("ALAC: Error initialising file\n");
- retval = CODEC_ERROR;
- goto done;
- }
-
- /* initialise the sound converter */
- create_alac(demux_res.sound_sample_size, demux_res.num_channels,&alac);
- alac_set_info(&alac, demux_res.codecdata);
-
- /* Set i for first frame, seek to desired sample position for resuming. */
- i=0;
- if (samplesdone > 0) {
- if (m4a_seek(&demux_res, &input_stream, samplesdone,
- &samplesdone, (int*) &i)) {
- elapsedtime = (samplesdone * 10) / (ci->id3->frequency / 100);
- ci->set_elapsed(elapsedtime);
- } else {
- samplesdone = 0;
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
+ size_t n;
+ demux_res_t demux_res;
+ stream_t input_stream;
+ uint32_t samplesdone;
+ uint32_t elapsedtime = 0;
+ int samplesdecoded;
+ unsigned int i;
+ unsigned char* buffer;
+ alac_file alac;
+ intptr_t param;
+
+ /* Clean and initialize decoder structures */
+ memset(&demux_res , 0, sizeof(demux_res));
+ if (codec_init()) {
+ LOGF("ALAC: Error initialising codec\n");
+ return CODEC_ERROR;
}
- }
- /* The main decoding loop */
- while (i < demux_res.num_sample_byte_sizes) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
- break;
+ ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
+ codec_set_replaygain(ci->id3);
+
+ ci->seek_buffer(0);
+
+ stream_create(&input_stream,ci);
+
+ /* Read from ci->id3->offset before calling qtmovie_read. */
+ samplesdone = (uint32_t)(((uint64_t)(ci->id3->offset) * ci->id3->frequency) /
+ (ci->id3->bitrate*128));
+
+ /* if qtmovie_read returns successfully, the stream is up to
+ * the movie data, which can be used directly by the decoder */
+ if (!qtmovie_read(&input_stream, &demux_res)) {
+ LOGF("ALAC: Error initialising file\n");
+ return CODEC_ERROR;
}
- /* Deal with any pending seek requests */
- if (ci->seek_time) {
- if (m4a_seek(&demux_res, &input_stream,
- ((ci->seek_time-1)/10) * (ci->id3->frequency/100),
- &samplesdone, (int *)&i)) {
- elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
- ci->set_elapsed(elapsedtime);
- }
- ci->seek_complete();
+ /* initialise the sound converter */
+ create_alac(demux_res.sound_sample_size, demux_res.num_channels,&alac);
+ alac_set_info(&alac, demux_res.codecdata);
+
+ /* Set i for first frame, seek to desired sample position for resuming. */
+ i=0;
+ if (samplesdone > 0) {
+ if (m4a_seek(&demux_res, &input_stream, samplesdone,
+ &samplesdone, (int*) &i)) {
+ elapsedtime = (samplesdone * 10) / (ci->id3->frequency / 100);
+ ci->set_elapsed(elapsedtime);
+ } else {
+ samplesdone = 0;
+ }
}
- /* Request the required number of bytes from the input buffer */
- buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE);
+ /* The main decoding loop */
+ while (i < demux_res.num_sample_byte_sizes) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ break;
- /* Decode one block - returned samples will be host-endian */
- ci->yield();
- samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, ci->yield);
+ /* Request the required number of bytes from the input buffer */
+ buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE);
- /* Advance codec buffer by amount of consumed bytes */
- ci->advance_buffer(alac.bytes_consumed);
+ /* Deal with any pending seek requests */
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (m4a_seek(&demux_res, &input_stream,
+ (param/10) * (ci->id3->frequency/100),
+ &samplesdone, (int *)&i)) {
+ elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
+ }
+ ci->set_elapsed(elapsedtime);
+ ci->seek_complete();
+ }
- /* Output the audio */
- ci->yield();
- ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded);
+ /* Request the required number of bytes from the input buffer */
+ buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE);
- /* Update the elapsed-time indicator */
- samplesdone+=samplesdecoded;
- elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
- ci->set_elapsed(elapsedtime);
+ /* Decode one block - returned samples will be host-endian */
+ samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, ci->yield);
+ ci->yield();
- i++;
- }
+ /* Advance codec buffer by amount of consumed bytes */
+ ci->advance_buffer(alac.bytes_consumed);
-done:
- LOGF("ALAC: Decoded %lu samples\n",(unsigned long)samplesdone);
+ /* Output the audio */
+ ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded);
- if (ci->request_next_track())
- goto next_track;
+ /* Update the elapsed-time indicator */
+ samplesdone+=samplesdecoded;
+ elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
+ ci->set_elapsed(elapsedtime);
+
+ i++;
+ }
-exit:
- return retval;
+ LOGF("ALAC: Decoded %lu samples\n",(unsigned long)samplesdone);
+ return CODEC_OK;
}
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,
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
struct ape_ctx_t ape_ctx;
uint32_t samplesdone;
uint32_t elapsedtime;
size_t bytesleft;
- int retval;
uint32_t currentframe;
uint32_t newfilepos;
@@ -145,33 +155,24 @@ enum codec_status codec_main(void)
int res;
int firstbyte;
size_t resume_offset;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1);
-
-next_track:
- retval = CODEC_OK;
+ intptr_t param;
if (codec_init()) {
LOGF("APE: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
/* Remember the resume position - when the codec is opened, the
playback engine will reset it. */
resume_offset = ci->id3->offset;
+ ci->seek_buffer(0);
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
/* Read the file headers to populate the ape_ctx struct */
if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) {
LOGF("APE: Error reading header\n");
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
/* Initialise the seektable for this file */
@@ -243,16 +244,16 @@ frame_start:
/* Decode the frame a chunk at a time */
while (nblocks > 0)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
goto done;
- }
/* Deal with any pending seek requests */
- if (ci->seek_time)
+ if (action == CODEC_ACTION_SEEK_TIME)
{
if (ape_calc_seekpos(&ape_ctx,
- ((ci->seek_time-1)/10) * (ci->id3->frequency/100),
+ (param/10) * (ci->id3->frequency/100),
&currentframe,
&newfilepos,
&samplestoskip))
@@ -266,9 +267,12 @@ frame_start:
ci->seek_buffer(newfilepos);
inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE);
+ elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100);
+ ci->set_elapsed(elapsedtime);
ci->seek_complete();
goto frame_start; /* Sorry... */
}
+
ci->seek_complete();
}
@@ -281,8 +285,7 @@ frame_start:
{
/* Frame decoding error, abort */
LOGF("APE: Frame %lu, error %d\n",(unsigned long)currentframe,res);
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->yield();
@@ -320,10 +323,5 @@ frame_start:
done:
LOGF("APE: Decoded %lu samples\n",(unsigned long)samplesdone);
-
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/asap.c b/apps/codecs/asap.c
index 9447c738d2..f12dc6a0c5 100644
--- a/apps/codecs/asap.c
+++ b/apps/codecs/asap.c
@@ -29,24 +29,21 @@ CODEC_HEADER
static byte samples[CHUNK_SIZE] IBSS_ATTR; /* The sample buffer */
static ASAP_State asap; /* asap codec state */
-/* 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)
{
int n_bytes;
int song;
int duration;
char* module;
int bytesPerSample =2;
+ intptr_t param;
-next_track:
if (codec_init()) {
DEBUGF("codec init failed\n");
return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
int bytes_done =0;
@@ -97,19 +94,20 @@ next_track:
/* The main decoder loop */
while (1) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- /* New time is ready in ci->seek_time */
-
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ /* New time is ready in param */
+
/* seek to pos */
- ASAP_Seek(&asap,ci->seek_time);
- /* update elapsed */
- ci->set_elapsed(ci->seek_time);
+ ASAP_Seek(&asap,param);
/* update bytes_done */
- bytes_done = ci->seek_time*44.1*2;
+ bytes_done = param*44.1*2;
+ /* update elapsed */
+ ci->set_elapsed((bytes_done / 2) / 44.1);
/* seek ready */
ci->seek_complete();
}
@@ -129,10 +127,6 @@ next_track:
if(n_bytes != sizeof(samples))
break;
}
-
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
return CODEC_OK;
}
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(&param);
+
+ 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;
}
diff --git a/apps/codecs/atrac3_rm.c b/apps/codecs/atrac3_rm.c
index 6a77d24283..1322e917ed 100644
--- a/apps/codecs/atrac3_rm.c
+++ b/apps/codecs/atrac3_rm.c
@@ -41,9 +41,9 @@ static void init_rm(RMContext *rmctx)
memcpy(ci->id3->id3v2buf, (char*)rmctx->codec_extradata, rmctx->extradata_size*sizeof(char));
}
-/* 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, consumed, i, time_offset;
uint8_t *bit_buffer;
@@ -52,16 +52,14 @@ enum codec_status codec_main(void)
int scrambling_unit_size, num_units, elapsed = 0;
int playback_on = -1;
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);
@@ -69,6 +67,7 @@ next_track:
ci->memset(&pkt,0,sizeof(RMPacket));
ci->memset(&q,0,sizeof(ATRAC3Context));
+ ci->seek_buffer(0);
init_rm(&rmctx);
ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
@@ -84,22 +83,25 @@ next_track:
h = rmctx.sub_packet_h;
scrambling_unit_size = h*fs;
- res =atrac3_decode_init(&q, ci->id3);
+ res = atrac3_decode_init(&q, ci->id3);
if(res < 0) {
DEBUGF("failed to initialize RM atrac decoder\n");
return CODEC_ERROR;
}
-
+
/* check for a mid-track resume and force a seek time accordingly */
if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) {
resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
num_units = (int)resume_offset / scrambling_unit_size;
/* put number of subpackets to skip in resume_offset */
resume_offset /= (sps + PACKET_HEADER_SIZE);
- ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate);
+ param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate);
+ action = CODEC_ACTION_SEEK_TIME;
}
-
- ci->set_elapsed(0);
+ else {
+ ci->set_elapsed(0);
+ }
+
ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
/* The main decoder loop */
@@ -115,22 +117,23 @@ seek_start :
return CODEC_ERROR;
}
else
- goto done;
+ return CODEC_OK;
}
for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track)
- goto done;
+ if (action == CODEC_ACTION_NULL)
+ action = ci->get_command(&param);
- if (ci->seek_time) {
- ci->set_elapsed(ci->seek_time);
+ if (action == CODEC_ACTION_HALT)
+ return CODEC_OK;
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* Do not allow seeking beyond the file's length */
- if ((unsigned) ci->seek_time > ci->id3->length) {
+ if ((unsigned) param > ci->id3->length) {
+ ci->set_elapsed(ci->id3->length);
ci->seek_complete();
- goto done;
+ return CODEC_OK;
}
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
@@ -139,12 +142,13 @@ seek_start :
rmctx.frame_number = 0;
/* Seek to the start of the track */
- if (ci->seek_time == 1) {
+ if (param == 0) {
ci->set_elapsed(0);
ci->seek_complete();
+ action = CODEC_ACTION_NULL;
goto seek_start;
}
- num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps));
+ num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps));
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units);
bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt);
@@ -155,12 +159,12 @@ seek_start :
return CODEC_ERROR;
}
else
- goto done;
+ return CODEC_OK;
}
packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units;
- rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate));
- while(rmctx.audiotimestamp > (unsigned) ci->seek_time) {
+ rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate));
+ while(rmctx.audiotimestamp > (unsigned) param) {
rmctx.audio_pkt_cnt = 0;
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1));
bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
@@ -168,16 +172,19 @@ seek_start :
packet_count += rmctx.audio_pkt_cnt;
num_units--;
}
- time_offset = ci->seek_time - rmctx.audiotimestamp;
+ time_offset = param - rmctx.audiotimestamp;
i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate));
elapsed = rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i;
ci->set_elapsed(elapsed);
ci->seek_complete();
}
+
+ action = CODEC_ACTION_NULL;
+
if(pkt.length)
res = atrac3_decode_frame(rmctx.block_align, &q, &datasize, pkt.frames[i], rmctx.block_align);
else /* indicates that there are no remaining frames */
- goto done;
+ return CODEC_OK;
if(res != rmctx.block_align) {
DEBUGF("codec error\n");
@@ -196,9 +203,5 @@ seek_start :
ci->advance_buffer(consumed);
}
- done :
- if (ci->request_next_track())
- goto next_track;
-
- return CODEC_OK;
+ return CODEC_OK;
}
diff --git a/apps/codecs/au.c b/apps/codecs/au.c
index 3f9436c9e7..e06f931cf9 100644
--- a/apps/codecs/au.c
+++ b/apps/codecs/au.c
@@ -106,9 +106,19 @@ static int convert_au_format(unsigned int encoding, struct pcm_format *fmt)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
struct pcm_format format;
uint32_t bytesdone, decodedsamples;
size_t n;
@@ -119,22 +129,13 @@ enum codec_status codec_main(void)
off_t firstblockposn; /* position of the first block in file */
const struct pcm_codec *codec;
int offset = 0;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
-
-next_track:
- status = CODEC_OK;
-
+ intptr_t param;
+
if (codec_init()) {
DEBUGF("codec_init() error\n");
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
codec_set_replaygain(ci->id3);
/* Need to save offset for later use (cleared indirectly by advance_buffer) */
@@ -145,6 +146,7 @@ next_track:
format.is_little_endian = false;
/* set format */
+ ci->seek_buffer(0);
buf = ci->request_buffer(&n, 24);
if (n < 24 || (memcmp(buf, ".snd", 4) != 0))
{
@@ -170,8 +172,7 @@ next_track:
if (offset < 24)
{
DEBUGF("CODEC_ERROR: sun audio offset size is small: %d\n", offset);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* data size */
format.numbytes = get_be32(buf + 8);
@@ -182,8 +183,7 @@ next_track:
if (format.formattag == AU_FORMAT_UNSUPPORT)
{
DEBUGF("CODEC_ERROR: sun audio unsupport format: %d\n", get_be32(buf + 12));
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* skip sample rate */
format.channels = get_be32(buf + 20);
@@ -202,20 +202,17 @@ next_track:
if (!codec)
{
DEBUGF("CODEC_ERROR: unsupport sun audio format: %x\n", (int)format.formattag);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (!codec->set_format(&format))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.numbytes == 0) {
DEBUGF("CODEC_ERROR: data size is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -225,8 +222,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -236,8 +232,7 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* make sure we're at the correct offset */
@@ -253,7 +248,6 @@ next_track:
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
} else {
/* already where we need to be */
bytesdone = 0;
@@ -263,22 +257,29 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* 3rd args(read_buffer) is unnecessary in the format which Sun Audio supports. */
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME, NULL);
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME, NULL);
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
@@ -290,11 +291,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(aubuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(aubuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -308,9 +308,5 @@ next_track:
}
done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/codec_crt0.c b/apps/codecs/codec_crt0.c
index cf14e460ec..33876272c6 100644
--- a/apps/codecs/codec_crt0.c
+++ b/apps/codecs/codec_crt0.c
@@ -27,39 +27,45 @@ struct codec_api *ci DATA_ATTR;
extern unsigned char plugin_bss_start[];
extern unsigned char plugin_end_addr[];
-extern enum codec_status codec_main(void);
+extern enum codec_status codec_main(enum codec_entry_call_reason reason);
/* stub, the entry point is called via its reference in __header to
* avoid warning with certain compilers */
int _start(void) {return 0;}
-enum codec_status codec_start(void)
+enum codec_status codec_start(enum codec_entry_call_reason reason)
{
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
-#ifdef USE_IRAM
- extern char iramcopy[], iramstart[], iramend[], iedata[], iend[];
- size_t iram_size = iramend - iramstart;
- size_t ibss_size = iend - iedata;
- if (iram_size > 0 || ibss_size > 0)
+ if (reason == CODEC_LOAD)
{
- ci->memcpy(iramstart, iramcopy, iram_size);
- ci->memset(iedata, 0, ibss_size);
- /* make the icache (if it exists) up to date with the new code */
+#ifdef USE_IRAM
+ extern char iramcopy[], iramstart[], iramend[], iedata[], iend[];
+ size_t iram_size = iramend - iramstart;
+ size_t ibss_size = iend - iedata;
+ if (iram_size > 0 || ibss_size > 0)
+ {
+ ci->memcpy(iramstart, iramcopy, iram_size);
+ ci->memset(iedata, 0, ibss_size);
+ /* make the icache (if it exists) up to date with the new code */
+ ci->cpucache_invalidate();
+ /* barrier to prevent reordering iram copy and BSS clearing,
+ * because the BSS segment alias the IRAM copy.
+ */
+ asm volatile ("" ::: "memory");
+ }
+#endif /* PLUGIN_USE_IRAM */
+ ci->memset(plugin_bss_start, 0, plugin_end_addr - plugin_bss_start);
+ /* Some parts of bss may be used via a no-cache alias (at least
+ * portalplayer has this). If we don't clear the cache, those aliases
+ * may read garbage */
ci->cpucache_invalidate();
- /* barrier to prevent reordering iram copy and BSS clearing,
- * because the BSS segment alias the IRAM copy.
- */
- asm volatile ("" ::: "memory");
}
-#endif /* PLUGIN_USE_IRAM */
- ci->memset(plugin_bss_start, 0, plugin_end_addr - plugin_bss_start);
- /* Some parts of bss may be used via a no-cache alias (at least
- * portalplayer has this). If we don't clear the cache, those aliases
- * may read garbage */
- ci->cpucache_invalidate();
-#endif
+#endif /* CONFIG_PLATFORM */
- return codec_main();
+ /* Note: If for any reason codec_main would not be called with CODEC_LOAD
+ * because the above code failed then it must not be ever be called with
+ * any other value and some strategy to avoid doing so must be conceived */
+ return codec_main(reason);
}
#if defined(CPU_ARM) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
diff --git a/apps/codecs/cook.c b/apps/codecs/cook.c
index 015618986c..a6b4a1153e 100644
--- a/apps/codecs/cook.c
+++ b/apps/codecs/cook.c
@@ -38,9 +38,9 @@ static void init_rm(RMContext *rmctx)
memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext));
}
-/* 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, consumed, i, time_offset;
uint8_t *bit_buffer;
@@ -48,16 +48,14 @@ enum codec_status codec_main(void)
uint32_t packet_count;
int scrambling_unit_size, num_units;
size_t resume_offset;
+ intptr_t param = 0;
+ 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);
@@ -65,6 +63,8 @@ next_track:
ci->memset(&pkt,0,sizeof(RMPacket));
ci->memset(&q,0,sizeof(COOKContext));
+ ci->seek_buffer(0);
+
init_rm(&rmctx);
ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
@@ -87,20 +87,21 @@ next_track:
DEBUGF("failed to initialize cook decoder\n");
return CODEC_ERROR;
}
-
+
/* check for a mid-track resume and force a seek time accordingly */
if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) {
resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
num_units = (int)resume_offset / scrambling_unit_size;
/* put number of subpackets to skip in resume_offset */
resume_offset /= (sps + PACKET_HEADER_SIZE);
- ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate);
+ param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate);
+ action = CODEC_ACTION_SEEK_TIME;
}
ci->set_elapsed(0);
ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
- /* The main decoder loop */
+ /* The main decoder loop */
seek_start :
while(packet_count)
{
@@ -112,18 +113,19 @@ seek_start :
}
for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++)
- {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
- goto done;
+ {
+ if (action == CODEC_ACTION_NULL)
+ action = ci->get_command(&param);
- if (ci->seek_time) {
- ci->set_elapsed(ci->seek_time);
+ if (action == CODEC_ACTION_HALT)
+ return CODEC_OK;
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* Do not allow seeking beyond the file's length */
- if ((unsigned) ci->seek_time > ci->id3->length) {
+ if ((unsigned) param > ci->id3->length) {
+ ci->set_elapsed(ci->id3->length);
ci->seek_complete();
- goto done;
+ return CODEC_OK;
}
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
@@ -132,22 +134,24 @@ seek_start :
rmctx.frame_number = 0;
/* Seek to the start of the track */
- if (ci->seek_time == 1) {
+ if (param == 0) {
ci->set_elapsed(0);
ci->seek_complete();
+ action = CODEC_ACTION_NULL;
goto seek_start;
}
- num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps));
+ num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps));
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units);
bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt);
if(consumed < 0) {
DEBUGF("rm_get_packet failed\n");
- return CODEC_ERROR;
+ ci->seek_complete();
+ return CODEC_ERROR;
}
packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units;
- rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate));
- while(rmctx.audiotimestamp > (unsigned) ci->seek_time) {
+ rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate));
+ while(rmctx.audiotimestamp > (unsigned) param) {
rmctx.audio_pkt_cnt = 0;
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1));
bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
@@ -155,11 +159,14 @@ seek_start :
packet_count += rmctx.audio_pkt_cnt;
num_units--;
}
- time_offset = ci->seek_time - rmctx.audiotimestamp;
+ time_offset = param - rmctx.audiotimestamp;
i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate));
ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i);
ci->seek_complete();
- }
+ }
+
+ action = CODEC_ACTION_NULL;
+
res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align);
rmctx.frame_number++;
@@ -181,9 +188,5 @@ seek_start :
ci->advance_buffer(consumed);
}
- done :
- if (ci->request_next_track())
- goto next_track;
-
- return CODEC_OK;
+ return CODEC_OK;
}
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index 89d14b98a7..a5521b584f 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -418,40 +418,40 @@ static bool flac_seek_offset(FLACContext* fc, uint32_t offset) {
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, FLAC_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
int8_t *buf;
FLACContext fc;
- uint32_t samplesdone = 0;
+ uint32_t samplesdone;
uint32_t elapsedtime;
size_t bytesleft;
int consumed;
int res;
int frame;
- int retval;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, FLAC_OUTPUT_DEPTH-1);
+ intptr_t param;
-next_track:
- retval = CODEC_OK;
-
if (codec_init()) {
LOGF("FLAC: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
/* Need to save offset for later use (cleared indirectly by flac_init) */
samplesdone = ci->id3->offset;
if (!flac_init(&fc,ci->id3->first_frame_offset)) {
LOGF("FLAC: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -459,35 +459,34 @@ next_track:
STEREO_MONO : STEREO_NONINTERLEAVED);
codec_set_replaygain(ci->id3);
- if (samplesdone) {
- flac_seek_offset(&fc, samplesdone);
- samplesdone=0;
- }
+ flac_seek_offset(&fc, samplesdone);
+ samplesdone=0;
/* The main decoding loop */
frame=0;
buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
while (bytesleft) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
/* Deal with any pending seek requests */
- if (ci->seek_time) {
- if (flac_seek(&fc,(uint32_t)(((uint64_t)(ci->seek_time-1)
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (flac_seek(&fc,(uint32_t)(((uint64_t)param
*ci->id3->frequency)/1000))) {
/* Refill the input buffer */
buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
}
+
+ ci->set_elapsed(param);
ci->seek_complete();
}
if((res=flac_decode_frame(&fc,decoded0,decoded1,buf,
bytesleft,ci->yield)) < 0) {
LOGF("FLAC: Frame %d, error %d\n",frame,res);
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
consumed=fc.gb.index/8;
frame++;
@@ -507,14 +506,7 @@ next_track:
buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
}
- retval = CODEC_OK;
-done:
LOGF("FLAC: Decoded %lu samples\n",(unsigned long)samplesdone);
-
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/lib/codeclib.c b/apps/codecs/lib/codeclib.c
index af0894c498..443c0bbdcf 100644
--- a/apps/codecs/lib/codeclib.c
+++ b/apps/codecs/lib/codeclib.c
@@ -33,6 +33,16 @@ unsigned char* mp3buf; // The actual MP3 buffer from Rockbox
unsigned char* mallocbuf; // 512K from the start of MP3 buffer
unsigned char* filebuf; // The rest of the MP3 buffer
+/* this is the default codec entry point for when nothing needs to be done
+ on load or unload */
+enum codec_status __attribute__((weak))
+codec_main(enum codec_entry_call_reason reason)
+{
+ /* Nothing to do */
+ return CODEC_OK;
+ (void)reason;
+}
+
int codec_init(void)
{
mem_ptr = 0;
@@ -41,7 +51,7 @@ int codec_init(void)
return 0;
}
-void codec_set_replaygain(struct mp3entry* id3)
+void codec_set_replaygain(const struct mp3entry *id3)
{
ci->configure(DSP_SET_TRACK_GAIN, id3->track_gain);
ci->configure(DSP_SET_ALBUM_GAIN, id3->album_gain);
@@ -49,19 +59,6 @@ void codec_set_replaygain(struct mp3entry* id3)
ci->configure(DSP_SET_ALBUM_PEAK, id3->album_peak);
}
-/* Note: codec really needs its own private metdata copy for the current
- track being processed in order to be stable. */
-int codec_wait_taginfo(void)
-{
- while (!*ci->taginfo_ready && !ci->stop_codec && !ci->new_track)
- ci->sleep(0);
- if (ci->stop_codec)
- return -1;
- if (ci->new_track)
- return 1;
- return 0;
-}
-
/* Various "helper functions" common to all the xxx2wav decoder plugins */
diff --git a/apps/codecs/lib/codeclib.h b/apps/codecs/lib/codeclib.h
index 41b466ed1f..30091c5333 100644
--- a/apps/codecs/lib/codeclib.h
+++ b/apps/codecs/lib/codeclib.h
@@ -156,8 +156,7 @@ static inline unsigned int bs_generic(unsigned int v, int mode)
/* Various codec helper functions */
int codec_init(void);
-void codec_set_replaygain(struct mp3entry* id3);
-int codec_wait_taginfo(void); /* 0 = success */
+void codec_set_replaygain(const struct mp3entry *id3);
#ifdef RB_PROFILE
void __cyg_profile_func_enter(void *this_fn, void *call_site)
diff --git a/apps/codecs/mod.c b/apps/codecs/mod.c
index 4ace721a1e..3dfaac663f 100644
--- a/apps/codecs/mod.c
+++ b/apps/codecs/mod.c
@@ -1218,47 +1218,37 @@ void synthrender(int32_t *renderbuffer, int samplecount)
}
}
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Make use of 44.1khz */
+ ci->configure(DSP_SET_FREQUENCY, 44100);
+ /* Sample depth is 28 bit host endian */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ /* Stereo output */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
+ }
+
+ return CODEC_OK;
+}
-enum codec_status codec_main(void)
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
size_t n;
unsigned char *modfile;
int old_patterntableposition;
-
int bytesdone;
+ intptr_t param;
-next_track:
if (codec_init()) {
return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
/* Load MOD file */
- /*
- * This is the save way
-
- size_t bytesfree;
- unsigned int filesize;
-
- p = modfile;
- bytesfree=sizeof(modfile);
- while ((n = ci->read_filebuf(p, bytesfree)) > 0) {
- p += n;
- bytesfree -= n;
- if (bytesfree == 0)
- return CODEC_ERROR;
- }
- filesize = p-modfile;
-
- if (filesize == 0)
- return CODEC_ERROR;
- */
-
- /* Directly use mod in buffer */
ci->seek_buffer(0);
modfile = ci->request_buffer(&n, ci->filesize);
if (!modfile || n < (size_t)ci->filesize) {
@@ -1268,27 +1258,22 @@ next_track:
initmodplayer();
loadmod(modfile);
- /* Make use of 44.1khz */
- ci->configure(DSP_SET_FREQUENCY, 44100);
- /* Sample depth is 28 bit host endian */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
- /* Stereo output */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
-
/* The main decoder loop */
ci->set_elapsed(0);
bytesdone = 0;
old_patterntableposition = 0;
while (1) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- /* New time is ready in ci->seek_time */
- modplayer.patterntableposition = ci->seek_time/1000;
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ /* New time is ready in param */
+ modplayer.patterntableposition = param/1000;
modplayer.currentline = 0;
+ ci->set_elapsed(modplayer.patterntableposition*1000+500);
ci->seek_complete();
}
@@ -1305,9 +1290,5 @@ next_track:
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
return CODEC_OK;
}
diff --git a/apps/codecs/mp3_enc.c b/apps/codecs/mp3_enc.c
index e7893fd14a..2f5528f74c 100644
--- a/apps/codecs/mp3_enc.c
+++ b/apps/codecs/mp3_enc.c
@@ -2584,45 +2584,46 @@ static bool enc_init(void)
return true;
} /* enc_init */
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- /* Generic codec initialisation */
- if (!enc_init())
- return CODEC_ERROR;
+ if (reason == CODEC_LOAD) {
+ if (!enc_init())
+ return CODEC_ERROR;
+ }
+ else if (reason == CODEC_UNLOAD) {
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(NULL);
+ }
+
+ return CODEC_OK;
+}
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
/* main encoding loop */
- while (!ci->stop_codec)
+ while(ci->get_command(NULL) != CODEC_ACTION_HALT)
{
- char *buffer;
-
- while ((buffer = ci->enc_get_pcm_data(pcm_chunk_size)) != NULL)
- {
- struct enc_chunk_hdr *chunk;
-
- if (ci->stop_codec)
- break;
+ char *buffer = buffer = ci->enc_get_pcm_data(pcm_chunk_size);
+ struct enc_chunk_hdr *chunk;
- chunk = ci->enc_get_chunk();
- chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
+ if(buffer == NULL)
+ continue;
- encode_frame(buffer, chunk);
+ chunk = ci->enc_get_chunk();
+ chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
- if (chunk->num_pcm < samp_per_frame)
- {
- ci->enc_unget_pcm_data(pcm_chunk_size - chunk->num_pcm*4);
- chunk->num_pcm = samp_per_frame;
- }
+ encode_frame(buffer, chunk);
- ci->enc_finish_chunk();
-
- ci->yield();
+ if (chunk->num_pcm < samp_per_frame)
+ {
+ ci->enc_unget_pcm_data(pcm_chunk_size - chunk->num_pcm*4);
+ chunk->num_pcm = samp_per_frame;
}
- ci->yield();
+ ci->enc_finish_chunk();
}
- /* reset parameters to initial state */
- ci->enc_set_parameters(NULL);
-
return CODEC_OK;
-} /* codec_start */
+}
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
index 4b49775029..c9e2131450 100644
--- a/apps/codecs/mpa.c
+++ b/apps/codecs/mpa.c
@@ -268,8 +268,8 @@ static bool mad_synth_thread_create(void)
static void mad_synth_thread_quit(void)
{
- /*mop up COP thread*/
- die=1;
+ /* mop up COP thread */
+ die = 1;
ci->semaphore_release(&synth_pending_sem);
ci->thread_wait(mad_synth_thread_id);
ci->cpucache_invalidate();
@@ -299,9 +299,30 @@ static inline void mad_synth_thread_unwait_pcm(void)
#endif /* MPA_SYNTH_ON_COP */
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Create a decoder instance */
+ if (codec_init())
+ return CODEC_ERROR;
+
+ ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
+
+ /* does nothing on 1 processor systems except return true */
+ if(!mad_synth_thread_create())
+ return CODEC_ERROR;
+ }
+ else if (reason == CODEC_UNLOAD) {
+ /* mop up COP thread - MT only */
+ mad_synth_thread_quit();
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
size_t size;
int file_end;
int samples_to_skip; /* samples to skip in total for this file (at start) */
@@ -312,27 +333,12 @@ enum codec_status codec_main(void)
unsigned long current_frequency = 0;
int framelength;
int padding = MAD_BUFFER_GUARD; /* to help mad decode the last frame */
-
- if (codec_init())
- return CODEC_ERROR;
-
- /* Create a decoder instance */
-
- ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
-
- /*does nothing on 1 processor systems except return true*/
- if(!mad_synth_thread_create())
- return CODEC_ERROR;
-
-next_track:
- status = CODEC_OK;
+ intptr_t param;
/* Reinitializing seems to be necessary to avoid playback quircks when seeking. */
init_mad();
file_end = 0;
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
current_frequency = ci->id3->frequency;
@@ -379,29 +385,35 @@ next_track:
/* This is the decoding loop. */
while (1) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
int newpos;
/*make sure the synth thread is idle before seeking - MT only*/
mad_synth_thread_wait_pcm();
mad_synth_thread_unwait_pcm();
- samplesdone = ((int64_t)(ci->seek_time-1))*current_frequency/1000;
+ samplesdone = ((int64_t)param)*current_frequency/1000;
- if (ci->seek_time-1 == 0) {
+ if (param == 0) {
newpos = ci->id3->first_frame_offset;
samples_to_skip = start_skip;
} else {
- newpos = get_file_pos(ci->seek_time-1);
+ newpos = get_file_pos(param);
samples_to_skip = 0;
}
if (!ci->seek_buffer(newpos))
+ {
+ ci->seek_complete();
break;
+ }
+
+ ci->set_elapsed((samplesdone * 1000) / current_frequency);
ci->seek_complete();
init_mad();
framelength = 0;
@@ -435,8 +447,7 @@ next_track:
continue;
} else {
/* Some other unrecoverable error */
- status = CODEC_ERROR;
- break;
+ return CODEC_ERROR;
}
}
@@ -504,12 +515,5 @@ next_track:
framelength - stop_skip);
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
- /*mop up COP thread - MT only*/
- mad_synth_thread_quit();
-
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c
index 187c37e597..bbe2d9943b 100644
--- a/apps/codecs/mpc.c
+++ b/apps/codecs/mpc.c
@@ -52,8 +52,20 @@ static mpc_int32_t get_size_impl(mpc_reader *reader)
return ci->filesize;
}
-/* This is the codec entry point. */
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* musepack's sample representation is 18.14
+ * DSP_SET_SAMPLE_DEPTH = 14 (FRACT) + 16 (NATIVE) - 1 (SIGN) = 29 */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
mpc_int64_t samplesdone;
uint32_t frequency; /* 0.1 kHz accuracy */
@@ -64,39 +76,27 @@ enum codec_status codec_main(void)
mpc_streaminfo info;
mpc_frame_info frame;
mpc_demux *demux = NULL;
- int retval;
+ intptr_t param;
frame.buffer = sample_buffer;
-
- /* musepack's sample representation is 18.14
- * DSP_SET_SAMPLE_DEPTH = 14 (FRACT) + 16 (NATIVE) - 1 (SIGN) = 29 */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
-
+
/* Create a decoder instance */
reader.read = read_impl;
reader.seek = seek_impl;
reader.tell = tell_impl;
reader.get_size = get_size_impl;
-next_track:
- retval = CODEC_OK;
-
if (codec_init())
- {
- retval = CODEC_ERROR;
- goto exit;
- }
+ return CODEC_ERROR;
- if (codec_wait_taginfo() != 0)
- goto done;
+ /* Prep position */
+ ci->seek_buffer(0);
/* Initialize demux/decoder. */
demux = mpc_demux_init(&reader);
if (NULL == demux)
- {
- retval = CODEC_ERROR;
- goto done;
- }
+ return CODEC_ERROR;
+
/* Read file's streaminfo data. */
mpc_demux_get_info(demux, &info);
@@ -117,11 +117,8 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
else if (info.channels == 1)
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
- else
- {
- retval = CODEC_ERROR;
- goto done;
- }
+ else
+ return CODEC_ERROR;
codec_set_replaygain(ci->id3);
@@ -142,21 +139,24 @@ next_track:
/* This is the decoding loop. */
do
{
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ return CODEC_OK;
+
/* Complete seek handler. */
- if (ci->seek_time)
+ if (action == CODEC_ACTION_SEEK_TIME)
{
- mpc_int64_t new_offset = ((ci->seek_time - 1)/10)*frequency;
+ mpc_int64_t new_offset = (param/10)*frequency;
if (mpc_demux_seek_sample(demux, new_offset) == MPC_STATUS_OK)
{
samplesdone = new_offset;
- ci->set_elapsed(ci->seek_time);
}
+
+ elapsed_time = (samplesdone*10)/frequency;
+ ci->set_elapsed(elapsed_time);
ci->seek_complete();
}
-
- /* Stop or skip occured, exit decoding loop. */
- if (ci->stop_codec || ci->new_track)
- break;
/* Decode one frame. */
status = mpc_demux_decode(demux, &frame);
@@ -164,8 +164,7 @@ next_track:
if (frame.bits == -1)
{
/* Decoding error, exit decoding loop. */
- retval = (status == MPC_STATUS_OK) ? CODEC_OK : CODEC_ERROR;
- goto done;
+ return (status == MPC_STATUS_OK) ? CODEC_OK : CODEC_ERROR;
}
else
{
@@ -181,11 +180,4 @@ next_track:
ci->set_offset( (samplesdone * byterate)/(frequency*100) );
}
} while (true);
-
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return retval;
}
diff --git a/apps/codecs/nsf.c b/apps/codecs/nsf.c
index 2f37da81d2..72f6974214 100644
--- a/apps/codecs/nsf.c
+++ b/apps/codecs/nsf.c
@@ -4307,46 +4307,44 @@ static void set_codec_track(int t, int d) {
nSilenceTrackMS=5000;
SetFadeTime(track,track+fade, fNSFPlaybackSpeed,def);
}
- ci->id3->elapsed=d*1000; /* d is track no to display */
+ ci->set_elapsed(d*1000); /* d is track no to display */
}
+/** Operational info **/
+static int track = 0;
+static char last_path[MAX_PATH];
+static int dontresettrack = 0;
+
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* we only render 16 bits, 44.1KHz, Stereo */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
+ ci->configure(DSP_SET_FREQUENCY, 44100);
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
+
+ RebuildOutputTables();
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
int written;
uint8_t *buf;
size_t n;
int endofstream; /* end of stream flag */
- int track;
- int dontresettrack;
- char last_path[MAX_PATH];
- int usingplaylist;
-
- /* we only render 16 bits */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
-
- ci->configure(DSP_SET_FREQUENCY, 44100);
- ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
-
- RebuildOutputTables();
-
- dontresettrack=0;
- last_path[0]='\0';
- track=0;
+ int usingplaylist = 0;
-next_track:
- usingplaylist=0;
DEBUGF("NSF: next_track\n");
if (codec_init()) {
return CODEC_ERROR;
}
DEBUGF("NSF: after init\n");
-
- /* wait for track info to load */
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
/* Read the entire file */
@@ -4408,22 +4406,27 @@ init_nsf:
reset_profile_timers();
while (!endofstream) {
+ intptr_t param;
+ enum codec_command_action action = ci->get_command(&param);
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time >0) {
- track=ci->seek_time/1000;
- if (usingplaylist) {
- if (track>=nPlaylistSize) break;
- } else {
- if (track>=nTrackCount) break;
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (param > 0) {
+ track=param/1000;
+ if (usingplaylist) {
+ if (track>=nPlaylistSize) break;
+ } else {
+ if (track>=nTrackCount) break;
+ }
+ dontresettrack=1;
+ ci->seek_complete();
+ goto init_nsf;
+ }
+ else {
+ ci->seek_complete();
}
- ci->seek_complete();
- dontresettrack=1;
- goto init_nsf;
}
ENTER_TIMER(total);
@@ -4449,22 +4452,17 @@ init_nsf:
print_timers(last_path,track);
-request_next_track:
- if (ci->request_next_track()) {
if (ci->global_settings->repeat_mode==REPEAT_ONE) {
/* in repeat one mode just advance to the next track */
track++;
if (track>=nTrackCount) track=0;
dontresettrack=1;
/* at this point we can't tell if another file has been selected */
- goto next_track;
} else {
/* otherwise do a proper load of the next file */
dontresettrack=0;
last_path[0]='\0';
}
- goto next_track; /* when we fall through here we'll reload the file */
- }
return CODEC_OK;
}
diff --git a/apps/codecs/raac.c b/apps/codecs/raac.c
index b322ae7df3..4b73f41462 100644
--- a/apps/codecs/raac.c
+++ b/apps/codecs/raac.c
@@ -35,8 +35,21 @@ static void init_rm(RMContext *rmctx)
static RMContext rmctx;
static RMPacket pkt;
+
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
static NeAACDecFrameInfo frame_info;
NeAACDecHandle decoder;
@@ -49,26 +62,21 @@ enum codec_status codec_main(void)
unsigned char c = 0; /* channels */
int playback_on = -1;
size_t resume_offset;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
-
-next_track:
- err = CODEC_OK;
+ intptr_t param;
+ enum codec_command_action action = CODEC_ACTION_NULL;
if (codec_init()) {
DEBUGF("FAAD: Codec init error\n");
return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
resume_offset = ci->id3->offset;
ci->memset(&rmctx,0,sizeof(RMContext));
ci->memset(&pkt,0,sizeof(RMPacket));
+
+ ci->seek_buffer(0);
+
init_rm(&rmctx);
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
codec_set_replaygain(ci->id3);
@@ -78,9 +86,9 @@ next_track:
if (!decoder) {
DEBUGF("FAAD: Decode open error\n");
- err = CODEC_ERROR;
- goto done;
- }
+ return CODEC_ERROR;
+ }
+
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
conf->outputFormat = FAAD_FMT_16BIT; /* irrelevant, we don't convert */
NeAACDecSetConfiguration(decoder, conf);
@@ -91,8 +99,7 @@ next_track:
if (err) {
DEBUGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type);
- err = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check for a mid-track resume and force a seek time accordingly */
@@ -100,36 +107,38 @@ next_track:
resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
/* put number of subpackets to skip in resume_offset */
resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE);
- ci->seek_time = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
+ param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
+ action = CODEC_ACTION_SEEK_TIME;
}
-
- ci->id3->frequency = s;
+
+ ci->id3->frequency = s; /* FIXME: Won't get it to the UI */
ci->set_elapsed(0);
ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
/* The main decoding loop */
-seek_start:
while (1) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ if (action == CODEC_ACTION_NULL)
+ action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
-
+ if (action == CODEC_ACTION_SEEK_TIME) {
/* Do not allow seeking beyond the file's length */
- if ((unsigned) ci->seek_time > ci->id3->length) {
+ if ((unsigned) param > ci->id3->length) {
+ ci->set_elapsed(ci->id3->length);
ci->seek_complete();
- goto done;
+ break;
}
ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
/* Seek to the start of the track */
- if (ci->seek_time == 1) {
+ if (param == 0) {
ci->set_elapsed(0);
ci->seek_complete();
- goto seek_start;
+ action = CODEC_ACTION_NULL;
+ continue;
}
skipped = 0;
@@ -141,21 +150,30 @@ seek_start:
if(playback_on == -1) {
/* Error only if packet-parsing failed and playback hadn't started */
DEBUGF("rm_get_packet failed\n");
+ ci->seek_complete();
return CODEC_ERROR;
}
- else
- goto done;
+ else {
+ ci->seek_complete();
+ return CODEC_OK;
+ }
}
skipped += pkt.length;
- if(pkt.timestamp > (unsigned)ci->seek_time) break;
+
+ if(pkt.timestamp > (unsigned)param)
+ break;
+
ci->advance_buffer(pkt.length);
}
ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE);
buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000);
NeAACDecPostSeekReset(decoder, decoder->frame);
+ ci->set_elapsed(pkt.timestamp);
ci->seek_complete();
}
+ action = CODEC_ACTION_NULL;
+
/* Request the required number of bytes from the input buffer */
buffer=ci->request_buffer(&n,rmctx.audio_framesize + 1000);
consumed = rm_get_packet(&buffer, &rmctx, &pkt);
@@ -167,20 +185,20 @@ seek_start:
return CODEC_ERROR;
}
else
- goto done;
+ break;
}
playback_on = 1;
if (pkt.timestamp >= ci->id3->length)
- goto done;
+ break;
+
/* Decode one block - returned samples will be host-endian */
for(i = 0; i < rmctx.sub_packet_cnt; i++) {
ret = NeAACDecDecode(decoder, &frame_info, buffer, rmctx.sub_packet_lengths[i]);
buffer += rmctx.sub_packet_lengths[i];
if (frame_info.error > 0) {
DEBUGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error));
- err = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(decoder->time_out[0],
decoder->time_out[1],
@@ -191,11 +209,5 @@ seek_start:
ci->advance_buffer(pkt.length);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return err;
+ return CODEC_OK;
}
-
diff --git a/apps/codecs/shorten.c b/apps/codecs/shorten.c
index 83a9c34da8..db66991679 100644
--- a/apps/codecs/shorten.c
+++ b/apps/codecs/shorten.c
@@ -37,7 +37,19 @@ static int32_t offset1[MAX_OFFSET_SIZE] IBSS_ATTR;
static int8_t ibuf[MAX_BUFFER_SIZE] IBSS_ATTR;
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
ShortenContext sc;
uint32_t samplesdone;
@@ -45,21 +57,14 @@ enum codec_status codec_main(void)
int8_t *buf;
int consumed, res, nsamples;
size_t bytesleft;
+ intptr_t param;
- /* Generic codec initialisation */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
-
-next_track:
/* Codec initialization */
if (codec_init()) {
LOGF("Shorten: codec_init error\n");
return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
/* Shorten decoder initialization */
@@ -103,14 +108,15 @@ seek_start:
samplesdone = 0;
buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
while (bytesleft) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
/* Seek to start of track */
- if (ci->seek_time == 1) {
- if (ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (param == 0 &&
+ ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) {
sc.bitindex = sc.header_bits - 8*(sc.header_bits/8);
ci->set_elapsed(0);
ci->seek_complete();
@@ -128,7 +134,7 @@ seek_start:
if (res == FN_ERROR) {
LOGF("Shorten: shorten_decode_frames error (%lu)\n",
(unsigned long)samplesdone);
- break;
+ return CODEC_ERROR;
} else {
/* Insert decoded samples in pcmbuf */
if (nsamples) {
@@ -153,9 +159,5 @@ seek_start:
sc.bitindex = sc.gb.index - 8*consumed;
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
return CODEC_OK;
}
diff --git a/apps/codecs/sid.c b/apps/codecs/sid.c
index 52c1289fff..0edbabe0b6 100644
--- a/apps/codecs/sid.c
+++ b/apps/codecs/sid.c
@@ -1203,34 +1203,47 @@ unsigned short LoadSIDFromMemory(void *pSidData, unsigned short *load_addr,
return *load_addr;
}
+static int nSamplesRendered = 0;
+static int nSamplesPerCall = 882; /* This is PAL SID single speed (44100/50Hz) */
+static int nSamplesToRender = 0;
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- unsigned int filesize;
+ if (reason == CODEC_LOAD) {
+ /* Make use of 44.1khz */
+ ci->configure(DSP_SWITCH_FREQUENCY, 44100);
+ /* Sample depth is 28 bit host endian */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ /* Mono output */
+ ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
+ }
+
+ return CODEC_OK;
+}
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
+ unsigned int filesize;
unsigned short load_addr, init_addr, play_addr;
unsigned char subSongsMax, subSong, song_speed;
+ intptr_t param;
- int nSamplesRendered = 0;
- int nSamplesPerCall = 882; /* This is PAL SID single speed (44100/50Hz) */
- int nSamplesToRender = 0;
-
-next_track:
if (codec_init()) {
return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto request_next_track;
-
codec_set_replaygain(ci->id3);
/* Load SID file the read_filebuf callback will return the full requested
- * size if at all possible, so there is no need to loop */
+ * size if at all possible, so there is no need to loop */
+ ci->seek_buffer(0);
filesize = ci->read_filebuf(sidfile, sizeof(sidfile));
- if (filesize == 0)
+ if (filesize == 0) {
return CODEC_ERROR;
+ }
c64Init(44100);
LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr,
@@ -1239,37 +1252,30 @@ next_track:
cpuJSR(init_addr, subSong); /* Start the song initialize */
- /* Make use of 44.1khz */
- ci->configure(DSP_SWITCH_FREQUENCY, 44100);
- /* Sample depth is 28 bit host endian */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
- /* Mono output */
- ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
-
-
/* Set the elapsed time to the current subsong (in seconds) */
ci->set_elapsed(subSong*1000);
/* The main decoder loop */
while (1) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- /* New time is ready in ci->seek_time */
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ /* New time is ready in param */
/* Start playing from scratch */
c64Init(44100);
- LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr, &subSongsMax, &subSong, &song_speed, filesize);
- sidPoke(24, 15); /* Turn on full volume */
- subSong = ci->seek_time / 1000; /* Now use the current seek time in seconds as subsong */
- cpuJSR(init_addr, subSong); /* Start the song initialize */
- nSamplesToRender = 0; /* Start the rendering from scratch */
-
- ci->seek_complete();
+ LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr,
+ &subSongsMax, &subSong, &song_speed, filesize);
+ sidPoke(24, 15); /* Turn on full volume */
+ subSong = param / 1000; /* Now use the current seek time in seconds as subsong */
+ cpuJSR(init_addr, subSong); /* Start the song initialize */
+ nSamplesToRender = 0; /* Start the rendering from scratch */
/* Set the elapsed time to the current subsong (in seconds) */
+ ci->seek_complete();
ci->set_elapsed(subSong*1000);
}
@@ -1306,9 +1312,5 @@ next_track:
ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE);
}
-request_next_track:
- if (ci->request_next_track())
- goto next_track;
-
return CODEC_OK;
}
diff --git a/apps/codecs/smaf.c b/apps/codecs/smaf.c
index 3e8a41387d..9211daa9aa 100644
--- a/apps/codecs/smaf.c
+++ b/apps/codecs/smaf.c
@@ -332,9 +332,20 @@ static uint8_t *read_buffer(size_t *realsize)
return buffer;
}
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
uint32_t decodedsamples;
size_t n;
int bufcount;
@@ -342,20 +353,10 @@ enum codec_status codec_main(void)
uint8_t *smafbuf;
off_t firstblockposn; /* position of the first block in file */
const struct pcm_codec *codec;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ intptr_t param;
-next_track:
- status = CODEC_OK;
-
- if (codec_init()) {
- status = CODEC_ERROR;
- goto exit;
- }
-
- if (codec_wait_taginfo() != 0)
- goto done;
+ if (codec_init())
+ return CODEC_ERROR;
codec_set_replaygain(ci->id3);
@@ -365,24 +366,22 @@ next_track:
decodedsamples = 0;
codec = 0;
+ ci->seek_buffer(0);
if (!parse_header(&format, &firstblockposn))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
codec = get_codec(format.formattag);
if (codec == 0)
{
DEBUGF("CODEC_ERROR: unsupport audio format: 0x%x\n", (int)format.formattag);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (!codec->set_format(&format))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -392,8 +391,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -404,12 +402,10 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels unsupported\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->seek_buffer(firstblockposn);
- ci->seek_complete();
/* make sure we're at the correct offset */
if (bytesdone > (uint32_t) firstblockposn)
@@ -419,13 +415,13 @@ next_track:
PCM_SEEK_POS, &read_buffer);
if (newpos->pos > format.numbytes)
- goto done;
+ return CODEC_OK;
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
}
else
{
@@ -437,23 +433,32 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME,
&read_buffer);
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
+
smafbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize);
if (n == 0)
@@ -464,11 +469,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(smafbuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(smafbuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -482,11 +486,5 @@ next_track:
ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return status;
+ return CODEC_OK;
}
-
diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c
index 4db2878964..1b49761810 100644
--- a/apps/codecs/spc.c
+++ b/apps/codecs/spc.c
@@ -260,14 +260,6 @@ static inline void samples_release_rdbuf(void)
static inline int32_t * samples_get_rdbuf(void)
{
ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK);
-
- if (ci->stop_codec || ci->new_track)
- {
- /* Told to stop. Buffer must be released. */
- samples_release_rdbuf();
- return NULL;
- }
-
return sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK].audio;
}
@@ -390,11 +382,10 @@ static inline void spc_emu_quit(void)
}
}
-static inline bool spc_play_get_samples(int32_t **samples)
+static inline int32_t * spc_play_get_samples(void)
{
/* obtain filled samples buffer */
- *samples = samples_get_rdbuf();
- return *samples != NULL;
+ return samples_get_rdbuf();
}
static inline void spc_play_send_samples(int32_t *samples)
@@ -433,15 +424,14 @@ static inline void spc_play_send_samples(int32_t *samples)
#define spc_emu_quit()
#define samples_release_rdbuf()
-static inline bool spc_play_get_samples(int32_t **samples)
+static inline int32_t * spc_play_get_samples(void)
{
ENTER_TIMER(render);
/* fill samples buffer */
if ( SPC_play(&spc_emu,WAV_CHUNK_SIZE*2,wav_chunk) )
assert( false );
EXIT_TIMER(render);
- *samples = wav_chunk;
- return true;
+ return wav_chunk;
}
#endif /* SPC_DUAL_CORE */
@@ -454,6 +444,7 @@ static int play_track( void )
unsigned long fadeendsample = (ID666.length+ID666.fade)*(long long) SAMPLE_RATE/1000;
int fadedec = 0;
int fadevol = 0x7fffffffl;
+ intptr_t param;
if (fadeendsample>fadestartsample)
fadedec=0x7fffffffl/(fadeendsample-fadestartsample)+1;
@@ -462,25 +453,26 @@ static int play_track( void )
while ( 1 )
{
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
int curtime = sampleswritten*1000LL/SAMPLE_RATE;
- DEBUGF("seek to %ld\ncurrently at %d\n",ci->seek_time,curtime);
- if (ci->seek_time < curtime) {
+ DEBUGF("seek to %ld\ncurrently at %d\n", (long)param, curtime);
+ if (param < curtime) {
DEBUGF("seek backwards = reset\n");
+ ci->set_elapsed(0);
ci->seek_complete();
return 1;
}
+
+ ci->set_elapsed(curtime);
ci->seek_complete();
}
- int32_t *samples;
- if (!spc_play_get_samples(&samples))
- break;
+ int32_t *samples = spc_play_get_samples();
sampleswritten += WAV_CHUNK_SIZE;
@@ -532,67 +524,61 @@ static int play_track( void )
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- enum codec_status stat = CODEC_ERROR;
-
- if (!spc_emu_start())
- goto codec_quit;
-
- do
- {
- DEBUGF("SPC: next_track\n");
- if (codec_init()) {
- goto codec_quit;
- }
- DEBUGF("SPC: after init\n");
+ if (reason == CODEC_LOAD) {
+ if (!spc_emu_start())
+ return CODEC_ERROR;
ci->configure(DSP_SET_SAMPLE_DEPTH, 24);
ci->configure(DSP_SET_FREQUENCY, SAMPLE_RATE);
ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
+ }
+ else if (reason == CODEC_UNLOAD) {
+ spc_emu_quit();
+ }
- /* wait for track info to load */
- if (codec_wait_taginfo() != 0)
- continue;
-
- codec_set_replaygain(ci->id3);
+ return CODEC_OK;
+}
- /* Read the entire file */
- DEBUGF("SPC: request initial buffer\n");
- ci->seek_buffer(0);
- size_t buffersize;
- uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize);
- if (!buffer) {
- goto codec_quit;
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
+ DEBUGF("SPC: next_track\n");
+ if (codec_init())
+ return CODEC_ERROR;
+ DEBUGF("SPC: after init\n");
+
+ codec_set_replaygain(ci->id3);
+
+ /* Read the entire file */
+ DEBUGF("SPC: request initial buffer\n");
+ ci->seek_buffer(0);
+ size_t buffersize;
+ uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize);
+ if (!buffer)
+ return CODEC_ERROR;
+
+ DEBUGF("SPC: read size = 0x%lx\n",(unsigned long)buffersize);
+ do
+ {
+ if (load_spc_buffer(buffer, buffersize)) {
+ DEBUGF("SPC load failure\n");
+ return CODEC_ERROR;
}
- DEBUGF("SPC: read size = 0x%lx\n",(unsigned long)buffersize);
- do
- {
- if (load_spc_buffer(buffer, buffersize)) {
- DEBUGF("SPC load failure\n");
- goto codec_quit;
- }
-
- LoadID666(buffer+0x2e);
+ LoadID666(buffer+0x2e);
- if (ci->global_settings->repeat_mode!=REPEAT_ONE && ID666.length==0) {
- ID666.length=3*60*1000; /* 3 minutes */
- ID666.fade=5*1000; /* 5 seconds */
- }
-
- reset_profile_timers();
+ if (ci->global_settings->repeat_mode!=REPEAT_ONE && ID666.length==0) {
+ ID666.length=3*60*1000; /* 3 minutes */
+ ID666.fade=5*1000; /* 5 seconds */
}
- while ( play_track() );
- print_timers(ci->id3->path);
+ reset_profile_timers();
}
- while ( ci->request_next_track() );
+ while ( play_track() );
- stat = CODEC_OK;
+ print_timers(ci->id3->path);
-codec_quit:
- spc_emu_quit();
-
- return stat;
+ return CODEC_OK;
}
diff --git a/apps/codecs/speex.c b/apps/codecs/speex.c
index 7a1efa9753..e394efc3d5 100644
--- a/apps/codecs/speex.c
+++ b/apps/codecs/speex.c
@@ -367,11 +367,12 @@ static void *process_header(spx_ogg_packet *op,
return st;
}
-/* 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)
{
+ int error = CODEC_ERROR;
+
SpeexBits bits;
- int error;
int eof = 0;
spx_ogg_sync_state oy;
spx_ogg_page og;
@@ -383,7 +384,7 @@ enum codec_status codec_main(void)
int eos = 0;
SpeexStereoState *stereo;
int channels = -1;
- int rate = 0, samplerate = 0;
+ int samplerate = 0;
int extra_headers = 0;
int stream_init = 0;
int page_nb_packets, frame_size, packet_count = 0;
@@ -392,26 +393,22 @@ enum codec_status codec_main(void)
unsigned long strtoffset = 0;
void *st = NULL;
int j = 0;
+ intptr_t param;
memset(&bits, 0, sizeof(bits));
memset(&oy, 0, sizeof(oy));
/* Ogg handling still uses mallocs, so reset the malloc buffer per track */
-next_track:
- error = CODEC_OK;
-
if (codec_init()) {
- error = CODEC_ERROR;
goto exit;
}
+ ci->seek_buffer(0);
+
stereo = speex_stereo_state_init();
spx_ogg_sync_init(&oy);
spx_ogg_alloc_buffer(&oy,2*CHUNKSIZE);
- if (codec_wait_taginfo() != 0)
- goto done;
-
strtoffset = ci->id3->offset;
samplerate = ci->id3->frequency;
@@ -419,30 +416,32 @@ next_track:
eof = 0;
while (!eof) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
/*seek (seeks to the page before the position) */
- if (ci->seek_time) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
if(samplerate!=0&&packet_count>1){
LOGF("Speex seek page:%lld,%lld,%ld,%lld,%d\n",
- ((spx_int64_t)ci->seek_time/1000) *
+ ((spx_int64_t)param/1000) *
(spx_int64_t)samplerate,
- page_granule, ci->seek_time,
+ page_granule, param,
(page_granule/samplerate)*1000, samplerate);
- speex_seek_page_granule(((spx_int64_t)ci->seek_time/1000) *
+ speex_seek_page_granule(((spx_int64_t)param/1000) *
(spx_int64_t)samplerate,
page_granule, &oy, headerssize);
- ci->seek_complete();
}
+
+ ci->set_elapsed(param);
+ ci->seek_complete();
}
next_page:
/*Get the ogg buffer for writing*/
if(get_more_data(&oy)<1){/*read error*/
- error=CODEC_ERROR;
goto done;
}
@@ -477,8 +476,7 @@ next_page:
nframes=1;
if (!st){
- error=CODEC_ERROR;
- goto exit;
+ goto done;
}
ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
@@ -557,31 +555,18 @@ next_page:
}
done:
- if (ci->request_next_track()) {
-
- /* Clean things up for the next track */
+ /* Clean things up for the next track */
+ speex_bits_destroy(&bits);
+ if (st)
if (st)
speex_decoder_destroy(st);
- if (stream_init == 1)
- spx_ogg_stream_reset(&os);
-
- spx_ogg_sync_reset(&oy);
-
- cur_granule = stream_init = rate = samplerate = headerssize
- = packet_count = eos = 0;
-
- goto next_track;
- }
-
-exit:
- speex_bits_destroy(&bits);
-
if (stream_init)
spx_ogg_stream_destroy(&os);
spx_ogg_sync_destroy(&oy);
+exit:
return error;
}
diff --git a/apps/codecs/tta.c b/apps/codecs/tta.c
index 1d0846ea61..c75f2b0a57 100644
--- a/apps/codecs/tta.c
+++ b/apps/codecs/tta.c
@@ -34,36 +34,36 @@ CODEC_HEADER
static int32_t samples[PCM_BUFFER_LENGTH * 2] IBSS_ATTR;
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, TTA_OUTPUT_DEPTH - 1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
tta_info info;
- int status;
unsigned int decodedsamples;
int endofstream;
int new_pos = 0;
int sample_count;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, TTA_OUTPUT_DEPTH - 1);
+ intptr_t param;
-next_track:
- status = CODEC_OK;
-
if (codec_init())
{
DEBUGF("codec_init() error\n");
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
+ ci->seek_buffer(0);
if (set_tta_info(&info) < 0 || player_init(&info) < 0)
- {
- status = CODEC_ERROR;
- goto exit;
- }
+ return CODEC_ERROR;
codec_set_replaygain(ci->id3);
@@ -74,8 +74,8 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels\n");
- status = CODEC_ERROR;
- goto done;
+ player_stop();
+ return CODEC_ERROR;
}
/* The main decoder loop */
@@ -88,31 +88,31 @@ next_track:
new_pos = set_position(ci->id3->offset, TTA_SEEK_POS);
if (new_pos >= 0)
decodedsamples = new_pos;
- ci->seek_complete();
}
while (!endofstream)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time)
+ if (action == CODEC_ACTION_SEEK_TIME)
{
- new_pos = set_position(ci->seek_time / SEEK_STEP, TTA_SEEK_TIME);
+ new_pos = set_position(param / SEEK_STEP, TTA_SEEK_TIME);
if (new_pos >= 0)
{
decodedsamples = new_pos;
- ci->seek_complete();
}
+
+ ci->set_elapsed((uint64_t)info.LENGTH * 1000 * decodedsamples / info.DATALENGTH);
+ ci->seek_complete();
}
sample_count = get_samples(samples);
if (sample_count < 0)
- {
- status = CODEC_ERROR;
break;
- }
+
ci->pcmbuf_insert(samples, NULL, sample_count);
decodedsamples += sample_count;
if (decodedsamples >= info.DATALENGTH)
@@ -120,11 +120,6 @@ next_track:
ci->set_elapsed((uint64_t)info.LENGTH * 1000 * decodedsamples / info.DATALENGTH);
}
-done:
player_stop();
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c
index 0a36a37c8b..e02d459262 100644
--- a/apps/codecs/vorbis.c
+++ b/apps/codecs/vorbis.c
@@ -104,14 +104,25 @@ static bool vorbis_set_codec_parameters(OggVorbis_File *vf)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ if (codec_init())
+ return CODEC_ERROR;
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 24);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
ov_callbacks callbacks;
OggVorbis_File vf;
ogg_int32_t **pcm;
- bool initialized = false; /* First init done? */
- int error;
+ int error = CODEC_ERROR;
long n;
int current_section;
int previous_section;
@@ -120,36 +131,24 @@ enum codec_status codec_main(void)
ogg_int64_t vf_dataoffsets;
ogg_uint32_t vf_serialnos;
ogg_int64_t vf_pcmlengths[2];
-
- ci->configure(DSP_SET_SAMPLE_DEPTH, 24);
-
- if (codec_init()) {
- error = CODEC_ERROR;
- goto exit;
- }
+ intptr_t param;
#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS)
if (setjmp(rb_jump_buf) != 0) {
- /* malloc failed; skip to next track */
- error = CODEC_ERROR;
+ /* malloc failed; finish with this track */
goto done;
}
#endif
-
-next_track:
- error = CODEC_OK;
-
ogg_malloc_init();
- if (codec_wait_taginfo() != 0)
- goto done;
-
/* Create a decoder instance */
callbacks.read_func = read_handler;
callbacks.seek_func = initial_seek_handler;
callbacks.tell_func = tell_handler;
callbacks.close_func = close_handler;
+ ci->seek_buffer(0);
+
/* Open a non-seekable stream */
error = ov_open_callbacks(ci, &vf, NULL, 0, callbacks);
@@ -186,15 +185,13 @@ next_track:
vf.end = ci->id3->filesize;
vf.ready_state = OPENED;
vf.links = 1;
- initialized = true;
} else {
DEBUGF("Vorbis: ov_open failed: %d\n", error);
- error = CODEC_ERROR;
goto done;
}
if (ci->id3->offset) {
- ci->advance_buffer(ci->id3->offset);
+ ci->seek_buffer(ci->id3->offset);
ov_raw_seek(&vf, ci->id3->offset);
ci->set_elapsed(ov_time_tell(&vf));
ci->set_offset(ov_raw_tell(&vf));
@@ -203,14 +200,17 @@ next_track:
previous_section = -1;
eof = 0;
while (!eof) {
- ci->yield();
- if (ci->stop_codec || ci->new_track)
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- if (ci->seek_time) {
- if (ov_time_seek(&vf, ci->seek_time - 1)) {
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (ov_time_seek(&vf, param)) {
//ci->logf("ov_time_seek failed");
}
+
+ ci->set_elapsed(ov_time_tell(&vf));
ci->seek_complete();
}
@@ -220,7 +220,6 @@ next_track:
/* Change DSP and buffer settings for this bitstream */
if (current_section != previous_section) {
if (!vorbis_set_codec_parameters(&vf)) {
- error = CODEC_ERROR;
goto done;
} else {
previous_section = current_section;
@@ -238,6 +237,7 @@ next_track:
}
}
+ error = CODEC_OK;
done:
#if 0 /* defined(SIMULATOR) */
{
@@ -249,18 +249,12 @@ done:
#endif
ogg_malloc_destroy();
- if (ci->request_next_track()) {
- if (!initialized)
- goto next_track;
- /* Clean things up for the next track */
- vf.dataoffsets = NULL;
- vf.offsets = NULL;
- vf.serialnos = NULL;
- vf.pcmlengths = NULL;
- ov_clear(&vf);
- goto next_track;
- }
-
-exit:
+ /* Clean things up for the next track */
+ vf.dataoffsets = NULL;
+ vf.offsets = NULL;
+ vf.serialnos = NULL;
+ vf.pcmlengths = NULL;
+ ov_clear(&vf);
+
return error;
}
diff --git a/apps/codecs/vox.c b/apps/codecs/vox.c
index c7f39342c3..bf274c6917 100644
--- a/apps/codecs/vox.c
+++ b/apps/codecs/vox.c
@@ -44,9 +44,19 @@ static uint8_t *read_buffer(size_t *realsize)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
uint32_t decodedsamples;
size_t n;
int bufcount;
@@ -54,26 +64,18 @@ enum codec_status codec_main(void)
uint8_t *voxbuf;
off_t firstblockposn = 0; /* position of the first block in file */
const struct pcm_codec *codec;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
-
-next_track:
- status = CODEC_OK;
+ intptr_t param;
if (codec_init()) {
DEBUGF("codec_init() error\n");
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
codec_set_replaygain(ci->id3);
/* Need to save offset for later use (cleared indirectly by advance_buffer) */
bytesdone = ci->id3->offset;
+ ci->seek_buffer(0);
ci->memset(&format, 0, sizeof(struct pcm_format));
@@ -96,20 +98,16 @@ next_track:
if (!codec)
{
DEBUGF("CODEC_ERROR: dialogic oki adpcm codec does not load.\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
- if (!codec->set_format(&format))
- {
- status = CODEC_ERROR;
- goto done;
+ if (!codec->set_format(&format)) {
+ return CODEC_ERROR;
}
if (format.numbytes == 0) {
DEBUGF("CODEC_ERROR: data size is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -118,8 +116,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -131,14 +128,14 @@ next_track:
struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
PCM_SEEK_POS, &read_buffer);
- if (newpos->pos > format.numbytes)
- goto done;
+ if (newpos->pos > format.numbytes) {
+ return CODEC_OK;
+ }
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
} else {
/* already where we need to be */
bytesdone = 0;
@@ -148,22 +145,29 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME,
&read_buffer);
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
@@ -175,11 +179,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(voxbuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(voxbuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -192,10 +195,5 @@ next_track:
ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index e179470f27..42bcc7081f 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -151,9 +151,19 @@ static uint8_t *read_buffer(size_t *realsize)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
uint32_t decodedsamples;
size_t n;
int bufcount;
@@ -163,38 +173,28 @@ enum codec_status codec_main(void)
off_t firstblockposn; /* position of the first block in file */
const struct pcm_codec *codec;
uint32_t size;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
-
-next_track:
- status = CODEC_OK;
+ intptr_t param;
if (codec_init()) {
DEBUGF("codec_init() error\n");
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
codec_set_replaygain(ci->id3);
/* Need to save offset for later use (cleared indirectly by advance_buffer) */
bytesdone = ci->id3->offset;
/* get RIFF chunk header */
+ ci->seek_buffer(0);
buf = ci->request_buffer(&n, 12);
if (n < 12) {
DEBUGF("request_buffer error\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
DEBUGF("CODEC_ERROR: missing riff header\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* advance to first WAVE chunk */
@@ -215,8 +215,7 @@ next_track:
if (n < 8) {
DEBUGF("data chunk request_buffer error\n");
/* no more chunks, 'data' chunk must not have been found */
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* chunkSize */
@@ -225,8 +224,7 @@ next_track:
if (size < 16) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%lu < 16\n",
(unsigned long)size);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* wFormatTag */
format.formattag=buf[8]|(buf[9]<<8);
@@ -256,8 +254,7 @@ next_track:
if (format.size < 22) {
DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is "
"missing extension\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* wValidBitsPerSample */
format.bitspersample = buf[26]|(buf[27]<<8);
@@ -273,8 +270,7 @@ next_track:
{
if (!set_msadpcm_coeffs(buf))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
}
@@ -284,8 +280,7 @@ next_track:
{
DEBUGF("CODEC_ERROR: unsupported wave format 0x%x\n",
(unsigned int) format.formattag);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* riff 8bit linear pcm is unsigned */
@@ -295,8 +290,7 @@ next_track:
/* set format, parse codec specific tag, check format, and calculate chunk size */
if (!codec->set_format(&format))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
} else if (memcmp(buf, "data", 4) == 0) {
format.numbytes = size;
@@ -324,31 +318,26 @@ next_track:
if (!codec)
{
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* common format check */
if (format.channels == 0) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.samplesperblock == 0) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-wSamplesPerBlock file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.blockalign == 0)
{
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-blockalign file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.numbytes == 0) {
DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -358,8 +347,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -369,8 +357,7 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* make sure we're at the correct offset */
@@ -380,13 +367,12 @@ next_track:
PCM_SEEK_POS, &read_buffer);
if (newpos->pos > format.numbytes)
- goto done;
+ return CODEC_OK;
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
} else {
/* already where we need to be */
bytesdone = 0;
@@ -396,22 +382,28 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME,
&read_buffer);
-
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
@@ -423,11 +415,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(wavbuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(wavbuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -440,10 +431,5 @@ next_track:
ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wav64.c b/apps/codecs/wav64.c
index 9dbdab8368..c763e6f7f0 100644
--- a/apps/codecs/wav64.c
+++ b/apps/codecs/wav64.c
@@ -159,9 +159,19 @@ static uint8_t *read_buffer(size_t *realsize)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
- int status;
uint32_t decodedsamples;
size_t n;
int bufcount;
@@ -171,39 +181,29 @@ enum codec_status codec_main(void)
off_t firstblockposn; /* position of the first block in file */
const struct pcm_codec *codec;
uint64_t size;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
-
-next_track:
- status = CODEC_OK;
+ intptr_t param;
if (codec_init()) {
DEBUGF("codec_init() error\n");
- status = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
- if (codec_wait_taginfo() != 0)
- goto done;
-
codec_set_replaygain(ci->id3);
/* Need to save offset for later use (cleared indirectly by advance_buffer) */
bytesdone = ci->id3->offset;
/* get RIFF chunk header */
+ ci->seek_buffer(0);
buf = ci->request_buffer(&n, 40);
if (n < 40) {
DEBUGF("request_buffer error\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if ((memcmp(buf , WAVE64_GUID_RIFF, 16) != 0) ||
(memcmp(buf+24, WAVE64_GUID_WAVE, 16) != 0))
{
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* advance to first WAVE chunk */
@@ -224,8 +224,7 @@ next_track:
if (n < 8) {
DEBUGF("data chunk request_buffer error\n");
/* no more chunks, 'data' chunk must not have been found */
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* chunkSize */
@@ -233,8 +232,7 @@ next_track:
if (memcmp(buf, WAVE64_GUID_FMT, 16) == 0) {
if (size < 16) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk size=%d < 16\n", (int)size);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* wFormatTag */
format.formattag=buf[24]|(buf[25]<<8);
@@ -263,8 +261,7 @@ next_track:
if (format.size < 22) {
DEBUGF("CODEC_ERROR: WAVE_FORMAT_EXTENSIBLE is "
"missing extension\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* wValidBitsPerSample */
format.bitspersample = buf[42]|(buf[43]<<8);
@@ -279,10 +276,7 @@ next_track:
if (format.formattag == WAVE_FORMAT_ADPCM)
{
if (!set_msadpcm_coeffs(buf))
- {
- status = CODEC_ERROR;
- goto done;
- }
+ return CODEC_ERROR;
}
/* get codec */
@@ -291,8 +285,7 @@ next_track:
{
DEBUGF("CODEC_ERROR: unsupported wave format 0x%x\n",
(unsigned int) format.formattag);
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* riff 8bit linear pcm is unsigned */
@@ -301,10 +294,7 @@ next_track:
/* check format, and calculate chunk size */
if (!codec->set_format(&format))
- {
- status = CODEC_ERROR;
- goto done;
- }
+ return CODEC_ERROR;
} else if (memcmp(buf, WAVE64_GUID_DATA, 16) == 0) {
format.numbytes = size;
/* advance to start of data */
@@ -330,31 +320,26 @@ next_track:
if (!codec)
{
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* common format check */
if (format.channels == 0) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-channels file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.samplesperblock == 0) {
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-wSamplesPerBlock file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.blockalign == 0)
{
DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-blockalign file\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
if (format.numbytes == 0) {
DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* check chunksize */
@@ -364,8 +349,7 @@ next_track:
if (format.chunksize == 0)
{
DEBUGF("CODEC_ERROR: chunksize is 0\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
@@ -375,8 +359,7 @@ next_track:
ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
} else {
DEBUGF("CODEC_ERROR: more than 2 channels\n");
- status = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* make sure we're at the correct offset */
@@ -385,14 +368,14 @@ next_track:
struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
PCM_SEEK_POS, &read_buffer);
- if (newpos->pos > format.numbytes)
- goto done;
+ if (newpos->pos > format.numbytes) {
+ return CODEC_OK;
+ }
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
- ci->seek_complete();
} else {
/* already where we need to be */
bytesdone = 0;
@@ -402,22 +385,29 @@ next_track:
endofstream = 0;
while (!endofstream) {
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
break;
- }
- if (ci->seek_time) {
- struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ struct pcm_pos *newpos = codec->get_seek_pos(param, PCM_SEEK_TIME,
&read_buffer);
if (newpos->pos > format.numbytes)
+ {
+ ci->set_elapsed(ci->id3->length);
+ ci->seek_complete();
break;
+ }
+
if (ci->seek_buffer(firstblockposn + newpos->pos))
{
bytesdone = newpos->pos;
decodedsamples = newpos->samples;
}
+
+ ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
ci->seek_complete();
}
@@ -429,11 +419,10 @@ next_track:
endofstream = 1;
}
- status = codec->decode(wavbuf, n, samples, &bufcount);
- if (status == CODEC_ERROR)
+ if (codec->decode(wavbuf, n, samples, &bufcount) == CODEC_ERROR)
{
DEBUGF("codec error\n");
- goto done;
+ return CODEC_ERROR;
}
ci->pcmbuf_insert(samples, NULL, bufcount);
@@ -445,12 +434,6 @@ next_track:
endofstream = 1;
ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
}
- status = CODEC_OK;
-
-done:
- if (ci->request_next_track())
- goto next_track;
-exit:
- return status;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wav_enc.c b/apps/codecs/wav_enc.c
index ef1a88ec23..e4afeaf93c 100644
--- a/apps/codecs/wav_enc.c
+++ b/apps/codecs/wav_enc.c
@@ -345,40 +345,42 @@ static bool init_encoder(void)
return true;
} /* init_encoder */
-/* main codec entry point */
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- if (!init_encoder())
- return CODEC_ERROR;
+ if (reason == CODEC_LOAD) {
+ if (!init_encoder())
+ return CODEC_ERROR;
+ }
+ else if (reason == CODEC_UNLOAD) {
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(NULL);
+ }
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
/* main encoding loop */
- while(!ci->stop_codec)
+ while(ci->get_command(NULL) != CODEC_ACTION_HALT)
{
- uint32_t *src;
+ uint32_t *src = (uint32_t *)ci->enc_get_pcm_data(PCM_CHUNK_SIZE);
+ struct enc_chunk_hdr *chunk;
- while ((src = (uint32_t *)ci->enc_get_pcm_data(PCM_CHUNK_SIZE)) != NULL)
- {
- struct enc_chunk_hdr *chunk;
-
- if (ci->stop_codec)
- break;
+ if(src == NULL)
+ continue;
- chunk = ci->enc_get_chunk();
- chunk->enc_size = enc_size;
- chunk->num_pcm = PCM_SAMP_PER_CHUNK;
- chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
+ chunk = ci->enc_get_chunk();
+ chunk->enc_size = enc_size;
+ chunk->num_pcm = PCM_SAMP_PER_CHUNK;
+ chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
- chunk_to_wav_format(src, (uint32_t *)chunk->enc_data);
+ chunk_to_wav_format(src, (uint32_t *)chunk->enc_data);
- ci->enc_finish_chunk();
- ci->yield();
- }
-
- ci->yield();
+ ci->enc_finish_chunk();
}
- /* reset parameters to initial state */
- ci->enc_set_parameters(NULL);
-
return CODEC_OK;
-} /* codec_start */
+}
diff --git a/apps/codecs/wavpack.c b/apps/codecs/wavpack.c
index d27a9fb621..ccb9f41190 100644
--- a/apps/codecs/wavpack.c
+++ b/apps/codecs/wavpack.c
@@ -31,39 +31,39 @@ static int32_t temp_buffer [BUFFER_SIZE] IBSS_ATTR;
static int32_t read_callback (void *buffer, int32_t bytes)
{
int32_t retval = ci->read_filebuf (buffer, bytes);
- ci->id3->offset = ci->curpos;
+ ci->set_offset(ci->curpos);
return retval;
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
WavpackContext *wpc;
char error [80];
int bps, nchans, sr_100;
- int retval;
+ intptr_t param;
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
+ if (codec_init())
+ return CODEC_ERROR;
-next_track:
- retval = CODEC_OK;
+ ci->seek_buffer (ci->id3->offset);
- if (codec_init()) {
- retval = CODEC_ERROR;
- goto exit;
- }
-
- if (codec_wait_taginfo() != 0)
- goto done;
-
/* Create a decoder instance */
wpc = WavpackOpenFileInput (read_callback, error);
- if (!wpc) {
- retval = CODEC_ERROR;
- goto done;
- }
+ if (!wpc)
+ return CODEC_ERROR;
ci->configure(DSP_SWITCH_FREQUENCY, WavpackGetSampleRate (wpc));
codec_set_replaygain(ci->id3);
@@ -77,56 +77,48 @@ next_track:
/* The main decoder loop */
while (1) {
- int32_t nsamples;
+ int32_t nsamples;
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ break;
- if (ci->seek_time && ci->taginfo_ready && ci->id3->length) {
- ci->seek_time--;
+ if (action == CODEC_ACTION_SEEK_TIME) {
int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10;
int n, d, skip;
- if (ci->seek_time > curpos_ms) {
- n = ci->seek_time - curpos_ms;
+ if (param > curpos_ms) {
+ n = param - curpos_ms;
d = ci->id3->length - curpos_ms;
skip = (int)((int64_t)(ci->filesize - ci->curpos) * n / d);
ci->seek_buffer (ci->curpos + skip);
}
- else {
- n = curpos_ms - ci->seek_time;
+ else if (curpos_ms != 0) {
+ n = curpos_ms - param;
d = curpos_ms;
skip = (int)((int64_t) ci->curpos * n / d);
ci->seek_buffer (ci->curpos - skip);
}
wpc = WavpackOpenFileInput (read_callback, error);
- ci->seek_complete();
-
if (!wpc)
+ {
+ ci->seek_complete();
break;
+ }
ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10);
- ci->yield ();
+ ci->seek_complete();
}
nsamples = WavpackUnpackSamples (wpc, temp_buffer, BUFFER_SIZE / nchans);
- if (!nsamples || ci->stop_codec || ci->new_track)
- break;
-
- ci->yield ();
-
- if (ci->stop_codec || ci->new_track)
+ if (!nsamples)
break;
ci->pcmbuf_insert (temp_buffer, NULL, nsamples);
-
ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10);
- ci->yield ();
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
-exit:
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wavpack_enc.c b/apps/codecs/wavpack_enc.c
index d908e284be..730cf0734b 100644
--- a/apps/codecs/wavpack_enc.c
+++ b/apps/codecs/wavpack_enc.c
@@ -389,77 +389,79 @@ static bool init_encoder(void)
return true;
} /* init_encoder */
-enum codec_status codec_main(void)
+/* this is the codec entry point */
+enum codec_status codec_main(enum codec_entry_call_reason reason)
{
- /* initialize params and config */
- if (!init_encoder())
- return CODEC_ERROR;
+ if (reason == CODEC_LOAD) {
+ /* initialize params and config */
+ if (!init_encoder())
+ return CODEC_ERROR;
+ }
+ else if (reason == CODEC_UNLOAD) {
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(NULL);
+ }
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
+{
/* main encoding loop */
- while(!ci->stop_codec)
+ while(ci->get_command(NULL) != CODEC_ACTION_HALT)
{
- uint8_t *src;
+ uint8_t *src = (uint8_t *)ci->enc_get_pcm_data(PCM_CHUNK_SIZE);
+ struct enc_chunk_hdr *chunk;
+ bool abort_chunk;
+ uint8_t *dst;
+ uint8_t *src_end;
- while ((src = ci->enc_get_pcm_data(PCM_CHUNK_SIZE)) != NULL)
- {
- struct enc_chunk_hdr *chunk;
- bool abort_chunk;
- uint8_t *dst;
- uint8_t *src_end;
-
- if(ci->stop_codec)
- break;
-
- abort_chunk = true;
+ if(src == NULL)
+ continue;
- chunk = ci->enc_get_chunk();
+ chunk = ci->enc_get_chunk();
- /* reset counts and pointer */
- chunk->enc_size = 0;
- chunk->num_pcm = 0;
- chunk->enc_data = NULL;
+ /* reset counts and pointer */
+ chunk->enc_size = 0;
+ chunk->num_pcm = 0;
+ chunk->enc_data = NULL;
- dst = ENC_CHUNK_SKIP_HDR(dst, chunk);
+ dst = ENC_CHUNK_SKIP_HDR(dst, chunk);
- WavpackStartBlock(wpc, dst, dst + data_size);
+ WavpackStartBlock(wpc, dst, dst + data_size);
- chunk_to_int32((uint32_t*)src);
- src = input_buffer;
- src_end = src + input_size;
+ chunk_to_int32((uint32_t*)src);
+ src = input_buffer;
+ src_end = src + input_size;
- /* encode chunk in four steps yielding between each */
- do
+ /* encode chunk in four steps yielding between each */
+ do
+ {
+ abort_chunk = true;
+ if (WavpackPackSamples(wpc, (int32_t *)src,
+ PCM_SAMP_PER_CHUNK/4))
{
- if (WavpackPackSamples(wpc, (int32_t *)src,
- PCM_SAMP_PER_CHUNK/4))
- {
- chunk->num_pcm += PCM_SAMP_PER_CHUNK/4;
- ci->yield();
- /* could've been stopped in some way */
- abort_chunk = ci->stop_codec ||
- (chunk->flags & CHUNKF_ABORT);
- }
-
- src += input_step;
+ chunk->num_pcm += PCM_SAMP_PER_CHUNK/4;
+ ci->yield();
+ /* could've been stopped in some way */
+ abort_chunk = chunk->flags & CHUNKF_ABORT;
}
- while (!abort_chunk && src < src_end);
- if (!abort_chunk)
- {
- chunk->enc_data = dst;
- if (chunk->num_pcm < PCM_SAMP_PER_CHUNK)
- ci->enc_unget_pcm_data(PCM_CHUNK_SIZE - chunk->num_pcm*4);
- /* finish the chunk and store chunk size info */
- chunk->enc_size = WavpackFinishBlock(wpc);
- ci->enc_finish_chunk();
- }
+ src += input_step;
}
+ while (!abort_chunk && src < src_end);
- ci->yield();
+ if (!abort_chunk)
+ {
+ chunk->enc_data = dst;
+ if (chunk->num_pcm < PCM_SAMP_PER_CHUNK)
+ ci->enc_unget_pcm_data(PCM_CHUNK_SIZE - chunk->num_pcm*4);
+ /* finish the chunk and store chunk size info */
+ chunk->enc_size = WavpackFinishBlock(wpc);
+ ci->enc_finish_chunk();
+ }
}
- /* reset parameters to initial state */
- ci->enc_set_parameters(NULL);
-
return CODEC_OK;
-} /* codec_start */
+}
diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c
index 1b46813444..c327fafb5a 100644
--- a/apps/codecs/wma.c
+++ b/apps/codecs/wma.c
@@ -29,53 +29,52 @@ CODEC_HEADER
static WMADecodeContext wmadec;
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
uint32_t elapsedtime;
- int retval;
asf_waveformatex_t wfx;
size_t resume_offset;
int i;
- int wmares, res;
+ int wmares;
+ int res = 0;
uint8_t* audiobuf;
int audiobufsize;
int packetlength = 0;
int errcount = 0;
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
-
-next_track:
- retval = CODEC_OK;
+ intptr_t param;
/* Proper reset of the decoder context. */
memset(&wmadec, 0, sizeof(wmadec));
- /* Wait for the metadata to be read */
- if (codec_wait_taginfo() != 0)
- goto done;
-
/* Remember the resume position - when the codec is opened, the
playback engine will reset it. */
resume_offset = ci->id3->offset;
restart_track:
- retval = CODEC_OK;
-
if (codec_init()) {
LOGF("WMA: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
/* Copy the format metadata we've stored in the id3 TOC field. This
saves us from parsing it again here. */
memcpy(&wfx, ci->id3->toc, sizeof(wfx));
+ ci->seek_buffer(ci->id3->first_frame_offset);
if (wma_decode_init(&wmadec,&wfx) < 0) {
LOGF("WMA: Unsupported or corrupt file\n");
- retval = CODEC_ERROR;
- goto exit;
+ return CODEC_ERROR;
}
if (resume_offset > ci->id3->first_frame_offset)
@@ -101,34 +100,35 @@ restart_track:
codec_set_replaygain(ci->id3);
/* The main decoding loop */
-
- res = 1;
while (res >= 0)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
- goto done;
- }
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ break;
/* Deal with any pending seek requests */
- if (ci->seek_time){
+ if (action == CODEC_ACTION_SEEK_TIME) {
- if (ci->seek_time == 1) {
+ if (param == 0) {
+ ci->set_elapsed(0);
ci->seek_complete();
goto restart_track; /* Pretend you never saw this... */
}
- elapsedtime = asf_seek(ci->seek_time, &wfx);
+ elapsedtime = asf_seek(param, &wfx);
if (elapsedtime < 1){
+ ci->set_elapsed(0);
ci->seek_complete();
- goto next_track;
+ break;
}
/*DEBUGF("Seek returned %d\n", (int)elapsedtime);*/
- ci->set_elapsed(elapsedtime);
/*flush the wma decoder state*/
wmadec.last_superframe_len = 0;
wmadec.last_bitoffset = 0;
+
+ ci->set_elapsed(elapsedtime);
ci->seek_complete();
}
errcount = 0;
@@ -140,10 +140,15 @@ new_packet:
* times. If we succeed, the error counter will be reset.
*/
+ if (res == ASF_ERROR_EOF) {
+ /* File ended - not an error */
+ break;
+ }
+
errcount++;
DEBUGF("read_packet error %d, errcount %d\n",wmares, errcount);
if (errcount > 5) {
- goto done;
+ return CODEC_ERROR;
} else {
ci->advance_buffer(packetlength);
goto new_packet;
@@ -163,7 +168,7 @@ new_packet:
errcount++;
DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount);
if (errcount > 5) {
- goto done;
+ return CODEC_ERROR;
} else {
ci->advance_buffer(packetlength);
goto new_packet;
@@ -173,18 +178,12 @@ new_packet:
elapsedtime += (wmares*10)/(wfx.rate/100);
ci->set_elapsed(elapsedtime);
}
- ci->yield();
}
}
ci->advance_buffer(packetlength);
}
-done:
/*LOGF("WMA: Decoded %ld samples\n",elapsedtime*wfx.rate/1000);*/
-
- if (ci->request_next_track())
- goto next_track;
-exit:
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wmapro.c b/apps/codecs/wmapro.c
index c02dddeeb3..b6a8e47f25 100644
--- a/apps/codecs/wmapro.c
+++ b/apps/codecs/wmapro.c
@@ -27,11 +27,22 @@ CODEC_HEADER
int32_t *dec[2]; /* pointers to the output buffers in WMAProDecodeCtx in wmaprodec.c */
+
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, WMAPRO_DSP_SAMPLE_DEPTH);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
uint32_t elapsedtime;
- int retval;
asf_waveformatex_t wfx; /* Holds the stream properties */
size_t resume_offset;
int res; /* Return values from asf_read_packet() and decode_packet() */
@@ -42,28 +53,15 @@ enum codec_status codec_main(void)
int pktcnt = 0; /* Count of the packets played */
uint8_t *data; /* Pointer to decoder input buffer */
int size; /* Size of the input frame to the decoder */
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, WMAPRO_DSP_SAMPLE_DEPTH);
-
-
-next_track:
- retval = CODEC_OK;
-
- /* Wait for the metadata to be read */
- if (codec_wait_taginfo() != 0)
- goto done;
+ intptr_t param;
/* Remember the resume position */
resume_offset = ci->id3->offset;
restart_track:
- retval = CODEC_OK;
-
if (codec_init()) {
LOGF("(WMA PRO) Error: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Copy the format metadata we've stored in the id3 TOC field. This
@@ -77,8 +75,7 @@ restart_track:
if (decode_init(&wfx) < 0) {
LOGF("(WMA PRO) Error: Unsupported or corrupt file\n");
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Now advance the file position to the first frame */
@@ -91,23 +88,24 @@ restart_track:
while (pktcnt < wfx.numpackets)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
- goto done;
- }
-
- /* Deal with any pending seek requests */
- if (ci->seek_time){
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ break;
- if (ci->seek_time == 1) {
+ /* Deal with any pending seek requests */
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ if (param == 0) {
+ ci->set_elapsed(0);
ci->seek_complete();
goto restart_track; /* Pretend you never saw this... */
}
- elapsedtime = asf_seek(ci->seek_time, &wfx);
+ elapsedtime = asf_seek(param, &wfx);
if (elapsedtime < 1){
+ ci->set_elapsed(0);
ci->seek_complete();
- goto next_track;
+ break;
}
ci->set_elapsed(elapsedtime);
@@ -117,8 +115,8 @@ restart_track:
res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &wfx);
if (res < 0) {
- LOGF("(WMA PRO) Warning: asf_read_packet returned %d", res);
- goto done;
+ LOGF("(WMA PRO) Warning: asf_read_packet returned %d", res);
+ return CODEC_ERROR;
} else {
data = audiobuf;
size = audiobufsize;
@@ -132,7 +130,7 @@ restart_track:
res = decode_packet(&wfx, dec, &outlen, data, size);
if(res < 0) {
LOGF("(WMA PRO) Error: decode_packet returned %d", res);
- goto done;
+ return CODEC_ERROR;
}
data += res;
size -= res;
@@ -152,10 +150,6 @@ restart_track:
ci->advance_buffer(packetlength);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
- return retval;
+ return CODEC_OK;
}
diff --git a/apps/codecs/wmavoice.c b/apps/codecs/wmavoice.c
index ddf66828f1..64c8cd1692 100644
--- a/apps/codecs/wmavoice.c
+++ b/apps/codecs/wmavoice.c
@@ -52,10 +52,20 @@ static void init_codec_ctx(AVCodecContext *avctx, asf_waveformatex_t *wfx)
}
/* this is the codec entry point */
-enum codec_status codec_main(void)
+enum codec_status codec_main(enum codec_entry_call_reason reason)
+{
+ if (reason == CODEC_LOAD) {
+ /* Generic codec initialisation */
+ ci->configure(DSP_SET_SAMPLE_DEPTH, 31);
+ }
+
+ return CODEC_OK;
+}
+
+/* this is called for each file to process */
+enum codec_status codec_run(void)
{
uint32_t elapsedtime;
- int retval;
asf_waveformatex_t wfx; /* Holds the stream properties */
size_t resume_offset;
int res; /* Return values from asf_read_packet() and decode_packet() */
@@ -64,27 +74,14 @@ enum codec_status codec_main(void)
int packetlength = 0; /* Logical packet size (minus the header size) */
int outlen = 0; /* Number of bytes written to the output buffer */
int pktcnt = 0; /* Count of the packets played */
-
- /* Generic codec initialisation */
- ci->configure(DSP_SET_SAMPLE_DEPTH, 31);
-
-
-next_track:
- retval = CODEC_OK;
-
- /* Wait for the metadata to be read */
- if (codec_wait_taginfo() != 0)
- goto done;
+ intptr_t param;
/* Remember the resume position */
resume_offset = ci->id3->offset;
restart_track:
- retval = CODEC_OK;
-
if (codec_init()) {
LOGF("(WMA Voice) Error: Error initialising codec\n");
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Copy the format metadata we've stored in the id3 TOC field. This
@@ -97,14 +94,15 @@ restart_track:
ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ?
STEREO_MONO : STEREO_INTERLEAVED);
codec_set_replaygain(ci->id3);
+
+ ci->seek_buffer(0);
/* Initialise the AVCodecContext */
init_codec_ctx(&avctx, &wfx);
if (wmavoice_decode_init(&avctx) < 0) {
LOGF("(WMA Voice) Error: Unsupported or corrupt file\n");
- retval = CODEC_ERROR;
- goto done;
+ return CODEC_ERROR;
}
/* Now advance the file position to the first frame */
@@ -117,21 +115,24 @@ restart_track:
while (pktcnt < wfx.numpackets)
{
- ci->yield();
- if (ci->stop_codec || ci->new_track) {
- goto done;
- }
-
+ enum codec_command_action action = ci->get_command(&param);
+
+ if (action == CODEC_ACTION_HALT)
+ break;
+
/* Deal with any pending seek requests */
- if (ci->seek_time){
+ if (action == CODEC_ACTION_SEEK_TIME) {
+ ci->set_elapsed(param);
- if (ci->seek_time == 1) {
+ if (param == 0) {
+ ci->set_elapsed(0);
ci->seek_complete();
goto restart_track; /* Pretend you never saw this... */
}
- elapsedtime = asf_seek(ci->seek_time, &wfx);
+ elapsedtime = asf_seek(param, &wfx);
if (elapsedtime < 1){
+ ci->set_elapsed(0);
ci->seek_complete();
goto next_track;
}
@@ -145,7 +146,7 @@ new_packet:
if (res < 0) {
LOGF("(WMA Voice) read_packet error %d\n",res);
- goto done;
+ return CODEC_ERROR;
} else {
avpkt.data = audiobuf;
avpkt.size = audiobufsize;
@@ -165,8 +166,9 @@ new_packet:
ci->advance_buffer(packetlength);
goto new_packet;
}
- else
- goto done;
+ else {
+ return CODEC_ERROR;
+ }
}
avpkt.data += res;
avpkt.size -= res;
@@ -186,10 +188,6 @@ new_packet:
ci->advance_buffer(packetlength);
}
-done:
- if (ci->request_next_track())
- goto next_track;
-
- return retval;
+ return CODEC_OK;
}