Remove tabs.
[kugel-rb.git] / apps / playback.c
blob3ff8d172147023f16aa5e8e72c0be3b2202dc359
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005-2007 Miika Pekkarinen
11 * Copyright (C) 2007-2008 Nicolas Pennequin
12 * Copyright (C) 2011 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "panic.h"
27 #include "buffer.h"
28 #include "sound.h"
29 #include "ata.h"
30 #include "usb.h"
31 #include "codecs.h"
32 #include "codec_thread.h"
33 #include "voice_thread.h"
34 #include "metadata.h"
35 #include "cuesheet.h"
36 #include "buffering.h"
37 #include "talk.h"
38 #include "playlist.h"
39 #include "abrepeat.h"
40 #include "pcmbuf.h"
41 #include "playback.h"
43 #ifdef HAVE_TAGCACHE
44 #include "tagcache.h"
45 #endif
47 #ifdef AUDIO_HAVE_RECORDING
48 #include "pcm_record.h"
49 #endif
51 #ifdef HAVE_LCD_BITMAP
52 #ifdef HAVE_ALBUMART
53 #include "albumart.h"
54 #endif
55 #endif
57 /* TODO: The audio thread really is doing multitasking of acting like a
58 consumer and producer of tracks. It may be advantageous to better
59 logically separate the two functions. I won't go that far just yet. */
61 /* Internal support for voice playback */
62 #define PLAYBACK_VOICE
64 #if CONFIG_PLATFORM & PLATFORM_NATIVE
65 /* Application builds don't support direct code loading */
66 #define HAVE_CODEC_BUFFERING
67 #endif
69 /* Amount of guess-space to allow for codecs that must hunt and peck
70 * for their correct seek target, 32k seems a good size */
71 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
73 /* Define LOGF_ENABLE to enable logf output in this file */
74 /* #define LOGF_ENABLE */
75 #include "logf.h"
77 /* Macros to enable logf for queues
78 logging on SYS_TIMEOUT can be disabled */
79 #ifdef SIMULATOR
80 /* Define this for logf output of all queuing except SYS_TIMEOUT */
81 #define PLAYBACK_LOGQUEUES
82 /* Define this to logf SYS_TIMEOUT messages */
83 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
84 #endif
86 #ifdef PLAYBACK_LOGQUEUES
87 #define LOGFQUEUE logf
88 #else
89 #define LOGFQUEUE(...)
90 #endif
92 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
93 #define LOGFQUEUE_SYS_TIMEOUT logf
94 #else
95 #define LOGFQUEUE_SYS_TIMEOUT(...)
96 #endif
98 /* Variables are commented with the threads that use them:
99 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
100 * read but not updated on that thread. Audio is the only user unless otherwise
101 * specified.
104 /** Miscellaneous **/
105 bool audio_is_initialized = false; /* (A,O-) */
106 extern struct codec_api ci; /* (A,C) */
108 /** Possible arrangements of the main buffer **/
109 static enum audio_buffer_state
111 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
112 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
113 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
114 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
116 /** Main state control **/
117 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
119 enum play_status
121 PLAY_STOPPED = 0,
122 PLAY_PLAYING = AUDIO_STATUS_PLAY,
123 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
124 } play_status = PLAY_STOPPED;
126 /* Sizeable things that only need exist during playback and not when stopped */
127 static struct audio_scratch_memory
129 struct mp3entry codec_id3; /* (A,C) */
130 struct mp3entry unbuffered_id3;
131 struct cuesheet *curr_cue; /* Will follow this structure */
132 } * audio_scratch_memory = NULL;
134 /* These are used to store the current, next and optionally the peek-ahead
135 * mp3entry's - this guarentees that the pointer returned by audio_current/
136 * next_track will be valid for the full duration of the currently playing
137 * track */
138 enum audio_id3_types
140 /* These are allocated statically */
141 PLAYING_ID3 = 0,
142 NEXTTRACK_ID3,
143 #ifdef AUDIO_FAST_SKIP_PREVIEW
144 /* The real playing metadata must has to be protected since it contains
145 critical info for other features */
146 PLAYING_PEEK_ID3,
147 #endif
148 ID3_TYPE_NUM_STATIC,
149 /* These go in the scratch memory */
150 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
151 CODEC_ID3,
153 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
155 /* Peeking functions can yield and mess us up */
156 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,0)*/
159 /** For Scrobbler support **/
161 /* Previous track elapsed time */
162 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
165 /** For album art support **/
166 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
167 #ifdef HAVE_ALBUMART
169 static struct albumart_slot
171 struct dim dim; /* Holds width, height of the albumart */
172 int used; /* Counter; increments if something uses it */
173 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
175 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
176 #endif /* HAVE_ALBUMART */
179 /** Information used for tracking buffer fills **/
181 /* Buffer and thread state tracking */
182 static enum filling_state
184 STATE_BOOT = 0, /* audio thread is not ready yet */
185 STATE_IDLE, /* audio is stopped: nothing to do */
186 STATE_FILLING, /* adding tracks to the buffer */
187 STATE_FULL, /* can't add any more tracks */
188 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
189 STATE_FINISHED, /* all remaining tracks are fully buffered */
190 STATE_ENDING, /* audio playback is ending */
191 STATE_ENDED, /* audio playback is done */
192 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
193 STATE_USB, /* USB mode, ignore most messages */
194 #endif
195 } filling = STATE_BOOT;
197 /* Track info - holds information about each track in the buffer */
198 struct track_info
200 /* In per-track allocated order: */
201 int id3_hid; /* Metadata handle ID */
202 int cuesheet_hid; /* Parsed cueesheet handle ID */
203 #ifdef HAVE_ALBUMART
204 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
205 #endif
206 #ifdef HAVE_CODEC_BUFFERING
207 int codec_hid; /* Buffered codec handle ID */
208 #endif
209 int audio_hid; /* Main audio data handle ID */
210 size_t filesize; /* File total length on disk
211 TODO: This should be stored
212 in the handle or the
213 id3 and would use less
214 ram */
217 /* Track list - holds info about all buffered tracks */
218 #if MEMORYSIZE >= 32
219 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
220 #elif MEMORYSIZE >= 16
221 #define TRACK_LIST_LEN 64
222 #elif MEMORYSIZE >= 8
223 #define TRACK_LIST_LEN 32
224 #else
225 #define TRACK_LIST_LEN 16
226 #endif
228 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
230 static struct
232 /* read, write and current are maintained unwrapped, limited only by the
233 unsigned int range and wrap-safe comparisons are used */
235 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
236 if 'end' follows 'start' in this structure, track_list_count performs
237 'start - end' rather than 'end - start', giving negative count values...
238 so leave it this way for now! */
239 unsigned int end; /* Next open position */
240 unsigned int start; /* First track in list */
241 unsigned int current; /* Currently decoding track */
242 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
243 } track_list; /* (A, O-) */
246 /* Playlist steps from playlist position to next track to be buffered */
247 static int playlist_peek_offset = 0;
249 /* Metadata handle of track load in progress (meaning all handles have not
250 yet been opened for the track, id3 always exists or the track does not)
252 Tracks are keyed by their metadata handles if track list pointers are
253 insufficient to make comparisons */
254 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
256 #ifdef HAVE_DISK_STORAGE
257 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
258 static size_t buffer_margin = 5;
259 #endif
261 /* Values returned for track loading */
262 enum track_load_status
264 LOAD_TRACK_ERR_START_CODEC = -6,
265 LOAD_TRACK_ERR_FINISH_FAILED = -5,
266 LOAD_TRACK_ERR_FINISH_FULL = -4,
267 LOAD_TRACK_ERR_BUSY = -3,
268 LOAD_TRACK_ERR_NO_MORE = -2,
269 LOAD_TRACK_ERR_FAILED = -1,
270 LOAD_TRACK_OK = 0,
271 LOAD_TRACK_READY = 1,
274 /** Track change controls **/
276 /* What sort of skip is pending globally? */
277 enum track_skip_type
279 /* Relative to what user is intended to see: */
280 /* Codec: +0, Track List: +0, Playlist: +0 */
281 TRACK_SKIP_NONE = 0, /* no track skip */
282 /* Codec: +1, Track List: +1, Playlist: +0 */
283 TRACK_SKIP_AUTO, /* codec-initiated skip */
284 /* Codec: +1, Track List: +1, Playlist: +1 */
285 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
286 /* Codec: xx, Track List: +0, Playlist: +0 */
287 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
288 /* Manual skip: Never pends */
289 TRACK_SKIP_MANUAL, /* manual track skip */
290 /* Manual skip: Never pends */
291 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
292 } skip_pending = TRACK_SKIP_NONE;
294 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
295 Fixing playlist code to be able to peek into the first song of
296 the next playlist would fix any issues and this wouldn't need
297 to be a special case since pre-advancing the playlist would be
298 unneeded - it could be much more like TRACK_SKIP_AUTO and all
299 actions that require reversal during an in-progress transition
300 would work as expected */
302 /* Used to indicate status for the events. Must be separate to satisfy all
303 clients so the correct metadata is read when sending the change events
304 and also so that it is read correctly outside the events. */
305 static bool automatic_skip = false; /* (A, O-) */
307 /* Pending manual track skip offset */
308 static int skip_offset = 0; /* (A, O) */
310 /* Track change notification */
311 static struct
313 unsigned int in; /* Number of pcmbuf posts (audio isr) */
314 unsigned int out; /* Number of times audio has read the difference */
315 } track_change = { 0, 0 };
317 /** Codec status **/
318 /* Did the codec notify us it finished while we were paused or while still
319 in an automatic transition?
321 If paused, it is necessary to defer a codec-initiated skip until resuming
322 or else the track will move forward while not playing audio!
324 If in-progress, skips should not build-up ahead of where the WPS is when
325 really short tracks finish decoding.
327 If it is forgotten, it will be missed altogether and playback will just sit
328 there looking stupid and comatose until the user does something */
329 static bool codec_skip_pending = false;
330 static int codec_skip_status;
331 static bool codec_seeking = false; /* Codec seeking ack expected? */
334 /* Event queues */
335 static struct event_queue audio_queue SHAREDBSS_ATTR;
337 /* Audio thread */
338 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
339 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
340 static const char audio_thread_name[] = "audio";
341 static unsigned int audio_thread_id = 0;
343 /* Forward declarations */
344 enum audio_start_playback_flags
346 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
347 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
350 static void audio_start_playback(size_t offset, unsigned int flags);
351 static void audio_stop_playback(void);
352 static void buffer_event_buffer_low_callback(void *data);
353 static void buffer_event_rebuffer_callback(void *data);
354 static void buffer_event_finished_callback(void *data);
357 /**************************************/
359 /** --- audio_queue helpers --- **/
361 /* codec thread needs access */
362 void audio_queue_post(long id, intptr_t data)
364 queue_post(&audio_queue, id, data);
367 static intptr_t audio_queue_send(long id, intptr_t data)
369 return queue_send(&audio_queue, id, data);
373 /** --- MP3Entry --- **/
375 /* Does the mp3entry have enough info for us to use it? */
376 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
378 return id3 && (id3->length != 0 || id3->filesize != 0) &&
379 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
382 /* Return a pointer to an mp3entry on the buffer, as it is */
383 static struct mp3entry * bufgetid3(int handle_id)
385 if (handle_id < 0)
386 return NULL;
388 struct mp3entry *id3;
389 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
391 if (ret != sizeof(struct mp3entry))
392 return NULL;
394 return id3;
397 /* Read an mp3entry from the buffer, adjusted */
398 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
400 struct mp3entry *id3 = bufgetid3(handle_id);
402 if (id3)
404 copy_mp3entry(id3out, id3);
405 return true;
408 return false;
411 /* Lock the id3 mutex */
412 static void id3_mutex_lock(void)
414 mutex_lock(&id3_mutex);
417 /* Unlock the id3 mutex */
418 static void id3_mutex_unlock(void)
420 mutex_unlock(&id3_mutex);
423 /* Return one of the collection of mp3entry pointers - collect them all here */
424 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
426 switch (id3_num)
428 case UNBUFFERED_ID3:
429 return &audio_scratch_memory->unbuffered_id3;
430 case CODEC_ID3:
431 return &audio_scratch_memory->codec_id3;
432 default:
433 return &static_id3_entries[id3_num];
437 /* Copy an mp3entry into one of the mp3 entries */
438 static void id3_write(enum audio_id3_types id3_num,
439 const struct mp3entry *id3_src)
441 struct mp3entry *dest_id3 = id3_get(id3_num);
443 if (id3_src)
444 copy_mp3entry(dest_id3, id3_src);
445 else
446 wipe_mp3entry(dest_id3);
449 /* Call id3_write "safely" because peek aheads can yield, even if the fast
450 preview isn't enabled */
451 static void id3_write_locked(enum audio_id3_types id3_num,
452 const struct mp3entry *id3_src)
454 id3_mutex_lock();
455 id3_write(id3_num, id3_src);
456 id3_mutex_unlock();
460 /** --- Track info --- **/
462 /* Close a handle and mark it invalid */
463 static void track_info_close_handle(int *hid_p)
465 int hid = *hid_p;
467 /* bufclose returns true if the handle is not found, or if it is closed
468 * successfully, so these checks are safe on non-existant handles */
469 if (hid >= 0)
470 bufclose(hid);
472 /* Always reset to "no handle" in case it was something else */
473 *hid_p = ERR_HANDLE_NOT_FOUND;
476 /* Close all handles in a struct track_info and clear it */
477 static void track_info_close(struct track_info *info)
479 /* Close them in the order they are allocated on the buffer to speed up
480 the handle searching */
481 track_info_close_handle(&info->id3_hid);
482 track_info_close_handle(&info->cuesheet_hid);
483 #ifdef HAVE_ALBUMART
484 int i;
485 FOREACH_ALBUMART(i)
486 track_info_close_handle(&info->aa_hid[i]);
487 #endif
488 #ifdef HAVE_CODEC_BUFFERING
489 track_info_close_handle(&info->codec_hid);
490 #endif
491 track_info_close_handle(&info->audio_hid);
492 info->filesize = 0;
495 /* Invalidate all members to initial values - does not close handles */
496 static void track_info_wipe(struct track_info * info)
498 info->id3_hid = ERR_HANDLE_NOT_FOUND;
499 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
500 #ifdef HAVE_ALBUMART
501 int i;
502 FOREACH_ALBUMART(i)
503 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
504 #endif
505 #ifdef HAVE_CODEC_BUFFERING
506 info->codec_hid = ERR_HANDLE_NOT_FOUND;
507 #endif
508 info->audio_hid = ERR_HANDLE_NOT_FOUND;
509 info->filesize = 0;
513 /** --- Track list --- **/
515 /* Initialize the track list */
516 static void track_list_init(void)
518 int i;
519 for (i = 0; i < TRACK_LIST_LEN; i++)
520 track_info_wipe(&track_list.tracks[i]);
522 track_list.start = track_list.end = track_list.current;
525 /* Return number of items allocated in the list */
526 static unsigned int track_list_count(void)
528 return track_list.end - track_list.start;
531 /* Return true if the list is empty */
532 static inline bool track_list_empty(void)
534 return track_list.end == track_list.start;
537 /* Returns true if the list is holding the maximum number of items */
538 static bool track_list_full(void)
540 return track_list.end - track_list.start >= TRACK_LIST_LEN;
543 /* Test if the index is within the allocated range */
544 static bool track_list_in_range(int pos)
546 return (int)(pos - track_list.start) >= 0 &&
547 (int)(pos - track_list.end) < 0;
550 static struct track_info * track_list_entry(int pos)
552 return &track_list.tracks[pos & TRACK_LIST_MASK];
555 /* Return the info of the last allocation plus an offset, NULL if result is
556 out of bounds */
557 static struct track_info * track_list_last(int offset)
559 /* Last is before the end since the end isn't inclusive */
560 unsigned int pos = track_list.end + offset - 1;
562 if (!track_list_in_range(pos))
563 return NULL;
565 return track_list_entry(pos);
568 /* Allocate space at the end for another track if not full */
569 static struct track_info * track_list_alloc_track(void)
571 if (track_list_full())
572 return NULL;
574 return track_list_entry(track_list.end++);
577 /* Remove the last track entry allocated in order to support backing out
578 of a track load */
579 static void track_list_unalloc_track(void)
581 if (track_list_empty())
582 return;
584 track_list.end--;
586 if (track_list.current == track_list.end &&
587 track_list.current != track_list.start)
589 /* Current _must_ remain within bounds */
590 track_list.current--;
594 /* Return current track plus an offset, NULL if result is out of bounds */
595 static struct track_info * track_list_current(int offset)
597 unsigned int pos = track_list.current + offset;
599 if (!track_list_in_range(pos))
600 return NULL;
602 return track_list_entry(pos);
605 /* Return current based upon what's intended that the user sees - not
606 necessarily where decoding is taking place */
607 static struct track_info * track_list_user_current(int offset)
609 if (skip_pending == TRACK_SKIP_AUTO ||
610 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
612 offset--;
615 return track_list_current(offset);
618 /* Advance current track by an offset, return false if result is out of
619 bounds */
620 static struct track_info * track_list_advance_current(int offset)
622 unsigned int pos = track_list.current + offset;
624 if (!track_list_in_range(pos))
625 return NULL;
627 track_list.current = pos;
628 return track_list_entry(pos);
631 /* Clear tracks in the list, optionally preserving the current track -
632 returns 'false' if the operation was changed */
633 enum track_clear_action
635 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
636 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
637 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
640 static void track_list_clear(enum track_clear_action action)
642 logf("%s(%d)", __func__, (int)action);
644 /* Don't care now since rebuffering is imminent */
645 buf_set_watermark(0);
647 if (action != TRACK_LIST_CLEAR_ALL)
649 struct track_info *cur = track_list_current(0);
651 if (!cur || cur->id3_hid < 0)
652 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
655 /* Noone should see this progressing */
656 int start = track_list.start;
657 int current = track_list.current;
658 int end = track_list.end;
660 track_list.start = current;
662 switch (action)
664 case TRACK_LIST_CLEAR_ALL:
665 /* Result: .start = .current, .end = .current */
666 track_list.end = current;
667 break;
669 case TRACK_LIST_KEEP_CURRENT:
670 /* Result: .start = .current, .end = .current + 1 */
671 track_list.end = current + 1;
672 break;
674 case TRACK_LIST_KEEP_NEW:
675 /* Result: .start = .current, .end = .end */
676 end = current;
677 break;
680 /* Close all open handles in the range except the for the current track
681 if preserving that */
682 while (start != end)
684 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
686 struct track_info *info =
687 &track_list.tracks[start & TRACK_LIST_MASK];
689 /* If this is the in-progress load, abort it */
690 if (in_progress_id3_hid >= 0 &&
691 info->id3_hid == in_progress_id3_hid)
693 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
696 track_info_close(info);
699 start++;
704 /** --- Audio buffer -- **/
706 /* What size is needed for the scratch buffer? */
707 static size_t scratch_mem_size(void)
709 size_t size = sizeof (struct audio_scratch_memory);
711 if (global_settings.cuesheet)
712 size += sizeof (struct cuesheet);
714 return size;
717 /* Initialize the memory area where data is stored that is only used when
718 playing audio and anything depending upon it */
719 static void scratch_mem_init(void *mem)
721 audio_scratch_memory = (struct audio_scratch_memory *)mem;
722 id3_write_locked(UNBUFFERED_ID3, NULL);
723 id3_write(CODEC_ID3, NULL);
724 ci.id3 = id3_get(CODEC_ID3);
725 audio_scratch_memory->curr_cue = NULL;
727 if (global_settings.cuesheet)
729 audio_scratch_memory->curr_cue =
730 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
731 sizeof (struct audio_scratch_memory));
735 /* Set up the audio buffer for playback */
736 static void audio_reset_buffer(void)
739 * Layout audio buffer as follows:
740 * [[|TALK]|SCRATCH|BUFFERING|PCM|]
743 /* see audio_get_recording_buffer if this is modified */
744 logf("%s()", __func__);
746 /* If the setup of anything allocated before the file buffer is
747 changed, do check the adjustments after the buffer_alloc call
748 as it will likely be affected and need sliding over */
750 /* Initially set up file buffer as all space available */
751 unsigned char *filebuf = audiobuf + talk_get_bufsize();
752 size_t filebuflen = audiobufend - filebuf;
753 size_t allocsize;
755 ALIGN_BUFFER(filebuf, filebuflen, sizeof (intptr_t));
757 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
758 allocsize = pcmbuf_init(filebuf + filebuflen);
760 /* Make sure filebuflen is a pointer sized multiple after adjustment */
761 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
762 if (allocsize > filebuflen)
763 goto bufpanic;
765 filebuflen -= allocsize;
767 /* Scratch memory */
768 allocsize = scratch_mem_size();
769 if (allocsize > filebuflen)
770 goto bufpanic;
772 scratch_mem_init(filebuf);
773 filebuf += allocsize;
774 filebuflen -= allocsize;
776 buffering_reset(filebuf, filebuflen);
778 /* Clear any references to the file buffer */
779 buffer_state = AUDIOBUF_STATE_INITIALIZED;
781 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
782 /* Make sure everything adds up - yes, some info is a bit redundant but
783 aids viewing and the sumation of certain variables should add up to
784 the location of others. */
786 size_t pcmbufsize;
787 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
788 logf("fbuf: %08X", (unsigned)filebuf);
789 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
790 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
791 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
792 logf("pcmb: %08X", (unsigned)pcmbuf);
793 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
795 #endif
797 return;
799 bufpanic:
800 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
803 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
804 static void audio_update_filebuf_watermark(int seconds)
806 size_t bytes = 0;
808 #ifdef HAVE_DISK_STORAGE
809 int spinup = ata_spinup_time();
811 if (seconds == 0)
813 /* By current setting */
814 seconds = buffer_margin;
816 else
818 /* New setting */
819 buffer_margin = seconds;
821 if (buf_get_watermark() == 0)
823 /* Write a watermark only if the audio thread already did so for
824 itself or it will fail to set the event and the watermark - if
825 it hasn't yet, it will use the new setting when it does */
826 return;
830 if (spinup)
831 seconds += (spinup / HZ) + 1;
832 else
833 seconds += 5;
835 seconds += buffer_margin;
836 #else
837 /* flash storage */
838 seconds = 1;
839 #endif
841 /* Watermark is a function of the bitrate of the last track in the buffer */
842 struct mp3entry *id3 = NULL;
843 struct track_info *info = track_list_last(0);
845 if (info)
846 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
848 if (id3)
850 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
852 bytes = id3->bitrate * (1000/8) * seconds;
854 else
856 /* Bitrate has no meaning to buffering margin for atomic audio -
857 rebuffer when it's the only track left unless it's the only
858 track that fits, in which case we should avoid constant buffer
859 low events */
860 if (track_list_count() > 1)
861 bytes = info->filesize + 1;
864 else
866 /* Then set the minimum - this should not occur anyway */
867 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
868 track_list.start, track_list.current, track_list.end);
871 /* Actually setting zero disables the notification and we use that
872 to detect that it has been reset */
873 buf_set_watermark(MAX(bytes, 1));
874 logf("fwmark: %lu", (unsigned long)bytes);
878 /** -- Track change notification -- **/
880 /* Check the pcmbuf track changes and return write the message into the event
881 if there are any */
882 static inline bool audio_pcmbuf_track_change_scan(void)
884 if (track_change.out != track_change.in)
886 track_change.out++;
887 return true;
890 return false;
893 /* Clear outstanding track change posts */
894 static inline void audio_pcmbuf_track_change_clear(void)
896 track_change.out = track_change.in;
899 /* Post a track change notification - called by audio ISR */
900 static inline void audio_pcmbuf_track_change_post(void)
902 track_change.in++;
906 /** --- Helper functions --- **/
908 /* Removes messages that might end up in the queue before or while processing
909 a manual track change. Responding to them would be harmful since they
910 belong to a previous track's playback period. Anything that would generate
911 the stale messages must first be put into a state where it will not do so.
913 static void audio_clear_track_notifications(void)
915 static const long filter_list[][2] =
917 /* codec messages */
918 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
919 /* track change messages */
920 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
923 const int filter_count = ARRAYLEN(filter_list) - 1;
925 /* Remove any pcmbuf notifications */
926 pcmbuf_monitor_track_change(false);
927 audio_pcmbuf_track_change_clear();
929 /* Scrub the audio queue of the old mold */
930 while (queue_peek_ex(&audio_queue, NULL,
931 filter_count | QPEEK_REMOVE_EVENTS,
932 filter_list))
934 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
938 /* Takes actions based upon track load status codes */
939 static void audio_handle_track_load_status(int trackstat)
941 switch (trackstat)
943 case LOAD_TRACK_ERR_NO_MORE:
944 if (track_list_count() > 0)
945 break;
947 case LOAD_TRACK_ERR_START_CODEC:
948 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
949 break;
951 default:
952 break;
956 /* Announce the end of playing the current track */
957 static void audio_playlist_track_finish(void)
959 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
961 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
963 if (id3)
965 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
966 prev_track_elapsed = id3->elapsed;
968 else
970 prev_track_elapsed = 0;
974 /* Announce the beginning of the new track */
975 static void audio_playlist_track_change(void)
977 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
979 if (id3)
980 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
982 playlist_update_resume_info(id3);
985 /* Change the data for the next track and send the event */
986 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
988 id3_write_locked(NEXTTRACK_ID3, id3_next);
989 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
990 id3_get(NEXTTRACK_ID3));
993 /* Bring the user current mp3entry up to date and set a new offset for the
994 buffered metadata */
995 static void playing_id3_sync(struct track_info *user_info, size_t offset)
997 id3_mutex_lock();
999 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1001 if (offset == (size_t)-1)
1003 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1004 size_t play_offset = ply_id3->offset;
1005 long play_elapsed = ply_id3->elapsed;
1006 id3_write(PLAYING_ID3, id3);
1007 ply_id3->offset = play_offset;
1008 ply_id3->elapsed = play_elapsed;
1009 offset = 0;
1011 else
1013 id3_write(PLAYING_ID3, id3);
1016 if (id3)
1017 id3->offset = offset;
1019 id3_mutex_unlock();
1022 /* Wipe-out track metadata - current is optional */
1023 static void wipe_track_metadata(bool current)
1025 id3_mutex_lock();
1027 if (current)
1028 id3_write(PLAYING_ID3, NULL);
1030 id3_write(NEXTTRACK_ID3, NULL);
1031 id3_write(UNBUFFERED_ID3, NULL);
1033 id3_mutex_unlock();
1036 /* Called when buffering is completed on the last track handle */
1037 static void filling_is_finished(void)
1039 logf("last track finished buffering");
1041 /* There's no more to load or watch for */
1042 buf_set_watermark(0);
1043 filling = STATE_FINISHED;
1046 /* Stop the codec decoding or waiting for its data to be ready - returns
1047 'false' if the codec ended up stopped */
1048 static bool halt_decoding_track(bool stop)
1050 /* If it was waiting for us to clear the buffer to make a rebuffer
1051 happen, it should cease otherwise codec_stop could deadlock waiting
1052 for the codec to go to its main loop - codec's request will now
1053 force-fail */
1054 bool retval = false;
1056 buf_signal_handle(ci.audio_hid, true);
1058 if (stop)
1059 codec_stop();
1060 else
1061 retval = codec_pause();
1063 audio_clear_track_notifications();
1065 /* We now know it's idle and not waiting for buffered data */
1066 buf_signal_handle(ci.audio_hid, false);
1068 codec_skip_pending = false;
1069 codec_seeking = false;
1071 return retval;
1074 /* Clear the PCM on a manual skip */
1075 static void audio_clear_paused_pcm(void)
1077 if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active())
1078 pcmbuf_play_stop();
1081 /* End the ff/rw mode */
1082 static void audio_ff_rewind_end(void)
1084 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1085 section */
1086 if (ff_rw_mode)
1088 ff_rw_mode = false;
1090 if (codec_seeking)
1092 /* Clear the buffer */
1093 pcmbuf_play_stop();
1096 if (play_status != PLAY_PAUSED)
1098 /* Seeking-while-playing, resume PCM playback */
1099 pcmbuf_pause(false);
1104 /* Complete the codec seek */
1105 static void audio_complete_codec_seek(void)
1107 /* If a seek completed while paused, 'paused' is true.
1108 * If seeking from seek mode, 'ff_rw_mode' is true. */
1109 if (codec_seeking)
1111 audio_ff_rewind_end();
1112 codec_seeking = false; /* set _after_ the call! */
1114 /* else it's waiting and we must repond */
1117 /* Get the current cuesheet pointer */
1118 static inline struct cuesheet * get_current_cuesheet(void)
1120 return audio_scratch_memory->curr_cue;
1123 /* Read the cuesheet from the buffer */
1124 static void buf_read_cuesheet(int handle_id)
1126 struct cuesheet *cue = get_current_cuesheet();
1128 if (!cue || handle_id < 0)
1129 return;
1131 bufread(handle_id, sizeof (struct cuesheet), cue);
1134 /* Backend to peek/current/next track metadata interface functions -
1135 fill in the mp3entry with as much information as we may obtain about
1136 the track at the specified offset from the user current track -
1137 returns false if no information exists with us */
1138 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1140 if (play_status == PLAY_STOPPED)
1141 return false;
1143 if (id3->path[0] != '\0')
1144 return true; /* Already filled */
1146 struct track_info *info = track_list_user_current(offset);
1148 if (!info)
1150 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1152 if (offset > 0 && track_list_user_current(offset - 1))
1154 /* Try the unbuffered id3 since we're moving forward */
1155 if (ub_id3->path[0] != '\0')
1157 copy_mp3entry(id3, ub_id3);
1158 return true;
1162 else if (bufreadid3(info->id3_hid, id3))
1164 return true;
1167 /* We didn't find the ID3 metadata, so we fill it with the little info we
1168 have and return that */
1170 char path[MAX_PATH+1];
1171 if (playlist_peek(offset, path, sizeof (path)))
1173 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1174 /* Try to get it from the database */
1175 if (!tagcache_fill_tags(id3, path))
1176 #endif
1178 /* By now, filename is the only source of info */
1179 fill_metadata_from_path(id3, path);
1182 return true;
1185 wipe_mp3entry(id3);
1187 return false;
1190 /* Get a resume rewind adjusted offset from the ID3 */
1191 unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1193 unsigned long offset = id3->offset;
1194 size_t resume_rewind = global_settings.resume_rewind *
1195 id3->bitrate * (1000/8);
1197 if (offset < resume_rewind)
1198 offset = 0;
1199 else
1200 offset -= resume_rewind;
1202 return offset;
1205 /* Get the codec into ram and initialize it - keep it if it's ready */
1206 static bool audio_init_codec(struct track_info *track_info,
1207 struct mp3entry *track_id3)
1209 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1210 int hid = ERR_HANDLE_NOT_FOUND;
1212 if (codt_loaded != AFMT_UNKNOWN)
1214 int codt = get_audio_base_codec_type(track_id3->codectype);
1216 if (codt == codt_loaded)
1218 /* Codec is the same base type */
1219 logf("Reusing prev. codec: %d", track_id3->codectype);
1220 #ifdef HAVE_CODEC_BUFFERING
1221 /* Close any buffered codec (we could have skipped directly to a
1222 format transistion that is the same format as the current track
1223 and the buffered one is no longer needed) */
1224 track_info_close_handle(&track_info->codec_hid);
1225 #endif
1226 return true;
1228 else
1230 /* New codec - first make sure the old one's gone */
1231 logf("Removing prev. codec: %d", codt_loaded);
1232 codec_unload();
1236 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1238 #ifdef HAVE_CODEC_BUFFERING
1239 /* Codec thread will close the handle even if it fails and will load from
1240 storage if hid is not valid or the buffer load fails */
1241 hid = track_info->codec_hid;
1242 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1243 #endif
1245 return codec_load(hid, track_id3->codectype);
1246 (void)track_info; /* When codec buffering isn't supported */
1249 /* Start the codec for the current track scheduled to be decoded */
1250 static bool audio_start_codec(bool auto_skip)
1252 struct track_info *info = track_list_current(0);
1253 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1255 if (!cur_id3)
1256 return false;
1258 buf_pin_handle(info->id3_hid, true);
1260 if (!audio_init_codec(info, cur_id3))
1262 buf_pin_handle(info->id3_hid, false);
1263 return false;
1266 #ifdef HAVE_TAGCACHE
1267 bool autoresume_enable = global_settings.autoresume_enable;
1269 if (autoresume_enable && !cur_id3->offset)
1271 /* Resume all manually selected tracks */
1272 bool resume = !auto_skip;
1274 /* Send the "buffer" event to obtain the resume position for the codec */
1275 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1277 if (!resume)
1279 /* Automatic skip - do further tests to see if we should just
1280 ignore any autoresume position */
1281 int autoresume_automatic = global_settings.autoresume_automatic;
1283 switch (autoresume_automatic)
1285 case AUTORESUME_NEXTTRACK_ALWAYS:
1286 /* Just resume unconditionally */
1287 resume = true;
1288 break;
1289 case AUTORESUME_NEXTTRACK_NEVER:
1290 /* Force-rewind it */
1291 break;
1292 default:
1293 /* Not "never resume" - pass resume filter? */
1294 resume = autoresumable(cur_id3);
1298 if (!resume)
1299 cur_id3->offset = 0;
1301 logf("%s: Set offset for %s to %lX\n", __func__,
1302 cur_id3->title, cur_id3->offset);
1304 #endif /* HAVE_TAGCACHE */
1306 /* Rewind the required amount - if an autoresume was done, this also rewinds
1307 that by the setting's amount
1309 It would be best to have bookkeeping about whether or not the track
1310 sounded or not since skipping to it or else skipping to it while paused
1311 and back again will cause accumulation of silent rewinds - that's not
1312 our job to track directly nor could it be in any reasonable way
1314 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1316 /* Update the codec API with the metadata and track info */
1317 id3_write(CODEC_ID3, cur_id3);
1319 ci.audio_hid = info->audio_hid;
1320 ci.filesize = info->filesize;
1321 buf_set_base_handle(info->audio_hid);
1323 /* All required data is now available for the codec */
1324 codec_go();
1326 #ifdef HAVE_TAGCACHE
1327 if (!autoresume_enable || cur_id3->offset)
1328 #endif
1330 /* Send the "buffer" event now */
1331 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1334 buf_pin_handle(info->id3_hid, false);
1335 return true;
1337 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1341 /** --- Audio thread --- **/
1343 /* Load and parse a cuesheet for the file - returns false if the buffer
1344 is full */
1345 static bool audio_load_cuesheet(struct track_info *info,
1346 struct mp3entry *track_id3)
1348 struct cuesheet *cue = get_current_cuesheet();
1349 track_id3->cuesheet = NULL;
1351 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1353 /* If error other than a full buffer, then mark it "unsupported" to
1354 avoid reloading attempt */
1355 int hid = ERR_UNSUPPORTED_TYPE;
1356 char cuepath[MAX_PATH];
1358 #ifdef HAVE_IO_PRIORITY
1359 buf_back_off_storage(true);
1360 #endif
1361 if (look_for_cuesheet_file(track_id3->path, cuepath))
1363 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1365 if (hid >= 0)
1367 void *cuesheet = NULL;
1368 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1370 if (parse_cuesheet(cuepath, (struct cuesheet *)cuesheet))
1372 /* Indicate cuesheet is present (while track remains
1373 buffered) */
1374 track_id3->cuesheet = cue;
1376 else
1378 bufclose(hid);
1379 hid = ERR_UNSUPPORTED_TYPE;
1384 #ifdef HAVE_IO_PRIORITY
1385 buf_back_off_storage(false);
1386 #endif
1387 if (hid == ERR_BUFFER_FULL)
1389 logf("buffer is full for now (%s)", __func__);
1390 return false;
1392 else
1394 if (hid < 0)
1395 logf("Cuesheet loading failed");
1397 info->cuesheet_hid = hid;
1401 return true;
1404 #ifdef HAVE_ALBUMART
1405 /* Load any album art for the file - returns false if the buffer is full */
1406 static bool audio_load_albumart(struct track_info *info,
1407 struct mp3entry *track_id3)
1409 int i;
1410 FOREACH_ALBUMART(i)
1412 struct bufopen_bitmap_data user_data;
1413 int *aa_hid = &info->aa_hid[i];
1414 int hid = ERR_UNSUPPORTED_TYPE;
1416 /* albumart_slots may change during a yield of bufopen,
1417 * but that's no problem */
1418 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1419 !albumart_slots[i].used)
1420 continue;
1422 memset(&user_data, 0, sizeof(user_data));
1423 user_data.dim = &albumart_slots[i].dim;
1425 #ifdef HAVE_IO_PRIORITY
1426 buf_back_off_storage(true);
1427 #endif
1429 /* We can only decode jpeg for embedded AA */
1430 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1432 user_data.embedded_albumart = &track_id3->albumart;
1433 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1436 if (hid < 0 && hid != ERR_BUFFER_FULL)
1438 /* No embedded AA or it couldn't be loaded - try other sources */
1439 char path[MAX_PATH];
1441 if (find_albumart(track_id3, path, sizeof(path),
1442 &albumart_slots[i].dim))
1444 user_data.embedded_albumart = NULL;
1445 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1449 #ifdef HAVE_IO_PRIORITY
1450 buf_back_off_storage(false);
1451 #endif
1452 if (hid == ERR_BUFFER_FULL)
1454 logf("buffer is full for now (%s)", __func__);
1455 return false;
1457 else
1459 /* If error other than a full buffer, then mark it "unsupported"
1460 to avoid reloading attempt */
1461 if (hid < 0)
1463 logf("Album art loading failed");
1464 hid = ERR_UNSUPPORTED_TYPE;
1467 *aa_hid = hid;
1471 return true;
1473 #endif /* HAVE_ALBUMART */
1475 #ifdef HAVE_CODEC_BUFFERING
1476 /* Load a codec for the file onto the buffer - assumes we're working from the
1477 currently loading track - not called for the current track */
1478 static bool audio_buffer_codec(struct track_info *track_info,
1479 struct mp3entry *track_id3)
1481 /* This will not be the current track -> it cannot be the first and the
1482 current track cannot be ahead of buffering -> there is a previous
1483 track entry which is either current or ahead of the current */
1484 struct track_info *prev_info = track_list_last(-1);
1485 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1487 /* If the previous codec is the same as this one, there is no need to
1488 put another copy of it on the file buffer (in other words, only
1489 buffer codecs at format transitions) */
1490 if (prev_id3)
1492 int codt = get_audio_base_codec_type(track_id3->codectype);
1493 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1495 if (codt == prev_codt)
1497 logf("Reusing prev. codec: %d", prev_id3->codectype);
1498 return true;
1501 /* else just load it (harmless) */
1503 /* Load the codec onto the buffer if possible */
1504 const char *codec_fn = get_codec_filename(track_id3->codectype);
1505 if (!codec_fn)
1506 return false;
1508 char codec_path[MAX_PATH+1]; /* Full path to codec */
1509 codec_get_full_path(codec_path, codec_fn);
1511 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1513 if (track_info->codec_hid >= 0)
1515 logf("Buffered codec: %d", afmt);
1516 return true;
1519 return false;
1521 #endif /* HAVE_CODEC_BUFFERING */
1523 /* Load metadata for the next track (with bufopen). The rest of the track
1524 loading will be handled by audio_finish_load_track once the metadata has
1525 been actually loaded by the buffering thread.
1527 Each track is arranged in the buffer as follows:
1528 <id3|[cuesheet|][album art|][codec|]audio>
1530 The next will not be loaded until the previous succeeds if the buffer was
1531 full at the time. To put any metadata after audio would make those handles
1532 unmovable.
1534 static int audio_load_track(void)
1536 if (in_progress_id3_hid >= 0)
1538 /* There must be an info pointer if the in-progress id3 is even there */
1539 struct track_info *info = track_list_last(0);
1541 if (info->id3_hid == in_progress_id3_hid)
1543 if (filling == STATE_FILLING)
1545 /* Haven't finished the metadata but the notification is
1546 anticipated to come soon */
1547 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1548 return LOAD_TRACK_OK;
1550 else if (filling == STATE_FULL)
1552 /* Buffer was full trying to complete the load after the
1553 metadata finished, so attempt to continue - older handles
1554 should have been cleared already */
1555 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1556 filling = STATE_FILLING;
1557 buffer_event_finished_callback(&info->id3_hid);
1558 return LOAD_TRACK_OK;
1562 /* Some old, stray buffering message */
1563 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1564 return LOAD_TRACK_ERR_BUSY;
1567 filling = STATE_FILLING;
1569 struct track_info *info = track_list_alloc_track();
1570 if (info == NULL)
1572 /* List is full so stop buffering tracks - however, attempt to obtain
1573 metadata as the unbuffered id3 */
1574 logf("No free tracks");
1575 filling = STATE_FULL;
1578 playlist_peek_offset++;
1580 logf("Buffering track: s%u/c%u/e%u/p%d",
1581 track_list.start, track_list.current, track_list.end,
1582 playlist_peek_offset);
1584 /* Get track name from current playlist read position */
1585 int fd = -1;
1586 char name_buf[MAX_PATH + 1];
1587 const char *trackname;
1589 while (1)
1592 trackname = playlist_peek(playlist_peek_offset, name_buf,
1593 sizeof (name_buf));
1595 if (!trackname)
1596 break;
1598 /* Test for broken playlists by probing for the files */
1599 fd = open(trackname, O_RDONLY);
1600 if (fd >= 0)
1601 break;
1603 logf("Open failed");
1604 /* Skip invalid entry from playlist */
1605 playlist_skip_entry(NULL, playlist_peek_offset);
1607 /* Sync the playlist if it isn't finished */
1608 if (playlist_peek(playlist_peek_offset, NULL, 0))
1609 playlist_next(0);
1612 if (!trackname)
1614 /* No track - exhausted the playlist entries */
1615 logf("End-of-playlist");
1616 id3_write_locked(UNBUFFERED_ID3, NULL);
1618 if (filling != STATE_FULL)
1619 track_list_unalloc_track(); /* Free this entry */
1621 playlist_peek_offset--; /* Maintain at last index */
1623 /* We can end up here after the real last track signals its completion
1624 and miss the transition to STATE_FINISHED esp. if dropping the last
1625 songs of a playlist late in their load (2nd stage) */
1626 info = track_list_last(0);
1628 if (info && buf_handle_remaining(info->audio_hid) == 0)
1629 filling_is_finished();
1630 else
1631 filling = STATE_END_OF_PLAYLIST;
1633 return LOAD_TRACK_ERR_NO_MORE;
1636 /* Successfully opened the file - get track metadata */
1637 if (filling == STATE_FULL ||
1638 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1640 /* Buffer or track list is full */
1641 struct mp3entry *ub_id3;
1643 playlist_peek_offset--;
1645 /* Load the metadata for the first unbuffered track */
1646 ub_id3 = id3_get(UNBUFFERED_ID3);
1647 id3_mutex_lock();
1648 get_metadata(ub_id3, fd, trackname);
1649 id3_mutex_unlock();
1651 if (filling != STATE_FULL)
1653 track_list_unalloc_track();
1654 filling = STATE_FULL;
1657 logf("%s: buffer is full for now (%u tracks)", __func__,
1658 track_list_count());
1660 else
1662 /* Successful load initiation */
1663 info->filesize = filesize(fd);
1664 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1667 close(fd);
1668 return LOAD_TRACK_OK;
1671 /* Second part of the track loading: We now have the metadata available, so we
1672 can load the codec, the album art and finally the audio data.
1673 This is called on the audio thread after the buffering thread calls the
1674 buffering_handle_finished_callback callback. */
1675 static int audio_finish_load_track(struct track_info *info)
1677 int trackstat = LOAD_TRACK_OK;
1679 if (info->id3_hid != in_progress_id3_hid)
1681 /* We must not be here if not! */
1682 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1683 in_progress_id3_hid);
1684 return LOAD_TRACK_ERR_BUSY;
1687 /* The current track for decoding (there is always one if the list is
1688 populated) */
1689 struct track_info *cur_info = track_list_current(0);
1690 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1692 if (!track_id3)
1694 /* This is an error condition. Track cannot be played without valid
1695 metadata; skip the track. */
1696 logf("No metadata for: %s", track_id3->path);
1697 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1698 goto audio_finish_load_track_exit;
1701 /* Try to load a cuesheet for the track */
1702 if (!audio_load_cuesheet(info, track_id3))
1704 /* No space for cuesheet on buffer, not an error */
1705 filling = STATE_FULL;
1706 goto audio_finish_load_track_exit;
1709 #ifdef HAVE_ALBUMART
1710 /* Try to load album art for the track */
1711 if (!audio_load_albumart(info, track_id3))
1713 /* No space for album art on buffer, not an error */
1714 filling = STATE_FULL;
1715 goto audio_finish_load_track_exit;
1717 #endif
1719 #ifdef HAVE_CODEC_BUFFERING
1720 /* Try to buffer a codec for the track */
1721 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1723 if (info->codec_hid == ERR_BUFFER_FULL)
1725 /* No space for codec on buffer, not an error */
1726 filling = STATE_FULL;
1727 logf("buffer is full for now (%s)", __func__);
1729 else
1731 /* This is an error condition, either no codec was found, or
1732 reading the codec file failed part way through, either way,
1733 skip the track */
1734 logf("No codec for: %s", track_id3->path);
1735 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1738 goto audio_finish_load_track_exit;
1740 #endif /* HAVE_CODEC_BUFFERING */
1742 /** Finally, load the audio **/
1743 size_t file_offset = 0;
1744 track_id3->elapsed = 0;
1746 if (track_id3->offset >= info->filesize)
1747 track_id3->offset = 0;
1749 logf("%s: set offset for %s to %lu\n", __func__,
1750 id3->title, (unsigned long)offset);
1752 /* Adjust for resume rewind so we know what to buffer - starting the codec
1753 calls it again, so we don't save it (and they shouldn't accumulate) */
1754 size_t offset = resume_rewind_adjusted_offset(track_id3);
1756 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1758 if (audiotype == TYPE_ATOMIC_AUDIO)
1759 logf("Loading atomic %d", track_id3->codectype);
1761 if (format_buffers_with_offset(track_id3->codectype))
1763 /* This format can begin buffering from any point */
1764 file_offset = offset;
1767 logf("load track: %s", track_id3->path);
1769 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1771 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1772 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1774 else
1776 /* No offset given or it is very minimal - begin at the first frame
1777 according to the metadata */
1778 file_offset = track_id3->first_frame_offset;
1781 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1783 if (hid >= 0)
1785 info->audio_hid = hid;
1787 if (info == cur_info)
1789 /* This is the current track to decode - should be started now */
1790 trackstat = LOAD_TRACK_READY;
1793 else
1795 /* Buffer could be full but not properly so if this is the only
1796 track! */
1797 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1799 filling = STATE_FULL;
1800 logf("Buffer is full for now (%s)", __func__);
1802 else
1804 /* Nothing to play if no audio handle - skip this */
1805 logf("Could not add audio data handle");
1806 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1810 audio_finish_load_track_exit:
1811 if (trackstat < LOAD_TRACK_OK)
1813 playlist_skip_entry(NULL, playlist_peek_offset);
1814 track_info_close(info);
1815 track_list_unalloc_track();
1817 if (playlist_peek(playlist_peek_offset, NULL, 0))
1818 playlist_next(0);
1820 playlist_peek_offset--;
1823 if (filling != STATE_FULL)
1825 /* Load next track - error or not */
1826 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1827 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1828 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1830 else
1832 /* Full */
1833 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1836 return trackstat;
1839 /* Start a new track load */
1840 static int audio_fill_file_buffer(void)
1842 if (play_status == PLAY_STOPPED)
1843 return LOAD_TRACK_ERR_FAILED;
1845 trigger_cpu_boost();
1847 /* Must reset the buffer before use if trashed or voice only - voice
1848 file size shouldn't have changed so we can go straight from
1849 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1850 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1851 audio_reset_buffer();
1853 logf("Starting buffer fill");
1855 int trackstat = audio_load_track();
1857 if (trackstat >= LOAD_TRACK_OK)
1859 if (track_list_current(0) == track_list_user_current(0))
1860 playlist_next(0);
1862 if (filling == STATE_FULL && !track_list_user_current(1))
1864 /* There are no user tracks on the buffer after this therefore
1865 this is the next track */
1866 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
1870 return trackstat;
1873 /* Discard unwanted tracks and start refill from after the specified playlist
1874 offset */
1875 static int audio_reset_and_rebuffer(
1876 enum track_clear_action action, int peek_offset)
1878 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
1880 id3_write_locked(UNBUFFERED_ID3, NULL);
1882 /* Remove unwanted tracks - caller must have ensured codec isn't using
1883 any */
1884 track_list_clear(action);
1886 /* Refill at specified position (-1 starts at index offset 0) */
1887 playlist_peek_offset = peek_offset;
1889 /* Fill the buffer */
1890 return audio_fill_file_buffer();
1893 /* Handle buffering events
1894 (Q_AUDIO_BUFFERING) */
1895 static void audio_on_buffering(int event)
1897 enum track_clear_action action;
1898 int peek_offset;
1900 if (track_list_empty())
1901 return;
1903 switch (event)
1905 case BUFFER_EVENT_BUFFER_LOW:
1906 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
1907 return; /* Should be nothing left to fill */
1909 /* Clear old tracks and continue buffering where it left off */
1910 action = TRACK_LIST_KEEP_NEW;
1911 peek_offset = playlist_peek_offset;
1912 break;
1914 case BUFFER_EVENT_REBUFFER:
1915 /* Remove all but the currently decoding track and redo buffering
1916 after that */
1917 action = TRACK_LIST_KEEP_CURRENT;
1918 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
1919 break;
1921 default:
1922 return;
1925 switch (skip_pending)
1927 case TRACK_SKIP_NONE:
1928 case TRACK_SKIP_AUTO:
1929 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
1930 audio_reset_and_rebuffer(action, peek_offset);
1931 break;
1933 case TRACK_SKIP_AUTO_END_PLAYLIST:
1934 /* Already finished */
1935 break;
1937 default:
1938 /* Invalid */
1939 logf("Buffering call, inv. state: %d", (int)skip_pending);
1943 /* Handle starting the next track load
1944 (Q_AUDIO_FILL_BUFFER) */
1945 static void audio_on_fill_buffer(void)
1947 audio_handle_track_load_status(audio_fill_file_buffer());
1950 /* Handle posted load track finish event
1951 (Q_AUDIO_FINISH_LOAD_TRACK) */
1952 static void audio_on_finish_load_track(int id3_hid)
1954 struct track_info *info = track_list_last(0);
1956 if (!info || !buf_is_handle(id3_hid))
1957 return;
1959 if (info == track_list_user_current(1))
1961 /* Just loaded the metadata right after the current position */
1962 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
1965 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
1966 return; /* Not current track */
1968 bool is_user_current = info == track_list_user_current(0);
1970 if (is_user_current)
1972 /* Copy cuesheet */
1973 buf_read_cuesheet(info->cuesheet_hid);
1976 if (audio_start_codec(automatic_skip))
1978 if (is_user_current)
1980 /* Be sure all tagtree info is synchronized; it will be needed for the
1981 track finish event - the sync will happen when finalizing a track
1982 change otherwise */
1983 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
1985 playing_id3_sync(info, -1);
1987 if (!was_valid)
1989 /* Playing id3 hadn't been updated yet because no valid track
1990 was yet available - treat like the first track */
1991 audio_playlist_track_change();
1995 else
1997 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2001 /* Called when handles other than metadata handles have finished buffering
2002 (Q_AUDIO_HANDLE_FINISHED) */
2003 static void audio_on_handle_finished(int hid)
2005 /* Right now, only audio handles should end up calling this */
2006 if (filling == STATE_END_OF_PLAYLIST)
2008 struct track_info *info = track_list_last(0);
2010 /* Really we don't know which order the handles will actually complete
2011 to zero bytes remaining since another thread is doing it - be sure
2012 it's the right one */
2013 if (info && info->audio_hid == hid)
2015 /* This was the last track in the playlist and we now have all the
2016 data we need */
2017 filling_is_finished();
2022 /* Called to make an outstanding track skip the current track and to send the
2023 transition events */
2024 static void audio_finalise_track_change(bool delayed)
2026 switch (skip_pending)
2028 case TRACK_SKIP_NONE: /* Manual skip */
2029 break;
2031 case TRACK_SKIP_AUTO:
2032 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2034 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2035 audio_playlist_track_finish();
2037 if (!playlist_peek(playlist_delta, NULL, 0))
2039 /* Track ended up rejected - push things ahead like the codec blew
2040 it (because it was never started and now we're here where it
2041 should have been decoding the next track by now) - next, a
2042 directory change or end of playback will most likely happen */
2043 skip_pending = TRACK_SKIP_NONE;
2044 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2045 return;
2048 if (!playlist_delta)
2049 break;
2051 playlist_peek_offset -= playlist_delta;
2052 if (playlist_next(playlist_delta) >= 0)
2053 break;
2054 /* What!? Disappear? Hopeless bleak despair */
2056 /* Fallthrough */
2057 case TRACK_SKIP_AUTO_END_PLAYLIST:
2058 default: /* Invalid */
2059 filling = STATE_ENDED;
2060 audio_stop_playback();
2061 return;
2064 struct track_info *info = track_list_current(0);
2065 struct mp3entry *track_id3 = NULL;
2067 id3_mutex_lock();
2069 /* Update the current cuesheet if any and enabled */
2070 if (info)
2072 buf_read_cuesheet(info->cuesheet_hid);
2073 track_id3 = bufgetid3(info->id3_hid);
2076 id3_write(PLAYING_ID3, track_id3);
2078 if (delayed)
2080 /* Delayed skip where codec is ahead of user's current track */
2081 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2082 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
2083 ply_id3->elapsed = ci_id3->elapsed;
2084 ply_id3->offset = ci_id3->offset;
2087 /* The skip is technically over */
2088 skip_pending = TRACK_SKIP_NONE;
2090 /* Sync the next track information */
2091 info = track_list_current(1);
2093 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2094 id3_get(UNBUFFERED_ID3));
2096 id3_mutex_unlock();
2098 audio_playlist_track_change();
2101 /* Actually begin a transition and take care of the codec change - may complete
2102 it now or ask pcmbuf for notification depending on the type and what pcmbuf
2103 has to say */
2104 static void audio_begin_track_change(bool auto_skip, int trackstat)
2106 /* Even if the new track is bad, the old track must be finished off */
2107 bool finalised = pcmbuf_start_track_change(auto_skip);
2109 if (finalised)
2111 /* pcmbuf says that the transition happens now - complete it */
2112 audio_finalise_track_change(false);
2114 if (play_status == PLAY_STOPPED)
2115 return; /* Stopped us */
2118 if (!auto_skip)
2119 audio_clear_paused_pcm();
2121 if (trackstat >= LOAD_TRACK_OK)
2123 struct track_info *info = track_list_current(0);
2125 if (info->audio_hid < 0)
2126 return;
2128 /* Everything needed for the codec is ready - start it */
2129 if (audio_start_codec(auto_skip))
2131 if (finalised)
2132 playing_id3_sync(info, -1);
2133 return;
2136 trackstat = LOAD_TRACK_ERR_START_CODEC;
2139 audio_handle_track_load_status(trackstat);
2142 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2143 static void audio_monitor_end_of_playlist(void)
2145 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2146 filling = STATE_ENDING;
2147 pcmbuf_monitor_track_change(true);
2150 /* Codec has completed decoding the track
2151 (usually Q_AUDIO_CODEC_COMPLETE) */
2152 static void audio_on_codec_complete(int status)
2154 logf("%s(%d)", __func__, status);
2156 if (play_status == PLAY_STOPPED)
2157 return;
2159 /* If it didn't notify us first, don't expect "seek complete" message
2160 since the codec can't post it now - do things like it would have
2161 done */
2162 audio_complete_codec_seek();
2164 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2166 /* Old-hay on the ip-skay - codec has completed decoding
2168 Paused: We're not sounding it, so just remember that it happened
2169 and the resume will begin the transition
2171 Skipping: There was already a skip in progress, remember it and
2172 allow no further progress until the PCM from the previous
2173 song has finished
2175 codec_skip_pending = true;
2176 codec_skip_status = status;
2177 return;
2180 codec_skip_pending = false;
2182 #ifdef AB_REPEAT_ENABLE
2183 if (status >= 0)
2185 /* Normal automatic skip */
2186 ab_end_of_track_report();
2188 #endif
2190 int trackstat = LOAD_TRACK_OK;
2192 automatic_skip = true;
2193 skip_pending = TRACK_SKIP_AUTO;
2195 /* Does this track have an entry allocated? */
2196 struct track_info *info = track_list_advance_current(1);
2198 if (!info || info->audio_hid < 0)
2200 bool end_of_playlist = false;
2202 if (info)
2204 /* Track load is not complete - it might have stopped on a
2205 full buffer without reaching the audio handle or we just
2206 arrived at it early
2208 If this type is atomic and we couldn't get the audio,
2209 perhaps it would need to wrap to make the allocation and
2210 handles are in the way - to maximize the liklihood it can
2211 be allocated, clear all handles to reset the buffer and
2212 its indexes to 0 - for packet audio, this should not be an
2213 issue and a pointless full reload of all the track's
2214 metadata may be avoided */
2216 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2218 if (track_id3 &&
2219 get_audio_base_data_type(track_id3->codectype)
2220 == TYPE_PACKET_AUDIO)
2222 /* Continue filling after this track */
2223 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2224 audio_begin_track_change(true, trackstat);
2225 return;
2227 /* else rebuffer at this track; status applies to the track we
2228 want */
2230 else if (!playlist_peek(1, NULL, 0))
2232 /* Play sequence is complete - directory change or other playlist
2233 resequencing - the playlist must now be advanced in order to
2234 continue since a peek ahead to the next track is not possible */
2235 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2236 end_of_playlist = playlist_next(1) < 0;
2239 if (!end_of_playlist)
2241 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2242 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2244 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2246 /* Failed to find anything afterall - do playlist switchover
2247 instead */
2248 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2249 end_of_playlist = playlist_next(1) < 0;
2253 if (end_of_playlist)
2255 audio_monitor_end_of_playlist();
2256 return;
2260 audio_begin_track_change(true, trackstat);
2263 /* Called when codec completes seek operation
2264 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2265 static void audio_on_codec_seek_complete(void)
2267 logf("%s()", __func__);
2268 audio_complete_codec_seek();
2269 codec_go();
2272 /* Called when PCM track change has completed
2273 (Q_AUDIO_TRACK_CHANGED) */
2274 static void audio_on_track_changed(void)
2276 /* Finish whatever is pending so that the WPS is in sync */
2277 audio_finalise_track_change(true);
2279 if (codec_skip_pending)
2281 /* Codec got ahead completing a short track - complete the
2282 codec's skip and begin the next */
2283 codec_skip_pending = false;
2284 audio_on_codec_complete(codec_skip_status);
2288 /* Begin playback from an idle state, transition to a new playlist or
2289 invalidate the buffer and resume (if playing).
2290 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2291 static void audio_start_playback(size_t offset, unsigned int flags)
2293 enum play_status old_status = play_status;
2295 if (flags & AUDIO_START_NEWBUF)
2297 /* Mark the buffer dirty - if not playing, it will be reset next
2298 time */
2299 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2300 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2303 if (old_status != PLAY_STOPPED)
2305 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2307 halt_decoding_track(true);
2309 automatic_skip = false;
2310 ff_rw_mode = false;
2312 if (flags & AUDIO_START_RESTART)
2314 /* Clear out some stuff to resume the current track where it
2315 left off */
2316 pcmbuf_play_stop();
2317 offset = id3_get(PLAYING_ID3)->offset;
2318 track_list_clear(TRACK_LIST_CLEAR_ALL);
2320 else
2322 /* This is more-or-less treated as manual track transition */
2323 /* Save resume information for current track */
2324 audio_playlist_track_finish();
2325 track_list_clear(TRACK_LIST_CLEAR_ALL);
2327 /* Indicate manual track change */
2328 pcmbuf_start_track_change(false);
2329 audio_clear_paused_pcm();
2330 wipe_track_metadata(true);
2333 /* Set after track finish event in case skip was in progress */
2334 skip_pending = TRACK_SKIP_NONE;
2336 else
2338 if (flags & AUDIO_START_RESTART)
2339 return; /* Must already be playing */
2341 /* Cold playback start from a stopped state */
2342 logf("%s(%lu): starting", __func__, offset);
2344 /* Set audio parameters */
2345 #if INPUT_SRC_CAPS != 0
2346 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2347 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2348 #endif
2349 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2350 sound_set_volume(global_settings.volume);
2351 #endif
2352 /* Update our state */
2353 play_status = PLAY_PLAYING;
2356 /* Start fill from beginning of playlist */
2357 playlist_peek_offset = -1;
2358 buf_set_base_handle(-1);
2360 /* Officially playing */
2361 queue_reply(&audio_queue, 1);
2363 /* Add these now - finish event for the first id3 will most likely be sent
2364 immediately */
2365 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2366 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2368 if (old_status == PLAY_STOPPED)
2370 /* Send coldstart event */
2371 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2374 /* Fill the buffer */
2375 int trackstat = audio_fill_file_buffer();
2377 if (trackstat >= LOAD_TRACK_OK)
2379 /* This is the currently playing track - get metadata, stat */
2380 playing_id3_sync(track_list_current(0), offset);
2382 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2384 /* Only if actually changing tracks... */
2385 if (!(flags & AUDIO_START_RESTART))
2386 audio_playlist_track_change();
2389 else
2391 /* Found nothing playable */
2392 audio_handle_track_load_status(trackstat);
2396 /* Stop playback and enter an idle state
2397 (usually Q_AUDIO_STOP) */
2398 static void audio_stop_playback(void)
2400 logf("%s()", __func__);
2402 if (play_status == PLAY_STOPPED)
2403 return;
2405 /* Stop the codec and unload it */
2406 halt_decoding_track(true);
2407 pcmbuf_play_stop();
2408 codec_unload();
2410 /* Save resume information - "filling" might have been set to
2411 "STATE_ENDED" by caller in order to facilitate end of playlist */
2412 audio_playlist_track_finish();
2414 skip_pending = TRACK_SKIP_NONE;
2415 automatic_skip = false;
2417 /* Close all tracks and mark them NULL */
2418 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2419 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2420 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2422 track_list_clear(TRACK_LIST_CLEAR_ALL);
2424 /* Update our state */
2425 ff_rw_mode = false;
2426 play_status = PLAY_STOPPED;
2428 wipe_track_metadata(true);
2430 /* Go idle */
2431 filling = STATE_IDLE;
2432 cancel_cpu_boost();
2435 /* Pause the playback of the current track
2436 (Q_AUDIO_PAUSE) */
2437 static void audio_on_pause(bool pause)
2439 logf("%s(%s)", __func__, pause ? "true" : "false");
2441 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2442 return;
2444 if (!ff_rw_mode)
2446 /* Not in ff/rw mode - may set the state (otherwise this could make
2447 old data play because seek hasn't completed and cleared it) */
2448 pcmbuf_pause(pause);
2451 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2453 if (!pause && codec_skip_pending)
2455 /* Actually do the skip that is due - resets the status flag */
2456 audio_on_codec_complete(codec_skip_status);
2460 /* Skip a certain number of tracks forwards or backwards
2461 (Q_AUDIO_SKIP) */
2462 static void audio_on_skip(void)
2464 id3_mutex_lock();
2466 /* Eat the delta to keep it synced, even if not playing */
2467 int toskip = skip_offset;
2468 skip_offset = 0;
2470 logf("%s(): %d", __func__, toskip);
2472 id3_mutex_unlock();
2474 if (play_status == PLAY_STOPPED)
2475 return;
2477 /* Force codec to abort this track */
2478 halt_decoding_track(true);
2480 /* Kill the ff/rw halt */
2481 ff_rw_mode = false;
2483 /* Manual skip */
2484 automatic_skip = false;
2486 /* If there was an auto skip in progress, there will be residual
2487 advancement of the playlist and/or track list so compensation will be
2488 required in order to end up in the right spot */
2489 int track_list_delta = toskip;
2490 int playlist_delta = toskip;
2492 if (skip_pending != TRACK_SKIP_NONE)
2494 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2495 track_list_delta--;
2497 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2498 playlist_delta--;
2501 audio_playlist_track_finish();
2502 skip_pending = TRACK_SKIP_NONE;
2504 /* Update the playlist current track now */
2505 while (playlist_next(playlist_delta) < 0)
2507 /* Manual skip out of range (because the playlist wasn't updated
2508 yet by us and so the check in audio_skip returned 'ok') - bring
2509 back into range */
2510 int d = toskip < 0 ? 1 : -1;
2512 while (!playlist_check(playlist_delta))
2514 if (playlist_delta == d)
2516 /* Had to move the opposite direction to correct, which is
2517 wrong - this is the end */
2518 filling = STATE_ENDED;
2519 audio_stop_playback();
2520 return;
2523 playlist_delta += d;
2524 track_list_delta += d;
2528 /* Adjust things by how much the playlist was manually moved */
2529 playlist_peek_offset -= playlist_delta;
2531 struct track_info *info = track_list_advance_current(track_list_delta);
2532 int trackstat = LOAD_TRACK_OK;
2534 if (!info || info->audio_hid < 0)
2536 /* We don't know the next track thus we know we don't have it */
2537 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2540 audio_begin_track_change(false, trackstat);
2543 /* Skip to the next/previous directory
2544 (Q_AUDIO_DIR_SKIP) */
2545 static void audio_on_dir_skip(int direction)
2547 logf("%s(%d)", __func__, direction);
2549 id3_mutex_lock();
2550 skip_offset = 0;
2551 id3_mutex_unlock();
2553 if (play_status == PLAY_STOPPED)
2554 return;
2556 /* Force codec to abort this track */
2557 halt_decoding_track(true);
2559 /* Kill the ff/rw halt */
2560 ff_rw_mode = false;
2562 /* Manual skip */
2563 automatic_skip = false;
2565 audio_playlist_track_finish();
2567 /* Unless automatic and gapless, skips do not pend */
2568 skip_pending = TRACK_SKIP_NONE;
2570 /* Regardless of the return value we need to rebuffer. If it fails the old
2571 playlist will resume, else the next dir will start playing. */
2572 playlist_next_dir(direction);
2574 wipe_track_metadata(false);
2576 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2578 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2580 /* The day the music died - finish-off whatever is playing and call it
2581 quits */
2582 audio_monitor_end_of_playlist();
2583 return;
2586 audio_begin_track_change(false, trackstat);
2589 /* Enter seek mode in order to start a seek
2590 (Q_AUDIO_PRE_FF_REWIND) */
2591 static void audio_on_pre_ff_rewind(void)
2593 logf("%s()", __func__);
2595 if (play_status == PLAY_STOPPED || ff_rw_mode)
2596 return;
2598 ff_rw_mode = true;
2600 if (play_status == PLAY_PAUSED)
2601 return;
2603 pcmbuf_pause(true);
2606 /* Seek the playback of the current track to the specified time
2607 (Q_AUDIO_FF_REWIND) */
2608 static void audio_on_ff_rewind(long time)
2610 logf("%s(%ld)", __func__, time);
2612 if (play_status == PLAY_STOPPED)
2613 return;
2615 enum track_skip_type pending = skip_pending;
2617 switch (pending)
2619 case TRACK_SKIP_NONE: /* The usual case */
2620 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2621 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2623 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2624 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2626 automatic_skip = false;
2628 /* Send event before clobbering the time */
2629 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2630 then skipping back to this track resumes properly. Something else
2631 should be sent. We're not _really_ finishing the track are we? */
2632 if (time == 0)
2633 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2635 /* Prevent user codec time update - coerce to something that is
2636 innocuous concerning lookaheads */
2637 if (pending == TRACK_SKIP_NONE)
2638 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2640 id3->elapsed = time;
2641 queue_reply(&audio_queue, 1);
2643 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2645 /* Need this set in case ff/rw mode + error but _after_ the codec
2646 halt that will reset it */
2647 codec_seeking = true;
2649 if (pending == TRACK_SKIP_AUTO)
2651 if (!track_list_advance_current(-1))
2653 /* Not in list - must rebuffer at the current playlist index */
2654 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2655 < LOAD_TRACK_OK)
2657 /* Codec is stopped */
2658 break;
2663 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2664 rebuffer is needed */
2665 skip_pending = TRACK_SKIP_NONE;
2666 struct track_info *cur_info = track_list_current(0);
2668 /* Track must complete the loading _now_ since a codec and audio
2669 handle are needed in order to do the seek */
2670 if (cur_info->audio_hid < 0 &&
2671 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2673 /* Call above should push any load sequence - no need for
2674 halt_decoding_track here if no skip was pending here because
2675 there would not be a codec started if no audio handle was yet
2676 opened */
2677 break;
2680 if (pending == TRACK_SKIP_AUTO)
2682 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2683 !audio_init_codec(cur_info, ci_id3))
2685 /* We should have still been able to get it - skip it and move
2686 onto the next one - like it or not this track is borken */
2687 break;
2690 /* Set the codec API to the correct metadata and track info */
2691 ci.audio_hid = cur_info->audio_hid;
2692 ci.filesize = cur_info->filesize;
2693 buf_set_base_handle(cur_info->audio_hid);
2696 if (!haltres)
2698 /* If codec must be (re)started, reset the offset */
2699 ci_id3->offset = 0;
2702 codec_seek(time);
2703 return;
2706 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2708 /* We cannot do this because the playlist must be reversed by one
2709 and it doesn't always return the same song when going backwards
2710 across boundaries as forwards (either because of randomization
2711 or inconsistency in deciding what the previous track should be),
2712 therefore the whole operation would often end up as nonsense -
2713 lock out seeking for a couple seconds */
2715 /* Sure as heck cancel seek mode too! */
2716 audio_ff_rewind_end();
2717 return;
2720 default:
2721 /* Won't see this */
2722 return;
2725 if (play_status == PLAY_STOPPED)
2727 /* Playback ended because of an error completing a track load */
2728 return;
2731 /* Always fake it as a codec start error which will handle mode
2732 cancellations and skip to the next track */
2733 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2736 /* Invalidates all but currently playing track
2737 (Q_AUDIO_FLUSH) */
2738 static void audio_on_audio_flush(void)
2740 logf("%s", __func__);
2742 if (track_list_empty())
2743 return; /* Nothing to flush out */
2745 switch (skip_pending)
2747 case TRACK_SKIP_NONE:
2748 case TRACK_SKIP_AUTO_END_PLAYLIST:
2749 /* Remove all but the currently playing track from the list and
2750 refill after that */
2751 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2752 playlist_peek_offset = 0;
2753 id3_write_locked(UNBUFFERED_ID3, NULL);
2754 audio_update_and_announce_next_track(NULL);
2756 /* Ignore return since it's about the next track, not this one */
2757 audio_fill_file_buffer();
2759 if (skip_pending == TRACK_SKIP_NONE)
2760 break;
2762 /* There's now a track after this one now - convert to auto skip -
2763 no skip should pend right now because multiple flush messages can
2764 be fired which would cause a restart in the below cases */
2765 skip_pending = TRACK_SKIP_NONE;
2766 audio_clear_track_notifications();
2767 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2768 break;
2770 case TRACK_SKIP_AUTO:
2771 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2772 /* Precisely removing what it already decoded for the next track is
2773 not possible so a restart is required in order to continue the
2774 currently playing track without the now invalid future track
2775 playing */
2776 audio_start_playback(0, AUDIO_START_RESTART);
2777 break;
2779 default: /* Nothing else is a state */
2780 break;
2784 #ifdef AUDIO_HAVE_RECORDING
2785 /* Load the requested encoder type
2786 (Q_AUDIO_LOAD_ENCODER) */
2787 static void audio_on_load_encoder(int afmt)
2789 bool res = true;
2791 if (play_status != PLAY_STOPPED)
2792 audio_stop_playback(); /* Can't load both types at once */
2793 else
2794 codec_unload(); /* Encoder still loaded, stop and unload it */
2796 if (afmt != AFMT_UNKNOWN)
2798 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2799 if (res)
2800 codec_go(); /* These are run immediately */
2803 queue_reply(&audio_queue, res);
2805 #endif /* AUDIO_HAVE_RECORDING */
2807 static void audio_thread(void)
2809 struct queue_event ev;
2811 pcm_postinit();
2813 filling = STATE_IDLE;
2815 while (1)
2817 switch (filling)
2819 /* Active states */
2820 case STATE_FULL:
2821 case STATE_END_OF_PLAYLIST:
2822 if (buf_get_watermark() == 0)
2824 /* End of buffering for now, let's calculate the watermark,
2825 register for a low buffer event and unboost */
2826 audio_update_filebuf_watermark(0);
2827 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2828 buffer_event_buffer_low_callback);
2830 /* Fall-through */
2831 case STATE_FINISHED:
2832 /* All data was buffered */
2833 cancel_cpu_boost();
2834 /* Fall-through */
2835 case STATE_FILLING:
2836 case STATE_ENDING:
2837 if (audio_pcmbuf_track_change_scan())
2839 /* Transfer notification to audio queue event */
2840 ev.id = Q_AUDIO_TRACK_CHANGED;
2841 ev.data = 1;
2843 else
2845 /* If doing auto skip, poll pcmbuf track notifications a bit
2846 faster to promply detect the transition */
2847 queue_wait_w_tmo(&audio_queue, &ev,
2848 skip_pending == TRACK_SKIP_NONE ?
2849 HZ/2 : HZ/10);
2851 break;
2853 /* Idle states */
2854 default:
2855 queue_wait(&audio_queue, &ev);
2857 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2858 switch (ev.id)
2860 #ifdef AUDIO_HAVE_RECORDING
2861 /* Must monitor the encoder message for recording so it can remove
2862 it if we process the insertion before it does. It cannot simply
2863 be removed from under recording however. */
2864 case Q_AUDIO_LOAD_ENCODER:
2865 break;
2866 #endif
2867 case SYS_USB_DISCONNECTED:
2868 filling = STATE_IDLE;
2869 break;
2871 default:
2872 if (filling == STATE_USB)
2873 continue;
2875 #endif /* CONFIG_PLATFORM */
2878 switch (ev.id)
2880 /** Codec and track change messages **/
2881 case Q_AUDIO_CODEC_COMPLETE:
2882 /* Codec is done processing track and has gone idle */
2883 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
2884 audio_on_codec_complete(ev.data);
2885 break;
2887 case Q_AUDIO_CODEC_SEEK_COMPLETE:
2888 /* Codec is done seeking */
2889 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2890 audio_on_codec_seek_complete();
2891 break;
2893 case Q_AUDIO_TRACK_CHANGED:
2894 /* PCM track change done */
2895 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2896 audio_on_track_changed();
2897 break;
2899 /** Control messages **/
2900 case Q_AUDIO_PLAY:
2901 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2902 audio_start_playback(ev.data, 0);
2903 break;
2905 case Q_AUDIO_STOP:
2906 LOGFQUEUE("audio < Q_AUDIO_STOP");
2907 audio_stop_playback();
2908 if (ev.data != 0)
2909 queue_clear(&audio_queue);
2910 break;
2912 case Q_AUDIO_PAUSE:
2913 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2914 audio_on_pause(ev.data);
2915 break;
2917 case Q_AUDIO_SKIP:
2918 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2919 audio_on_skip();
2920 break;
2922 case Q_AUDIO_DIR_SKIP:
2923 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2924 audio_on_dir_skip(ev.data);
2925 break;
2927 case Q_AUDIO_PRE_FF_REWIND:
2928 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2929 audio_on_pre_ff_rewind();
2930 break;
2932 case Q_AUDIO_FF_REWIND:
2933 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2934 audio_on_ff_rewind(ev.data);
2935 break;
2937 case Q_AUDIO_FLUSH:
2938 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
2939 audio_on_audio_flush();
2940 break;
2942 /** Buffering messages **/
2943 case Q_AUDIO_BUFFERING:
2944 /* some buffering event */
2945 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
2946 audio_on_buffering(ev.data);
2947 break;
2949 case Q_AUDIO_FILL_BUFFER:
2950 /* continue buffering next track */
2951 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
2952 audio_on_fill_buffer();
2953 break;
2955 case Q_AUDIO_FINISH_LOAD_TRACK:
2956 /* metadata is buffered */
2957 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
2958 audio_on_finish_load_track(ev.data);
2959 break;
2961 case Q_AUDIO_HANDLE_FINISHED:
2962 /* some other type is buffered */
2963 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
2964 audio_on_handle_finished(ev.data);
2965 break;
2967 /** Miscellaneous messages **/
2968 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
2969 /* buffer needs to be reinitialized */
2970 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
2971 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
2972 break;
2974 #ifdef HAVE_DISK_STORAGE
2975 case Q_AUDIO_UPDATE_WATERMARK:
2976 /* buffering watermark needs updating */
2977 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
2978 audio_update_filebuf_watermark(ev.data);
2979 break;
2980 #endif /* HAVE_DISK_STORAGE */
2982 #ifdef AUDIO_HAVE_RECORDING
2983 case Q_AUDIO_LOAD_ENCODER:
2984 /* load an encoder for recording */
2985 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
2986 audio_on_load_encoder(ev.data);
2987 break;
2988 #endif /* AUDIO_HAVE_RECORDING */
2990 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2991 case SYS_USB_CONNECTED:
2992 LOGFQUEUE("audio < SYS_USB_CONNECTED");
2993 audio_stop_playback();
2994 #ifdef PLAYBACK_VOICE
2995 voice_stop();
2996 #endif
2997 filling = STATE_USB;
2998 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2999 break;
3000 #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
3002 case SYS_TIMEOUT:
3003 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3004 break;
3006 default:
3007 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3008 break;
3009 } /* end switch */
3010 } /* end while */
3014 /* --- Buffering callbacks --- */
3016 /* Called when fullness is below the watermark level */
3017 static void buffer_event_buffer_low_callback(void *data)
3019 logf("low buffer callback");
3020 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3021 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3022 (void)data;
3025 /* Called when handles must be discarded in order to buffer new data */
3026 static void buffer_event_rebuffer_callback(void *data)
3028 logf("rebuffer callback");
3029 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3030 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3031 (void)data;
3034 /* A handle has completed buffering and all required data is available */
3035 static void buffer_event_finished_callback(void *data)
3037 int hid = *(const int *)data;
3038 const enum data_type htype = buf_handle_data_type(hid);
3040 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3042 /* Limit queue traffic */
3043 switch (htype)
3045 case TYPE_ID3:
3046 /* The metadata handle for the last loaded track has been buffered.
3047 We can ask the audio thread to load the rest of the track's data. */
3048 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3049 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3050 break;
3052 case TYPE_PACKET_AUDIO:
3053 /* Strip any useless trailing tags that are left. */
3054 strip_tags(hid);
3055 /* Fall-through */
3056 case TYPE_ATOMIC_AUDIO:
3057 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3058 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3059 break;
3061 default:
3062 /* Don't care to know about these */
3063 break;
3068 /** -- Codec callbacks -- **/
3070 /* Update elapsed times with latency-adjusted values */
3071 void audio_codec_update_elapsed(unsigned long value)
3073 #ifdef AB_REPEAT_ENABLE
3074 ab_position_report(value);
3075 #endif
3077 unsigned long latency = pcmbuf_get_latency();
3079 if (LIKELY(value >= latency))
3081 unsigned long elapsed = value - latency;
3083 if (elapsed > value || elapsed < value - 2)
3084 value = elapsed;
3086 else
3088 value = 0;
3091 /* Track codec: used later when updating the playing at the user
3092 transition */
3093 id3_get(CODEC_ID3)->elapsed = value;
3095 /* If a skip is pending, the PCM buffer is updating the time on the
3096 previous song */
3097 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3098 id3_get(PLAYING_ID3)->elapsed = value;
3101 /* Update offsets with latency-adjusted values */
3102 void audio_codec_update_offset(size_t value)
3104 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
3105 unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8;
3107 if (LIKELY(value >= latency))
3109 value -= latency;
3111 else
3113 value = 0;
3116 /* Track codec: used later when updating the playing id3 at the user
3117 transition */
3118 ci_id3->offset = value;
3120 /* If a skip is pending, the PCM buffer is updating the time on the
3121 previous song */
3122 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3123 id3_get(PLAYING_ID3)->offset = value;
3127 /** --- Pcmbuf callbacks --- **/
3129 /* Between the codec and PCM track change, we need to keep updating the
3130 * "elapsed" value of the previous (to the codec, but current to the
3131 * user/PCM/WPS) track, so that the progressbar reaches the end. */
3132 void audio_pcmbuf_position_callback(unsigned int time)
3134 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3136 time += id3->elapsed;
3138 id3->elapsed = MIN(time, id3->length);
3141 /* Post message from pcmbuf that the end of the previous track has just
3142 * been played */
3143 void audio_pcmbuf_track_change(bool pcmbuf)
3145 if (pcmbuf)
3147 /* Notify of the change in special-purpose semaphore object */
3148 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3149 audio_pcmbuf_track_change_post();
3151 else
3153 /* Safe to post directly to the queue */
3154 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3155 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3159 /* May pcmbuf start PCM playback when the buffer is full enough? */
3160 bool audio_pcmbuf_may_play(void)
3162 return play_status == PLAY_PLAYING && !ff_rw_mode;
3166 /** -- External interfaces -- **/
3168 /* Return the playback and recording status */
3169 int audio_status(void)
3171 unsigned int ret = play_status;
3173 #ifdef AUDIO_HAVE_RECORDING
3174 /* Do this here for constitency with mpeg.c version */
3175 ret |= pcm_rec_status();
3176 #endif
3178 return (int)ret;
3181 /* Clear all accumulated audio errors for playback and recording */
3182 void audio_error_clear(void)
3184 #ifdef AUDIO_HAVE_RECORDING
3185 pcm_rec_error_clear();
3186 #endif
3189 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3190 bool audio_peek_track(struct mp3entry *id3, int offset)
3192 bool retval = false;
3194 id3_mutex_lock();
3196 if (play_status != PLAY_STOPPED)
3198 id3->path[0] = '\0'; /* Null path means it should be filled now */
3199 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3200 id3->path[0] != '\0';
3203 id3_mutex_unlock();
3205 return retval;
3208 /* Return the mp3entry for the currently playing track */
3209 struct mp3entry * audio_current_track(void)
3211 struct mp3entry *id3;
3213 id3_mutex_lock();
3215 #ifdef AUDIO_FAST_SKIP_PREVIEW
3216 if (skip_offset != 0)
3218 /* This is a peekahead */
3219 id3 = id3_get(PLAYING_PEEK_ID3);
3220 audio_peek_track(id3, 0);
3222 else
3223 #endif
3225 /* Normal case */
3226 id3 = id3_get(PLAYING_ID3);
3227 audio_get_track_metadata(0, id3);
3230 id3_mutex_unlock();
3232 return id3;
3235 /* Obtains the mp3entry for the next track from the current */
3236 struct mp3entry * audio_next_track(void)
3238 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3240 id3_mutex_lock();
3242 #ifdef AUDIO_FAST_SKIP_PREVIEW
3243 if (skip_offset != 0)
3245 /* This is a peekahead */
3246 if (!audio_peek_track(id3, 1))
3247 id3 = NULL;
3249 else
3250 #endif
3252 /* Normal case */
3253 if (!audio_get_track_metadata(1, id3))
3254 id3 = NULL;
3257 id3_mutex_unlock();
3259 return id3;
3262 /* Start playback at the specified offset */
3263 void audio_play(long offset)
3265 logf("audio_play");
3267 #ifdef PLAYBACK_VOICE
3268 /* Truncate any existing voice output so we don't have spelling
3269 * etc. over the first part of the played track */
3270 talk_force_shutup();
3271 #endif
3273 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3274 audio_queue_send(Q_AUDIO_PLAY, offset);
3277 /* Stop playback if playing */
3278 void audio_stop(void)
3280 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3281 audio_queue_send(Q_AUDIO_STOP, 0);
3284 /* Pause playback if playing */
3285 void audio_pause(void)
3287 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3288 audio_queue_send(Q_AUDIO_PAUSE, true);
3291 /* This sends a stop message and the audio thread will dump all its
3292 subsequent messages */
3293 void audio_hard_stop(void)
3295 /* Stop playback */
3296 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3297 audio_queue_send(Q_AUDIO_STOP, 1);
3298 #ifdef PLAYBACK_VOICE
3299 voice_stop();
3300 #endif
3303 /* Resume playback if paused */
3304 void audio_resume(void)
3306 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3307 audio_queue_send(Q_AUDIO_PAUSE, false);
3310 /* Skip the specified number of tracks forward or backward from the current */
3311 void audio_skip(int offset)
3313 id3_mutex_lock();
3315 /* If offset has to be backed-out to stay in range, no skip is done */
3316 int accum = skip_offset + offset;
3318 while (offset != 0 && !playlist_check(accum))
3320 offset += offset < 0 ? 1 : -1;
3321 accum = skip_offset + offset;
3324 if (offset != 0)
3326 /* Accumulate net manual skip count since the audio thread last
3327 processed one */
3328 skip_offset = accum;
3330 if (global_settings.beep)
3331 pcmbuf_beep(2000, 100, 2500*global_settings.beep);
3333 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3335 #ifdef AUDIO_FAST_SKIP_PREVIEW
3336 /* Do this before posting so that the audio thread can correct us
3337 when things settle down - additionally, if audio gets a message
3338 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3339 handler a skip event with the correct info but doesn't skip */
3340 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3341 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3343 /* Playback only needs the final state even if more than one is
3344 processed because it wasn't removed in time */
3345 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3346 audio_queue_post(Q_AUDIO_SKIP, 0);
3348 else
3350 /* No more tracks */
3351 if (global_settings.beep)
3352 pcmbuf_beep(1000, 100, 1500*global_settings.beep);
3355 id3_mutex_unlock();
3358 /* Skip one track forward from the current */
3359 void audio_next(void)
3361 audio_skip(1);
3364 /* Skip one track backward from the current */
3365 void audio_prev(void)
3367 audio_skip(-1);
3370 /* Move one directory forward */
3371 void audio_next_dir(void)
3373 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3374 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3377 /* Move one directory backward */
3378 void audio_prev_dir(void)
3380 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3381 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3384 /* Pause playback in order to start a seek that flushes the old audio */
3385 void audio_pre_ff_rewind(void)
3387 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3388 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3391 /* Seek to the new time in the current track */
3392 void audio_ff_rewind(long time)
3394 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3395 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3398 /* Clear all but the currently playing track then rebuffer */
3399 void audio_flush_and_reload_tracks(void)
3401 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3402 audio_queue_post(Q_AUDIO_FLUSH, 0);
3405 /* Return the pointer to the main audio buffer, optionally preserving
3406 voicing */
3407 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3409 unsigned char *buf, *end;
3411 if (audio_is_initialized)
3413 audio_hard_stop();
3415 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3417 if (buffer_size == NULL)
3419 /* Special case for talk_init to use since it already knows it's
3420 trashed */
3421 buffer_state = AUDIOBUF_STATE_TRASHED;
3422 return NULL;
3425 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3426 || !talk_voice_required())
3428 logf("get buffer: talk, audio");
3429 /* Ok to use everything from audiobuf to audiobufend - voice is loaded,
3430 the talk buffer is not needed because voice isn't being used, or
3431 could be AUDIOBUF_STATE_TRASHED already. If state is
3432 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't written
3433 without the caller knowing what's going on. Changing certain settings
3434 may move it to a worse condition but the memory in use by something
3435 else will remain undisturbed.
3437 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3439 talk_buffer_steal();
3440 buffer_state = AUDIOBUF_STATE_TRASHED;
3443 buf = audiobuf;
3444 end = audiobufend;
3446 else
3448 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3449 still AUDIOBUF_STATE_INITIALIZED */
3450 /* Skip talk buffer and move pcm buffer to end to maximize available
3451 contiguous memory - no audio running means voice will not need the
3452 swap space */
3453 logf("get buffer: audio");
3454 buf = audiobuf + talk_get_bufsize();
3455 end = audiobufend - pcmbuf_init(audiobufend);
3456 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3459 *buffer_size = end - buf;
3461 return buf;
3464 #ifdef HAVE_RECORDING
3465 /* Stop audio, voice and obtain all available buffer space */
3466 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3468 audio_hard_stop();
3469 talk_buffer_steal();
3471 unsigned char *end = audiobufend;
3472 buffer_state = AUDIOBUF_STATE_TRASHED;
3473 *buffer_size = end - audiobuf;
3475 return (unsigned char *)audiobuf;
3477 #endif /* HAVE_RECORDING */
3479 /* Restore audio buffer to a particular state (one more valid than the current
3480 state) */
3481 bool audio_restore_playback(int type)
3483 switch (type)
3485 case AUDIO_WANT_PLAYBACK:
3486 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3487 audio_reset_buffer();
3488 return true;
3489 case AUDIO_WANT_VOICE:
3490 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3491 audio_reset_buffer();
3492 return true;
3493 default:
3494 return false;
3498 /* Has the playback buffer been completely claimed? */
3499 bool audio_buffer_state_trashed(void)
3501 return buffer_state == AUDIOBUF_STATE_TRASHED;
3505 /** --- Miscellaneous public interfaces --- **/
3507 #ifdef HAVE_ALBUMART
3508 /* Return which album art handle is current for the user in the given slot */
3509 int playback_current_aa_hid(int slot)
3511 if ((unsigned)slot < MAX_MULTIPLE_AA)
3513 struct track_info *info = track_list_user_current(skip_offset);
3515 if (!info && abs(skip_offset) <= 1)
3517 /* Give the actual position a go */
3518 info = track_list_user_current(0);
3521 if (info)
3522 return info->aa_hid[slot];
3525 return ERR_HANDLE_NOT_FOUND;
3528 /* Find an album art slot that doesn't match the dimensions of another that
3529 is already claimed - increment the use count if it is */
3530 int playback_claim_aa_slot(struct dim *dim)
3532 int i;
3534 /* First try to find a slot already having the size to reuse it since we
3535 don't want albumart of the same size buffered multiple times */
3536 FOREACH_ALBUMART(i)
3538 struct albumart_slot *slot = &albumart_slots[i];
3540 if (slot->dim.width == dim->width &&
3541 slot->dim.height == dim->height)
3543 slot->used++;
3544 return i;
3548 /* Size is new, find a free slot */
3549 FOREACH_ALBUMART(i)
3551 if (!albumart_slots[i].used)
3553 albumart_slots[i].used++;
3554 albumart_slots[i].dim = *dim;
3555 return i;
3559 /* Sorry, no free slot */
3560 return -1;
3563 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3564 void playback_release_aa_slot(int slot)
3566 if ((unsigned)slot < MAX_MULTIPLE_AA)
3568 struct albumart_slot *aa_slot = &albumart_slots[slot];
3570 if (aa_slot->used > 0)
3571 aa_slot->used--;
3574 #endif /* HAVE_ALBUMART */
3577 #ifdef HAVE_RECORDING
3578 /* Load an encoder and run it */
3579 bool audio_load_encoder(int afmt)
3581 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3582 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3583 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3584 #else
3585 (void)afmt;
3586 return true;
3587 #endif
3590 /* Stop an encoder and unload it */
3591 void audio_remove_encoder(void)
3593 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3594 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3595 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3596 #endif
3598 #endif /* HAVE_RECORDING */
3600 /* Is an automatic skip in progress? If called outside transistion callbacks,
3601 indicates the last skip type at the time it was processed and isn't very
3602 meaningful. */
3603 bool audio_automatic_skip(void)
3605 return automatic_skip;
3608 /* Would normally calculate byte offset from an elapsed time but is not
3609 used on SWCODEC */
3610 int audio_get_file_pos(void)
3612 return 0;
3615 /* Return the elasped time of the track previous to the current */
3616 unsigned long audio_prev_elapsed(void)
3618 return prev_track_elapsed;
3621 /* Is the audio thread ready to accept commands? */
3622 bool audio_is_thread_ready(void)
3624 return filling != STATE_BOOT;
3627 /* Return total file buffer length after accounting for the talk buf */
3628 size_t audio_get_filebuflen(void)
3630 return buf_length();
3633 /* How many tracks exist on the buffer - full or partial */
3634 int audio_track_count(void)
3635 __attribute__((alias("track_list_count")));
3637 /* Return total ringbuffer space occupied - ridx to widx */
3638 long audio_filebufused(void)
3640 return buf_used();
3644 /** -- Settings -- **/
3646 /* Enable or disable cuesheet support and allocate/don't allocate the
3647 extra associated resources */
3648 void audio_set_cuesheet(int enable)
3650 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3652 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3653 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3657 #ifdef HAVE_DISK_STORAGE
3658 /* Set the audio antiskip buffer margin by index */
3659 void audio_set_buffer_margin(int setting)
3661 static const unsigned short lookup[] =
3662 { 5, 15, 30, 60, 120, 180, 300, 600 };
3664 if ((unsigned)setting >= ARRAYLEN(lookup))
3665 setting = 0;
3667 logf("buffer margin: %u", (unsigned)lookup[setting]);
3669 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3670 (unsigned)lookup[setting]);
3671 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3673 #endif /* HAVE_DISK_STORAGE */
3675 #ifdef HAVE_CROSSFADE
3676 /* Take necessary steps to enable or disable the crossfade setting */
3677 void audio_set_crossfade(int enable)
3679 /* Tell it the next setting to use */
3680 pcmbuf_request_crossfade_enable(enable);
3682 /* Return if size hasn't changed or this is too early to determine
3683 which in the second case there's no way we could be playing
3684 anything at all */
3685 if (!pcmbuf_is_same_size())
3687 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3688 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3691 #endif /* HAVE_CROSSFADE */
3694 /** -- Startup -- **/
3696 /* Initialize the audio system - called from init() in main.c */
3697 void audio_init(void)
3699 /* Can never do this twice */
3700 if (audio_is_initialized)
3702 logf("audio: already initialized");
3703 return;
3706 logf("audio: initializing");
3708 /* Initialize queues before giving control elsewhere in case it likes
3709 to send messages. Thread creation will be delayed however so nothing
3710 starts running until ready if something yields such as talk_init. */
3711 queue_init(&audio_queue, true);
3713 mutex_init(&id3_mutex);
3715 pcm_init();
3717 codec_init_codec_api();
3719 make_codec_thread();
3721 /* This thread does buffer, so match its priority */
3722 audio_thread_id = create_thread(audio_thread, audio_stack,
3723 sizeof(audio_stack), CREATE_THREAD_FROZEN,
3724 audio_thread_name
3725 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3726 IF_COP(, CPU));
3728 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3729 audio_thread_id);
3731 #ifdef PLAYBACK_VOICE
3732 voice_thread_init();
3733 #endif
3735 /* audio_reset_buffer must to know the size of voice buffer so init
3736 talk first */
3737 talk_init();
3739 #ifdef HAVE_CROSSFADE
3740 /* Set crossfade setting for next buffer init which should be about... */
3741 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3742 #endif
3744 /* Initialize the buffering system */
3745 track_list_init();
3746 buffering_init();
3747 /* ...now! Set up the buffers */
3748 audio_reset_buffer();
3750 /* Probably safe to say */
3751 audio_is_initialized = true;
3753 sound_settings_apply();
3754 #ifdef HAVE_DISK_STORAGE
3755 audio_set_buffer_margin(global_settings.buffer_margin);
3756 #endif
3758 /* It's safe to let the threads run now */
3759 #ifdef PLAYBACK_VOICE
3760 voice_thread_resume();
3761 #endif
3762 codec_thread_resume();
3763 thread_thaw(audio_thread_id);