Pull yesno_pop out of the radio code as it is a nice simple resuasble yesno api worth...
[kugel-rb.git] / apps / playback.c
blobfe9bd579d4777d8353346aa90af04c7e2da36842
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"
42 #include "misc.h"
44 #ifdef HAVE_TAGCACHE
45 #include "tagcache.h"
46 #endif
48 #ifdef AUDIO_HAVE_RECORDING
49 #include "pcm_record.h"
50 #endif
52 #ifdef HAVE_LCD_BITMAP
53 #ifdef HAVE_ALBUMART
54 #include "albumart.h"
55 #endif
56 #endif
58 /* TODO: The audio thread really is doing multitasking of acting like a
59 consumer and producer of tracks. It may be advantageous to better
60 logically separate the two functions. I won't go that far just yet. */
62 /* Internal support for voice playback */
63 #define PLAYBACK_VOICE
65 #if CONFIG_PLATFORM & PLATFORM_NATIVE
66 /* Application builds don't support direct code loading */
67 #define HAVE_CODEC_BUFFERING
68 #endif
70 /* Amount of guess-space to allow for codecs that must hunt and peck
71 * for their correct seek target, 32k seems a good size */
72 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
74 /* Define LOGF_ENABLE to enable logf output in this file */
75 /* #define LOGF_ENABLE */
76 #include "logf.h"
78 /* Macros to enable logf for queues
79 logging on SYS_TIMEOUT can be disabled */
80 #ifdef SIMULATOR
81 /* Define this for logf output of all queuing except SYS_TIMEOUT */
82 #define PLAYBACK_LOGQUEUES
83 /* Define this to logf SYS_TIMEOUT messages */
84 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
85 #endif
87 #ifdef PLAYBACK_LOGQUEUES
88 #define LOGFQUEUE logf
89 #else
90 #define LOGFQUEUE(...)
91 #endif
93 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
94 #define LOGFQUEUE_SYS_TIMEOUT logf
95 #else
96 #define LOGFQUEUE_SYS_TIMEOUT(...)
97 #endif
99 /* Variables are commented with the threads that use them:
100 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
101 * read but not updated on that thread. Audio is the only user unless otherwise
102 * specified.
105 /** Miscellaneous **/
106 bool audio_is_initialized = false; /* (A,O-) */
107 extern struct codec_api ci; /* (A,C) */
109 /** Possible arrangements of the main buffer **/
110 static enum audio_buffer_state
112 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
113 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
114 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
115 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
117 /** Main state control **/
118 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
120 enum play_status
122 PLAY_STOPPED = 0,
123 PLAY_PLAYING = AUDIO_STATUS_PLAY,
124 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
125 } play_status = PLAY_STOPPED;
127 /* Sizeable things that only need exist during playback and not when stopped */
128 static struct audio_scratch_memory
130 struct mp3entry codec_id3; /* (A,C) */
131 struct mp3entry unbuffered_id3;
132 struct cuesheet *curr_cue; /* Will follow this structure */
133 } * audio_scratch_memory = NULL;
135 /* These are used to store the current, next and optionally the peek-ahead
136 * mp3entry's - this guarantees that the pointer returned by audio_current/
137 * next_track will be valid for the full duration of the currently playing
138 * track */
139 enum audio_id3_types
141 /* These are allocated statically */
142 PLAYING_ID3 = 0,
143 NEXTTRACK_ID3,
144 #ifdef AUDIO_FAST_SKIP_PREVIEW
145 /* The real playing metadata must has to be protected since it contains
146 critical info for other features */
147 PLAYING_PEEK_ID3,
148 #endif
149 ID3_TYPE_NUM_STATIC,
150 /* These go in the scratch memory */
151 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
152 CODEC_ID3,
154 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
156 /* Peeking functions can yield and mess us up */
157 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/
160 /** For Scrobbler support **/
162 /* Previous track elapsed time */
163 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
166 /** For album art support **/
167 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
168 #ifdef HAVE_ALBUMART
170 static struct albumart_slot
172 struct dim dim; /* Holds width, height of the albumart */
173 int used; /* Counter; increments if something uses it */
174 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
176 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
177 #endif /* HAVE_ALBUMART */
180 /** Information used for tracking buffer fills **/
182 /* Buffer and thread state tracking */
183 static enum filling_state
185 STATE_BOOT = 0, /* audio thread is not ready yet */
186 STATE_IDLE, /* audio is stopped: nothing to do */
187 STATE_FILLING, /* adding tracks to the buffer */
188 STATE_FULL, /* can't add any more tracks */
189 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
190 STATE_FINISHED, /* all remaining tracks are fully buffered */
191 STATE_ENDING, /* audio playback is ending */
192 STATE_ENDED, /* audio playback is done */
193 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
194 STATE_USB, /* USB mode, ignore most messages */
195 #endif
196 } filling = STATE_BOOT;
198 /* Track info - holds information about each track in the buffer */
199 struct track_info
201 /* In per-track allocated order: */
202 int id3_hid; /* Metadata handle ID */
203 int cuesheet_hid; /* Parsed cuesheet handle ID */
204 #ifdef HAVE_ALBUMART
205 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
206 #endif
207 #ifdef HAVE_CODEC_BUFFERING
208 int codec_hid; /* Buffered codec handle ID */
209 #endif
210 int audio_hid; /* Main audio data handle ID */
211 size_t filesize; /* File total length on disk
212 TODO: This should be stored
213 in the handle or the
214 id3 and would use less
215 ram */
218 /* Track list - holds info about all buffered tracks */
219 #if MEMORYSIZE >= 32
220 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
221 #elif MEMORYSIZE >= 16
222 #define TRACK_LIST_LEN 64
223 #elif MEMORYSIZE >= 8
224 #define TRACK_LIST_LEN 32
225 #else
226 #define TRACK_LIST_LEN 16
227 #endif
229 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
231 static struct
233 /* read, write and current are maintained unwrapped, limited only by the
234 unsigned int range and wrap-safe comparisons are used */
236 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
237 if 'end' follows 'start' in this structure, track_list_count performs
238 'start - end' rather than 'end - start', giving negative count values...
239 so leave it this way for now! */
240 unsigned int end; /* Next open position */
241 unsigned int start; /* First track in list */
242 unsigned int current; /* Currently decoding track */
243 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
244 } track_list; /* (A, O-) */
247 /* Playlist steps from playlist position to next track to be buffered */
248 static int playlist_peek_offset = 0;
250 /* Metadata handle of track load in progress (meaning all handles have not
251 yet been opened for the track, id3 always exists or the track does not)
253 Tracks are keyed by their metadata handles if track list pointers are
254 insufficient to make comparisons */
255 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
257 #ifdef HAVE_DISK_STORAGE
258 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
259 static size_t buffer_margin = 5;
260 #endif
262 /* Values returned for track loading */
263 enum track_load_status
265 LOAD_TRACK_ERR_START_CODEC = -6,
266 LOAD_TRACK_ERR_FINISH_FAILED = -5,
267 LOAD_TRACK_ERR_FINISH_FULL = -4,
268 LOAD_TRACK_ERR_BUSY = -3,
269 LOAD_TRACK_ERR_NO_MORE = -2,
270 LOAD_TRACK_ERR_FAILED = -1,
271 LOAD_TRACK_OK = 0,
272 LOAD_TRACK_READY = 1,
275 /** Track change controls **/
277 /* What sort of skip is pending globally? */
278 enum track_skip_type
280 /* Relative to what user is intended to see: */
281 /* Codec: +0, Track List: +0, Playlist: +0 */
282 TRACK_SKIP_NONE = 0, /* no track skip */
283 /* Codec: +1, Track List: +1, Playlist: +0 */
284 TRACK_SKIP_AUTO, /* codec-initiated skip */
285 /* Codec: +1, Track List: +1, Playlist: +1 */
286 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
287 /* Codec: xx, Track List: +0, Playlist: +0 */
288 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
289 /* Manual skip: Never pends */
290 TRACK_SKIP_MANUAL, /* manual track skip */
291 /* Manual skip: Never pends */
292 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
293 } skip_pending = TRACK_SKIP_NONE;
295 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
296 Fixing playlist code to be able to peek into the first song of
297 the next playlist would fix any issues and this wouldn't need
298 to be a special case since pre-advancing the playlist would be
299 unneeded - it could be much more like TRACK_SKIP_AUTO and all
300 actions that require reversal during an in-progress transition
301 would work as expected */
303 /* Used to indicate status for the events. Must be separate to satisfy all
304 clients so the correct metadata is read when sending the change events
305 and also so that it is read correctly outside the events. */
306 static bool automatic_skip = false; /* (A, O-) */
308 /* Pending manual track skip offset */
309 static int skip_offset = 0; /* (A, O) */
311 /* Track change notification */
312 static struct
314 unsigned int in; /* Number of pcmbuf posts (audio isr) */
315 unsigned int out; /* Number of times audio has read the difference */
316 } track_change = { 0, 0 };
318 /** Codec status **/
319 /* Did the codec notify us it finished while we were paused or while still
320 in an automatic transition?
322 If paused, it is necessary to defer a codec-initiated skip until resuming
323 or else the track will move forward while not playing audio!
325 If in-progress, skips should not build-up ahead of where the WPS is when
326 really short tracks finish decoding.
328 If it is forgotten, it will be missed altogether and playback will just sit
329 there looking stupid and comatose until the user does something */
330 static bool codec_skip_pending = false;
331 static int codec_skip_status;
332 static bool codec_seeking = false; /* Codec seeking ack expected? */
335 /* Event queues */
336 static struct event_queue audio_queue SHAREDBSS_ATTR;
338 /* Audio thread */
339 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
340 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
341 static const char audio_thread_name[] = "audio";
342 static unsigned int audio_thread_id = 0;
344 /* Forward declarations */
345 enum audio_start_playback_flags
347 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
348 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
351 static void audio_start_playback(size_t offset, unsigned int flags);
352 static void audio_stop_playback(void);
353 static void buffer_event_buffer_low_callback(void *data);
354 static void buffer_event_rebuffer_callback(void *data);
355 static void buffer_event_finished_callback(void *data);
358 /**************************************/
360 /** --- audio_queue helpers --- **/
362 /* codec thread needs access */
363 void audio_queue_post(long id, intptr_t data)
365 queue_post(&audio_queue, id, data);
368 static intptr_t audio_queue_send(long id, intptr_t data)
370 return queue_send(&audio_queue, id, data);
374 /** --- MP3Entry --- **/
376 /* Does the mp3entry have enough info for us to use it? */
377 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
379 return id3 && (id3->length != 0 || id3->filesize != 0) &&
380 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
383 /* Return a pointer to an mp3entry on the buffer, as it is */
384 static struct mp3entry * bufgetid3(int handle_id)
386 if (handle_id < 0)
387 return NULL;
389 struct mp3entry *id3;
390 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
392 if (ret != sizeof(struct mp3entry))
393 return NULL;
395 return id3;
398 /* Read an mp3entry from the buffer, adjusted */
399 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
401 struct mp3entry *id3 = bufgetid3(handle_id);
403 if (id3)
405 copy_mp3entry(id3out, id3);
406 return true;
409 return false;
412 /* Lock the id3 mutex */
413 static void id3_mutex_lock(void)
415 mutex_lock(&id3_mutex);
418 /* Unlock the id3 mutex */
419 static void id3_mutex_unlock(void)
421 mutex_unlock(&id3_mutex);
424 /* Return one of the collection of mp3entry pointers - collect them all here */
425 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
427 switch (id3_num)
429 case UNBUFFERED_ID3:
430 return &audio_scratch_memory->unbuffered_id3;
431 case CODEC_ID3:
432 return &audio_scratch_memory->codec_id3;
433 default:
434 return &static_id3_entries[id3_num];
438 /* Copy an mp3entry into one of the mp3 entries */
439 static void id3_write(enum audio_id3_types id3_num,
440 const struct mp3entry *id3_src)
442 struct mp3entry *dest_id3 = id3_get(id3_num);
444 if (id3_src)
445 copy_mp3entry(dest_id3, id3_src);
446 else
447 wipe_mp3entry(dest_id3);
450 /* Call id3_write "safely" because peek aheads can yield, even if the fast
451 preview isn't enabled */
452 static void id3_write_locked(enum audio_id3_types id3_num,
453 const struct mp3entry *id3_src)
455 id3_mutex_lock();
456 id3_write(id3_num, id3_src);
457 id3_mutex_unlock();
461 /** --- Track info --- **/
463 /* Close a handle and mark it invalid */
464 static void track_info_close_handle(int *hid_p)
466 int hid = *hid_p;
468 /* bufclose returns true if the handle is not found, or if it is closed
469 * successfully, so these checks are safe on non-existant handles */
470 if (hid >= 0)
471 bufclose(hid);
473 /* Always reset to "no handle" in case it was something else */
474 *hid_p = ERR_HANDLE_NOT_FOUND;
477 /* Close all handles in a struct track_info and clear it */
478 static void track_info_close(struct track_info *info)
480 /* Close them in the order they are allocated on the buffer to speed up
481 the handle searching */
482 track_info_close_handle(&info->id3_hid);
483 track_info_close_handle(&info->cuesheet_hid);
484 #ifdef HAVE_ALBUMART
485 int i;
486 FOREACH_ALBUMART(i)
487 track_info_close_handle(&info->aa_hid[i]);
488 #endif
489 #ifdef HAVE_CODEC_BUFFERING
490 track_info_close_handle(&info->codec_hid);
491 #endif
492 track_info_close_handle(&info->audio_hid);
493 info->filesize = 0;
496 /* Invalidate all members to initial values - does not close handles */
497 static void track_info_wipe(struct track_info * info)
499 info->id3_hid = ERR_HANDLE_NOT_FOUND;
500 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
501 #ifdef HAVE_ALBUMART
502 int i;
503 FOREACH_ALBUMART(i)
504 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
505 #endif
506 #ifdef HAVE_CODEC_BUFFERING
507 info->codec_hid = ERR_HANDLE_NOT_FOUND;
508 #endif
509 info->audio_hid = ERR_HANDLE_NOT_FOUND;
510 info->filesize = 0;
514 /** --- Track list --- **/
516 /* Initialize the track list */
517 static void track_list_init(void)
519 int i;
520 for (i = 0; i < TRACK_LIST_LEN; i++)
521 track_info_wipe(&track_list.tracks[i]);
523 track_list.start = track_list.end = track_list.current;
526 /* Return number of items allocated in the list */
527 static unsigned int track_list_count(void)
529 return track_list.end - track_list.start;
532 /* Return true if the list is empty */
533 static inline bool track_list_empty(void)
535 return track_list.end == track_list.start;
538 /* Returns true if the list is holding the maximum number of items */
539 static bool track_list_full(void)
541 return track_list.end - track_list.start >= TRACK_LIST_LEN;
544 /* Test if the index is within the allocated range */
545 static bool track_list_in_range(int pos)
547 return (int)(pos - track_list.start) >= 0 &&
548 (int)(pos - track_list.end) < 0;
551 static struct track_info * track_list_entry(int pos)
553 return &track_list.tracks[pos & TRACK_LIST_MASK];
556 /* Return the info of the last allocation plus an offset, NULL if result is
557 out of bounds */
558 static struct track_info * track_list_last(int offset)
560 /* Last is before the end since the end isn't inclusive */
561 unsigned int pos = track_list.end + offset - 1;
563 if (!track_list_in_range(pos))
564 return NULL;
566 return track_list_entry(pos);
569 /* Allocate space at the end for another track if not full */
570 static struct track_info * track_list_alloc_track(void)
572 if (track_list_full())
573 return NULL;
575 return track_list_entry(track_list.end++);
578 /* Remove the last track entry allocated in order to support backing out
579 of a track load */
580 static void track_list_unalloc_track(void)
582 if (track_list_empty())
583 return;
585 track_list.end--;
587 if (track_list.current == track_list.end &&
588 track_list.current != track_list.start)
590 /* Current _must_ remain within bounds */
591 track_list.current--;
595 /* Return current track plus an offset, NULL if result is out of bounds */
596 static struct track_info * track_list_current(int offset)
598 unsigned int pos = track_list.current + offset;
600 if (!track_list_in_range(pos))
601 return NULL;
603 return track_list_entry(pos);
606 /* Return current based upon what's intended that the user sees - not
607 necessarily where decoding is taking place */
608 static struct track_info * track_list_user_current(int offset)
610 if (skip_pending == TRACK_SKIP_AUTO ||
611 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
613 offset--;
616 return track_list_current(offset);
619 /* Advance current track by an offset, return false if result is out of
620 bounds */
621 static struct track_info * track_list_advance_current(int offset)
623 unsigned int pos = track_list.current + offset;
625 if (!track_list_in_range(pos))
626 return NULL;
628 track_list.current = pos;
629 return track_list_entry(pos);
632 /* Clear tracks in the list, optionally preserving the current track -
633 returns 'false' if the operation was changed */
634 enum track_clear_action
636 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
637 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
638 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
641 static void track_list_clear(enum track_clear_action action)
643 logf("%s(%d)", __func__, (int)action);
645 /* Don't care now since rebuffering is imminent */
646 buf_set_watermark(0);
648 if (action != TRACK_LIST_CLEAR_ALL)
650 struct track_info *cur = track_list_current(0);
652 if (!cur || cur->id3_hid < 0)
653 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
656 /* Noone should see this progressing */
657 int start = track_list.start;
658 int current = track_list.current;
659 int end = track_list.end;
661 track_list.start = current;
663 switch (action)
665 case TRACK_LIST_CLEAR_ALL:
666 /* Result: .start = .current, .end = .current */
667 track_list.end = current;
668 break;
670 case TRACK_LIST_KEEP_CURRENT:
671 /* Result: .start = .current, .end = .current + 1 */
672 track_list.end = current + 1;
673 break;
675 case TRACK_LIST_KEEP_NEW:
676 /* Result: .start = .current, .end = .end */
677 end = current;
678 break;
681 /* Close all open handles in the range except the for the current track
682 if preserving that */
683 while (start != end)
685 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
687 struct track_info *info =
688 &track_list.tracks[start & TRACK_LIST_MASK];
690 /* If this is the in-progress load, abort it */
691 if (in_progress_id3_hid >= 0 &&
692 info->id3_hid == in_progress_id3_hid)
694 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
697 track_info_close(info);
700 start++;
705 /** --- Audio buffer -- **/
707 /* What size is needed for the scratch buffer? */
708 static size_t scratch_mem_size(void)
710 size_t size = sizeof (struct audio_scratch_memory);
712 if (global_settings.cuesheet)
713 size += sizeof (struct cuesheet);
715 return size;
718 /* Initialize the memory area where data is stored that is only used when
719 playing audio and anything depending upon it */
720 static void scratch_mem_init(void *mem)
722 audio_scratch_memory = (struct audio_scratch_memory *)mem;
723 id3_write_locked(UNBUFFERED_ID3, NULL);
724 id3_write(CODEC_ID3, NULL);
725 ci.id3 = id3_get(CODEC_ID3);
726 audio_scratch_memory->curr_cue = NULL;
728 if (global_settings.cuesheet)
730 audio_scratch_memory->curr_cue =
731 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
732 sizeof (struct audio_scratch_memory));
736 /* Set up the audio buffer for playback */
737 static void audio_reset_buffer(void)
740 * Layout audio buffer as follows:
741 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
744 /* see audio_get_recording_buffer if this is modified */
745 logf("%s()", __func__);
747 /* If the setup of anything allocated before the file buffer is
748 changed, do check the adjustments after the buffer_alloc call
749 as it will likely be affected and need sliding over */
751 /* Initially set up file buffer as all space available */
752 unsigned char *filebuf = audiobuf + talk_get_bufsize();
753 size_t filebuflen = audiobufend - filebuf;
754 size_t allocsize;
756 ALIGN_BUFFER(filebuf, filebuflen, sizeof (intptr_t));
758 if (talk_voice_required())
760 /* Need a space for voice PCM output */
761 allocsize = voicebuf_init(filebuf + filebuflen);
763 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
764 if (allocsize > filebuflen)
765 goto bufpanic;
767 filebuflen -= allocsize;
770 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
771 allocsize = pcmbuf_init(filebuf + filebuflen);
773 /* Make sure filebuflen is a pointer sized multiple after adjustment */
774 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
775 if (allocsize > filebuflen)
776 goto bufpanic;
778 filebuflen -= allocsize;
780 /* Scratch memory */
781 allocsize = scratch_mem_size();
782 if (allocsize > filebuflen)
783 goto bufpanic;
785 scratch_mem_init(filebuf);
786 filebuf += allocsize;
787 filebuflen -= allocsize;
789 buffering_reset(filebuf, filebuflen);
791 /* Clear any references to the file buffer */
792 buffer_state = AUDIOBUF_STATE_INITIALIZED;
794 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
795 /* Make sure everything adds up - yes, some info is a bit redundant but
796 aids viewing and the summation of certain variables should add up to
797 the location of others. */
799 size_t pcmbufsize;
800 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
801 logf("fbuf: %08X", (unsigned)filebuf);
802 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
803 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
804 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
805 logf("pcmb: %08X", (unsigned)pcmbuf);
806 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
808 #endif
810 return;
812 bufpanic:
813 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
816 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
817 static void audio_update_filebuf_watermark(int seconds)
819 size_t bytes = 0;
821 #ifdef HAVE_DISK_STORAGE
822 int spinup = ata_spinup_time();
824 if (seconds == 0)
826 /* By current setting */
827 seconds = buffer_margin;
829 else
831 /* New setting */
832 buffer_margin = seconds;
834 if (buf_get_watermark() == 0)
836 /* Write a watermark only if the audio thread already did so for
837 itself or it will fail to set the event and the watermark - if
838 it hasn't yet, it will use the new setting when it does */
839 return;
843 if (spinup)
844 seconds += (spinup / HZ) + 1;
845 else
846 seconds += 5;
848 seconds += buffer_margin;
849 #else
850 /* flash storage */
851 seconds = 1;
852 #endif
854 /* Watermark is a function of the bitrate of the last track in the buffer */
855 struct mp3entry *id3 = NULL;
856 struct track_info *info = track_list_last(0);
858 if (info)
859 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
861 if (id3)
863 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
865 bytes = id3->bitrate * (1000/8) * seconds;
867 else
869 /* Bitrate has no meaning to buffering margin for atomic audio -
870 rebuffer when it's the only track left unless it's the only
871 track that fits, in which case we should avoid constant buffer
872 low events */
873 if (track_list_count() > 1)
874 bytes = info->filesize + 1;
877 else
879 /* Then set the minimum - this should not occur anyway */
880 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
881 track_list.start, track_list.current, track_list.end);
884 /* Actually setting zero disables the notification and we use that
885 to detect that it has been reset */
886 buf_set_watermark(MAX(bytes, 1));
887 logf("fwmark: %lu", (unsigned long)bytes);
891 /** -- Track change notification -- **/
893 /* Check the pcmbuf track changes and return write the message into the event
894 if there are any */
895 static inline bool audio_pcmbuf_track_change_scan(void)
897 if (track_change.out != track_change.in)
899 track_change.out++;
900 return true;
903 return false;
906 /* Clear outstanding track change posts */
907 static inline void audio_pcmbuf_track_change_clear(void)
909 track_change.out = track_change.in;
912 /* Post a track change notification - called by audio ISR */
913 static inline void audio_pcmbuf_track_change_post(void)
915 track_change.in++;
919 /** --- Helper functions --- **/
921 /* Removes messages that might end up in the queue before or while processing
922 a manual track change. Responding to them would be harmful since they
923 belong to a previous track's playback period. Anything that would generate
924 the stale messages must first be put into a state where it will not do so.
926 static void audio_clear_track_notifications(void)
928 static const long filter_list[][2] =
930 /* codec messages */
931 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
932 /* track change messages */
933 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
936 const int filter_count = ARRAYLEN(filter_list) - 1;
938 /* Remove any pcmbuf notifications */
939 pcmbuf_monitor_track_change(false);
940 audio_pcmbuf_track_change_clear();
942 /* Scrub the audio queue of the old mold */
943 while (queue_peek_ex(&audio_queue, NULL,
944 filter_count | QPEEK_REMOVE_EVENTS,
945 filter_list))
947 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
951 /* Takes actions based upon track load status codes */
952 static void audio_handle_track_load_status(int trackstat)
954 switch (trackstat)
956 case LOAD_TRACK_ERR_NO_MORE:
957 if (track_list_count() > 0)
958 break;
960 case LOAD_TRACK_ERR_START_CODEC:
961 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
962 break;
964 default:
965 break;
969 /* Announce the end of playing the current track */
970 static void audio_playlist_track_finish(void)
972 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
974 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
976 if (id3)
978 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
979 prev_track_elapsed = id3->elapsed;
981 else
983 prev_track_elapsed = 0;
987 /* Announce the beginning of the new track */
988 static void audio_playlist_track_change(void)
990 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
992 if (id3)
993 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
995 playlist_update_resume_info(id3);
998 /* Change the data for the next track and send the event */
999 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1001 id3_write_locked(NEXTTRACK_ID3, id3_next);
1002 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1003 id3_get(NEXTTRACK_ID3));
1006 /* Bring the user current mp3entry up to date and set a new offset for the
1007 buffered metadata */
1008 static void playing_id3_sync(struct track_info *user_info, size_t offset)
1010 id3_mutex_lock();
1012 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1014 if (offset == (size_t)-1)
1016 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1017 size_t play_offset = ply_id3->offset;
1018 long play_elapsed = ply_id3->elapsed;
1019 id3_write(PLAYING_ID3, id3);
1020 ply_id3->offset = play_offset;
1021 ply_id3->elapsed = play_elapsed;
1022 offset = 0;
1024 else
1026 id3_write(PLAYING_ID3, id3);
1029 if (id3)
1030 id3->offset = offset;
1032 id3_mutex_unlock();
1035 /* Wipe-out track metadata - current is optional */
1036 static void wipe_track_metadata(bool current)
1038 id3_mutex_lock();
1040 if (current)
1041 id3_write(PLAYING_ID3, NULL);
1043 id3_write(NEXTTRACK_ID3, NULL);
1044 id3_write(UNBUFFERED_ID3, NULL);
1046 id3_mutex_unlock();
1049 /* Called when buffering is completed on the last track handle */
1050 static void filling_is_finished(void)
1052 logf("last track finished buffering");
1054 /* There's no more to load or watch for */
1055 buf_set_watermark(0);
1056 filling = STATE_FINISHED;
1059 /* Stop the codec decoding or waiting for its data to be ready - returns
1060 'false' if the codec ended up stopped */
1061 static bool halt_decoding_track(bool stop)
1063 /* If it was waiting for us to clear the buffer to make a rebuffer
1064 happen, it should cease otherwise codec_stop could deadlock waiting
1065 for the codec to go to its main loop - codec's request will now
1066 force-fail */
1067 bool retval = false;
1069 buf_signal_handle(ci.audio_hid, true);
1071 if (stop)
1072 codec_stop();
1073 else
1074 retval = codec_pause();
1076 audio_clear_track_notifications();
1078 /* We now know it's idle and not waiting for buffered data */
1079 buf_signal_handle(ci.audio_hid, false);
1081 codec_skip_pending = false;
1082 codec_seeking = false;
1084 return retval;
1087 /* Clear the PCM on a manual skip */
1088 static void audio_clear_paused_pcm(void)
1090 if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active())
1091 pcmbuf_play_stop();
1094 /* End the ff/rw mode */
1095 static void audio_ff_rewind_end(void)
1097 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1098 section */
1099 if (ff_rw_mode)
1101 ff_rw_mode = false;
1103 if (codec_seeking)
1105 /* Clear the buffer */
1106 pcmbuf_play_stop();
1109 if (play_status != PLAY_PAUSED)
1111 /* Seeking-while-playing, resume PCM playback */
1112 pcmbuf_pause(false);
1117 /* Complete the codec seek */
1118 static void audio_complete_codec_seek(void)
1120 /* If a seek completed while paused, 'paused' is true.
1121 * If seeking from seek mode, 'ff_rw_mode' is true. */
1122 if (codec_seeking)
1124 audio_ff_rewind_end();
1125 codec_seeking = false; /* set _after_ the call! */
1127 /* else it's waiting and we must repond */
1130 /* Get the current cuesheet pointer */
1131 static inline struct cuesheet * get_current_cuesheet(void)
1133 return audio_scratch_memory->curr_cue;
1136 /* Read the cuesheet from the buffer */
1137 static void buf_read_cuesheet(int handle_id)
1139 struct cuesheet *cue = get_current_cuesheet();
1141 if (!cue || handle_id < 0)
1142 return;
1144 bufread(handle_id, sizeof (struct cuesheet), cue);
1147 /* Backend to peek/current/next track metadata interface functions -
1148 fill in the mp3entry with as much information as we may obtain about
1149 the track at the specified offset from the user current track -
1150 returns false if no information exists with us */
1151 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1153 if (play_status == PLAY_STOPPED)
1154 return false;
1156 if (id3->path[0] != '\0')
1157 return true; /* Already filled */
1159 struct track_info *info = track_list_user_current(offset);
1161 if (!info)
1163 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1165 if (offset > 0 && track_list_user_current(offset - 1))
1167 /* Try the unbuffered id3 since we're moving forward */
1168 if (ub_id3->path[0] != '\0')
1170 copy_mp3entry(id3, ub_id3);
1171 return true;
1175 else if (bufreadid3(info->id3_hid, id3))
1177 return true;
1180 /* We didn't find the ID3 metadata, so we fill it with the little info we
1181 have and return that */
1183 char path[MAX_PATH+1];
1184 if (playlist_peek(offset, path, sizeof (path)))
1186 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1187 /* Try to get it from the database */
1188 if (!tagcache_fill_tags(id3, path))
1189 #endif
1191 /* By now, filename is the only source of info */
1192 fill_metadata_from_path(id3, path);
1195 return true;
1198 wipe_mp3entry(id3);
1200 return false;
1203 /* Get a resume rewind adjusted offset from the ID3 */
1204 unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1206 unsigned long offset = id3->offset;
1207 size_t resume_rewind = global_settings.resume_rewind *
1208 id3->bitrate * (1000/8);
1210 if (offset < resume_rewind)
1211 offset = 0;
1212 else
1213 offset -= resume_rewind;
1215 return offset;
1218 /* Get the codec into ram and initialize it - keep it if it's ready */
1219 static bool audio_init_codec(struct track_info *track_info,
1220 struct mp3entry *track_id3)
1222 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1223 int hid = ERR_HANDLE_NOT_FOUND;
1225 if (codt_loaded != AFMT_UNKNOWN)
1227 int codt = get_audio_base_codec_type(track_id3->codectype);
1229 if (codt == codt_loaded)
1231 /* Codec is the same base type */
1232 logf("Reusing prev. codec: %d", track_id3->codectype);
1233 #ifdef HAVE_CODEC_BUFFERING
1234 /* Close any buffered codec (we could have skipped directly to a
1235 format transistion that is the same format as the current track
1236 and the buffered one is no longer needed) */
1237 track_info_close_handle(&track_info->codec_hid);
1238 #endif
1239 return true;
1241 else
1243 /* New codec - first make sure the old one's gone */
1244 logf("Removing prev. codec: %d", codt_loaded);
1245 codec_unload();
1249 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1251 #ifdef HAVE_CODEC_BUFFERING
1252 /* Codec thread will close the handle even if it fails and will load from
1253 storage if hid is not valid or the buffer load fails */
1254 hid = track_info->codec_hid;
1255 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1256 #endif
1258 return codec_load(hid, track_id3->codectype);
1259 (void)track_info; /* When codec buffering isn't supported */
1262 /* Start the codec for the current track scheduled to be decoded */
1263 static bool audio_start_codec(bool auto_skip)
1265 struct track_info *info = track_list_current(0);
1266 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1268 if (!cur_id3)
1269 return false;
1271 buf_pin_handle(info->id3_hid, true);
1273 if (!audio_init_codec(info, cur_id3))
1275 buf_pin_handle(info->id3_hid, false);
1276 return false;
1279 #ifdef HAVE_TAGCACHE
1280 bool autoresume_enable = global_settings.autoresume_enable;
1282 if (autoresume_enable && !cur_id3->offset)
1284 /* Resume all manually selected tracks */
1285 bool resume = !auto_skip;
1287 /* Send the "buffer" event to obtain the resume position for the codec */
1288 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1290 if (!resume)
1292 /* Automatic skip - do further tests to see if we should just
1293 ignore any autoresume position */
1294 int autoresume_automatic = global_settings.autoresume_automatic;
1296 switch (autoresume_automatic)
1298 case AUTORESUME_NEXTTRACK_ALWAYS:
1299 /* Just resume unconditionally */
1300 resume = true;
1301 break;
1302 case AUTORESUME_NEXTTRACK_NEVER:
1303 /* Force-rewind it */
1304 break;
1305 default:
1306 /* Not "never resume" - pass resume filter? */
1307 resume = autoresumable(cur_id3);
1311 if (!resume)
1312 cur_id3->offset = 0;
1314 logf("%s: Set offset for %s to %lX\n", __func__,
1315 cur_id3->title, cur_id3->offset);
1317 #endif /* HAVE_TAGCACHE */
1319 /* Rewind the required amount - if an autoresume was done, this also rewinds
1320 that by the setting's amount
1322 It would be best to have bookkeeping about whether or not the track
1323 sounded or not since skipping to it or else skipping to it while paused
1324 and back again will cause accumulation of silent rewinds - that's not
1325 our job to track directly nor could it be in any reasonable way
1327 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1329 /* Update the codec API with the metadata and track info */
1330 id3_write(CODEC_ID3, cur_id3);
1332 ci.audio_hid = info->audio_hid;
1333 ci.filesize = info->filesize;
1334 buf_set_base_handle(info->audio_hid);
1336 /* All required data is now available for the codec */
1337 codec_go();
1339 #ifdef HAVE_TAGCACHE
1340 if (!autoresume_enable || cur_id3->offset)
1341 #endif
1343 /* Send the "buffer" event now */
1344 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1347 buf_pin_handle(info->id3_hid, false);
1348 return true;
1350 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1354 /** --- Audio thread --- **/
1356 /* Load and parse a cuesheet for the file - returns false if the buffer
1357 is full */
1358 static bool audio_load_cuesheet(struct track_info *info,
1359 struct mp3entry *track_id3)
1361 struct cuesheet *cue = get_current_cuesheet();
1362 track_id3->cuesheet = NULL;
1364 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1366 /* If error other than a full buffer, then mark it "unsupported" to
1367 avoid reloading attempt */
1368 int hid = ERR_UNSUPPORTED_TYPE;
1369 char cuepath[MAX_PATH];
1371 #ifdef HAVE_IO_PRIORITY
1372 buf_back_off_storage(true);
1373 #endif
1374 if (look_for_cuesheet_file(track_id3->path, cuepath))
1376 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1378 if (hid >= 0)
1380 void *cuesheet = NULL;
1381 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1383 if (parse_cuesheet(cuepath, (struct cuesheet *)cuesheet))
1385 /* Indicate cuesheet is present (while track remains
1386 buffered) */
1387 track_id3->cuesheet = cue;
1389 else
1391 bufclose(hid);
1392 hid = ERR_UNSUPPORTED_TYPE;
1397 #ifdef HAVE_IO_PRIORITY
1398 buf_back_off_storage(false);
1399 #endif
1400 if (hid == ERR_BUFFER_FULL)
1402 logf("buffer is full for now (%s)", __func__);
1403 return false;
1405 else
1407 if (hid < 0)
1408 logf("Cuesheet loading failed");
1410 info->cuesheet_hid = hid;
1414 return true;
1417 #ifdef HAVE_ALBUMART
1418 /* Load any album art for the file - returns false if the buffer is full */
1419 static bool audio_load_albumart(struct track_info *info,
1420 struct mp3entry *track_id3)
1422 int i;
1423 FOREACH_ALBUMART(i)
1425 struct bufopen_bitmap_data user_data;
1426 int *aa_hid = &info->aa_hid[i];
1427 int hid = ERR_UNSUPPORTED_TYPE;
1429 /* albumart_slots may change during a yield of bufopen,
1430 * but that's no problem */
1431 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1432 !albumart_slots[i].used)
1433 continue;
1435 memset(&user_data, 0, sizeof(user_data));
1436 user_data.dim = &albumart_slots[i].dim;
1438 #ifdef HAVE_IO_PRIORITY
1439 buf_back_off_storage(true);
1440 #endif
1442 /* We can only decode jpeg for embedded AA */
1443 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1445 user_data.embedded_albumart = &track_id3->albumart;
1446 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1449 if (hid < 0 && hid != ERR_BUFFER_FULL)
1451 /* No embedded AA or it couldn't be loaded - try other sources */
1452 char path[MAX_PATH];
1454 if (find_albumart(track_id3, path, sizeof(path),
1455 &albumart_slots[i].dim))
1457 user_data.embedded_albumart = NULL;
1458 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1462 #ifdef HAVE_IO_PRIORITY
1463 buf_back_off_storage(false);
1464 #endif
1465 if (hid == ERR_BUFFER_FULL)
1467 logf("buffer is full for now (%s)", __func__);
1468 return false;
1470 else
1472 /* If error other than a full buffer, then mark it "unsupported"
1473 to avoid reloading attempt */
1474 if (hid < 0)
1476 logf("Album art loading failed");
1477 hid = ERR_UNSUPPORTED_TYPE;
1480 *aa_hid = hid;
1484 return true;
1486 #endif /* HAVE_ALBUMART */
1488 #ifdef HAVE_CODEC_BUFFERING
1489 /* Load a codec for the file onto the buffer - assumes we're working from the
1490 currently loading track - not called for the current track */
1491 static bool audio_buffer_codec(struct track_info *track_info,
1492 struct mp3entry *track_id3)
1494 /* This will not be the current track -> it cannot be the first and the
1495 current track cannot be ahead of buffering -> there is a previous
1496 track entry which is either current or ahead of the current */
1497 struct track_info *prev_info = track_list_last(-1);
1498 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1500 /* If the previous codec is the same as this one, there is no need to
1501 put another copy of it on the file buffer (in other words, only
1502 buffer codecs at format transitions) */
1503 if (prev_id3)
1505 int codt = get_audio_base_codec_type(track_id3->codectype);
1506 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1508 if (codt == prev_codt)
1510 logf("Reusing prev. codec: %d", prev_id3->codectype);
1511 return true;
1514 /* else just load it (harmless) */
1516 /* Load the codec onto the buffer if possible */
1517 const char *codec_fn = get_codec_filename(track_id3->codectype);
1518 if (!codec_fn)
1519 return false;
1521 char codec_path[MAX_PATH+1]; /* Full path to codec */
1522 codec_get_full_path(codec_path, codec_fn);
1524 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1526 if (track_info->codec_hid >= 0)
1528 logf("Buffered codec: %d", afmt);
1529 return true;
1532 return false;
1534 #endif /* HAVE_CODEC_BUFFERING */
1536 /* Load metadata for the next track (with bufopen). The rest of the track
1537 loading will be handled by audio_finish_load_track once the metadata has
1538 been actually loaded by the buffering thread.
1540 Each track is arranged in the buffer as follows:
1541 <id3|[cuesheet|][album art|][codec|]audio>
1543 The next will not be loaded until the previous succeeds if the buffer was
1544 full at the time. To put any metadata after audio would make those handles
1545 unmovable.
1547 static int audio_load_track(void)
1549 if (in_progress_id3_hid >= 0)
1551 /* There must be an info pointer if the in-progress id3 is even there */
1552 struct track_info *info = track_list_last(0);
1554 if (info->id3_hid == in_progress_id3_hid)
1556 if (filling == STATE_FILLING)
1558 /* Haven't finished the metadata but the notification is
1559 anticipated to come soon */
1560 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1561 return LOAD_TRACK_OK;
1563 else if (filling == STATE_FULL)
1565 /* Buffer was full trying to complete the load after the
1566 metadata finished, so attempt to continue - older handles
1567 should have been cleared already */
1568 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1569 filling = STATE_FILLING;
1570 buffer_event_finished_callback(&info->id3_hid);
1571 return LOAD_TRACK_OK;
1575 /* Some old, stray buffering message */
1576 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1577 return LOAD_TRACK_ERR_BUSY;
1580 filling = STATE_FILLING;
1582 struct track_info *info = track_list_alloc_track();
1583 if (info == NULL)
1585 /* List is full so stop buffering tracks - however, attempt to obtain
1586 metadata as the unbuffered id3 */
1587 logf("No free tracks");
1588 filling = STATE_FULL;
1591 playlist_peek_offset++;
1593 logf("Buffering track: s%u/c%u/e%u/p%d",
1594 track_list.start, track_list.current, track_list.end,
1595 playlist_peek_offset);
1597 /* Get track name from current playlist read position */
1598 int fd = -1;
1599 char name_buf[MAX_PATH + 1];
1600 const char *trackname;
1602 while (1)
1605 trackname = playlist_peek(playlist_peek_offset, name_buf,
1606 sizeof (name_buf));
1608 if (!trackname)
1609 break;
1611 /* Test for broken playlists by probing for the files */
1612 fd = open(trackname, O_RDONLY);
1613 if (fd >= 0)
1614 break;
1616 logf("Open failed");
1617 /* Skip invalid entry from playlist */
1618 playlist_skip_entry(NULL, playlist_peek_offset);
1620 /* Sync the playlist if it isn't finished */
1621 if (playlist_peek(playlist_peek_offset, NULL, 0))
1622 playlist_next(0);
1625 if (!trackname)
1627 /* No track - exhausted the playlist entries */
1628 logf("End-of-playlist");
1629 id3_write_locked(UNBUFFERED_ID3, NULL);
1631 if (filling != STATE_FULL)
1632 track_list_unalloc_track(); /* Free this entry */
1634 playlist_peek_offset--; /* Maintain at last index */
1636 /* We can end up here after the real last track signals its completion
1637 and miss the transition to STATE_FINISHED esp. if dropping the last
1638 songs of a playlist late in their load (2nd stage) */
1639 info = track_list_last(0);
1641 if (info && buf_handle_remaining(info->audio_hid) == 0)
1642 filling_is_finished();
1643 else
1644 filling = STATE_END_OF_PLAYLIST;
1646 return LOAD_TRACK_ERR_NO_MORE;
1649 /* Successfully opened the file - get track metadata */
1650 if (filling == STATE_FULL ||
1651 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1653 /* Buffer or track list is full */
1654 struct mp3entry *ub_id3;
1656 playlist_peek_offset--;
1658 /* Load the metadata for the first unbuffered track */
1659 ub_id3 = id3_get(UNBUFFERED_ID3);
1660 id3_mutex_lock();
1661 get_metadata(ub_id3, fd, trackname);
1662 id3_mutex_unlock();
1664 if (filling != STATE_FULL)
1666 track_list_unalloc_track();
1667 filling = STATE_FULL;
1670 logf("%s: buffer is full for now (%u tracks)", __func__,
1671 track_list_count());
1673 else
1675 /* Successful load initiation */
1676 info->filesize = filesize(fd);
1677 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1680 close(fd);
1681 return LOAD_TRACK_OK;
1684 /* Second part of the track loading: We now have the metadata available, so we
1685 can load the codec, the album art and finally the audio data.
1686 This is called on the audio thread after the buffering thread calls the
1687 buffering_handle_finished_callback callback. */
1688 static int audio_finish_load_track(struct track_info *info)
1690 int trackstat = LOAD_TRACK_OK;
1692 if (info->id3_hid != in_progress_id3_hid)
1694 /* We must not be here if not! */
1695 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1696 in_progress_id3_hid);
1697 return LOAD_TRACK_ERR_BUSY;
1700 /* The current track for decoding (there is always one if the list is
1701 populated) */
1702 struct track_info *cur_info = track_list_current(0);
1703 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1705 if (!track_id3)
1707 /* This is an error condition. Track cannot be played without valid
1708 metadata; skip the track. */
1709 logf("No metadata for: %s", track_id3->path);
1710 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1711 goto audio_finish_load_track_exit;
1714 /* Try to load a cuesheet for the track */
1715 if (!audio_load_cuesheet(info, track_id3))
1717 /* No space for cuesheet on buffer, not an error */
1718 filling = STATE_FULL;
1719 goto audio_finish_load_track_exit;
1722 #ifdef HAVE_ALBUMART
1723 /* Try to load album art for the track */
1724 if (!audio_load_albumart(info, track_id3))
1726 /* No space for album art on buffer, not an error */
1727 filling = STATE_FULL;
1728 goto audio_finish_load_track_exit;
1730 #endif
1732 /* All handles available to external routines are ready - audio and codec
1733 information is private */
1735 if (info == track_list_user_current(0))
1737 /* Send only when the track handles could not all be opened ahead of
1738 time for the user's current track - otherwise everything is ready
1739 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1740 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1743 #ifdef HAVE_CODEC_BUFFERING
1744 /* Try to buffer a codec for the track */
1745 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1747 if (info->codec_hid == ERR_BUFFER_FULL)
1749 /* No space for codec on buffer, not an error */
1750 filling = STATE_FULL;
1751 logf("buffer is full for now (%s)", __func__);
1753 else
1755 /* This is an error condition, either no codec was found, or
1756 reading the codec file failed part way through, either way,
1757 skip the track */
1758 logf("No codec for: %s", track_id3->path);
1759 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1762 goto audio_finish_load_track_exit;
1764 #endif /* HAVE_CODEC_BUFFERING */
1766 /** Finally, load the audio **/
1767 size_t file_offset = 0;
1768 track_id3->elapsed = 0;
1770 if (track_id3->offset >= info->filesize)
1771 track_id3->offset = 0;
1773 logf("%s: set offset for %s to %lu\n", __func__,
1774 id3->title, (unsigned long)offset);
1776 /* Adjust for resume rewind so we know what to buffer - starting the codec
1777 calls it again, so we don't save it (and they shouldn't accumulate) */
1778 size_t offset = resume_rewind_adjusted_offset(track_id3);
1780 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1782 if (audiotype == TYPE_ATOMIC_AUDIO)
1783 logf("Loading atomic %d", track_id3->codectype);
1785 if (format_buffers_with_offset(track_id3->codectype))
1787 /* This format can begin buffering from any point */
1788 file_offset = offset;
1791 logf("load track: %s", track_id3->path);
1793 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1795 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1796 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1798 else
1800 /* No offset given or it is very minimal - begin at the first frame
1801 according to the metadata */
1802 file_offset = track_id3->first_frame_offset;
1805 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1807 if (hid >= 0)
1809 info->audio_hid = hid;
1811 if (info == cur_info)
1813 /* This is the current track to decode - should be started now */
1814 trackstat = LOAD_TRACK_READY;
1817 else
1819 /* Buffer could be full but not properly so if this is the only
1820 track! */
1821 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1823 filling = STATE_FULL;
1824 logf("Buffer is full for now (%s)", __func__);
1826 else
1828 /* Nothing to play if no audio handle - skip this */
1829 logf("Could not add audio data handle");
1830 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1834 audio_finish_load_track_exit:
1835 if (trackstat < LOAD_TRACK_OK)
1837 playlist_skip_entry(NULL, playlist_peek_offset);
1838 track_info_close(info);
1839 track_list_unalloc_track();
1841 if (playlist_peek(playlist_peek_offset, NULL, 0))
1842 playlist_next(0);
1844 playlist_peek_offset--;
1847 if (filling != STATE_FULL)
1849 /* Load next track - error or not */
1850 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1851 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1852 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1854 else
1856 /* Full */
1857 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1860 return trackstat;
1863 /* Start a new track load */
1864 static int audio_fill_file_buffer(void)
1866 if (play_status == PLAY_STOPPED)
1867 return LOAD_TRACK_ERR_FAILED;
1869 trigger_cpu_boost();
1871 /* Must reset the buffer before use if trashed or voice only - voice
1872 file size shouldn't have changed so we can go straight from
1873 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1874 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1875 audio_reset_buffer();
1877 logf("Starting buffer fill");
1879 int trackstat = audio_load_track();
1881 if (trackstat >= LOAD_TRACK_OK)
1883 if (track_list_current(0) == track_list_user_current(0))
1884 playlist_next(0);
1886 if (filling == STATE_FULL && !track_list_user_current(1))
1888 /* There are no user tracks on the buffer after this therefore
1889 this is the next track */
1890 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
1894 return trackstat;
1897 /* Discard unwanted tracks and start refill from after the specified playlist
1898 offset */
1899 static int audio_reset_and_rebuffer(
1900 enum track_clear_action action, int peek_offset)
1902 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
1904 id3_write_locked(UNBUFFERED_ID3, NULL);
1906 /* Remove unwanted tracks - caller must have ensured codec isn't using
1907 any */
1908 track_list_clear(action);
1910 /* Refill at specified position (-1 starts at index offset 0) */
1911 playlist_peek_offset = peek_offset;
1913 /* Fill the buffer */
1914 return audio_fill_file_buffer();
1917 /* Handle buffering events
1918 (Q_AUDIO_BUFFERING) */
1919 static void audio_on_buffering(int event)
1921 enum track_clear_action action;
1922 int peek_offset;
1924 if (track_list_empty())
1925 return;
1927 switch (event)
1929 case BUFFER_EVENT_BUFFER_LOW:
1930 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
1931 return; /* Should be nothing left to fill */
1933 /* Clear old tracks and continue buffering where it left off */
1934 action = TRACK_LIST_KEEP_NEW;
1935 peek_offset = playlist_peek_offset;
1936 break;
1938 case BUFFER_EVENT_REBUFFER:
1939 /* Remove all but the currently decoding track and redo buffering
1940 after that */
1941 action = TRACK_LIST_KEEP_CURRENT;
1942 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
1943 break;
1945 default:
1946 return;
1949 switch (skip_pending)
1951 case TRACK_SKIP_NONE:
1952 case TRACK_SKIP_AUTO:
1953 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
1954 audio_reset_and_rebuffer(action, peek_offset);
1955 break;
1957 case TRACK_SKIP_AUTO_END_PLAYLIST:
1958 /* Already finished */
1959 break;
1961 default:
1962 /* Invalid */
1963 logf("Buffering call, inv. state: %d", (int)skip_pending);
1967 /* Handle starting the next track load
1968 (Q_AUDIO_FILL_BUFFER) */
1969 static void audio_on_fill_buffer(void)
1971 audio_handle_track_load_status(audio_fill_file_buffer());
1974 /* Handle posted load track finish event
1975 (Q_AUDIO_FINISH_LOAD_TRACK) */
1976 static void audio_on_finish_load_track(int id3_hid)
1978 struct track_info *info = track_list_last(0);
1980 if (!info || !buf_is_handle(id3_hid))
1981 return;
1983 if (info == track_list_user_current(1))
1985 /* Just loaded the metadata right after the current position */
1986 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
1989 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
1990 return; /* Not current track */
1992 bool is_user_current = info == track_list_user_current(0);
1994 if (is_user_current)
1996 /* Copy cuesheet */
1997 buf_read_cuesheet(info->cuesheet_hid);
2000 if (audio_start_codec(automatic_skip))
2002 if (is_user_current)
2004 /* Be sure all tagtree info is synchronized; it will be needed for the
2005 track finish event - the sync will happen when finalizing a track
2006 change otherwise */
2007 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2009 playing_id3_sync(info, -1);
2011 if (!was_valid)
2013 /* Playing id3 hadn't been updated yet because no valid track
2014 was yet available - treat like the first track */
2015 audio_playlist_track_change();
2019 else
2021 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2025 /* Called when handles other than metadata handles have finished buffering
2026 (Q_AUDIO_HANDLE_FINISHED) */
2027 static void audio_on_handle_finished(int hid)
2029 /* Right now, only audio handles should end up calling this */
2030 if (filling == STATE_END_OF_PLAYLIST)
2032 struct track_info *info = track_list_last(0);
2034 /* Really we don't know which order the handles will actually complete
2035 to zero bytes remaining since another thread is doing it - be sure
2036 it's the right one */
2037 if (info && info->audio_hid == hid)
2039 /* This was the last track in the playlist and we now have all the
2040 data we need */
2041 filling_is_finished();
2046 /* Called to make an outstanding track skip the current track and to send the
2047 transition events */
2048 static void audio_finalise_track_change(bool delayed)
2050 switch (skip_pending)
2052 case TRACK_SKIP_NONE: /* Manual skip */
2053 break;
2055 case TRACK_SKIP_AUTO:
2056 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2058 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2059 audio_playlist_track_finish();
2061 if (!playlist_peek(playlist_delta, NULL, 0))
2063 /* Track ended up rejected - push things ahead like the codec blew
2064 it (because it was never started and now we're here where it
2065 should have been decoding the next track by now) - next, a
2066 directory change or end of playback will most likely happen */
2067 skip_pending = TRACK_SKIP_NONE;
2068 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2069 return;
2072 if (!playlist_delta)
2073 break;
2075 playlist_peek_offset -= playlist_delta;
2076 if (playlist_next(playlist_delta) >= 0)
2077 break;
2078 /* What!? Disappear? Hopeless bleak despair */
2080 /* Fallthrough */
2081 case TRACK_SKIP_AUTO_END_PLAYLIST:
2082 default: /* Invalid */
2083 filling = STATE_ENDED;
2084 audio_stop_playback();
2085 return;
2088 struct track_info *info = track_list_current(0);
2089 struct mp3entry *track_id3 = NULL;
2091 id3_mutex_lock();
2093 /* Update the current cuesheet if any and enabled */
2094 if (info)
2096 buf_read_cuesheet(info->cuesheet_hid);
2097 track_id3 = bufgetid3(info->id3_hid);
2100 id3_write(PLAYING_ID3, track_id3);
2102 if (delayed)
2104 /* Delayed skip where codec is ahead of user's current track */
2105 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2106 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
2107 ply_id3->elapsed = ci_id3->elapsed;
2108 ply_id3->offset = ci_id3->offset;
2111 /* The skip is technically over */
2112 skip_pending = TRACK_SKIP_NONE;
2114 /* Sync the next track information */
2115 info = track_list_current(1);
2117 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2118 id3_get(UNBUFFERED_ID3));
2120 id3_mutex_unlock();
2122 audio_playlist_track_change();
2125 /* Actually begin a transition and take care of the codec change - may complete
2126 it now or ask pcmbuf for notification depending on the type and what pcmbuf
2127 has to say */
2128 static void audio_begin_track_change(bool auto_skip, int trackstat)
2130 /* Even if the new track is bad, the old track must be finished off */
2131 bool finalised = pcmbuf_start_track_change(auto_skip);
2133 if (finalised)
2135 /* pcmbuf says that the transition happens now - complete it */
2136 audio_finalise_track_change(false);
2138 if (play_status == PLAY_STOPPED)
2139 return; /* Stopped us */
2142 if (!auto_skip)
2143 audio_clear_paused_pcm();
2145 if (trackstat >= LOAD_TRACK_OK)
2147 struct track_info *info = track_list_current(0);
2149 if (info->audio_hid < 0)
2150 return;
2152 /* Everything needed for the codec is ready - start it */
2153 if (audio_start_codec(auto_skip))
2155 if (finalised)
2156 playing_id3_sync(info, -1);
2157 return;
2160 trackstat = LOAD_TRACK_ERR_START_CODEC;
2163 audio_handle_track_load_status(trackstat);
2166 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2167 static void audio_monitor_end_of_playlist(void)
2169 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2170 filling = STATE_ENDING;
2171 pcmbuf_monitor_track_change(true);
2174 /* Codec has completed decoding the track
2175 (usually Q_AUDIO_CODEC_COMPLETE) */
2176 static void audio_on_codec_complete(int status)
2178 logf("%s(%d)", __func__, status);
2180 if (play_status == PLAY_STOPPED)
2181 return;
2183 /* If it didn't notify us first, don't expect "seek complete" message
2184 since the codec can't post it now - do things like it would have
2185 done */
2186 audio_complete_codec_seek();
2188 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2190 /* Old-hay on the ip-skay - codec has completed decoding
2192 Paused: We're not sounding it, so just remember that it happened
2193 and the resume will begin the transition
2195 Skipping: There was already a skip in progress, remember it and
2196 allow no further progress until the PCM from the previous
2197 song has finished
2199 codec_skip_pending = true;
2200 codec_skip_status = status;
2201 return;
2204 codec_skip_pending = false;
2206 #ifdef AB_REPEAT_ENABLE
2207 if (status >= 0)
2209 /* Normal automatic skip */
2210 ab_end_of_track_report();
2212 #endif
2214 int trackstat = LOAD_TRACK_OK;
2216 automatic_skip = true;
2217 skip_pending = TRACK_SKIP_AUTO;
2219 /* Does this track have an entry allocated? */
2220 struct track_info *info = track_list_advance_current(1);
2222 if (!info || info->audio_hid < 0)
2224 bool end_of_playlist = false;
2226 if (info)
2228 /* Track load is not complete - it might have stopped on a
2229 full buffer without reaching the audio handle or we just
2230 arrived at it early
2232 If this type is atomic and we couldn't get the audio,
2233 perhaps it would need to wrap to make the allocation and
2234 handles are in the way - to maximize the liklihood it can
2235 be allocated, clear all handles to reset the buffer and
2236 its indexes to 0 - for packet audio, this should not be an
2237 issue and a pointless full reload of all the track's
2238 metadata may be avoided */
2240 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2242 if (track_id3 &&
2243 get_audio_base_data_type(track_id3->codectype)
2244 == TYPE_PACKET_AUDIO)
2246 /* Continue filling after this track */
2247 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2248 audio_begin_track_change(true, trackstat);
2249 return;
2251 /* else rebuffer at this track; status applies to the track we
2252 want */
2254 else if (!playlist_peek(1, NULL, 0))
2256 /* Play sequence is complete - directory change or other playlist
2257 resequencing - the playlist must now be advanced in order to
2258 continue since a peek ahead to the next track is not possible */
2259 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2260 end_of_playlist = playlist_next(1) < 0;
2263 if (!end_of_playlist)
2265 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2266 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2268 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2270 /* Failed to find anything after all - do playlist switchover
2271 instead */
2272 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2273 end_of_playlist = playlist_next(1) < 0;
2277 if (end_of_playlist)
2279 audio_monitor_end_of_playlist();
2280 return;
2284 audio_begin_track_change(true, trackstat);
2287 /* Called when codec completes seek operation
2288 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2289 static void audio_on_codec_seek_complete(void)
2291 logf("%s()", __func__);
2292 audio_complete_codec_seek();
2293 codec_go();
2296 /* Called when PCM track change has completed
2297 (Q_AUDIO_TRACK_CHANGED) */
2298 static void audio_on_track_changed(void)
2300 /* Finish whatever is pending so that the WPS is in sync */
2301 audio_finalise_track_change(true);
2303 if (codec_skip_pending)
2305 /* Codec got ahead completing a short track - complete the
2306 codec's skip and begin the next */
2307 codec_skip_pending = false;
2308 audio_on_codec_complete(codec_skip_status);
2312 /* Begin playback from an idle state, transition to a new playlist or
2313 invalidate the buffer and resume (if playing).
2314 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2315 static void audio_start_playback(size_t offset, unsigned int flags)
2317 enum play_status old_status = play_status;
2319 if (flags & AUDIO_START_NEWBUF)
2321 /* Mark the buffer dirty - if not playing, it will be reset next
2322 time */
2323 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2324 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2327 if (old_status != PLAY_STOPPED)
2329 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2331 halt_decoding_track(true);
2333 automatic_skip = false;
2334 ff_rw_mode = false;
2336 if (flags & AUDIO_START_RESTART)
2338 /* Clear out some stuff to resume the current track where it
2339 left off */
2340 pcmbuf_play_stop();
2341 offset = id3_get(PLAYING_ID3)->offset;
2342 track_list_clear(TRACK_LIST_CLEAR_ALL);
2344 else
2346 /* This is more-or-less treated as manual track transition */
2347 /* Save resume information for current track */
2348 audio_playlist_track_finish();
2349 track_list_clear(TRACK_LIST_CLEAR_ALL);
2351 /* Indicate manual track change */
2352 pcmbuf_start_track_change(false);
2353 audio_clear_paused_pcm();
2354 wipe_track_metadata(true);
2357 /* Set after track finish event in case skip was in progress */
2358 skip_pending = TRACK_SKIP_NONE;
2360 else
2362 if (flags & AUDIO_START_RESTART)
2363 return; /* Must already be playing */
2365 /* Cold playback start from a stopped state */
2366 logf("%s(%lu): starting", __func__, offset);
2368 /* Set audio parameters */
2369 #if INPUT_SRC_CAPS != 0
2370 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2371 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2372 #endif
2373 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2374 sound_set_volume(global_settings.volume);
2375 #endif
2376 /* Be sure channel is audible */
2377 pcmbuf_fade(false, true);
2379 /* Update our state */
2380 play_status = PLAY_PLAYING;
2383 /* Start fill from beginning of playlist */
2384 playlist_peek_offset = -1;
2385 buf_set_base_handle(-1);
2387 /* Officially playing */
2388 queue_reply(&audio_queue, 1);
2390 /* Add these now - finish event for the first id3 will most likely be sent
2391 immediately */
2392 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2393 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2395 if (old_status == PLAY_STOPPED)
2397 /* Send coldstart event */
2398 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2401 /* Fill the buffer */
2402 int trackstat = audio_fill_file_buffer();
2404 if (trackstat >= LOAD_TRACK_OK)
2406 /* This is the currently playing track - get metadata, stat */
2407 playing_id3_sync(track_list_current(0), offset);
2409 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2411 /* Only if actually changing tracks... */
2412 if (!(flags & AUDIO_START_RESTART))
2413 audio_playlist_track_change();
2416 else
2418 /* Found nothing playable */
2419 audio_handle_track_load_status(trackstat);
2423 /* Stop playback and enter an idle state
2424 (usually Q_AUDIO_STOP) */
2425 static void audio_stop_playback(void)
2427 logf("%s()", __func__);
2429 if (play_status == PLAY_STOPPED)
2430 return;
2432 pcmbuf_fade(global_settings.fade_on_stop, false);
2434 /* Stop the codec and unload it */
2435 halt_decoding_track(true);
2436 pcmbuf_play_stop();
2437 codec_unload();
2439 /* Save resume information - "filling" might have been set to
2440 "STATE_ENDED" by caller in order to facilitate end of playlist */
2441 audio_playlist_track_finish();
2443 skip_pending = TRACK_SKIP_NONE;
2444 automatic_skip = false;
2446 /* Close all tracks and mark them NULL */
2447 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2448 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2449 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2451 track_list_clear(TRACK_LIST_CLEAR_ALL);
2453 /* Update our state */
2454 ff_rw_mode = false;
2455 play_status = PLAY_STOPPED;
2457 wipe_track_metadata(true);
2459 /* Go idle */
2460 filling = STATE_IDLE;
2461 cancel_cpu_boost();
2464 /* Pause the playback of the current track
2465 (Q_AUDIO_PAUSE) */
2466 static void audio_on_pause(bool pause)
2468 logf("%s(%s)", __func__, pause ? "true" : "false");
2470 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2471 return;
2473 bool const do_fade = global_settings.fade_on_stop;
2475 if (pause)
2476 pcmbuf_fade(do_fade, false);
2478 if (!ff_rw_mode)
2480 /* Not in ff/rw mode - may set the state (otherwise this could make
2481 old data play because seek hasn't completed and cleared it) */
2482 pcmbuf_pause(pause);
2485 if (!pause)
2486 pcmbuf_fade(do_fade, true);
2488 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2490 if (!pause && codec_skip_pending)
2492 /* Actually do the skip that is due - resets the status flag */
2493 audio_on_codec_complete(codec_skip_status);
2497 /* Skip a certain number of tracks forwards or backwards
2498 (Q_AUDIO_SKIP) */
2499 static void audio_on_skip(void)
2501 id3_mutex_lock();
2503 /* Eat the delta to keep it synced, even if not playing */
2504 int toskip = skip_offset;
2505 skip_offset = 0;
2507 logf("%s(): %d", __func__, toskip);
2509 id3_mutex_unlock();
2511 if (play_status == PLAY_STOPPED)
2512 return;
2514 /* Force codec to abort this track */
2515 halt_decoding_track(true);
2517 /* Kill the ff/rw halt */
2518 ff_rw_mode = false;
2520 /* Manual skip */
2521 automatic_skip = false;
2523 /* If there was an auto skip in progress, there will be residual
2524 advancement of the playlist and/or track list so compensation will be
2525 required in order to end up in the right spot */
2526 int track_list_delta = toskip;
2527 int playlist_delta = toskip;
2529 if (skip_pending != TRACK_SKIP_NONE)
2531 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2532 track_list_delta--;
2534 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2535 playlist_delta--;
2538 audio_playlist_track_finish();
2539 skip_pending = TRACK_SKIP_NONE;
2541 /* Update the playlist current track now */
2542 while (playlist_next(playlist_delta) < 0)
2544 /* Manual skip out of range (because the playlist wasn't updated
2545 yet by us and so the check in audio_skip returned 'ok') - bring
2546 back into range */
2547 int d = toskip < 0 ? 1 : -1;
2549 while (!playlist_check(playlist_delta))
2551 if (playlist_delta == d)
2553 /* Had to move the opposite direction to correct, which is
2554 wrong - this is the end */
2555 filling = STATE_ENDED;
2556 audio_stop_playback();
2557 return;
2560 playlist_delta += d;
2561 track_list_delta += d;
2565 /* Adjust things by how much the playlist was manually moved */
2566 playlist_peek_offset -= playlist_delta;
2568 struct track_info *info = track_list_advance_current(track_list_delta);
2569 int trackstat = LOAD_TRACK_OK;
2571 if (!info || info->audio_hid < 0)
2573 /* We don't know the next track thus we know we don't have it */
2574 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2577 audio_begin_track_change(false, trackstat);
2580 /* Skip to the next/previous directory
2581 (Q_AUDIO_DIR_SKIP) */
2582 static void audio_on_dir_skip(int direction)
2584 logf("%s(%d)", __func__, direction);
2586 id3_mutex_lock();
2587 skip_offset = 0;
2588 id3_mutex_unlock();
2590 if (play_status == PLAY_STOPPED)
2591 return;
2593 /* Force codec to abort this track */
2594 halt_decoding_track(true);
2596 /* Kill the ff/rw halt */
2597 ff_rw_mode = false;
2599 /* Manual skip */
2600 automatic_skip = false;
2602 audio_playlist_track_finish();
2604 /* Unless automatic and gapless, skips do not pend */
2605 skip_pending = TRACK_SKIP_NONE;
2607 /* Regardless of the return value we need to rebuffer. If it fails the old
2608 playlist will resume, else the next dir will start playing. */
2609 playlist_next_dir(direction);
2611 wipe_track_metadata(false);
2613 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2615 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2617 /* The day the music died - finish-off whatever is playing and call it
2618 quits */
2619 audio_monitor_end_of_playlist();
2620 return;
2623 audio_begin_track_change(false, trackstat);
2626 /* Enter seek mode in order to start a seek
2627 (Q_AUDIO_PRE_FF_REWIND) */
2628 static void audio_on_pre_ff_rewind(void)
2630 logf("%s()", __func__);
2632 if (play_status == PLAY_STOPPED || ff_rw_mode)
2633 return;
2635 ff_rw_mode = true;
2637 if (play_status == PLAY_PAUSED)
2638 return;
2640 pcmbuf_pause(true);
2643 /* Seek the playback of the current track to the specified time
2644 (Q_AUDIO_FF_REWIND) */
2645 static void audio_on_ff_rewind(long time)
2647 logf("%s(%ld)", __func__, time);
2649 if (play_status == PLAY_STOPPED)
2650 return;
2652 enum track_skip_type pending = skip_pending;
2654 switch (pending)
2656 case TRACK_SKIP_NONE: /* The usual case */
2657 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2658 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2660 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2661 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2663 automatic_skip = false;
2665 /* Send event before clobbering the time */
2666 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2667 then skipping back to this track resumes properly. Something else
2668 should be sent. We're not _really_ finishing the track are we? */
2669 if (time == 0)
2670 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2672 /* Prevent user codec time update - coerce to something that is
2673 innocuous concerning lookaheads */
2674 if (pending == TRACK_SKIP_NONE)
2675 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2677 id3->elapsed = time;
2678 queue_reply(&audio_queue, 1);
2680 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2682 /* Need this set in case ff/rw mode + error but _after_ the codec
2683 halt that will reset it */
2684 codec_seeking = true;
2686 if (pending == TRACK_SKIP_AUTO)
2688 if (!track_list_advance_current(-1))
2690 /* Not in list - must rebuffer at the current playlist index */
2691 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2692 < LOAD_TRACK_OK)
2694 /* Codec is stopped */
2695 break;
2700 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2701 rebuffer is needed */
2702 skip_pending = TRACK_SKIP_NONE;
2703 struct track_info *cur_info = track_list_current(0);
2705 /* Track must complete the loading _now_ since a codec and audio
2706 handle are needed in order to do the seek */
2707 if (cur_info->audio_hid < 0 &&
2708 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2710 /* Call above should push any load sequence - no need for
2711 halt_decoding_track here if no skip was pending here because
2712 there would not be a codec started if no audio handle was yet
2713 opened */
2714 break;
2717 if (pending == TRACK_SKIP_AUTO)
2719 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2720 !audio_init_codec(cur_info, ci_id3))
2722 /* We should have still been able to get it - skip it and move
2723 onto the next one - like it or not this track is broken */
2724 break;
2727 /* Set the codec API to the correct metadata and track info */
2728 ci.audio_hid = cur_info->audio_hid;
2729 ci.filesize = cur_info->filesize;
2730 buf_set_base_handle(cur_info->audio_hid);
2733 if (!haltres)
2735 /* If codec must be (re)started, reset the offset */
2736 ci_id3->offset = 0;
2739 codec_seek(time);
2740 return;
2743 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2745 /* We cannot do this because the playlist must be reversed by one
2746 and it doesn't always return the same song when going backwards
2747 across boundaries as forwards (either because of randomization
2748 or inconsistency in deciding what the previous track should be),
2749 therefore the whole operation would often end up as nonsense -
2750 lock out seeking for a couple seconds */
2752 /* Sure as heck cancel seek mode too! */
2753 audio_ff_rewind_end();
2754 return;
2757 default:
2758 /* Won't see this */
2759 return;
2762 if (play_status == PLAY_STOPPED)
2764 /* Playback ended because of an error completing a track load */
2765 return;
2768 /* Always fake it as a codec start error which will handle mode
2769 cancellations and skip to the next track */
2770 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2773 /* Invalidates all but currently playing track
2774 (Q_AUDIO_FLUSH) */
2775 static void audio_on_audio_flush(void)
2777 logf("%s", __func__);
2779 if (track_list_empty())
2780 return; /* Nothing to flush out */
2782 switch (skip_pending)
2784 case TRACK_SKIP_NONE:
2785 case TRACK_SKIP_AUTO_END_PLAYLIST:
2786 /* Remove all but the currently playing track from the list and
2787 refill after that */
2788 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2789 playlist_peek_offset = 0;
2790 id3_write_locked(UNBUFFERED_ID3, NULL);
2791 audio_update_and_announce_next_track(NULL);
2793 /* Ignore return since it's about the next track, not this one */
2794 audio_fill_file_buffer();
2796 if (skip_pending == TRACK_SKIP_NONE)
2797 break;
2799 /* There's now a track after this one now - convert to auto skip -
2800 no skip should pend right now because multiple flush messages can
2801 be fired which would cause a restart in the below cases */
2802 skip_pending = TRACK_SKIP_NONE;
2803 audio_clear_track_notifications();
2804 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2805 break;
2807 case TRACK_SKIP_AUTO:
2808 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2809 /* Precisely removing what it already decoded for the next track is
2810 not possible so a restart is required in order to continue the
2811 currently playing track without the now invalid future track
2812 playing */
2813 audio_start_playback(0, AUDIO_START_RESTART);
2814 break;
2816 default: /* Nothing else is a state */
2817 break;
2821 #ifdef AUDIO_HAVE_RECORDING
2822 /* Load the requested encoder type
2823 (Q_AUDIO_LOAD_ENCODER) */
2824 static void audio_on_load_encoder(int afmt)
2826 bool res = true;
2828 if (play_status != PLAY_STOPPED)
2829 audio_stop_playback(); /* Can't load both types at once */
2830 else
2831 codec_unload(); /* Encoder still loaded, stop and unload it */
2833 if (afmt != AFMT_UNKNOWN)
2835 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2836 if (res)
2837 codec_go(); /* These are run immediately */
2840 queue_reply(&audio_queue, res);
2842 #endif /* AUDIO_HAVE_RECORDING */
2844 static void audio_thread(void)
2846 struct queue_event ev;
2848 pcm_postinit();
2850 filling = STATE_IDLE;
2852 while (1)
2854 switch (filling)
2856 /* Active states */
2857 case STATE_FULL:
2858 case STATE_END_OF_PLAYLIST:
2859 if (buf_get_watermark() == 0)
2861 /* End of buffering for now, let's calculate the watermark,
2862 register for a low buffer event and unboost */
2863 audio_update_filebuf_watermark(0);
2864 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2865 buffer_event_buffer_low_callback);
2867 /* Fall-through */
2868 case STATE_FINISHED:
2869 /* All data was buffered */
2870 cancel_cpu_boost();
2871 /* Fall-through */
2872 case STATE_FILLING:
2873 case STATE_ENDING:
2874 if (audio_pcmbuf_track_change_scan())
2876 /* Transfer notification to audio queue event */
2877 ev.id = Q_AUDIO_TRACK_CHANGED;
2878 ev.data = 1;
2880 else
2882 /* If doing auto skip, poll pcmbuf track notifications a bit
2883 faster to promply detect the transition */
2884 queue_wait_w_tmo(&audio_queue, &ev,
2885 skip_pending == TRACK_SKIP_NONE ?
2886 HZ/2 : HZ/10);
2888 break;
2890 /* Idle states */
2891 default:
2892 queue_wait(&audio_queue, &ev);
2894 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2895 switch (ev.id)
2897 #ifdef AUDIO_HAVE_RECORDING
2898 /* Must monitor the encoder message for recording so it can remove
2899 it if we process the insertion before it does. It cannot simply
2900 be removed from under recording however. */
2901 case Q_AUDIO_LOAD_ENCODER:
2902 break;
2903 #endif
2904 case SYS_USB_DISCONNECTED:
2905 filling = STATE_IDLE;
2906 break;
2908 default:
2909 if (filling == STATE_USB)
2910 continue;
2912 #endif /* CONFIG_PLATFORM */
2915 switch (ev.id)
2917 /** Codec and track change messages **/
2918 case Q_AUDIO_CODEC_COMPLETE:
2919 /* Codec is done processing track and has gone idle */
2920 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
2921 audio_on_codec_complete(ev.data);
2922 break;
2924 case Q_AUDIO_CODEC_SEEK_COMPLETE:
2925 /* Codec is done seeking */
2926 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2927 audio_on_codec_seek_complete();
2928 break;
2930 case Q_AUDIO_TRACK_CHANGED:
2931 /* PCM track change done */
2932 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2933 audio_on_track_changed();
2934 break;
2936 /** Control messages **/
2937 case Q_AUDIO_PLAY:
2938 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2939 audio_start_playback(ev.data, 0);
2940 break;
2942 case Q_AUDIO_STOP:
2943 LOGFQUEUE("audio < Q_AUDIO_STOP");
2944 audio_stop_playback();
2945 if (ev.data != 0)
2946 queue_clear(&audio_queue);
2947 break;
2949 case Q_AUDIO_PAUSE:
2950 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2951 audio_on_pause(ev.data);
2952 break;
2954 case Q_AUDIO_SKIP:
2955 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2956 audio_on_skip();
2957 break;
2959 case Q_AUDIO_DIR_SKIP:
2960 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2961 audio_on_dir_skip(ev.data);
2962 break;
2964 case Q_AUDIO_PRE_FF_REWIND:
2965 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2966 audio_on_pre_ff_rewind();
2967 break;
2969 case Q_AUDIO_FF_REWIND:
2970 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2971 audio_on_ff_rewind(ev.data);
2972 break;
2974 case Q_AUDIO_FLUSH:
2975 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
2976 audio_on_audio_flush();
2977 break;
2979 /** Buffering messages **/
2980 case Q_AUDIO_BUFFERING:
2981 /* some buffering event */
2982 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
2983 audio_on_buffering(ev.data);
2984 break;
2986 case Q_AUDIO_FILL_BUFFER:
2987 /* continue buffering next track */
2988 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
2989 audio_on_fill_buffer();
2990 break;
2992 case Q_AUDIO_FINISH_LOAD_TRACK:
2993 /* metadata is buffered */
2994 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
2995 audio_on_finish_load_track(ev.data);
2996 break;
2998 case Q_AUDIO_HANDLE_FINISHED:
2999 /* some other type is buffered */
3000 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3001 audio_on_handle_finished(ev.data);
3002 break;
3004 /** Miscellaneous messages **/
3005 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3006 /* buffer needs to be reinitialized */
3007 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3008 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3009 break;
3011 #ifdef HAVE_DISK_STORAGE
3012 case Q_AUDIO_UPDATE_WATERMARK:
3013 /* buffering watermark needs updating */
3014 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3015 audio_update_filebuf_watermark(ev.data);
3016 break;
3017 #endif /* HAVE_DISK_STORAGE */
3019 #ifdef AUDIO_HAVE_RECORDING
3020 case Q_AUDIO_LOAD_ENCODER:
3021 /* load an encoder for recording */
3022 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3023 audio_on_load_encoder(ev.data);
3024 break;
3025 #endif /* AUDIO_HAVE_RECORDING */
3027 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3028 case SYS_USB_CONNECTED:
3029 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3030 audio_stop_playback();
3031 #ifdef PLAYBACK_VOICE
3032 voice_stop();
3033 #endif
3034 filling = STATE_USB;
3035 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3036 break;
3037 #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
3039 case SYS_TIMEOUT:
3040 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3041 break;
3043 default:
3044 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3045 break;
3046 } /* end switch */
3047 } /* end while */
3051 /* --- Buffering callbacks --- */
3053 /* Called when fullness is below the watermark level */
3054 static void buffer_event_buffer_low_callback(void *data)
3056 logf("low buffer callback");
3057 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3058 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3059 (void)data;
3062 /* Called when handles must be discarded in order to buffer new data */
3063 static void buffer_event_rebuffer_callback(void *data)
3065 logf("rebuffer callback");
3066 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3067 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3068 (void)data;
3071 /* A handle has completed buffering and all required data is available */
3072 static void buffer_event_finished_callback(void *data)
3074 int hid = *(const int *)data;
3075 const enum data_type htype = buf_handle_data_type(hid);
3077 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3079 /* Limit queue traffic */
3080 switch (htype)
3082 case TYPE_ID3:
3083 /* The metadata handle for the last loaded track has been buffered.
3084 We can ask the audio thread to load the rest of the track's data. */
3085 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3086 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3087 break;
3089 case TYPE_PACKET_AUDIO:
3090 /* Strip any useless trailing tags that are left. */
3091 strip_tags(hid);
3092 /* Fall-through */
3093 case TYPE_ATOMIC_AUDIO:
3094 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3095 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3096 break;
3098 default:
3099 /* Don't care to know about these */
3100 break;
3105 /** -- Codec callbacks -- **/
3107 /* Update elapsed times with latency-adjusted values */
3108 void audio_codec_update_elapsed(unsigned long value)
3110 #ifdef AB_REPEAT_ENABLE
3111 ab_position_report(value);
3112 #endif
3114 unsigned long latency = pcmbuf_get_latency();
3116 if (LIKELY(value >= latency))
3118 unsigned long elapsed = value - latency;
3120 if (elapsed > value || elapsed < value - 2)
3121 value = elapsed;
3123 else
3125 value = 0;
3128 /* Track codec: used later when updating the playing at the user
3129 transition */
3130 id3_get(CODEC_ID3)->elapsed = value;
3132 /* If a skip is pending, the PCM buffer is updating the time on the
3133 previous song */
3134 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3135 id3_get(PLAYING_ID3)->elapsed = value;
3138 /* Update offsets with latency-adjusted values */
3139 void audio_codec_update_offset(size_t value)
3141 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
3142 unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8;
3144 if (LIKELY(value >= latency))
3146 value -= latency;
3148 else
3150 value = 0;
3153 /* Track codec: used later when updating the playing id3 at the user
3154 transition */
3155 ci_id3->offset = value;
3157 /* If a skip is pending, the PCM buffer is updating the time on the
3158 previous song */
3159 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3160 id3_get(PLAYING_ID3)->offset = value;
3164 /** --- Pcmbuf callbacks --- **/
3166 /* Between the codec and PCM track change, we need to keep updating the
3167 * "elapsed" value of the previous (to the codec, but current to the
3168 * user/PCM/WPS) track, so that the progressbar reaches the end. */
3169 void audio_pcmbuf_position_callback(unsigned int time)
3171 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3173 time += id3->elapsed;
3175 id3->elapsed = MIN(time, id3->length);
3178 /* Post message from pcmbuf that the end of the previous track has just
3179 * been played */
3180 void audio_pcmbuf_track_change(bool pcmbuf)
3182 if (pcmbuf)
3184 /* Notify of the change in special-purpose semaphore object */
3185 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3186 audio_pcmbuf_track_change_post();
3188 else
3190 /* Safe to post directly to the queue */
3191 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3192 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3196 /* May pcmbuf start PCM playback when the buffer is full enough? */
3197 bool audio_pcmbuf_may_play(void)
3199 return play_status == PLAY_PLAYING && !ff_rw_mode;
3203 /** -- External interfaces -- **/
3205 /* Return the playback and recording status */
3206 int audio_status(void)
3208 unsigned int ret = play_status;
3210 #ifdef AUDIO_HAVE_RECORDING
3211 /* Do this here for constitency with mpeg.c version */
3212 ret |= pcm_rec_status();
3213 #endif
3215 return (int)ret;
3218 /* Clear all accumulated audio errors for playback and recording */
3219 void audio_error_clear(void)
3221 #ifdef AUDIO_HAVE_RECORDING
3222 pcm_rec_error_clear();
3223 #endif
3226 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3227 bool audio_peek_track(struct mp3entry *id3, int offset)
3229 bool retval = false;
3231 id3_mutex_lock();
3233 if (play_status != PLAY_STOPPED)
3235 id3->path[0] = '\0'; /* Null path means it should be filled now */
3236 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3237 id3->path[0] != '\0';
3240 id3_mutex_unlock();
3242 return retval;
3245 /* Return the mp3entry for the currently playing track */
3246 struct mp3entry * audio_current_track(void)
3248 struct mp3entry *id3;
3250 id3_mutex_lock();
3252 #ifdef AUDIO_FAST_SKIP_PREVIEW
3253 if (skip_offset != 0)
3255 /* This is a peekahead */
3256 id3 = id3_get(PLAYING_PEEK_ID3);
3257 audio_peek_track(id3, 0);
3259 else
3260 #endif
3262 /* Normal case */
3263 id3 = id3_get(PLAYING_ID3);
3264 audio_get_track_metadata(0, id3);
3267 id3_mutex_unlock();
3269 return id3;
3272 /* Obtains the mp3entry for the next track from the current */
3273 struct mp3entry * audio_next_track(void)
3275 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3277 id3_mutex_lock();
3279 #ifdef AUDIO_FAST_SKIP_PREVIEW
3280 if (skip_offset != 0)
3282 /* This is a peekahead */
3283 if (!audio_peek_track(id3, 1))
3284 id3 = NULL;
3286 else
3287 #endif
3289 /* Normal case */
3290 if (!audio_get_track_metadata(1, id3))
3291 id3 = NULL;
3294 id3_mutex_unlock();
3296 return id3;
3299 /* Start playback at the specified offset */
3300 void audio_play(long offset)
3302 logf("audio_play");
3304 #ifdef PLAYBACK_VOICE
3305 /* Truncate any existing voice output so we don't have spelling
3306 * etc. over the first part of the played track */
3307 talk_force_shutup();
3308 #endif
3310 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3311 audio_queue_send(Q_AUDIO_PLAY, offset);
3314 /* Stop playback if playing */
3315 void audio_stop(void)
3317 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3318 audio_queue_send(Q_AUDIO_STOP, 0);
3321 /* Pause playback if playing */
3322 void audio_pause(void)
3324 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3325 audio_queue_send(Q_AUDIO_PAUSE, true);
3328 /* This sends a stop message and the audio thread will dump all its
3329 subsequent messages */
3330 void audio_hard_stop(void)
3332 /* Stop playback */
3333 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3334 audio_queue_send(Q_AUDIO_STOP, 1);
3335 #ifdef PLAYBACK_VOICE
3336 voice_stop();
3337 #endif
3340 /* Resume playback if paused */
3341 void audio_resume(void)
3343 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3344 audio_queue_send(Q_AUDIO_PAUSE, false);
3347 /* Skip the specified number of tracks forward or backward from the current */
3348 void audio_skip(int offset)
3350 id3_mutex_lock();
3352 /* If offset has to be backed-out to stay in range, no skip is done */
3353 int accum = skip_offset + offset;
3355 while (offset != 0 && !playlist_check(accum))
3357 offset += offset < 0 ? 1 : -1;
3358 accum = skip_offset + offset;
3361 if (offset != 0)
3363 /* Accumulate net manual skip count since the audio thread last
3364 processed one */
3365 skip_offset = accum;
3367 system_sound_play(SOUND_TRACK_SKIP);
3369 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3371 #ifdef AUDIO_FAST_SKIP_PREVIEW
3372 /* Do this before posting so that the audio thread can correct us
3373 when things settle down - additionally, if audio gets a message
3374 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3375 handler a skip event with the correct info but doesn't skip */
3376 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3377 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3379 /* Playback only needs the final state even if more than one is
3380 processed because it wasn't removed in time */
3381 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3382 audio_queue_post(Q_AUDIO_SKIP, 0);
3384 else
3386 /* No more tracks */
3387 system_sound_play(SOUND_TRACK_NO_MORE);
3390 id3_mutex_unlock();
3393 /* Skip one track forward from the current */
3394 void audio_next(void)
3396 audio_skip(1);
3399 /* Skip one track backward from the current */
3400 void audio_prev(void)
3402 audio_skip(-1);
3405 /* Move one directory forward */
3406 void audio_next_dir(void)
3408 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3409 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3412 /* Move one directory backward */
3413 void audio_prev_dir(void)
3415 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3416 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3419 /* Pause playback in order to start a seek that flushes the old audio */
3420 void audio_pre_ff_rewind(void)
3422 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3423 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3426 /* Seek to the new time in the current track */
3427 void audio_ff_rewind(long time)
3429 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3430 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3433 /* Clear all but the currently playing track then rebuffer */
3434 void audio_flush_and_reload_tracks(void)
3436 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3437 audio_queue_post(Q_AUDIO_FLUSH, 0);
3440 /* Return the pointer to the main audio buffer, optionally preserving
3441 voicing */
3442 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3444 unsigned char *buf, *end;
3446 if (audio_is_initialized)
3448 audio_hard_stop();
3450 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3452 if (buffer_size == NULL)
3454 /* Special case for talk_init to use since it already knows it's
3455 trashed */
3456 buffer_state = AUDIOBUF_STATE_TRASHED;
3457 return NULL;
3460 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3461 || !talk_voice_required())
3463 logf("get buffer: talk, audio");
3464 /* Ok to use everything from audiobuf to audiobufend - voice is loaded,
3465 the talk buffer is not needed because voice isn't being used, or
3466 could be AUDIOBUF_STATE_TRASHED already. If state is
3467 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3468 written without the caller knowing what's going on. Changing certain
3469 settings may move it to a worse condition but the memory in use by
3470 something else will remain undisturbed.
3472 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3474 talk_buffer_steal();
3475 buffer_state = AUDIOBUF_STATE_TRASHED;
3478 buf = audiobuf;
3479 end = audiobufend;
3481 else
3483 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3484 still AUDIOBUF_STATE_INITIALIZED */
3485 /* Skip talk buffer and move pcm buffer to end to maximize available
3486 contiguous memory - no audio running means voice will not need the
3487 swap space */
3488 logf("get buffer: audio");
3489 buf = audiobuf + talk_get_bufsize();
3490 end = audiobufend - voicebuf_init(audiobufend);
3491 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3494 *buffer_size = end - buf;
3496 return buf;
3499 #ifdef HAVE_RECORDING
3500 /* Stop audio, voice and obtain all available buffer space */
3501 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3503 audio_hard_stop();
3504 talk_buffer_steal();
3506 unsigned char *end = audiobufend;
3507 buffer_state = AUDIOBUF_STATE_TRASHED;
3508 *buffer_size = end - audiobuf;
3510 return (unsigned char *)audiobuf;
3512 #endif /* HAVE_RECORDING */
3514 /* Restore audio buffer to a particular state (one more valid than the current
3515 state) */
3516 bool audio_restore_playback(int type)
3518 switch (type)
3520 case AUDIO_WANT_PLAYBACK:
3521 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3522 audio_reset_buffer();
3523 return true;
3524 case AUDIO_WANT_VOICE:
3525 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3526 audio_reset_buffer();
3527 return true;
3528 default:
3529 return false;
3533 /* Has the playback buffer been completely claimed? */
3534 bool audio_buffer_state_trashed(void)
3536 return buffer_state == AUDIOBUF_STATE_TRASHED;
3540 /** --- Miscellaneous public interfaces --- **/
3542 #ifdef HAVE_ALBUMART
3543 /* Return which album art handle is current for the user in the given slot */
3544 int playback_current_aa_hid(int slot)
3546 if ((unsigned)slot < MAX_MULTIPLE_AA)
3548 struct track_info *info = track_list_user_current(skip_offset);
3550 if (!info && abs(skip_offset) <= 1)
3552 /* Give the actual position a go */
3553 info = track_list_user_current(0);
3556 if (info)
3557 return info->aa_hid[slot];
3560 return ERR_HANDLE_NOT_FOUND;
3563 /* Find an album art slot that doesn't match the dimensions of another that
3564 is already claimed - increment the use count if it is */
3565 int playback_claim_aa_slot(struct dim *dim)
3567 int i;
3569 /* First try to find a slot already having the size to reuse it since we
3570 don't want albumart of the same size buffered multiple times */
3571 FOREACH_ALBUMART(i)
3573 struct albumart_slot *slot = &albumart_slots[i];
3575 if (slot->dim.width == dim->width &&
3576 slot->dim.height == dim->height)
3578 slot->used++;
3579 return i;
3583 /* Size is new, find a free slot */
3584 FOREACH_ALBUMART(i)
3586 if (!albumart_slots[i].used)
3588 albumart_slots[i].used++;
3589 albumart_slots[i].dim = *dim;
3590 return i;
3594 /* Sorry, no free slot */
3595 return -1;
3598 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3599 void playback_release_aa_slot(int slot)
3601 if ((unsigned)slot < MAX_MULTIPLE_AA)
3603 struct albumart_slot *aa_slot = &albumart_slots[slot];
3605 if (aa_slot->used > 0)
3606 aa_slot->used--;
3609 #endif /* HAVE_ALBUMART */
3612 #ifdef HAVE_RECORDING
3613 /* Load an encoder and run it */
3614 bool audio_load_encoder(int afmt)
3616 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3617 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3618 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3619 #else
3620 (void)afmt;
3621 return true;
3622 #endif
3625 /* Stop an encoder and unload it */
3626 void audio_remove_encoder(void)
3628 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3629 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3630 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3631 #endif
3633 #endif /* HAVE_RECORDING */
3635 /* Is an automatic skip in progress? If called outside transition callbacks,
3636 indicates the last skip type at the time it was processed and isn't very
3637 meaningful. */
3638 bool audio_automatic_skip(void)
3640 return automatic_skip;
3643 /* Would normally calculate byte offset from an elapsed time but is not
3644 used on SWCODEC */
3645 int audio_get_file_pos(void)
3647 return 0;
3650 /* Return the elapsed time of the track previous to the current */
3651 unsigned long audio_prev_elapsed(void)
3653 return prev_track_elapsed;
3656 /* Is the audio thread ready to accept commands? */
3657 bool audio_is_thread_ready(void)
3659 return filling != STATE_BOOT;
3662 /* Return total file buffer length after accounting for the talk buf */
3663 size_t audio_get_filebuflen(void)
3665 return buf_length();
3668 /* How many tracks exist on the buffer - full or partial */
3669 int audio_track_count(void)
3670 __attribute__((alias("track_list_count")));
3672 /* Return total ringbuffer space occupied - ridx to widx */
3673 long audio_filebufused(void)
3675 return buf_used();
3679 /** -- Settings -- **/
3681 /* Enable or disable cuesheet support and allocate/don't allocate the
3682 extra associated resources */
3683 void audio_set_cuesheet(int enable)
3685 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3687 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3688 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3692 #ifdef HAVE_DISK_STORAGE
3693 /* Set the audio antiskip buffer margin by index */
3694 void audio_set_buffer_margin(int setting)
3696 static const unsigned short lookup[] =
3697 { 5, 15, 30, 60, 120, 180, 300, 600 };
3699 if ((unsigned)setting >= ARRAYLEN(lookup))
3700 setting = 0;
3702 logf("buffer margin: %u", (unsigned)lookup[setting]);
3704 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3705 (unsigned)lookup[setting]);
3706 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3708 #endif /* HAVE_DISK_STORAGE */
3710 #ifdef HAVE_CROSSFADE
3711 /* Take necessary steps to enable or disable the crossfade setting */
3712 void audio_set_crossfade(int enable)
3714 /* Tell it the next setting to use */
3715 pcmbuf_request_crossfade_enable(enable);
3717 /* Return if size hasn't changed or this is too early to determine
3718 which in the second case there's no way we could be playing
3719 anything at all */
3720 if (!pcmbuf_is_same_size())
3722 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3723 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3726 #endif /* HAVE_CROSSFADE */
3729 /** -- Startup -- **/
3731 /* Initialize the audio system - called from init() in main.c */
3732 void audio_init(void)
3734 /* Can never do this twice */
3735 if (audio_is_initialized)
3737 logf("audio: already initialized");
3738 return;
3741 logf("audio: initializing");
3743 /* Initialize queues before giving control elsewhere in case it likes
3744 to send messages. Thread creation will be delayed however so nothing
3745 starts running until ready if something yields such as talk_init. */
3746 queue_init(&audio_queue, true);
3748 mutex_init(&id3_mutex);
3750 pcm_init();
3752 codec_init_codec_api();
3754 make_codec_thread();
3756 /* This thread does buffer, so match its priority */
3757 audio_thread_id = create_thread(audio_thread, audio_stack,
3758 sizeof(audio_stack), CREATE_THREAD_FROZEN,
3759 audio_thread_name
3760 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3761 IF_COP(, CPU));
3763 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3764 audio_thread_id);
3766 #ifdef PLAYBACK_VOICE
3767 voice_thread_init();
3768 #endif
3770 /* audio_reset_buffer must know the size of voice buffer so init
3771 talk first */
3772 talk_init();
3774 #ifdef HAVE_CROSSFADE
3775 /* Set crossfade setting for next buffer init which should be about... */
3776 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3777 #endif
3779 /* Initialize the buffering system */
3780 track_list_init();
3781 buffering_init();
3782 /* ...now! Set up the buffers */
3783 audio_reset_buffer();
3785 /* Probably safe to say */
3786 audio_is_initialized = true;
3788 sound_settings_apply();
3789 #ifdef HAVE_DISK_STORAGE
3790 audio_set_buffer_margin(global_settings.buffer_margin);
3791 #endif
3793 /* It's safe to let the threads run now */
3794 #ifdef PLAYBACK_VOICE
3795 voice_thread_resume();
3796 #endif
3797 codec_thread_resume();
3798 thread_thaw(audio_thread_id);