mpegplayer: Use the core DSP to process audio. Removes the sample rate restriction...
[kugel-rb.git] / apps / plugins / mpegplayer / audio_thread.c
blob2bb766ad885bbf657eddb429193a7bc3c852812a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * mpegplayer audio thread implementation
12 * Copyright (c) 2007 Michael Sevakis
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "mpegplayer.h"
23 #include "../../codecs/libmad/bit.h"
24 #include "../../codecs/libmad/mad.h"
26 /** Audio stream and thread **/
27 struct pts_queue_slot;
28 struct audio_thread_data
30 struct queue_event ev; /* Our event queue to receive commands */
31 int state; /* Thread state */
32 int status; /* Media status (STREAM_PLAYING, etc.) */
33 int mad_errors; /* A count of the errors in each frame */
34 unsigned samplerate; /* Current stream sample rate */
35 int nchannels; /* Number of audio channels */
36 struct dsp_config *dsp; /* The DSP we're using */
39 /* The audio stack is stolen from the core codec thread (but not in uisim) */
40 /* Used for stealing codec thread's stack */
41 static uint32_t* audio_stack;
42 static size_t audio_stack_size; /* Keep gcc happy and init */
43 #define AUDIO_STACKSIZE (9*1024)
44 #ifndef SIMULATOR
45 static uint32_t codec_stack_copy[AUDIO_STACKSIZE / sizeof(uint32_t)];
46 #endif
47 static struct event_queue audio_str_queue NOCACHEBSS_ATTR;
48 static struct queue_sender_list audio_str_queue_send NOCACHEBSS_ATTR;
49 struct stream audio_str IBSS_ATTR;
51 /* libmad related definitions */
52 static struct mad_stream stream IBSS_ATTR;
53 static struct mad_frame frame IBSS_ATTR;
54 static struct mad_synth synth IBSS_ATTR;
56 /* 2567 bytes */
57 static unsigned char mad_main_data[MAD_BUFFER_MDLEN];
59 /* There isn't enough room for this in IRAM on PortalPlayer, but there
60 is for Coldfire. */
62 /* 4608 bytes */
63 #ifdef CPU_COLDFIRE
64 static mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR;
65 #else
66 static mad_fixed_t mad_frame_overlap[2][32][18];
67 #endif
69 /** A queue for saving needed information about MPEG audio packets **/
70 #define AUDIODESC_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient -
71 if not, the case is handled */
72 #define AUDIODESC_QUEUE_MASK (AUDIODESC_QUEUE_LEN-1)
73 struct audio_frame_desc
75 uint32_t time; /* Time stamp for packet in audio ticks */
76 ssize_t size; /* Number of unprocessed bytes left in packet */
79 /* This starts out wr == rd but will never be emptied to zero during
80 streaming again in order to support initializing the first packet's
81 timestamp without a special case */
82 struct
84 /* Compressed audio data */
85 uint8_t *start; /* Start of encoded audio buffer */
86 uint8_t *ptr; /* Pointer to next encoded audio data */
87 ssize_t used; /* Number of bytes in MPEG audio buffer */
88 /* Compressed audio data descriptors */
89 unsigned read, write;
90 struct audio_frame_desc *curr; /* Current slot */
91 struct audio_frame_desc descs[AUDIODESC_QUEUE_LEN];
92 } audio_queue;
94 static inline int audiodesc_queue_count(void)
96 return audio_queue.write - audio_queue.read;
99 static inline bool audiodesc_queue_full(void)
101 return audio_queue.used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD ||
102 audiodesc_queue_count() >= AUDIODESC_QUEUE_LEN;
105 /* Increments the queue tail postion - should be used to preincrement */
106 static inline void audiodesc_queue_add_tail(void)
108 if (audiodesc_queue_full())
110 DEBUGF("audiodesc_queue_add_tail: audiodesc queue full!\n");
111 return;
114 audio_queue.write++;
117 /* Increments the queue tail position - leaves one slot as current */
118 static inline bool audiodesc_queue_remove_head(void)
120 if (audio_queue.write == audio_queue.read)
121 return false;
123 audio_queue.read++;
124 return true;
127 /* Returns the "tail" at the index just behind the write index */
128 static inline struct audio_frame_desc * audiodesc_queue_tail(void)
130 return &audio_queue.descs[(audio_queue.write - 1) & AUDIODESC_QUEUE_MASK];
133 /* Returns a pointer to the current head */
134 static inline struct audio_frame_desc * audiodesc_queue_head(void)
136 return &audio_queue.descs[audio_queue.read & AUDIODESC_QUEUE_MASK];
139 /* Resets the pts queue - call when starting and seeking */
140 static void audio_queue_reset(void)
142 audio_queue.ptr = audio_queue.start;
143 audio_queue.used = 0;
144 audio_queue.read = 0;
145 audio_queue.write = 0;
146 rb->memset(audio_queue.descs, 0, sizeof (audio_queue.descs));
147 audio_queue.curr = audiodesc_queue_head();
150 static void audio_queue_advance_pos(ssize_t len)
152 audio_queue.ptr += len;
153 audio_queue.used -= len;
154 audio_queue.curr->size -= len;
157 static int audio_buffer(struct stream *str, enum stream_parse_mode type)
159 int ret = STREAM_OK;
161 /* Carry any overshoot to the next size since we're technically
162 -size bytes into it already. If size is negative an audio
163 frame was split across packets. Old has to be saved before
164 moving the head. */
165 if (audio_queue.curr->size <= 0 && audiodesc_queue_remove_head())
167 struct audio_frame_desc *old = audio_queue.curr;
168 audio_queue.curr = audiodesc_queue_head();
169 audio_queue.curr->size += old->size;
170 old->size = 0;
173 /* Add packets to compressed audio buffer until it's full or the
174 * timestamp queue is full - whichever happens first */
175 while (!audiodesc_queue_full())
177 ret = parser_get_next_data(str, type);
178 struct audio_frame_desc *curr;
179 ssize_t len;
181 if (ret != STREAM_OK)
182 break;
184 /* Get data from next audio packet */
185 len = str->curr_packet_end - str->curr_packet;
187 if (str->pkt_flags & PKT_HAS_TS)
189 audiodesc_queue_add_tail();
190 curr = audiodesc_queue_tail();
191 curr->time = TS_TO_TICKS(str->pts);
192 /* pts->size should have been zeroed when slot was
193 freed */
195 else
197 /* Add to the one just behind the tail - this may be
198 * the head or the previouly added tail - whether or
199 * not we'll ever reach this is quite in question
200 * since audio always seems to have every packet
201 * timestamped */
202 curr = audiodesc_queue_tail();
205 curr->size += len;
207 /* Slide any remainder over to beginning */
208 if (audio_queue.ptr > audio_queue.start && audio_queue.used > 0)
210 rb->memmove(audio_queue.start, audio_queue.ptr,
211 audio_queue.used);
214 /* Splice this packet onto any remainder */
215 rb->memcpy(audio_queue.start + audio_queue.used,
216 str->curr_packet, len);
218 audio_queue.used += len;
219 audio_queue.ptr = audio_queue.start;
221 rb->yield();
224 return ret;
227 /* Initialise libmad */
228 static void init_mad(void)
230 mad_stream_init(&stream);
231 mad_frame_init(&frame);
232 mad_synth_init(&synth);
234 /* We do this so libmad doesn't try to call codec_calloc() */
235 rb->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
236 frame.overlap = (void *)mad_frame_overlap;
238 rb->memset(mad_main_data, 0, sizeof(mad_main_data));
239 stream.main_data = &mad_main_data;
242 /* Sync audio stream to a particular frame - see main decoder loop for
243 * detailed remarks */
244 static int audio_sync(struct audio_thread_data *td,
245 struct str_sync_data *sd)
247 int retval = STREAM_MATCH;
248 uint32_t sdtime = TS_TO_TICKS(clip_time(&audio_str, sd->time));
249 uint32_t time;
250 uint32_t duration = 0;
251 struct stream *str;
252 struct stream tmp_str;
253 struct mad_header header;
254 struct mad_stream stream;
256 if (td->ev.id == STREAM_SYNC)
258 /* Actually syncing for playback - use real stream */
259 time = 0;
260 str = &audio_str;
262 else
264 /* Probing - use temp stream */
265 time = INVALID_TIMESTAMP;
266 str = &tmp_str;
267 str->id = audio_str.id;
270 str->hdr.pos = sd->sk.pos;
271 str->hdr.limit = sd->sk.pos + sd->sk.len;
273 mad_stream_init(&stream);
274 mad_header_init(&header);
276 while (1)
278 if (audio_buffer(str, STREAM_PM_RANDOM_ACCESS) == STREAM_DATA_END)
280 DEBUGF("audio_sync:STR_DATA_END\n aqu:%ld swl:%ld swr:%ld\n",
281 audio_queue.used, str->hdr.win_left, str->hdr.win_right);
282 if (audio_queue.used <= MAD_BUFFER_GUARD)
283 goto sync_data_end;
286 stream.error = 0;
287 mad_stream_buffer(&stream, audio_queue.ptr, audio_queue.used);
289 if (stream.sync && mad_stream_sync(&stream) < 0)
291 DEBUGF(" audio: mad_stream_sync failed\n");
292 audio_queue_advance_pos(MAX(audio_queue.curr->size - 1, 1));
293 continue;
296 stream.sync = 0;
298 if (mad_header_decode(&header, &stream) < 0)
300 DEBUGF(" audio: mad_header_decode failed:%s\n",
301 mad_stream_errorstr(&stream));
302 audio_queue_advance_pos(1);
303 continue;
306 duration = 32*MAD_NSBSAMPLES(&header);
307 time = audio_queue.curr->time;
309 DEBUGF(" audio: ft:%u t:%u fe:%u nsamp:%u sampr:%u\n",
310 (unsigned)TICKS_TO_TS(time), (unsigned)sd->time,
311 (unsigned)TICKS_TO_TS(time + duration),
312 (unsigned)duration, header.samplerate);
314 audio_queue_advance_pos(stream.this_frame - audio_queue.ptr);
316 if (time <= sdtime && sdtime < time + duration)
318 DEBUGF(" audio: ft<=t<fe\n");
319 retval = STREAM_PERFECT_MATCH;
320 break;
322 else if (time > sdtime)
324 DEBUGF(" audio: ft>t\n");
325 break;
328 audio_queue_advance_pos(stream.next_frame - audio_queue.ptr);
329 audio_queue.curr->time += duration;
331 rb->yield();
334 sync_data_end:
335 if (td->ev.id == STREAM_FIND_END_TIME)
337 if (time != INVALID_TIMESTAMP)
339 time = TICKS_TO_TS(time);
340 duration = TICKS_TO_TS(duration);
341 sd->time = time + duration;
342 retval = STREAM_PERFECT_MATCH;
344 else
346 retval = STREAM_NOT_FOUND;
350 DEBUGF(" audio header: 0x%02X%02X%02X%02X\n",
351 (unsigned)audio_queue.ptr[0], (unsigned)audio_queue.ptr[1],
352 (unsigned)audio_queue.ptr[2], (unsigned)audio_queue.ptr[3]);
354 return retval;
355 (void)td;
358 static void audio_thread_msg(struct audio_thread_data *td)
360 while (1)
362 intptr_t reply = 0;
364 switch (td->ev.id)
366 case STREAM_PLAY:
367 td->status = STREAM_PLAYING;
369 switch (td->state)
371 case TSTATE_INIT:
372 td->state = TSTATE_DECODE;
373 case TSTATE_DECODE:
374 case TSTATE_RENDER_WAIT:
375 case TSTATE_RENDER_WAIT_END:
376 break;
378 case TSTATE_EOS:
379 /* At end of stream - no playback possible so fire the
380 * completion event */
381 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
382 break;
385 break;
387 case STREAM_PAUSE:
388 td->status = STREAM_PAUSED;
389 reply = td->state != TSTATE_EOS;
390 break;
392 case STREAM_STOP:
393 if (td->state == TSTATE_DATA)
394 stream_clear_notify(&audio_str, DISK_BUF_DATA_NOTIFY);
396 td->status = STREAM_STOPPED;
397 td->state = TSTATE_EOS;
399 reply = true;
400 break;
402 case STREAM_RESET:
403 if (td->state == TSTATE_DATA)
404 stream_clear_notify(&audio_str, DISK_BUF_DATA_NOTIFY);
406 td->status = STREAM_STOPPED;
407 td->state = TSTATE_INIT;
408 td->samplerate = 0;
409 td->nchannels = 0;
411 init_mad();
412 td->mad_errors = 0;
414 audio_queue_reset();
416 reply = true;
417 break;
419 case STREAM_NEEDS_SYNC:
420 reply = true; /* Audio always needs to */
421 break;
423 case STREAM_SYNC:
424 case STREAM_FIND_END_TIME:
425 if (td->state != TSTATE_INIT)
426 break;
428 reply = audio_sync(td, (struct str_sync_data *)td->ev.data);
429 break;
431 case DISK_BUF_DATA_NOTIFY:
432 /* Our bun is done */
433 if (td->state != TSTATE_DATA)
434 break;
436 td->state = TSTATE_DECODE;
437 str_data_notify_received(&audio_str);
438 break;
440 case STREAM_QUIT:
441 /* Time to go - make thread exit */
442 td->state = TSTATE_EOS;
443 return;
446 str_reply_msg(&audio_str, reply);
448 if (td->status == STREAM_PLAYING)
450 switch (td->state)
452 case TSTATE_DECODE:
453 case TSTATE_RENDER_WAIT:
454 case TSTATE_RENDER_WAIT_END:
455 /* These return when in playing state */
456 return;
460 str_get_msg(&audio_str, &td->ev);
464 static void audio_thread(void)
466 struct audio_thread_data td;
468 rb->memset(&td, 0, sizeof (td));
469 td.status = STREAM_STOPPED;
470 td.state = TSTATE_EOS;
472 /* We need this here to init the EMAC for Coldfire targets */
473 init_mad();
475 td.dsp = (struct dsp_config *)rb->dsp_configure(NULL, DSP_MYDSP,
476 CODEC_IDX_AUDIO);
477 rb->sound_set_pitch(1000);
478 rb->dsp_configure(td.dsp, DSP_RESET, 0);
479 rb->dsp_configure(td.dsp, DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
481 goto message_wait;
483 /* This is the decoding loop. */
484 while (1)
486 td.state = TSTATE_DECODE;
488 /* Check for any pending messages and process them */
489 if (str_have_msg(&audio_str))
491 message_wait:
492 /* Wait for a message to be queued */
493 str_get_msg(&audio_str, &td.ev);
495 message_process:
496 /* Process a message already dequeued */
497 audio_thread_msg(&td);
499 switch (td.state)
501 /* These states are the only ones that should return */
502 case TSTATE_DECODE: goto audio_decode;
503 case TSTATE_RENDER_WAIT: goto render_wait;
504 case TSTATE_RENDER_WAIT_END: goto render_wait_end;
505 /* Anything else is interpreted as an exit */
506 default: return;
510 audio_decode:
512 /** Buffering **/
513 switch (audio_buffer(&audio_str, STREAM_PM_STREAMING))
515 case STREAM_DATA_NOT_READY:
517 td.state = TSTATE_DATA;
518 goto message_wait;
519 } /* STREAM_DATA_NOT_READY: */
521 case STREAM_DATA_END:
523 if (audio_queue.used > MAD_BUFFER_GUARD)
524 break;
526 /* Used up remainder of compressed audio buffer.
527 * Force any residue to play if audio ended before
528 * reaching the threshold */
529 td.state = TSTATE_RENDER_WAIT_END;
530 audio_queue_reset();
532 render_wait_end:
533 pcm_output_drain();
535 while (pcm_output_used() > (ssize_t)PCMOUT_LOW_WM)
537 str_get_msg_w_tmo(&audio_str, &td.ev, 1);
538 if (td.ev.id != SYS_TIMEOUT)
539 goto message_process;
542 td.state = TSTATE_EOS;
543 if (td.status == STREAM_PLAYING)
544 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
546 rb->yield();
547 goto message_wait;
548 } /* STREAM_DATA_END: */
551 /** Decoding **/
552 mad_stream_buffer(&stream, audio_queue.ptr, audio_queue.used);
554 int mad_stat = mad_frame_decode(&frame, &stream);
556 ssize_t len = stream.next_frame - audio_queue.ptr;
558 if (mad_stat != 0)
560 DEBUGF("audio: Stream error: %s\n",
561 mad_stream_errorstr(&stream));
563 /* If something's goofed - try to perform resync by moving
564 * at least one byte at a time */
565 audio_queue_advance_pos(MAX(len, 1));
567 if (stream.error == MAD_FLAG_INCOMPLETE
568 || stream.error == MAD_ERROR_BUFLEN)
570 /* This makes the codec support partially corrupted files */
571 if (++td.mad_errors <= MPA_MAX_FRAME_SIZE)
573 stream.error = 0;
574 rb->yield();
575 continue;
577 DEBUGF("audio: Too many errors\n");
579 else if (MAD_RECOVERABLE(stream.error))
581 /* libmad says it can recover - just keep on decoding */
582 rb->yield();
583 continue;
585 else
587 /* Some other unrecoverable error */
588 DEBUGF("audio: Unrecoverable error\n");
591 /* This is too hard - bail out */
592 td.state = TSTATE_EOS;
594 if (td.status == STREAM_PLAYING)
595 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
597 td.status = STREAM_ERROR;
598 goto message_wait;
601 /* Adjust sizes by the frame size */
602 audio_queue_advance_pos(len);
603 td.mad_errors = 0; /* Clear errors */
605 /* Generate the pcm samples */
606 mad_synth_frame(&synth, &frame);
608 /** Output **/
609 if (frame.header.samplerate != td.samplerate)
611 td.samplerate = frame.header.samplerate;
612 rb->dsp_configure(td.dsp, DSP_SWITCH_FREQUENCY,
613 td.samplerate);
616 if (MAD_NCHANNELS(&frame.header) != td.nchannels)
618 td.nchannels = MAD_NCHANNELS(&frame.header);
619 rb->dsp_configure(td.dsp, DSP_SET_STEREO_MODE,
620 td.nchannels == 1 ?
621 STEREO_MONO : STEREO_NONINTERLEAVED);
624 td.state = TSTATE_RENDER_WAIT;
626 /* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
627 render_wait:
628 if (synth.pcm.length > 0)
630 struct pcm_frame_header *dst_hdr = pcm_output_get_buffer();
631 const char *src[2] =
632 { (char *)synth.pcm.samples[0], (char *)synth.pcm.samples[1] };
633 int out_count = (synth.pcm.length * CLOCK_RATE
634 + (td.samplerate - 1)) / td.samplerate;
635 ssize_t size = sizeof(*dst_hdr) + out_count*4;
637 /* Wait for required amount of free buffer space */
638 while (pcm_output_free() < size)
640 /* Wait one frame */
641 int timeout = out_count*HZ / td.samplerate;
642 str_get_msg_w_tmo(&audio_str, &td.ev, MAX(timeout, 1));
643 if (td.ev.id != SYS_TIMEOUT)
644 goto message_process;
647 out_count = rb->dsp_process(td.dsp, dst_hdr->data, src,
648 synth.pcm.length);
650 if (out_count <= 0)
651 break;
653 dst_hdr->size = sizeof(*dst_hdr) + out_count*4;
654 dst_hdr->time = audio_queue.curr->time;
656 /* As long as we're on this timestamp, the time is just
657 incremented by the number of samples */
658 audio_queue.curr->time += out_count;
660 /* Make this data available to DMA */
661 pcm_output_add_data();
664 rb->yield();
665 } /* end decoding loop */
668 /* Initializes the audio thread resources and starts the thread */
669 bool audio_thread_init(void)
671 int i;
672 #ifdef SIMULATOR
673 /* The simulator thread implementation doesn't have stack buffers, and
674 these parameters are ignored. */
675 (void)i; /* Keep gcc happy */
676 audio_stack = NULL;
677 audio_stack_size = 0;
678 #else
679 /* Borrow the codec thread's stack (in IRAM on most targets) */
680 audio_stack = NULL;
681 for (i = 0; i < MAXTHREADS; i++)
683 if (rb->strcmp(rb->threads[i].name, "codec") == 0)
685 /* Wait to ensure the codec thread has blocked */
686 while (rb->threads[i].state != STATE_BLOCKED)
687 rb->yield();
689 /* Now we can steal the stack */
690 audio_stack = rb->threads[i].stack;
691 audio_stack_size = rb->threads[i].stack_size;
693 /* Backup the codec thread's stack */
694 rb->memcpy(codec_stack_copy, audio_stack, audio_stack_size);
695 break;
699 if (audio_stack == NULL)
701 /* This shouldn't happen, but deal with it anyway by using
702 the copy instead */
703 audio_stack = codec_stack_copy;
704 audio_stack_size = AUDIO_STACKSIZE;
706 #endif
708 /* Initialise the encoded audio buffer and its descriptors */
709 audio_queue.start = mpeg_malloc(AUDIOBUF_ALLOC_SIZE,
710 MPEG_ALLOC_AUDIOBUF);
711 if (audio_queue.start == NULL)
712 return false;
714 /* Start the audio thread */
715 audio_str.hdr.q = &audio_str_queue;
716 rb->queue_init(audio_str.hdr.q, false);
717 rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send);
719 /* One-up on the priority since the core DSP over-yields internally */
720 audio_str.thread = rb->create_thread(
721 audio_thread, audio_stack, audio_stack_size, 0,
722 "mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK-1) IF_COP(, CPU));
724 if (audio_str.thread == NULL)
725 return false;
727 /* Wait for thread to initialize */
728 str_send_msg(&audio_str, STREAM_NULL, 0);
730 return true;
733 /* Stops the audio thread */
734 void audio_thread_exit(void)
736 if (audio_str.thread != NULL)
738 str_post_msg(&audio_str, STREAM_QUIT, 0);
739 rb->thread_wait(audio_str.thread);
740 audio_str.thread = NULL;
743 #ifndef SIMULATOR
744 /* Restore the codec thread's stack */
745 rb->memcpy(audio_stack, codec_stack_copy, audio_stack_size);
746 #endif