diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-07 05:17:28 +0000 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-07 05:17:28 +0000 |
| commit | 39107956ab680b37ade979e5379cf98a06604b13 (patch) | |
| tree | 156c4197b5ad0d99c165e07d81da7a3e1d3671b1 /apps/plugins/mpegplayer/audio_thread.c | |
| parent | b1a1831a17b17574b8a201dfcb348714772068b8 (diff) | |
| download | rockbox-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.c | 57 |
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(); |