summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/audio_thread.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-07 05:17:28 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-07 05:17:28 +0000
commit39107956ab680b37ade979e5379cf98a06604b13 (patch)
tree156c4197b5ad0d99c165e07d81da7a3e1d3671b1 /apps/plugins/mpegplayer/audio_thread.c
parentb1a1831a17b17574b8a201dfcb348714772068b8 (diff)
downloadrockbox-39107956ab680b37ade979e5379cf98a06604b13.zip
rockbox-39107956ab680b37ade979e5379cf98a06604b13.tar.gz
rockbox-39107956ab680b37ade979e5379cf98a06604b13.tar.bz2
rockbox-39107956ab680b37ade979e5379cf98a06604b13.tar.xz
MPEGPlyaer: A bit of audio mutation. Remove a useless thread state. Take some control over the buffer away from the audio thread itself. Some atomicity corrections.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28984 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/mpegplayer/audio_thread.c')
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 9e39680..ecb8b1f 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -112,7 +112,7 @@ static inline void audiodesc_queue_add_tail(void)
audio_queue.write++;
}
-/* Increments the queue tail position - leaves one slot as current */
+/* Increments the queue head position - leaves one slot as current */
static inline bool audiodesc_queue_remove_head(void)
{
if (audio_queue.write == audio_queue.read)
@@ -375,8 +375,6 @@ static void audio_thread_msg(struct audio_thread_data *td)
case TSTATE_INIT:
td->state = TSTATE_DECODE;
case TSTATE_DECODE:
- case TSTATE_RENDER_WAIT:
- case TSTATE_RENDER_WAIT_END:
break;
case TSTATE_EOS:
@@ -455,7 +453,6 @@ static void audio_thread_msg(struct audio_thread_data *td)
{
case TSTATE_DECODE:
case TSTATE_RENDER_WAIT:
- case TSTATE_RENDER_WAIT_END:
/* These return when in playing state */
return;
}
@@ -512,7 +509,6 @@ static void audio_thread(void)
/* These states are the only ones that should return */
case TSTATE_DECODE: goto audio_decode;
case TSTATE_RENDER_WAIT: goto render_wait;
- case TSTATE_RENDER_WAIT_END: goto render_wait_end;
/* Anything else is interpreted as an exit */
default:
{
@@ -538,29 +534,28 @@ static void audio_thread(void)
case STREAM_DATA_END:
{
if (audio_queue.used > MAD_BUFFER_GUARD)
- break;
+ break; /* Still have frames to decode */
- /* Used up remainder of compressed audio buffer.
- * Force any residue to play if audio ended before
- * reaching the threshold */
- td.state = TSTATE_RENDER_WAIT_END;
+ /* Used up remainder of compressed audio buffer. Wait for
+ * samples on PCM buffer to finish playing. */
audio_queue_reset();
- render_wait_end:
- pcm_output_drain();
-
- while (pcm_output_used() > (ssize_t)PCMOUT_LOW_WM)
+ while (1)
{
+ if (pcm_output_empty())
+ {
+ td.state = TSTATE_EOS;
+ stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
+ break;
+ }
+
+ pcm_output_drain();
str_get_msg_w_tmo(&audio_str, &td.ev, 1);
+
if (td.ev.id != SYS_TIMEOUT)
- goto message_process;
+ break;
}
- td.state = TSTATE_EOS;
- if (td.status == STREAM_PLAYING)
- stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
-
- rb->yield();
goto message_wait;
} /* STREAM_DATA_END: */
}
@@ -606,11 +601,9 @@ static void audio_thread(void)
/* This is too hard - bail out */
td.state = TSTATE_EOS;
-
- if (td.status == STREAM_PLAYING)
- stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
-
td.status = STREAM_ERROR;
+ stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
+
goto message_wait;
}
@@ -643,15 +636,15 @@ static void audio_thread(void)
render_wait:
if (synth.pcm.length > 0)
{
- struct pcm_frame_header *dst_hdr = pcm_output_get_buffer();
const char *src[2] =
{ (char *)synth.pcm.samples[0], (char *)synth.pcm.samples[1] };
int out_count = (synth.pcm.length * CLOCK_RATE
+ (td.samplerate - 1)) / td.samplerate;
- ssize_t size = sizeof(*dst_hdr) + out_count*4;
+ unsigned char *out_buf;
+ ssize_t size = out_count*4;
/* Wait for required amount of free buffer space */
- while (pcm_output_free() < size)
+ while ((out_buf = pcm_output_get_buffer(&size)) == NULL)
{
/* Wait one frame */
int timeout = out_count*HZ / td.samplerate;
@@ -660,21 +653,17 @@ static void audio_thread(void)
goto message_process;
}
- out_count = rb->dsp_process(td.dsp, dst_hdr->data, src,
- synth.pcm.length);
+ out_count = rb->dsp_process(td.dsp, out_buf, src, synth.pcm.length);
if (out_count <= 0)
break;
- dst_hdr->size = sizeof(*dst_hdr) + out_count*4;
- dst_hdr->time = audio_queue.curr->time;
+ /* Make this data available to DMA */
+ pcm_output_commit_data(out_count*4, audio_queue.curr->time);
/* As long as we're on this timestamp, the time is just
incremented by the number of samples */
audio_queue.curr->time += out_count;
-
- /* Make this data available to DMA */
- pcm_output_add_data();
}
rb->yield();