summaryrefslogtreecommitdiff
path: root/apps/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/mpeg.c')
-rw-r--r--apps/mpeg.c1979
1 files changed, 0 insertions, 1979 deletions
diff --git a/apps/mpeg.c b/apps/mpeg.c
deleted file mode 100644
index e04c227cb1..0000000000
--- a/apps/mpeg.c
+++ /dev/null
@@ -1,1979 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdbool.h>
22#include <stdlib.h>
23#include "config.h"
24
25#if CONFIG_CODEC != SWCODEC
26
27#include "debug.h"
28#include "panic.h"
29#include "metadata.h"
30#include "mpeg.h"
31#include "audio.h"
32#include "storage.h"
33#include "string.h"
34#include <kernel.h>
35#include "thread.h"
36#include "errno.h"
37#include "mp3data.h"
38#include "core_alloc.h"
39#include "mp3_playback.h"
40#include "talk.h"
41#include "sound.h"
42#include "system.h"
43#include "appevents.h"
44#include "playlist.h"
45#include "cuesheet.h"
46#include "settings.h"
47#ifndef SIMULATOR
48#include "i2c.h"
49#include "system.h"
50#include "usb.h"
51#include "file.h"
52#include "hwcompat.h"
53#endif /* !SIMULATOR */
54#ifdef HAVE_LCD_BITMAP
55#include "lcd.h"
56#endif /* CONFIG_CODEC != SWCODEC */
57
58#define MPEG_SWAP_CHUNKSIZE 0x2000
59#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
60 wouldn't be able to see the difference between
61 an empty buffer and a full one. */
62#define MPEG_LOW_WATER 0x60000
63#define MPEG_RECORDING_LOW_WATER 0x80000
64#define MPEG_LOW_WATER_CHUNKSIZE 0x40000
65#define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
66#if (CONFIG_STORAGE & STORAGE_MMC)
67#define MPEG_PLAY_PENDING_THRESHOLD 0x20000
68#define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
69#else
70#define MPEG_PLAY_PENDING_THRESHOLD 0x10000
71#define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
72#endif
73
74#define MPEG_MAX_PRERECORD_SECONDS 30
75
76/* For ID3 info and VBR header */
77#define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
78
79#ifndef SIMULATOR
80extern unsigned long mas_version_code;
81#endif
82
83#define MPEG_PLAY 1
84#define MPEG_STOP 2
85#define MPEG_PAUSE 3
86#define MPEG_RESUME 4
87#define MPEG_NEXT 5
88#define MPEG_PREV 6
89#define MPEG_FF_REWIND 7
90#define MPEG_FLUSH_RELOAD 8
91#define MPEG_RECORD 9
92#define MPEG_INIT_RECORDING 10
93#define MPEG_INIT_PLAYBACK 11
94#define MPEG_NEW_FILE 12
95#define MPEG_PAUSE_RECORDING 13
96#define MPEG_RESUME_RECORDING 14
97#define MPEG_NEED_DATA 100
98#define MPEG_TRACK_CHANGE 101
99#define MPEG_SAVE_DATA 102
100#define MPEG_STOP_DONE 103
101#define MPEG_PRERECORDING_TICK 104
102
103/* indicator for MPEG_NEED_DATA */
104#define GENERATE_UNBUFFER_EVENTS 1
105
106/* list of tracks in memory */
107#define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
108#define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
109
110struct trackdata
111{
112 struct mp3entry id3;
113 int mempos;
114 int load_ahead_index;
115};
116
117static struct trackdata trackdata[MAX_TRACK_ENTRIES];
118
119static unsigned int current_track_counter = 0;
120
121#ifndef SIMULATOR
122static void stop_playing(void);
123
124static int track_read_idx = 0;
125static int track_write_idx = 0;
126#endif /* !SIMULATOR */
127
128/* Cuesheet support */
129static struct cuesheet *curr_cuesheet = NULL;
130static bool checked_for_cuesheet = false;
131
132static const char mpeg_thread_name[] = "mpeg";
133static unsigned int audio_thread_id;
134static bool audio_is_initialized;
135static unsigned int mpeg_errno;
136
137static bool playing = false; /* We are playing an MP3 stream */
138static bool is_playing = false; /* We are (attempting to) playing MP3 files */
139static bool paused; /* playback is paused */
140static int audiobuf_handle; /* handle to the audio buffer */
141static char* mpeg_audiobuf; /* poiunter to the audio buffer */
142static long audiobuflen; /* length of the audio buffer */
143#define AUDIO_BUFFER_RESERVE (256*1024)
144#ifdef SIMULATOR
145static char mpeg_stack[DEFAULT_STACK_SIZE];
146static struct mp3entry taginfo;
147#else /* !SIMULATOR */
148static struct event_queue mpeg_queue SHAREDBSS_ATTR;
149static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
150
151static int audiobuf_write;
152static int audiobuf_swapwrite;
153static long audiobuf_read;
154
155static int mpeg_file;
156
157static bool play_pending; /* We are about to start playing */
158static bool play_pending_track_change; /* When starting play we're starting a new file */
159static bool filling; /* We are filling the buffer with data from disk */
160static bool dma_underrun; /* True when the DMA has stopped because of
161 slow disk reading (read error, shaking) */
162static bool mpeg_stop_done;
163
164static int last_dma_tick = 0;
165static int last_dma_chunk_size;
166
167static long low_watermark; /* Dynamic low watermark level */
168static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
169static long lowest_watermark_level; /* Debug value to observe the buffer
170 usage */
171
172struct audio_resume_info
173{
174 unsigned long elapsed;
175 unsigned long offset;
176};
177
178#ifdef HAVE_RECORDING
179static const unsigned char empty_id3_header[] =
180{
181 'I', 'D', '3', 0x03, 0x00, 0x00,
182 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
183};
184#endif /* HAVE_RECORDING */
185
186
187static int get_unplayed_space(void);
188static int get_playable_space(void);
189static int get_unswapped_space(void);
190#endif /* !SIMULATOR */
191
192static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
193static void audio_reset_buffer(void);
194
195
196#ifndef SIMULATOR
197static int num_tracks_in_memory(void)
198{
199 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
200}
201
202#ifdef DEBUG_TAGS
203static void debug_tags(void)
204{
205 int i;
206
207 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
208 {
209 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
210 }
211 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
212 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
213}
214#else /* !DEBUG_TAGS */
215#define debug_tags()
216#endif /* !DEBUG_TAGS */
217
218static void remove_current_tag(void)
219{
220 if(num_tracks_in_memory() > 0)
221 {
222 /* First move the index, so nobody tries to access the tag */
223 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
224 checked_for_cuesheet = false;
225 debug_tags();
226 }
227 else
228 {
229 DEBUGF("remove_current_tag: no tracks to remove\n");
230 }
231}
232
233static void remove_all_non_current_tags(void)
234{
235 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
236 debug_tags();
237}
238
239static void remove_all_tags(void)
240{
241 track_write_idx = track_read_idx;
242
243 debug_tags();
244}
245
246static struct trackdata *get_trackdata(int offset)
247{
248 if(offset >= num_tracks_in_memory())
249 return NULL;
250 else
251 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
252}
253#endif /* !SIMULATOR */
254
255/***********************************************************************/
256/* audio event handling */
257
258#define MAX_EVENT_HANDLERS 10
259struct event_handlers_table
260{
261 AUDIO_EVENT_HANDLER handler;
262 unsigned short mask;
263};
264static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
265static int event_handlers_count = 0;
266
267void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
268{
269 if (event_handlers_count < MAX_EVENT_HANDLERS)
270 {
271 event_handlers[event_handlers_count].handler = handler;
272 event_handlers[event_handlers_count].mask = mask;
273 event_handlers_count++;
274 }
275}
276
277/* dispatch calls each handler in the order registered and returns after some
278 handler actually handles the event (the event is assumed to no longer be valid
279 after this, due to the handler changing some condition); returns true if someone
280 handled the event, which is expected to cause the caller to skip its own handling
281 of the event */
282#ifndef SIMULATOR
283static bool audio_dispatch_event(unsigned short event, unsigned long data)
284{
285 int i = 0;
286 for(i=0; i < event_handlers_count; i++)
287 {
288 if ( event_handlers[i].mask & event )
289 {
290 int rc = event_handlers[i].handler(event, data);
291 if ( rc == AUDIO_EVENT_RC_HANDLED )
292 return true;
293 }
294 }
295 return false;
296}
297
298static void send_track_event(unsigned int id, struct mp3entry *id3)
299{
300 struct mp3entry *cur_id3 =
301 &trackdata[track_read_idx & MAX_TRACK_ENTRIES_MASK].id3;
302 unsigned int flags = id3 == cur_id3 ? TEF_CURRENT : 0;
303 send_event(id, &(struct track_event){ .flags = flags, .id3 = id3 });
304}
305#endif /* SIMULATOR */
306
307/***********************************************************************/
308
309static void set_elapsed(struct mp3entry* id3)
310{
311 if ( id3->vbr ) {
312 if ( id3->has_toc ) {
313 /* calculate elapsed time using TOC */
314 int i;
315 unsigned int remainder, plen, relpos, nextpos;
316
317 /* find wich percent we're at */
318 for (i=0; i<100; i++ )
319 {
320 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
321 {
322 break;
323 }
324 }
325
326 i--;
327 if (i < 0)
328 i = 0;
329
330 relpos = id3->toc[i];
331
332 if (i < 99)
333 {
334 nextpos = id3->toc[i+1];
335 }
336 else
337 {
338 nextpos = 256;
339 }
340
341 remainder = id3->offset - (relpos * (id3->filesize / 256));
342
343 /* set time for this percent (divide before multiply to prevent
344 overflow on long files. loss of precision is negligible on
345 short files) */
346 id3->elapsed = i * (id3->length / 100);
347
348 /* calculate remainder time */
349 plen = (nextpos - relpos) * (id3->filesize / 256);
350 id3->elapsed += (((remainder * 100) / plen) *
351 (id3->length / 10000));
352 }
353 else {
354 /* no TOC exists. set a rough estimate using average bitrate */
355 int tpk = id3->length / (id3->filesize / 1024);
356 id3->elapsed = id3->offset / 1024 * tpk;
357 }
358 }
359 else
360 /* constant bitrate, use exact calculation */
361 id3->elapsed = id3->offset / (id3->bitrate / 8);
362}
363
364static int audio_get_file_pos_int(struct mp3entry *id3)
365{
366 int pos = -1;
367
368 if (id3->vbr)
369 {
370 if (id3->has_toc)
371 {
372 /* Use the TOC to find the new position */
373 unsigned int percent, remainder;
374 int curtoc, nexttoc, plen;
375
376 percent = (id3->elapsed*100)/id3->length;
377 if (percent > 99)
378 percent = 99;
379
380 curtoc = id3->toc[percent];
381
382 if (percent < 99)
383 nexttoc = id3->toc[percent+1];
384 else
385 nexttoc = 256;
386
387 pos = (id3->filesize/256)*curtoc;
388
389 /* Use the remainder to get a more accurate position */
390 remainder = (id3->elapsed*100)%id3->length;
391 remainder = (remainder*100)/id3->length;
392 plen = (nexttoc - curtoc)*(id3->filesize/256);
393 pos += (plen/100)*remainder;
394 }
395 else
396 {
397 /* No TOC exists, estimate the new position */
398 pos = (id3->filesize / (id3->length / 1000)) *
399 (id3->elapsed / 1000);
400 }
401 }
402 else if (id3->bitrate)
403 pos = id3->elapsed * (id3->bitrate / 8);
404 else
405 {
406 return -1;
407 }
408
409 if (pos >= (int)(id3->filesize - id3->id3v1len))
410 {
411 /* Don't seek right to the end of the file so that we can
412 transition properly to the next song */
413 pos = id3->filesize - id3->id3v1len - 1;
414 }
415 else if (pos < (int)id3->first_frame_offset)
416 {
417 /* skip past id3v2 tag and other leading garbage */
418 pos = id3->first_frame_offset;
419 }
420 return pos;
421}
422
423int audio_get_file_pos(void)
424{
425 struct mp3entry *id3 = audio_current_track();
426 return id3 ? audio_get_file_pos_int(id3) : 0;
427}
428
429unsigned long mpeg_get_last_header(void)
430{
431#ifdef SIMULATOR
432 return 0;
433#else /* !SIMULATOR */
434 unsigned long tmp[2];
435
436 /* Read the frame data from the MAS and reconstruct it with the
437 frame sync and all */
438 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
439 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
440#endif /* !SIMULATOR */
441}
442
443static void do_stop(void)
444{
445 is_playing = false;
446 paused = false;
447
448#ifndef SIMULATOR
449 if (playing)
450 playlist_update_resume_info(audio_current_track());
451
452 stop_playing();
453 mpeg_stop_done = true;
454#else
455 playing = false;
456#endif
457}
458
459/* Buffer must not move. */
460static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
461{
462 ssize_t extradata_size = old_size - audiobuflen;
463 /* check what buflib requests */
464 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
465 ssize_t size = (ssize_t)old_size - wanted_size;
466
467 /* keep at least 256K for the buffering */
468 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE)
469 {
470 /* check if buflib needs the memory really hard. if yes we give
471 * up playback for now, otherwise refuse to shrink to keep at least
472 * 256K for the buffering */
473 if ((hints & BUFLIB_SHRINK_POS_MASK) != BUFLIB_SHRINK_POS_MASK)
474 return BUFLIB_CB_CANNOT_SHRINK;
475 }
476 /* TODO: Do it without stopping playback, if possible */
477 bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
478 struct mp3entry *id3 = audio_current_track();
479 unsigned long elapsed = 0, offset = 0;
480 if (id3)
481 {
482 elapsed = id3->elapsed;
483 offset = id3->offset;
484 }
485 /* don't call audio_hard_stop() as it frees this handle */
486 if (thread_self() == audio_thread_id)
487 { /* inline case MPEG_STOP (audio_stop()) response
488 * if we're in the audio thread since audio_stop() otherwise deadlocks */
489 do_stop();
490 }
491 else
492 audio_stop();
493
494 switch (hints & BUFLIB_SHRINK_POS_MASK)
495 {
496 case BUFLIB_SHRINK_POS_BACK:
497 core_shrink(handle, start, size);
498 audio_reset_buffer_noalloc(start, size);
499 break;
500 case BUFLIB_SHRINK_POS_FRONT:
501 core_shrink(handle, start + wanted_size, size);
502 audio_reset_buffer_noalloc(start + wanted_size, size);
503 break;
504 case BUFLIB_SHRINK_POS_MASK:
505 audiobuf_handle = core_free(audiobuf_handle);
506 mpeg_audiobuf = NULL;
507 talk_buffer_set_policy(TALK_BUFFER_DEFAULT);
508 playing = false;
509 break;
510 }
511 if (playing)
512 { /* safe to call even from the audio thread (due to queue_post()) */
513 audio_play(elapsed, offset);
514 }
515
516 return BUFLIB_CB_OK;
517}
518
519static struct buflib_callbacks ops = {
520 .move_callback = NULL,
521 .shrink_callback = shrink_callback,
522};
523
524#ifndef SIMULATOR
525/* Send callback events to notify about removing old tracks. */
526static void generate_unbuffer_events(void)
527{
528 int i;
529 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
530 int cur_idx = track_write_idx;
531
532 for (i = 0; i < numentries; i++)
533 {
534 /* Send an event to notify that track has finished. */
535 send_track_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
536 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
537 }
538}
539
540/* Send callback events to notify about new tracks. */
541static void generate_postbuffer_events(void)
542{
543 int i;
544 int numentries = num_tracks_in_memory();
545 int cur_idx = track_read_idx;
546
547 for (i = 0; i < numentries; i++)
548 {
549 send_track_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
550 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
551 }
552}
553
554static void recalculate_watermark(int bitrate)
555{
556 int bytes_per_sec;
557 int time = storage_spinup_time();
558
559 /* A bitrate of 0 probably means empty VBR header. We play safe
560 and set a high threshold */
561 if(bitrate == 0)
562 bitrate = 320;
563
564 bytes_per_sec = bitrate * 1000 / 8;
565
566 if(time)
567 {
568 /* No drive spins up faster than 3.5s */
569 if(time < 350)
570 time = 350;
571
572 time = time * 3;
573 low_watermark = ((low_watermark_margin * HZ + time) *
574 bytes_per_sec) / HZ;
575 }
576 else
577 {
578 low_watermark = MPEG_LOW_WATER;
579 }
580}
581
582#ifdef HAVE_DISK_STORAGE
583void audio_set_buffer_margin(int setting)
584{
585 low_watermark_margin = setting; /* in seconds */
586}
587#endif
588
589void audio_get_debugdata(struct audio_debug *dbgdata)
590{
591 dbgdata->audiobuflen = audiobuflen;
592 dbgdata->audiobuf_write = audiobuf_write;
593 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
594 dbgdata->audiobuf_read = audiobuf_read;
595
596 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
597
598 dbgdata->playing = playing;
599 dbgdata->play_pending = play_pending;
600 dbgdata->is_playing = is_playing;
601 dbgdata->filling = filling;
602 dbgdata->dma_underrun = dma_underrun;
603
604 dbgdata->unplayed_space = get_unplayed_space();
605 dbgdata->playable_space = get_playable_space();
606 dbgdata->unswapped_space = get_unswapped_space();
607
608 dbgdata->low_watermark_level = low_watermark;
609 dbgdata->lowest_watermark_level = lowest_watermark_level;
610}
611
612#ifdef DEBUG
613static void dbg_timer_start(void)
614{
615 /* We are using timer 2 */
616
617 TSTR &= ~0x04; /* Stop the timer */
618 TSNC &= ~0x04; /* No synchronization */
619 TMDR &= ~0x44; /* Operate normally */
620
621 TCNT2 = 0; /* Start counting at 0 */
622 TCR2 = 0x03; /* Sysclock/8 */
623
624 TSTR |= 0x04; /* Start timer 2 */
625}
626
627static int dbg_cnt2us(unsigned int cnt)
628{
629 return (cnt * 10000) / (FREQ/800);
630}
631#endif /* DEBUG */
632
633static int get_unplayed_space(void)
634{
635 int space = audiobuf_write - audiobuf_read;
636 if (space < 0)
637 space += audiobuflen;
638 return space;
639}
640
641static int get_playable_space(void)
642{
643 int space = audiobuf_swapwrite - audiobuf_read;
644 if (space < 0)
645 space += audiobuflen;
646 return space;
647}
648
649static int get_unplayed_space_current_song(void)
650{
651 int space;
652
653 if (num_tracks_in_memory() > 1)
654 {
655 space = get_trackdata(1)->mempos - audiobuf_read;
656 }
657 else
658 {
659 space = audiobuf_write - audiobuf_read;
660 }
661
662 if (space < 0)
663 space += audiobuflen;
664
665 return space;
666}
667
668static int get_unswapped_space(void)
669{
670 int space = audiobuf_write - audiobuf_swapwrite;
671 if (space < 0)
672 space += audiobuflen;
673 return space;
674}
675
676void playback_tick(void)
677{
678 struct trackdata *ptd = get_trackdata(0);
679 if(ptd)
680 {
681 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
682 last_dma_tick = current_tick;
683 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
684 (unsigned long)ptd->id3.elapsed);
685 }
686}
687
688static void reset_mp3_buffer(void)
689{
690 audiobuf_read = 0;
691 audiobuf_write = 0;
692 audiobuf_swapwrite = 0;
693 lowest_watermark_level = audiobuflen;
694}
695
696 /* DMA transfer end interrupt callback */
697static void transfer_end(const void** ppbuf, size_t* psize)
698{
699 if(playing && !paused)
700 {
701 int unplayed_space_left;
702 int space_until_end_of_buffer;
703 int track_offset = 1;
704 struct trackdata *track;
705
706 audiobuf_read += last_dma_chunk_size;
707 if(audiobuf_read >= audiobuflen)
708 audiobuf_read = 0;
709
710 /* First, check if we are on a track boundary */
711 if (num_tracks_in_memory() > 1)
712 {
713 if (audiobuf_read == get_trackdata(track_offset)->mempos)
714 {
715 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
716 {
717 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
718 track_offset++;
719 }
720 }
721 }
722
723 unplayed_space_left = get_unplayed_space();
724
725 space_until_end_of_buffer = audiobuflen - audiobuf_read;
726
727 if(!filling && unplayed_space_left < low_watermark)
728 {
729 filling = true;
730 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
731 }
732
733 if(unplayed_space_left)
734 {
735 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
736 last_dma_chunk_size = MIN(last_dma_chunk_size,
737 space_until_end_of_buffer);
738
739 /* several tracks loaded? */
740 track = get_trackdata(track_offset);
741 if(track)
742 {
743 /* will we move across the track boundary? */
744 if (( audiobuf_read < track->mempos ) &&
745 ((audiobuf_read+last_dma_chunk_size) >
746 track->mempos ))
747 {
748 /* Make sure that we end exactly on the boundary */
749 last_dma_chunk_size = track->mempos - audiobuf_read;
750 }
751 }
752
753 *psize = last_dma_chunk_size & 0xffff;
754 *ppbuf = mpeg_audiobuf + audiobuf_read;
755 track = get_trackdata(0);
756 if(track)
757 track->id3.offset += last_dma_chunk_size;
758
759 /* Update the watermark debug level */
760 if(unplayed_space_left < lowest_watermark_level)
761 lowest_watermark_level = unplayed_space_left;
762 }
763 else
764 {
765 /* Check if the end of data is because of a hard disk error.
766 If there is an open file handle, we are still playing music.
767 If not, the last file has been loaded, and the file handle is
768 closed. */
769 if(mpeg_file >= 0)
770 {
771 /* Update the watermark debug level */
772 if(unplayed_space_left < lowest_watermark_level)
773 lowest_watermark_level = unplayed_space_left;
774
775 DEBUGF("DMA underrun.\n");
776 dma_underrun = true;
777 }
778 else
779 {
780 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
781 {
782 DEBUGF("No more MP3 data. Stopping.\n");
783 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
784 playing = false;
785 }
786 }
787 *psize = 0; /* no more transfer */
788 }
789 }
790}
791
792static struct trackdata *add_track_to_tag_list(const char *filename)
793{
794 struct trackdata *track;
795 bool send_nid3_event;
796
797 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
798 {
799 DEBUGF("Tag memory is full\n");
800 return NULL;
801 }
802
803 track = &trackdata[track_write_idx];
804
805 /* grab id3 tag of new file and
806 remember where in memory it starts */
807 if(mp3info(&track->id3, filename))
808 {
809 DEBUGF("Bad mp3\n");
810 return NULL;
811 }
812 track->mempos = audiobuf_write;
813 track->id3.elapsed = 0;
814#ifdef HAVE_LCD_BITMAP
815 if (track->id3.title)
816 lcd_getstringsize(track->id3.title, NULL, NULL);
817 if (track->id3.artist)
818 lcd_getstringsize(track->id3.artist, NULL, NULL);
819 if (track->id3.album)
820 lcd_getstringsize(track->id3.album, NULL, NULL);
821#endif
822
823 /* if this track is the next track then let the UI know it can get it */
824 send_nid3_event = (track_write_idx == track_read_idx + 1);
825 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
826 if (send_nid3_event)
827 send_track_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, &track->id3);
828 debug_tags();
829 return track;
830}
831
832static int new_file(int steps)
833{
834 int max_steps = playlist_amount();
835 int start = 0;
836 int i;
837 struct trackdata *track;
838 char name_buf[MAX_PATH+1];
839 const char *trackname;
840
841 /* Find out how many steps to advance. The load_ahead_index field tells
842 us how many playlist entries it had to skip to get to a valid one.
843 We add those together to find out where to start. */
844 if(steps > 0 && num_tracks_in_memory() > 1)
845 {
846 /* Begin with the song after the currently playing one */
847 i = 1;
848 while((track = get_trackdata(i++)))
849 {
850 start += track->load_ahead_index;
851 }
852 }
853
854 do {
855 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
856 if ( !trackname )
857 return -1;
858
859 DEBUGF("Loading %s\n", trackname);
860
861 mpeg_file = open(trackname, O_RDONLY);
862 if(mpeg_file < 0) {
863 DEBUGF("Couldn't open file: %s\n",trackname);
864 if(steps < 0)
865 steps--;
866 else
867 steps++;
868 }
869 else
870 {
871 struct trackdata *track = add_track_to_tag_list(trackname);
872
873 if(!track)
874 {
875 /* Bad mp3 file */
876 if(steps < 0)
877 steps--;
878 else
879 steps++;
880 close(mpeg_file);
881 mpeg_file = -1;
882 }
883 else
884 {
885 /* skip past id3v2 tag */
886 lseek(mpeg_file,
887 track->id3.first_frame_offset,
888 SEEK_SET);
889 track->id3.index = steps;
890 track->load_ahead_index = steps;
891 track->id3.offset = 0;
892
893 if(track->id3.vbr)
894 /* Average bitrate * 1.5 */
895 recalculate_watermark(
896 (track->id3.bitrate * 3) / 2);
897 else
898 recalculate_watermark(
899 track->id3.bitrate);
900
901 }
902 }
903
904 /* Bail out if no file could be opened */
905 if(abs(steps) > max_steps)
906 return -1;
907 } while ( mpeg_file < 0 );
908
909 return 0;
910}
911
912static void stop_playing(void)
913{
914 /* Stop the current stream */
915 mp3_play_stop();
916 playing = false;
917 filling = false;
918
919 if(mpeg_file >= 0)
920 close(mpeg_file);
921 mpeg_file = -1;
922 remove_all_tags();
923 generate_unbuffer_events();
924 reset_mp3_buffer();
925}
926
927static void end_current_track(void)
928{
929 play_pending = false;
930 playing = false;
931 mp3_play_pause(false);
932
933 reset_mp3_buffer();
934 remove_all_tags();
935 generate_unbuffer_events();
936
937 if(mpeg_file >= 0)
938 close(mpeg_file);
939}
940
941/* Is this a really the end of playback or is a new playlist starting */
942static void check_playlist_end(int direction)
943{
944 /* Use the largest possible step size to account for skipped tracks */
945 int steps = playlist_amount();
946
947 if (direction < 0)
948 steps = -steps;
949
950 if (playlist_next(steps) < 0)
951 is_playing = false;
952}
953
954static void update_playlist(void)
955{
956 if (num_tracks_in_memory() > 0)
957 {
958 struct trackdata *track = get_trackdata(0);
959 track->id3.index = playlist_next(track->id3.index);
960 }
961 else
962 {
963 /* End of playlist? */
964 check_playlist_end(1);
965 }
966
967 playlist_update_resume_info(audio_current_track());
968}
969
970static void track_change(void)
971{
972 DEBUGF("Track change\n");
973
974 if (num_tracks_in_memory() > 0)
975 {
976 remove_current_tag();
977 update_playlist();
978 if (is_playing)
979 {
980 send_track_event(PLAYBACK_EVENT_TRACK_CHANGE,
981 audio_current_track());
982 }
983 }
984
985 current_track_counter++;
986}
987
988#ifdef DEBUG
989void hexdump(const unsigned char *buf, int len)
990{
991 int i;
992
993 for(i = 0;i < len;i++)
994 {
995 if(i && (i & 15) == 0)
996 {
997 DEBUGF("\n");
998 }
999 DEBUGF("%02x ", buf[i]);
1000 }
1001 DEBUGF("\n");
1002}
1003#endif /* DEBUG */
1004
1005static void start_playback_if_ready(void)
1006{
1007 int playable_space;
1008
1009 playable_space = audiobuf_swapwrite - audiobuf_read;
1010 if(playable_space < 0)
1011 playable_space += audiobuflen;
1012
1013 /* See if we have started playing yet. If not, do it. */
1014 if(play_pending || dma_underrun)
1015 {
1016 /* If the filling has stopped, and we still haven't reached
1017 the watermark, the file must be smaller than the
1018 watermark. We must still play it. */
1019 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1020 !filling || dma_underrun)
1021 {
1022 DEBUGF("P\n");
1023 if (play_pending) /* don't do this when recovering from DMA underrun */
1024 {
1025 generate_postbuffer_events(); /* signal first track as buffered */
1026 if (play_pending_track_change)
1027 {
1028 play_pending_track_change = false;
1029 send_track_event(PLAYBACK_EVENT_TRACK_CHANGE,
1030 audio_current_track());
1031 }
1032 play_pending = false;
1033 }
1034 playing = true;
1035
1036 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1037 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1038 dma_underrun = false;
1039
1040 if (!paused)
1041 {
1042 last_dma_tick = current_tick;
1043 mp3_play_pause(true);
1044 }
1045
1046 /* Tell ourselves that we need more data */
1047 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1048 }
1049 }
1050}
1051
1052static bool swap_one_chunk(void)
1053{
1054 int free_space_left;
1055 int amount_to_swap;
1056
1057 free_space_left = get_unswapped_space();
1058
1059 if(free_space_left == 0 && !play_pending)
1060 return false;
1061
1062 /* Swap in larger chunks when the user is waiting for the playback
1063 to start, or when there is dangerously little playable data left */
1064 if(play_pending)
1065 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1066 else
1067 {
1068 if(get_playable_space() < low_watermark)
1069 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1070 free_space_left);
1071 else
1072 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1073 }
1074
1075 if(audiobuf_write < audiobuf_swapwrite)
1076 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1077 amount_to_swap);
1078 else
1079 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1080 amount_to_swap);
1081
1082 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1083
1084 audiobuf_swapwrite += amount_to_swap;
1085 if(audiobuf_swapwrite >= audiobuflen)
1086 {
1087 audiobuf_swapwrite = 0;
1088 }
1089
1090 return true;
1091}
1092
1093static void mpeg_thread(void)
1094{
1095 static int pause_tick = 0;
1096 static unsigned int pause_track = 0;
1097 struct queue_event ev;
1098 int len;
1099 int free_space_left;
1100 int unplayed_space_left;
1101 int amount_to_read;
1102 int t1, t2;
1103 unsigned long start_elapsed, start_offset;
1104
1105 is_playing = false;
1106 play_pending = false;
1107 playing = false;
1108 mpeg_file = -1;
1109
1110 while(1)
1111 {
1112 yield();
1113
1114 /* Swap if necessary, and don't block on the queue_wait() */
1115 if(swap_one_chunk())
1116 {
1117 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1118 }
1119 else if (playing)
1120 {
1121 /* periodically update resume info */
1122 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1123 }
1124 else
1125 {
1126 DEBUGF("S R:%x W:%x SW:%x\n",
1127 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1128 queue_wait(&mpeg_queue, &ev);
1129 }
1130
1131 start_playback_if_ready();
1132
1133 switch(ev.id)
1134 {
1135 case MPEG_PLAY:
1136 DEBUGF("MPEG_PLAY\n");
1137
1138#if CONFIG_TUNER
1139 /* Silence the A/D input, it may be on because the radio
1140 may be playing */
1141 mas_codec_writereg(6, 0x0000);
1142#endif /* CONFIG_TUNER */
1143
1144 /* Stop the current stream */
1145 paused = false;
1146 end_current_track();
1147
1148 if ( new_file(0) == -1 )
1149 {
1150 is_playing = false;
1151 track_change();
1152 break;
1153 }
1154
1155 start_elapsed = ((struct audio_resume_info *)ev.data)->elapsed;
1156 start_offset = ((struct audio_resume_info *)ev.data)->offset;
1157
1158 /* mid-song resume? */
1159 if (!start_offset && start_elapsed) {
1160 struct mp3entry *id3 = &get_trackdata(0)->id3;
1161 id3->elapsed = start_elapsed;
1162 start_offset = audio_get_file_pos_int(id3);
1163 }
1164
1165 if (start_offset) {
1166 struct mp3entry* id3 = &get_trackdata(0)->id3;
1167 lseek(mpeg_file, start_offset, SEEK_SET);
1168 id3->offset = start_offset;
1169 set_elapsed(id3);
1170 }
1171 else {
1172 /* skip past id3v2 tag */
1173 lseek(mpeg_file,
1174 get_trackdata(0)->id3.first_frame_offset,
1175 SEEK_SET);
1176
1177 }
1178
1179 /* Make it read more data */
1180 filling = true;
1181 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1182
1183 /* Tell the file loading code that we want to start playing
1184 as soon as we have some data */
1185 play_pending = true;
1186 play_pending_track_change = true;
1187
1188 update_playlist();
1189 current_track_counter++;
1190 break;
1191
1192 case MPEG_STOP:
1193 do_stop();
1194 break;
1195
1196 case MPEG_PAUSE:
1197 DEBUGF("MPEG_PAUSE\n");
1198 /* Stop the current stream */
1199 if (playing)
1200 playlist_update_resume_info(audio_current_track());
1201 paused = true;
1202 playing = false;
1203 pause_tick = current_tick;
1204 pause_track = current_track_counter;
1205 mp3_play_pause(false);
1206 break;
1207
1208 case MPEG_RESUME:
1209 DEBUGF("MPEG_RESUME\n");
1210 /* Continue the current stream */
1211 paused = false;
1212 if (!play_pending)
1213 {
1214 playing = true;
1215 if ( current_track_counter == pause_track )
1216 last_dma_tick += current_tick - pause_tick;
1217 else
1218 last_dma_tick = current_tick;
1219 pause_tick = 0;
1220 mp3_play_pause(true);
1221 }
1222 break;
1223
1224 case MPEG_NEXT:
1225 DEBUGF("MPEG_NEXT\n");
1226 /* is next track in ram? */
1227 if ( num_tracks_in_memory() > 1 ) {
1228 int unplayed_space_left, unswapped_space_left;
1229
1230 /* stop the current stream */
1231 play_pending = false;
1232 playing = false;
1233 mp3_play_pause(false);
1234
1235 track_change();
1236 audiobuf_read = get_trackdata(0)->mempos;
1237 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1238 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1239 dma_underrun = false;
1240 last_dma_tick = current_tick;
1241
1242 unplayed_space_left = get_unplayed_space();
1243 unswapped_space_left = get_unswapped_space();
1244
1245 /* should we start reading more data? */
1246 if(!filling && (unplayed_space_left < low_watermark)) {
1247 filling = true;
1248 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1249 play_pending = true;
1250 } else if(unswapped_space_left &&
1251 unswapped_space_left > unplayed_space_left) {
1252 /* Stop swapping the data from the previous file */
1253 audiobuf_swapwrite = audiobuf_read;
1254 play_pending = true;
1255 } else {
1256 playing = true;
1257 if (!paused)
1258 mp3_play_pause(true);
1259 }
1260 }
1261 else {
1262 if (!playlist_check(1))
1263 break;
1264
1265 /* stop the current stream */
1266 end_current_track();
1267
1268 if (new_file(1) < 0) {
1269 DEBUGF("No more files to play\n");
1270 filling = false;
1271
1272 check_playlist_end(1);
1273 current_track_counter++;
1274 } else {
1275 /* Make it read more data */
1276 filling = true;
1277 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1278
1279 /* Tell the file loading code that we want
1280 to start playing as soon as we have some data */
1281 play_pending = true;
1282 play_pending_track_change = true;
1283
1284 update_playlist();
1285 current_track_counter++;
1286 }
1287 }
1288 break;
1289
1290 case MPEG_PREV: {
1291 DEBUGF("MPEG_PREV\n");
1292
1293 if (!playlist_check(-1))
1294 break;
1295
1296 /* stop the current stream */
1297 end_current_track();
1298
1299 /* Open the next file */
1300 if (new_file(-1) < 0) {
1301 DEBUGF("No more files to play\n");
1302 filling = false;
1303
1304 check_playlist_end(-1);
1305 current_track_counter++;
1306 } else {
1307 /* Make it read more data */
1308 filling = true;
1309 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1310
1311 /* Tell the file loading code that we want to
1312 start playing as soon as we have some data */
1313 play_pending = true;
1314 play_pending_track_change = true;
1315
1316 update_playlist();
1317 current_track_counter++;
1318 }
1319 break;
1320 }
1321
1322 case MPEG_FF_REWIND: {
1323 struct mp3entry *id3 = audio_current_track();
1324 unsigned int oldtime = id3->elapsed;
1325 unsigned int newtime = (unsigned int)ev.data;
1326 int curpos, newpos, diffpos;
1327 DEBUGF("MPEG_FF_REWIND\n");
1328
1329 id3->elapsed = newtime;
1330
1331 newpos = audio_get_file_pos_int(id3);
1332 if(newpos < 0)
1333 {
1334 id3->elapsed = oldtime;
1335 break;
1336 }
1337
1338 if (mpeg_file >= 0)
1339 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1340 else
1341 curpos = id3->filesize;
1342
1343 if (num_tracks_in_memory() > 1)
1344 {
1345 /* We have started loading other tracks that need to be
1346 accounted for */
1347 struct trackdata *track;
1348 int i = 0;
1349
1350 while((track = get_trackdata(i++)))
1351 {
1352 curpos += track->id3.filesize;
1353 }
1354 }
1355
1356 diffpos = curpos - newpos;
1357
1358 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1359 {
1360 int unplayed_space_left, unswapped_space_left;
1361
1362 /* We are changing to a position that's already in
1363 memory, so we just move the DMA read pointer. */
1364 audiobuf_read = audiobuf_write - diffpos;
1365 if (audiobuf_read < 0)
1366 {
1367 audiobuf_read += audiobuflen;
1368 }
1369
1370 unplayed_space_left = get_unplayed_space();
1371 unswapped_space_left = get_unswapped_space();
1372
1373 /* If unswapped_space_left is larger than
1374 unplayed_space_left, it means that the swapwrite pointer
1375 hasn't yet advanced up to the new location of the read
1376 pointer. We just move it, there is no need to swap
1377 data that won't be played anyway. */
1378
1379 if (unswapped_space_left > unplayed_space_left)
1380 {
1381 DEBUGF("Moved swapwrite\n");
1382 audiobuf_swapwrite = audiobuf_read;
1383 play_pending = true;
1384 }
1385
1386 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1387 {
1388 /* We need to load more data before starting */
1389 filling = true;
1390 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1391 play_pending = true;
1392 }
1393 else
1394 {
1395 /* resume will start at new position */
1396 last_dma_chunk_size =
1397 MIN(0x2000, get_unplayed_space_current_song());
1398 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1399 last_dma_chunk_size, transfer_end);
1400 dma_underrun = false;
1401 }
1402 }
1403 else
1404 {
1405 /* Move to the new position in the file and start
1406 loading data */
1407 reset_mp3_buffer();
1408
1409 if (num_tracks_in_memory() > 1)
1410 {
1411 /* We have to reload the current track */
1412 close(mpeg_file);
1413 remove_all_non_current_tags();
1414 generate_unbuffer_events();
1415 mpeg_file = -1;
1416 }
1417
1418 if (mpeg_file < 0)
1419 {
1420 mpeg_file = open(id3->path, O_RDONLY);
1421 if (mpeg_file < 0)
1422 {
1423 id3->elapsed = oldtime;
1424 break;
1425 }
1426 }
1427
1428 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1429 {
1430 id3->elapsed = oldtime;
1431 break;
1432 }
1433
1434 filling = true;
1435 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1436
1437 /* Tell the file loading code that we want to start playing
1438 as soon as we have some data */
1439 play_pending = true;
1440 }
1441
1442 id3->offset = newpos;
1443
1444 break;
1445 }
1446
1447 case MPEG_FLUSH_RELOAD: {
1448 int numtracks = num_tracks_in_memory();
1449 bool reload_track = false;
1450
1451 if (numtracks > 1)
1452 {
1453 /* Reset the buffer */
1454 audiobuf_write = get_trackdata(1)->mempos;
1455
1456 /* Reset swapwrite unless we're still swapping current
1457 track */
1458 if (get_unplayed_space() <= get_playable_space())
1459 audiobuf_swapwrite = audiobuf_write;
1460
1461 close(mpeg_file);
1462 remove_all_non_current_tags();
1463 generate_unbuffer_events();
1464 mpeg_file = -1;
1465 reload_track = true;
1466 }
1467 else if (numtracks == 1 && mpeg_file < 0)
1468 {
1469 reload_track = true;
1470 }
1471
1472 if(reload_track && new_file(1) >= 0)
1473 {
1474 /* Tell ourselves that we want more data */
1475 filling = true;
1476 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1477 }
1478
1479 break;
1480 }
1481
1482 case MPEG_NEED_DATA:
1483 free_space_left = audiobuf_read - audiobuf_write;
1484
1485 /* We interpret 0 as "empty buffer" */
1486 if(free_space_left <= 0)
1487 free_space_left += audiobuflen;
1488
1489 unplayed_space_left = audiobuflen - free_space_left;
1490
1491 /* Make sure that we don't fill the entire buffer */
1492 free_space_left -= MPEG_HIGH_WATER;
1493
1494 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1495 generate_unbuffer_events();
1496
1497 /* do we have any more buffer space to fill? */
1498 if(free_space_left <= 0)
1499 {
1500 DEBUGF("0\n");
1501 filling = false;
1502 generate_postbuffer_events();
1503 storage_sleep();
1504 break;
1505 }
1506
1507 /* Read small chunks while we are below the low water mark */
1508 if(unplayed_space_left < low_watermark)
1509 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1510 free_space_left);
1511 else
1512 amount_to_read = free_space_left;
1513
1514 /* Don't read more than until the end of the buffer */
1515 amount_to_read = MIN(audiobuflen - audiobuf_write,
1516 amount_to_read);
1517#if (CONFIG_STORAGE & STORAGE_MMC)
1518 /* MMC is slow, so don't read too large chunks */
1519 amount_to_read = MIN(0x40000, amount_to_read);
1520#elif MEMORYSIZE == 8
1521 amount_to_read = MIN(0x100000, amount_to_read);
1522#endif
1523
1524 /* Read as much mpeg data as we can fit in the buffer */
1525 if(mpeg_file >= 0)
1526 {
1527 DEBUGF("R\n");
1528 t1 = current_tick;
1529 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1530 amount_to_read);
1531 if(len > 0)
1532 {
1533 t2 = current_tick;
1534 DEBUGF("time: %d\n", t2 - t1);
1535 DEBUGF("R: %x\n", len);
1536
1537 /* Now make sure that we don't feed the MAS with ID3V1
1538 data */
1539 if (len < amount_to_read)
1540 {
1541 int i;
1542 static const unsigned char tag[] = "TAG";
1543 int taglen = 128;
1544 int tagptr = audiobuf_write + len - 128;
1545
1546 /* Really rare case: entire potential tag wasn't
1547 read in this call AND audiobuf_write < 128 */
1548 if (tagptr < 0)
1549 tagptr += audiobuflen;
1550
1551 for(i = 0;i < 3;i++)
1552 {
1553 if(tagptr >= audiobuflen)
1554 tagptr -= audiobuflen;
1555
1556 if(mpeg_audiobuf[tagptr] != tag[i])
1557 {
1558 taglen = 0;
1559 break;
1560 }
1561
1562 tagptr++;
1563 }
1564
1565 if(taglen)
1566 {
1567 /* Skip id3v1 tag */
1568 DEBUGF("Skipping ID3v1 tag\n");
1569 len -= taglen;
1570
1571 /* In the very rare case when the entire tag
1572 wasn't read in this read() len will be < 0.
1573 Take care of this when changing the write
1574 pointer. */
1575 }
1576 }
1577
1578 audiobuf_write += len;
1579
1580 if (audiobuf_write < 0)
1581 audiobuf_write += audiobuflen;
1582
1583 if(audiobuf_write >= audiobuflen)
1584 {
1585 audiobuf_write = 0;
1586 DEBUGF("W\n");
1587 }
1588
1589 /* Tell ourselves that we want more data */
1590 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1591 }
1592 else
1593 {
1594 if(len < 0)
1595 {
1596 DEBUGF("MPEG read error\n");
1597 }
1598
1599 close(mpeg_file);
1600 mpeg_file = -1;
1601
1602 if(new_file(1) < 0)
1603 {
1604 /* No more data to play */
1605 DEBUGF("No more files to play\n");
1606 filling = false;
1607 }
1608 else
1609 {
1610 /* Tell ourselves that we want more data */
1611 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1612 }
1613 }
1614 }
1615 break;
1616
1617 case MPEG_TRACK_CHANGE:
1618 track_change();
1619 break;
1620
1621#ifndef USB_NONE
1622 case SYS_USB_CONNECTED:
1623 is_playing = false;
1624 paused = false;
1625 stop_playing();
1626
1627 /* Tell the USB thread that we are safe */
1628 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1629 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1630
1631 /* Wait until the USB cable is extracted again */
1632 usb_wait_for_disconnect(&mpeg_queue);
1633 break;
1634#endif /* !USB_NONE */
1635
1636 case SYS_TIMEOUT:
1637 if (playing)
1638 playlist_update_resume_info(audio_current_track());
1639 break;
1640 }
1641 }
1642}
1643#endif /* !SIMULATOR */
1644
1645struct mp3entry* audio_current_track(void)
1646{
1647#ifdef SIMULATOR
1648 struct mp3entry *id3 = &taginfo;
1649#else /* !SIMULATOR */
1650 if(num_tracks_in_memory())
1651 {
1652 struct mp3entry *id3 = &get_trackdata(0)->id3;
1653#endif
1654 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
1655 {
1656 checked_for_cuesheet = true; /* only check once per track */
1657 struct cuesheet_file cue_file;
1658
1659 if (look_for_cuesheet_file(id3, &cue_file) &&
1660 parse_cuesheet(&cue_file, curr_cuesheet))
1661 {
1662 id3->cuesheet = curr_cuesheet;
1663 }
1664 }
1665 return id3;
1666#ifndef SIMULATOR
1667 }
1668 else
1669 return NULL;
1670#endif /* !SIMULATOR */
1671}
1672
1673struct mp3entry* audio_next_track(void)
1674{
1675#ifdef SIMULATOR
1676 return &taginfo;
1677#else /* !SIMULATOR */
1678 if(num_tracks_in_memory() > 1)
1679 return &get_trackdata(1)->id3;
1680 else
1681 return NULL;
1682#endif /* !SIMULATOR */
1683}
1684
1685size_t audio_buffer_size(void)
1686{
1687 if (audiobuf_handle > 0)
1688 return audiobuflen;
1689 return 0;
1690}
1691
1692size_t audio_buffer_available(void)
1693{
1694 size_t size = 0;
1695 size_t core_size = core_available();
1696 if (audiobuf_handle > 0)
1697 return audiobuflen - AUDIO_BUFFER_RESERVE - 128;
1698 return MAX(core_size, size);
1699}
1700
1701static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
1702{
1703 mpeg_audiobuf = buf;
1704 audiobuflen = bufsize;
1705 if (global_settings.cuesheet)
1706 { /* enable cuesheet support */
1707 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
1708 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
1709 audiobuflen -= sizeof(struct cuesheet);
1710 }
1711}
1712
1713static void audio_reset_buffer(void)
1714{
1715 size_t bufsize = audiobuflen;
1716
1717 /* alloc buffer if it's was never allocated or freed by audio_hard_stop()
1718 * because voice cannot be played during audio playback make
1719 * talk.c give up all buffers and disable itself */
1720 if (!audiobuf_handle)
1721 {
1722 talk_buffer_set_policy(TALK_BUFFER_LOOSE);
1723 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
1724 }
1725
1726 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
1727}
1728
1729void audio_play(unsigned long elapsed, unsigned long offset)
1730{
1731 audio_reset_buffer();
1732#ifdef SIMULATOR
1733 char name_buf[MAX_PATH+1];
1734 const char* trackname;
1735 int steps=0;
1736
1737 is_playing = true;
1738
1739 do {
1740 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
1741 if (!trackname)
1742 break;
1743 if(mp3info(&taginfo, trackname)) {
1744 /* bad mp3, move on */
1745 if(++steps > playlist_amount())
1746 break;
1747 continue;
1748 }
1749#ifdef HAVE_MPEG_PLAY
1750 real_mpeg_play(trackname);
1751#endif
1752 playlist_next(steps);
1753 if (!offset && elapsed)
1754 {
1755 /* has an elapsed time but no offset; elapsed may take
1756 precedence in this case */
1757 taginfo.elapsed = elapsed;
1758 taginfo.offset = audio_get_file_pos_int(&taginfo);
1759 }
1760 else
1761 {
1762 taginfo.offset = offset;
1763 set_elapsed(&taginfo);
1764 }
1765 is_playing = true;
1766 playing = true;
1767 break;
1768 } while(1);
1769#else /* !SIMULATOR */
1770 static struct audio_resume_info resume;
1771 is_playing = true;
1772 resume.elapsed = elapsed;
1773 resume.offset = offset;
1774 queue_post(&mpeg_queue, MPEG_PLAY, (intptr_t)&resume);
1775#endif /* !SIMULATOR */
1776
1777 mpeg_errno = 0;
1778}
1779
1780void audio_stop(void)
1781{
1782 if (audiobuf_handle <= 0)
1783 return; /* nothing to do, must be hard-stopped already */
1784#ifndef SIMULATOR
1785 mpeg_stop_done = false;
1786 queue_post(&mpeg_queue, MPEG_STOP, 0);
1787 while(!mpeg_stop_done)
1788 yield();
1789#else /* SIMULATOR */
1790 paused = false;
1791 is_playing = false;
1792 playing = false;
1793#endif /* SIMULATOR */
1794}
1795
1796/* dummy */
1797void audio_stop_recording(void)
1798{
1799 audio_stop();
1800}
1801
1802void audio_hard_stop(void)
1803{
1804 if (audiobuf_handle > 0)
1805 {
1806 audio_stop();
1807 audiobuf_handle = core_free(audiobuf_handle);
1808 mpeg_audiobuf = NULL;
1809 talk_buffer_set_policy(TALK_BUFFER_DEFAULT);
1810 }
1811}
1812
1813void audio_pause(void)
1814{
1815#ifndef SIMULATOR
1816 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
1817#else /* SIMULATOR */
1818 is_playing = true;
1819 playing = false;
1820 paused = true;
1821#endif /* SIMULATOR */
1822}
1823
1824void audio_resume(void)
1825{
1826#ifndef SIMULATOR
1827 queue_post(&mpeg_queue, MPEG_RESUME, 0);
1828#else /* SIMULATOR */
1829 is_playing = true;
1830 playing = true;
1831 paused = false;
1832#endif /* SIMULATOR */
1833}
1834
1835void audio_next(void)
1836{
1837#ifndef SIMULATOR
1838 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
1839 queue_post(&mpeg_queue, MPEG_NEXT, 0);
1840#else /* SIMULATOR */
1841 char name_buf[MAX_PATH+1];
1842 const char* file;
1843 int steps = 1;
1844
1845 do {
1846 file = playlist_peek(steps, name_buf, sizeof(name_buf));
1847 if(!file)
1848 break;
1849 if(mp3info(&taginfo, file)) {
1850 if(++steps > playlist_amount())
1851 break;
1852 continue;
1853 }
1854 playlist_next(steps);
1855 current_track_counter++;
1856 is_playing = true;
1857 playing = true;
1858 break;
1859 } while(1);
1860#endif /* SIMULATOR */
1861}
1862
1863void audio_prev(void)
1864{
1865#ifndef SIMULATOR
1866 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
1867 queue_post(&mpeg_queue, MPEG_PREV, 0);
1868#else /* SIMULATOR */
1869 char name_buf[MAX_PATH+1];
1870 const char* file;
1871 int steps = -1;
1872
1873 do {
1874 file = playlist_peek(steps, name_buf, sizeof(name_buf));
1875 if(!file)
1876 break;
1877 if(mp3info(&taginfo, file)) {
1878 steps--;
1879 continue;
1880 }
1881 playlist_next(steps);
1882 current_track_counter++;
1883 is_playing = true;
1884 playing = true;
1885 break;
1886 } while(1);
1887#endif /* SIMULATOR */
1888}
1889
1890void audio_ff_rewind(long newpos)
1891{
1892#ifndef SIMULATOR
1893 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
1894#else /* SIMULATOR */
1895 (void)newpos;
1896#endif /* SIMULATOR */
1897}
1898
1899void audio_flush_and_reload_tracks(void)
1900{
1901#ifndef SIMULATOR
1902 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
1903#endif /* !SIMULATOR*/
1904}
1905
1906int audio_status(void)
1907{
1908 int ret = 0;
1909
1910 if(is_playing)
1911 ret |= AUDIO_STATUS_PLAY;
1912
1913 if(paused)
1914 ret |= AUDIO_STATUS_PAUSE;
1915
1916 if(mpeg_errno)
1917 ret |= AUDIO_STATUS_ERROR;
1918
1919 return ret;
1920}
1921
1922/* Unused function
1923unsigned int audio_error(void)
1924{
1925 return mpeg_errno;
1926}
1927*/
1928
1929void audio_error_clear(void)
1930{
1931 mpeg_errno = 0;
1932}
1933
1934#ifdef SIMULATOR
1935static void mpeg_thread(void)
1936{
1937 struct mp3entry* id3;
1938 while ( 1 ) {
1939 if (is_playing) {
1940 id3 = audio_current_track();
1941 if (!paused)
1942 {
1943 id3->elapsed+=1000;
1944 id3->offset+=1000;
1945 }
1946 if (id3->elapsed>=id3->length)
1947 audio_next();
1948 }
1949 sleep(HZ);
1950 }
1951}
1952#endif /* SIMULATOR */
1953
1954void audio_init(void)
1955{
1956 mpeg_errno = 0;
1957
1958 audio_reset_buffer();
1959
1960#ifndef SIMULATOR
1961 queue_init(&mpeg_queue, true);
1962#endif /* !SIMULATOR */
1963 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
1964 sizeof(mpeg_stack), 0, mpeg_thread_name
1965 IF_PRIO(, PRIORITY_SYSTEM)
1966 IF_COP(, CPU));
1967
1968 memset(trackdata, 0, sizeof(trackdata));
1969
1970#ifdef DEBUG
1971#ifndef SIMULATOR
1972 dbg_timer_start();
1973 dbg_cnt2us(0);
1974#endif /* !SIMULATOR */
1975#endif /* DEBUG */
1976 audio_is_initialized = true;
1977}
1978
1979#endif /* CONFIG_CODEC != SWCODEC */