GSoC/Buflib: Add buflib memory alocator to the core.
[kugel-rb.git] / apps / playback.c
blobb1652f8960be2934308fb8de914c1264dbc7b966
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 "core_alloc.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 /* Buffer must not move. And not shrink for now */
737 static struct buflib_callbacks ops = { NULL, NULL };
738 static int audiobuf_handle;
739 /* Set up the audio buffer for playback */
740 static void audio_reset_buffer(void)
743 * Layout audio buffer as follows:
744 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
747 /* see audio_get_recording_buffer if this is modified */
748 logf("%s()", __func__);
750 /* If the setup of anything allocated before the file buffer is
751 changed, do check the adjustments after the buffer_alloc call
752 as it will likely be affected and need sliding over */
754 /* Initially set up file buffer as all space available */
755 size_t filebuflen, allocsize;
756 if (audiobuf_handle > 0)
758 core_free(audiobuf_handle);
759 audiobuf_handle = 0;
761 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
762 unsigned char *filebuf = core_get_data(audiobuf_handle);
764 /* Subtract whatever voice needs */
765 allocsize = talkbuf_init(filebuf);
766 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
767 if (allocsize > filebuflen)
768 goto bufpanic;
770 filebuf += allocsize;
771 filebuflen -= allocsize;
773 if (talk_voice_required())
775 /* Need a space for voice PCM output */
776 allocsize = voicebuf_init(filebuf + filebuflen);
778 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
779 if (allocsize > filebuflen)
780 goto bufpanic;
782 filebuflen -= allocsize;
785 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
786 allocsize = pcmbuf_init(filebuf + filebuflen);
788 /* Make sure filebuflen is a pointer sized multiple after adjustment */
789 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
790 if (allocsize > filebuflen)
791 goto bufpanic;
793 filebuflen -= allocsize;
795 /* Scratch memory */
796 allocsize = scratch_mem_size();
797 if (allocsize > filebuflen)
798 goto bufpanic;
800 scratch_mem_init(filebuf);
801 filebuf += allocsize;
802 filebuflen -= allocsize;
804 buffering_reset(filebuf, filebuflen);
806 /* Clear any references to the file buffer */
807 buffer_state = AUDIOBUF_STATE_INITIALIZED;
809 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
810 /* Make sure everything adds up - yes, some info is a bit redundant but
811 aids viewing and the summation of certain variables should add up to
812 the location of others. */
814 size_t pcmbufsize;
815 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
816 logf("fbuf: %08X", (unsigned)filebuf);
817 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
818 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
819 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
820 logf("pcmb: %08X", (unsigned)pcmbuf);
821 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
823 #endif
825 return;
827 bufpanic:
828 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
831 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
832 static void audio_update_filebuf_watermark(int seconds)
834 size_t bytes = 0;
836 #ifdef HAVE_DISK_STORAGE
837 int spinup = ata_spinup_time();
839 if (seconds == 0)
841 /* By current setting */
842 seconds = buffer_margin;
844 else
846 /* New setting */
847 buffer_margin = seconds;
849 if (buf_get_watermark() == 0)
851 /* Write a watermark only if the audio thread already did so for
852 itself or it will fail to set the event and the watermark - if
853 it hasn't yet, it will use the new setting when it does */
854 return;
858 if (spinup)
859 seconds += (spinup / HZ) + 1;
860 else
861 seconds += 5;
863 seconds += buffer_margin;
864 #else
865 /* flash storage */
866 seconds = 1;
867 #endif
869 /* Watermark is a function of the bitrate of the last track in the buffer */
870 struct mp3entry *id3 = NULL;
871 struct track_info *info = track_list_last(0);
873 if (info)
874 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
876 if (id3)
878 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
880 bytes = id3->bitrate * (1000/8) * seconds;
882 else
884 /* Bitrate has no meaning to buffering margin for atomic audio -
885 rebuffer when it's the only track left unless it's the only
886 track that fits, in which case we should avoid constant buffer
887 low events */
888 if (track_list_count() > 1)
889 bytes = info->filesize + 1;
892 else
894 /* Then set the minimum - this should not occur anyway */
895 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
896 track_list.start, track_list.current, track_list.end);
899 /* Actually setting zero disables the notification and we use that
900 to detect that it has been reset */
901 buf_set_watermark(MAX(bytes, 1));
902 logf("fwmark: %lu", (unsigned long)bytes);
906 /** -- Track change notification -- **/
908 /* Check the pcmbuf track changes and return write the message into the event
909 if there are any */
910 static inline bool audio_pcmbuf_track_change_scan(void)
912 if (track_change.out != track_change.in)
914 track_change.out++;
915 return true;
918 return false;
921 /* Clear outstanding track change posts */
922 static inline void audio_pcmbuf_track_change_clear(void)
924 track_change.out = track_change.in;
927 /* Post a track change notification - called by audio ISR */
928 static inline void audio_pcmbuf_track_change_post(void)
930 track_change.in++;
934 /** --- Helper functions --- **/
936 /* Removes messages that might end up in the queue before or while processing
937 a manual track change. Responding to them would be harmful since they
938 belong to a previous track's playback period. Anything that would generate
939 the stale messages must first be put into a state where it will not do so.
941 static void audio_clear_track_notifications(void)
943 static const long filter_list[][2] =
945 /* codec messages */
946 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
947 /* track change messages */
948 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
951 const int filter_count = ARRAYLEN(filter_list) - 1;
953 /* Remove any pcmbuf notifications */
954 pcmbuf_monitor_track_change(false);
955 audio_pcmbuf_track_change_clear();
957 /* Scrub the audio queue of the old mold */
958 while (queue_peek_ex(&audio_queue, NULL,
959 filter_count | QPEEK_REMOVE_EVENTS,
960 filter_list))
962 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
966 /* Takes actions based upon track load status codes */
967 static void audio_handle_track_load_status(int trackstat)
969 switch (trackstat)
971 case LOAD_TRACK_ERR_NO_MORE:
972 if (track_list_count() > 0)
973 break;
975 case LOAD_TRACK_ERR_START_CODEC:
976 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
977 break;
979 default:
980 break;
984 /* Announce the end of playing the current track */
985 static void audio_playlist_track_finish(void)
987 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
989 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
991 if (id3)
993 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
994 prev_track_elapsed = id3->elapsed;
996 else
998 prev_track_elapsed = 0;
1002 /* Announce the beginning of the new track */
1003 static void audio_playlist_track_change(void)
1005 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
1007 if (id3)
1008 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
1010 playlist_update_resume_info(id3);
1013 /* Change the data for the next track and send the event */
1014 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1016 id3_write_locked(NEXTTRACK_ID3, id3_next);
1017 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1018 id3_get(NEXTTRACK_ID3));
1021 /* Bring the user current mp3entry up to date and set a new offset for the
1022 buffered metadata */
1023 static void playing_id3_sync(struct track_info *user_info, size_t offset)
1025 id3_mutex_lock();
1027 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1029 if (offset == (size_t)-1)
1031 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1032 size_t play_offset = ply_id3->offset;
1033 long play_elapsed = ply_id3->elapsed;
1034 id3_write(PLAYING_ID3, id3);
1035 ply_id3->offset = play_offset;
1036 ply_id3->elapsed = play_elapsed;
1037 offset = 0;
1039 else
1041 id3_write(PLAYING_ID3, id3);
1044 if (id3)
1045 id3->offset = offset;
1047 id3_mutex_unlock();
1050 /* Wipe-out track metadata - current is optional */
1051 static void wipe_track_metadata(bool current)
1053 id3_mutex_lock();
1055 if (current)
1056 id3_write(PLAYING_ID3, NULL);
1058 id3_write(NEXTTRACK_ID3, NULL);
1059 id3_write(UNBUFFERED_ID3, NULL);
1061 id3_mutex_unlock();
1064 /* Called when buffering is completed on the last track handle */
1065 static void filling_is_finished(void)
1067 logf("last track finished buffering");
1069 /* There's no more to load or watch for */
1070 buf_set_watermark(0);
1071 filling = STATE_FINISHED;
1074 /* Stop the codec decoding or waiting for its data to be ready - returns
1075 'false' if the codec ended up stopped */
1076 static bool halt_decoding_track(bool stop)
1078 /* If it was waiting for us to clear the buffer to make a rebuffer
1079 happen, it should cease otherwise codec_stop could deadlock waiting
1080 for the codec to go to its main loop - codec's request will now
1081 force-fail */
1082 bool retval = false;
1084 buf_signal_handle(ci.audio_hid, true);
1086 if (stop)
1087 codec_stop();
1088 else
1089 retval = codec_pause();
1091 audio_clear_track_notifications();
1093 /* We now know it's idle and not waiting for buffered data */
1094 buf_signal_handle(ci.audio_hid, false);
1096 codec_skip_pending = false;
1097 codec_seeking = false;
1099 return retval;
1102 /* Clear the PCM on a manual skip */
1103 static void audio_clear_paused_pcm(void)
1105 if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active())
1106 pcmbuf_play_stop();
1109 /* End the ff/rw mode */
1110 static void audio_ff_rewind_end(void)
1112 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1113 section */
1114 if (ff_rw_mode)
1116 ff_rw_mode = false;
1118 if (codec_seeking)
1120 /* Clear the buffer */
1121 pcmbuf_play_stop();
1124 if (play_status != PLAY_PAUSED)
1126 /* Seeking-while-playing, resume PCM playback */
1127 pcmbuf_pause(false);
1132 /* Complete the codec seek */
1133 static void audio_complete_codec_seek(void)
1135 /* If a seek completed while paused, 'paused' is true.
1136 * If seeking from seek mode, 'ff_rw_mode' is true. */
1137 if (codec_seeking)
1139 audio_ff_rewind_end();
1140 codec_seeking = false; /* set _after_ the call! */
1142 /* else it's waiting and we must repond */
1145 /* Get the current cuesheet pointer */
1146 static inline struct cuesheet * get_current_cuesheet(void)
1148 return audio_scratch_memory->curr_cue;
1151 /* Read the cuesheet from the buffer */
1152 static void buf_read_cuesheet(int handle_id)
1154 struct cuesheet *cue = get_current_cuesheet();
1156 if (!cue || handle_id < 0)
1157 return;
1159 bufread(handle_id, sizeof (struct cuesheet), cue);
1162 /* Backend to peek/current/next track metadata interface functions -
1163 fill in the mp3entry with as much information as we may obtain about
1164 the track at the specified offset from the user current track -
1165 returns false if no information exists with us */
1166 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1168 if (play_status == PLAY_STOPPED)
1169 return false;
1171 if (id3->path[0] != '\0')
1172 return true; /* Already filled */
1174 struct track_info *info = track_list_user_current(offset);
1176 if (!info)
1178 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1180 if (offset > 0 && track_list_user_current(offset - 1))
1182 /* Try the unbuffered id3 since we're moving forward */
1183 if (ub_id3->path[0] != '\0')
1185 copy_mp3entry(id3, ub_id3);
1186 return true;
1190 else if (bufreadid3(info->id3_hid, id3))
1192 return true;
1195 /* We didn't find the ID3 metadata, so we fill it with the little info we
1196 have and return that */
1198 char path[MAX_PATH+1];
1199 if (playlist_peek(offset, path, sizeof (path)))
1201 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1202 /* Try to get it from the database */
1203 if (!tagcache_fill_tags(id3, path))
1204 #endif
1206 /* By now, filename is the only source of info */
1207 fill_metadata_from_path(id3, path);
1210 return true;
1213 wipe_mp3entry(id3);
1215 return false;
1218 /* Get a resume rewind adjusted offset from the ID3 */
1219 unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1221 unsigned long offset = id3->offset;
1222 size_t resume_rewind = global_settings.resume_rewind *
1223 id3->bitrate * (1000/8);
1225 if (offset < resume_rewind)
1226 offset = 0;
1227 else
1228 offset -= resume_rewind;
1230 return offset;
1233 /* Get the codec into ram and initialize it - keep it if it's ready */
1234 static bool audio_init_codec(struct track_info *track_info,
1235 struct mp3entry *track_id3)
1237 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1238 int hid = ERR_HANDLE_NOT_FOUND;
1240 if (codt_loaded != AFMT_UNKNOWN)
1242 int codt = get_audio_base_codec_type(track_id3->codectype);
1244 if (codt == codt_loaded)
1246 /* Codec is the same base type */
1247 logf("Reusing prev. codec: %d", track_id3->codectype);
1248 #ifdef HAVE_CODEC_BUFFERING
1249 /* Close any buffered codec (we could have skipped directly to a
1250 format transistion that is the same format as the current track
1251 and the buffered one is no longer needed) */
1252 track_info_close_handle(&track_info->codec_hid);
1253 #endif
1254 return true;
1256 else
1258 /* New codec - first make sure the old one's gone */
1259 logf("Removing prev. codec: %d", codt_loaded);
1260 codec_unload();
1264 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1266 #ifdef HAVE_CODEC_BUFFERING
1267 /* Codec thread will close the handle even if it fails and will load from
1268 storage if hid is not valid or the buffer load fails */
1269 hid = track_info->codec_hid;
1270 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1271 #endif
1273 return codec_load(hid, track_id3->codectype);
1274 (void)track_info; /* When codec buffering isn't supported */
1277 /* Start the codec for the current track scheduled to be decoded */
1278 static bool audio_start_codec(bool auto_skip)
1280 struct track_info *info = track_list_current(0);
1281 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1283 if (!cur_id3)
1284 return false;
1286 buf_pin_handle(info->id3_hid, true);
1288 if (!audio_init_codec(info, cur_id3))
1290 buf_pin_handle(info->id3_hid, false);
1291 return false;
1294 #ifdef HAVE_TAGCACHE
1295 bool autoresume_enable = global_settings.autoresume_enable;
1297 if (autoresume_enable && !cur_id3->offset)
1299 /* Resume all manually selected tracks */
1300 bool resume = !auto_skip;
1302 /* Send the "buffer" event to obtain the resume position for the codec */
1303 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1305 if (!resume)
1307 /* Automatic skip - do further tests to see if we should just
1308 ignore any autoresume position */
1309 int autoresume_automatic = global_settings.autoresume_automatic;
1311 switch (autoresume_automatic)
1313 case AUTORESUME_NEXTTRACK_ALWAYS:
1314 /* Just resume unconditionally */
1315 resume = true;
1316 break;
1317 case AUTORESUME_NEXTTRACK_NEVER:
1318 /* Force-rewind it */
1319 break;
1320 default:
1321 /* Not "never resume" - pass resume filter? */
1322 resume = autoresumable(cur_id3);
1326 if (!resume)
1327 cur_id3->offset = 0;
1329 logf("%s: Set offset for %s to %lX\n", __func__,
1330 cur_id3->title, cur_id3->offset);
1332 #endif /* HAVE_TAGCACHE */
1334 /* Rewind the required amount - if an autoresume was done, this also rewinds
1335 that by the setting's amount
1337 It would be best to have bookkeeping about whether or not the track
1338 sounded or not since skipping to it or else skipping to it while paused
1339 and back again will cause accumulation of silent rewinds - that's not
1340 our job to track directly nor could it be in any reasonable way
1342 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1344 /* Update the codec API with the metadata and track info */
1345 id3_write(CODEC_ID3, cur_id3);
1347 ci.audio_hid = info->audio_hid;
1348 ci.filesize = info->filesize;
1349 buf_set_base_handle(info->audio_hid);
1351 /* All required data is now available for the codec */
1352 codec_go();
1354 #ifdef HAVE_TAGCACHE
1355 if (!autoresume_enable || cur_id3->offset)
1356 #endif
1358 /* Send the "buffer" event now */
1359 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1362 buf_pin_handle(info->id3_hid, false);
1363 return true;
1365 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1369 /** --- Audio thread --- **/
1371 /* Load and parse a cuesheet for the file - returns false if the buffer
1372 is full */
1373 static bool audio_load_cuesheet(struct track_info *info,
1374 struct mp3entry *track_id3)
1376 struct cuesheet *cue = get_current_cuesheet();
1377 track_id3->cuesheet = NULL;
1379 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1381 /* If error other than a full buffer, then mark it "unsupported" to
1382 avoid reloading attempt */
1383 int hid = ERR_UNSUPPORTED_TYPE;
1384 char cuepath[MAX_PATH];
1386 #ifdef HAVE_IO_PRIORITY
1387 buf_back_off_storage(true);
1388 #endif
1389 if (look_for_cuesheet_file(track_id3->path, cuepath))
1391 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1393 if (hid >= 0)
1395 void *cuesheet = NULL;
1396 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1398 if (parse_cuesheet(cuepath, (struct cuesheet *)cuesheet))
1400 /* Indicate cuesheet is present (while track remains
1401 buffered) */
1402 track_id3->cuesheet = cue;
1404 else
1406 bufclose(hid);
1407 hid = ERR_UNSUPPORTED_TYPE;
1412 #ifdef HAVE_IO_PRIORITY
1413 buf_back_off_storage(false);
1414 #endif
1415 if (hid == ERR_BUFFER_FULL)
1417 logf("buffer is full for now (%s)", __func__);
1418 return false;
1420 else
1422 if (hid < 0)
1423 logf("Cuesheet loading failed");
1425 info->cuesheet_hid = hid;
1429 return true;
1432 #ifdef HAVE_ALBUMART
1433 /* Load any album art for the file - returns false if the buffer is full */
1434 static bool audio_load_albumart(struct track_info *info,
1435 struct mp3entry *track_id3)
1437 int i;
1438 FOREACH_ALBUMART(i)
1440 struct bufopen_bitmap_data user_data;
1441 int *aa_hid = &info->aa_hid[i];
1442 int hid = ERR_UNSUPPORTED_TYPE;
1444 /* albumart_slots may change during a yield of bufopen,
1445 * but that's no problem */
1446 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1447 !albumart_slots[i].used)
1448 continue;
1450 memset(&user_data, 0, sizeof(user_data));
1451 user_data.dim = &albumart_slots[i].dim;
1453 #ifdef HAVE_IO_PRIORITY
1454 buf_back_off_storage(true);
1455 #endif
1457 /* We can only decode jpeg for embedded AA */
1458 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1460 user_data.embedded_albumart = &track_id3->albumart;
1461 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1464 if (hid < 0 && hid != ERR_BUFFER_FULL)
1466 /* No embedded AA or it couldn't be loaded - try other sources */
1467 char path[MAX_PATH];
1469 if (find_albumart(track_id3, path, sizeof(path),
1470 &albumart_slots[i].dim))
1472 user_data.embedded_albumart = NULL;
1473 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1477 #ifdef HAVE_IO_PRIORITY
1478 buf_back_off_storage(false);
1479 #endif
1480 if (hid == ERR_BUFFER_FULL)
1482 logf("buffer is full for now (%s)", __func__);
1483 return false;
1485 else
1487 /* If error other than a full buffer, then mark it "unsupported"
1488 to avoid reloading attempt */
1489 if (hid < 0)
1491 logf("Album art loading failed");
1492 hid = ERR_UNSUPPORTED_TYPE;
1495 *aa_hid = hid;
1499 return true;
1501 #endif /* HAVE_ALBUMART */
1503 #ifdef HAVE_CODEC_BUFFERING
1504 /* Load a codec for the file onto the buffer - assumes we're working from the
1505 currently loading track - not called for the current track */
1506 static bool audio_buffer_codec(struct track_info *track_info,
1507 struct mp3entry *track_id3)
1509 /* This will not be the current track -> it cannot be the first and the
1510 current track cannot be ahead of buffering -> there is a previous
1511 track entry which is either current or ahead of the current */
1512 struct track_info *prev_info = track_list_last(-1);
1513 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1515 /* If the previous codec is the same as this one, there is no need to
1516 put another copy of it on the file buffer (in other words, only
1517 buffer codecs at format transitions) */
1518 if (prev_id3)
1520 int codt = get_audio_base_codec_type(track_id3->codectype);
1521 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1523 if (codt == prev_codt)
1525 logf("Reusing prev. codec: %d", prev_id3->codectype);
1526 return true;
1529 /* else just load it (harmless) */
1531 /* Load the codec onto the buffer if possible */
1532 const char *codec_fn = get_codec_filename(track_id3->codectype);
1533 if (!codec_fn)
1534 return false;
1536 char codec_path[MAX_PATH+1]; /* Full path to codec */
1537 codec_get_full_path(codec_path, codec_fn);
1539 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1541 if (track_info->codec_hid >= 0)
1543 logf("Buffered codec: %d", afmt);
1544 return true;
1547 return false;
1549 #endif /* HAVE_CODEC_BUFFERING */
1551 /* Load metadata for the next track (with bufopen). The rest of the track
1552 loading will be handled by audio_finish_load_track once the metadata has
1553 been actually loaded by the buffering thread.
1555 Each track is arranged in the buffer as follows:
1556 <id3|[cuesheet|][album art|][codec|]audio>
1558 The next will not be loaded until the previous succeeds if the buffer was
1559 full at the time. To put any metadata after audio would make those handles
1560 unmovable.
1562 static int audio_load_track(void)
1564 if (in_progress_id3_hid >= 0)
1566 /* There must be an info pointer if the in-progress id3 is even there */
1567 struct track_info *info = track_list_last(0);
1569 if (info->id3_hid == in_progress_id3_hid)
1571 if (filling == STATE_FILLING)
1573 /* Haven't finished the metadata but the notification is
1574 anticipated to come soon */
1575 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1576 return LOAD_TRACK_OK;
1578 else if (filling == STATE_FULL)
1580 /* Buffer was full trying to complete the load after the
1581 metadata finished, so attempt to continue - older handles
1582 should have been cleared already */
1583 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1584 filling = STATE_FILLING;
1585 buffer_event_finished_callback(&info->id3_hid);
1586 return LOAD_TRACK_OK;
1590 /* Some old, stray buffering message */
1591 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1592 return LOAD_TRACK_ERR_BUSY;
1595 filling = STATE_FILLING;
1597 struct track_info *info = track_list_alloc_track();
1598 if (info == NULL)
1600 /* List is full so stop buffering tracks - however, attempt to obtain
1601 metadata as the unbuffered id3 */
1602 logf("No free tracks");
1603 filling = STATE_FULL;
1606 playlist_peek_offset++;
1608 logf("Buffering track: s%u/c%u/e%u/p%d",
1609 track_list.start, track_list.current, track_list.end,
1610 playlist_peek_offset);
1612 /* Get track name from current playlist read position */
1613 int fd = -1;
1614 char name_buf[MAX_PATH + 1];
1615 const char *trackname;
1617 while (1)
1620 trackname = playlist_peek(playlist_peek_offset, name_buf,
1621 sizeof (name_buf));
1623 if (!trackname)
1624 break;
1626 /* Test for broken playlists by probing for the files */
1627 fd = open(trackname, O_RDONLY);
1628 if (fd >= 0)
1629 break;
1631 logf("Open failed");
1632 /* Skip invalid entry from playlist */
1633 playlist_skip_entry(NULL, playlist_peek_offset);
1635 /* Sync the playlist if it isn't finished */
1636 if (playlist_peek(playlist_peek_offset, NULL, 0))
1637 playlist_next(0);
1640 if (!trackname)
1642 /* No track - exhausted the playlist entries */
1643 logf("End-of-playlist");
1644 id3_write_locked(UNBUFFERED_ID3, NULL);
1646 if (filling != STATE_FULL)
1647 track_list_unalloc_track(); /* Free this entry */
1649 playlist_peek_offset--; /* Maintain at last index */
1651 /* We can end up here after the real last track signals its completion
1652 and miss the transition to STATE_FINISHED esp. if dropping the last
1653 songs of a playlist late in their load (2nd stage) */
1654 info = track_list_last(0);
1656 if (info && buf_handle_remaining(info->audio_hid) == 0)
1657 filling_is_finished();
1658 else
1659 filling = STATE_END_OF_PLAYLIST;
1661 return LOAD_TRACK_ERR_NO_MORE;
1664 /* Successfully opened the file - get track metadata */
1665 if (filling == STATE_FULL ||
1666 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1668 /* Buffer or track list is full */
1669 struct mp3entry *ub_id3;
1671 playlist_peek_offset--;
1673 /* Load the metadata for the first unbuffered track */
1674 ub_id3 = id3_get(UNBUFFERED_ID3);
1675 id3_mutex_lock();
1676 get_metadata(ub_id3, fd, trackname);
1677 id3_mutex_unlock();
1679 if (filling != STATE_FULL)
1681 track_list_unalloc_track();
1682 filling = STATE_FULL;
1685 logf("%s: buffer is full for now (%u tracks)", __func__,
1686 track_list_count());
1688 else
1690 /* Successful load initiation */
1691 info->filesize = filesize(fd);
1692 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1695 close(fd);
1696 return LOAD_TRACK_OK;
1699 /* Second part of the track loading: We now have the metadata available, so we
1700 can load the codec, the album art and finally the audio data.
1701 This is called on the audio thread after the buffering thread calls the
1702 buffering_handle_finished_callback callback. */
1703 static int audio_finish_load_track(struct track_info *info)
1705 int trackstat = LOAD_TRACK_OK;
1707 if (info->id3_hid != in_progress_id3_hid)
1709 /* We must not be here if not! */
1710 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1711 in_progress_id3_hid);
1712 return LOAD_TRACK_ERR_BUSY;
1715 /* The current track for decoding (there is always one if the list is
1716 populated) */
1717 struct track_info *cur_info = track_list_current(0);
1718 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1720 if (!track_id3)
1722 /* This is an error condition. Track cannot be played without valid
1723 metadata; skip the track. */
1724 logf("No metadata for: %s", track_id3->path);
1725 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1726 goto audio_finish_load_track_exit;
1729 /* Try to load a cuesheet for the track */
1730 if (!audio_load_cuesheet(info, track_id3))
1732 /* No space for cuesheet on buffer, not an error */
1733 filling = STATE_FULL;
1734 goto audio_finish_load_track_exit;
1737 #ifdef HAVE_ALBUMART
1738 /* Try to load album art for the track */
1739 if (!audio_load_albumart(info, track_id3))
1741 /* No space for album art on buffer, not an error */
1742 filling = STATE_FULL;
1743 goto audio_finish_load_track_exit;
1745 #endif
1747 /* All handles available to external routines are ready - audio and codec
1748 information is private */
1750 if (info == track_list_user_current(0))
1752 /* Send only when the track handles could not all be opened ahead of
1753 time for the user's current track - otherwise everything is ready
1754 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1755 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1758 #ifdef HAVE_CODEC_BUFFERING
1759 /* Try to buffer a codec for the track */
1760 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1762 if (info->codec_hid == ERR_BUFFER_FULL)
1764 /* No space for codec on buffer, not an error */
1765 filling = STATE_FULL;
1766 logf("buffer is full for now (%s)", __func__);
1768 else
1770 /* This is an error condition, either no codec was found, or
1771 reading the codec file failed part way through, either way,
1772 skip the track */
1773 logf("No codec for: %s", track_id3->path);
1774 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1777 goto audio_finish_load_track_exit;
1779 #endif /* HAVE_CODEC_BUFFERING */
1781 /** Finally, load the audio **/
1782 size_t file_offset = 0;
1783 track_id3->elapsed = 0;
1785 if (track_id3->offset >= info->filesize)
1786 track_id3->offset = 0;
1788 logf("%s: set offset for %s to %lu\n", __func__,
1789 id3->title, (unsigned long)offset);
1791 /* Adjust for resume rewind so we know what to buffer - starting the codec
1792 calls it again, so we don't save it (and they shouldn't accumulate) */
1793 size_t offset = resume_rewind_adjusted_offset(track_id3);
1795 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1797 if (audiotype == TYPE_ATOMIC_AUDIO)
1798 logf("Loading atomic %d", track_id3->codectype);
1800 if (format_buffers_with_offset(track_id3->codectype))
1802 /* This format can begin buffering from any point */
1803 file_offset = offset;
1806 logf("load track: %s", track_id3->path);
1808 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1810 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1811 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1813 else
1815 /* No offset given or it is very minimal - begin at the first frame
1816 according to the metadata */
1817 file_offset = track_id3->first_frame_offset;
1820 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1822 if (hid >= 0)
1824 info->audio_hid = hid;
1826 if (info == cur_info)
1828 /* This is the current track to decode - should be started now */
1829 trackstat = LOAD_TRACK_READY;
1832 else
1834 /* Buffer could be full but not properly so if this is the only
1835 track! */
1836 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1838 filling = STATE_FULL;
1839 logf("Buffer is full for now (%s)", __func__);
1841 else
1843 /* Nothing to play if no audio handle - skip this */
1844 logf("Could not add audio data handle");
1845 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1849 audio_finish_load_track_exit:
1850 if (trackstat < LOAD_TRACK_OK)
1852 playlist_skip_entry(NULL, playlist_peek_offset);
1853 track_info_close(info);
1854 track_list_unalloc_track();
1856 if (playlist_peek(playlist_peek_offset, NULL, 0))
1857 playlist_next(0);
1859 playlist_peek_offset--;
1862 if (filling != STATE_FULL)
1864 /* Load next track - error or not */
1865 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1866 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1867 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1869 else
1871 /* Full */
1872 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1875 return trackstat;
1878 /* Start a new track load */
1879 static int audio_fill_file_buffer(void)
1881 if (play_status == PLAY_STOPPED)
1882 return LOAD_TRACK_ERR_FAILED;
1884 trigger_cpu_boost();
1886 /* Must reset the buffer before use if trashed or voice only - voice
1887 file size shouldn't have changed so we can go straight from
1888 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1889 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1890 audio_reset_buffer();
1892 logf("Starting buffer fill");
1894 int trackstat = audio_load_track();
1896 if (trackstat >= LOAD_TRACK_OK)
1898 if (track_list_current(0) == track_list_user_current(0))
1899 playlist_next(0);
1901 if (filling == STATE_FULL && !track_list_user_current(1))
1903 /* There are no user tracks on the buffer after this therefore
1904 this is the next track */
1905 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
1909 return trackstat;
1912 /* Discard unwanted tracks and start refill from after the specified playlist
1913 offset */
1914 static int audio_reset_and_rebuffer(
1915 enum track_clear_action action, int peek_offset)
1917 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
1919 id3_write_locked(UNBUFFERED_ID3, NULL);
1921 /* Remove unwanted tracks - caller must have ensured codec isn't using
1922 any */
1923 track_list_clear(action);
1925 /* Refill at specified position (-1 starts at index offset 0) */
1926 playlist_peek_offset = peek_offset;
1928 /* Fill the buffer */
1929 return audio_fill_file_buffer();
1932 /* Handle buffering events
1933 (Q_AUDIO_BUFFERING) */
1934 static void audio_on_buffering(int event)
1936 enum track_clear_action action;
1937 int peek_offset;
1939 if (track_list_empty())
1940 return;
1942 switch (event)
1944 case BUFFER_EVENT_BUFFER_LOW:
1945 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
1946 return; /* Should be nothing left to fill */
1948 /* Clear old tracks and continue buffering where it left off */
1949 action = TRACK_LIST_KEEP_NEW;
1950 peek_offset = playlist_peek_offset;
1951 break;
1953 case BUFFER_EVENT_REBUFFER:
1954 /* Remove all but the currently decoding track and redo buffering
1955 after that */
1956 action = TRACK_LIST_KEEP_CURRENT;
1957 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
1958 break;
1960 default:
1961 return;
1964 switch (skip_pending)
1966 case TRACK_SKIP_NONE:
1967 case TRACK_SKIP_AUTO:
1968 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
1969 audio_reset_and_rebuffer(action, peek_offset);
1970 break;
1972 case TRACK_SKIP_AUTO_END_PLAYLIST:
1973 /* Already finished */
1974 break;
1976 default:
1977 /* Invalid */
1978 logf("Buffering call, inv. state: %d", (int)skip_pending);
1982 /* Handle starting the next track load
1983 (Q_AUDIO_FILL_BUFFER) */
1984 static void audio_on_fill_buffer(void)
1986 audio_handle_track_load_status(audio_fill_file_buffer());
1989 /* Handle posted load track finish event
1990 (Q_AUDIO_FINISH_LOAD_TRACK) */
1991 static void audio_on_finish_load_track(int id3_hid)
1993 struct track_info *info = track_list_last(0);
1995 if (!info || !buf_is_handle(id3_hid))
1996 return;
1998 if (info == track_list_user_current(1))
2000 /* Just loaded the metadata right after the current position */
2001 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
2004 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
2005 return; /* Not current track */
2007 bool is_user_current = info == track_list_user_current(0);
2009 if (is_user_current)
2011 /* Copy cuesheet */
2012 buf_read_cuesheet(info->cuesheet_hid);
2015 if (audio_start_codec(automatic_skip))
2017 if (is_user_current)
2019 /* Be sure all tagtree info is synchronized; it will be needed for the
2020 track finish event - the sync will happen when finalizing a track
2021 change otherwise */
2022 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2024 playing_id3_sync(info, -1);
2026 if (!was_valid)
2028 /* Playing id3 hadn't been updated yet because no valid track
2029 was yet available - treat like the first track */
2030 audio_playlist_track_change();
2034 else
2036 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2040 /* Called when handles other than metadata handles have finished buffering
2041 (Q_AUDIO_HANDLE_FINISHED) */
2042 static void audio_on_handle_finished(int hid)
2044 /* Right now, only audio handles should end up calling this */
2045 if (filling == STATE_END_OF_PLAYLIST)
2047 struct track_info *info = track_list_last(0);
2049 /* Really we don't know which order the handles will actually complete
2050 to zero bytes remaining since another thread is doing it - be sure
2051 it's the right one */
2052 if (info && info->audio_hid == hid)
2054 /* This was the last track in the playlist and we now have all the
2055 data we need */
2056 filling_is_finished();
2061 /* Called to make an outstanding track skip the current track and to send the
2062 transition events */
2063 static void audio_finalise_track_change(bool delayed)
2065 switch (skip_pending)
2067 case TRACK_SKIP_NONE: /* Manual skip */
2068 break;
2070 case TRACK_SKIP_AUTO:
2071 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2073 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2074 audio_playlist_track_finish();
2076 if (!playlist_peek(playlist_delta, NULL, 0))
2078 /* Track ended up rejected - push things ahead like the codec blew
2079 it (because it was never started and now we're here where it
2080 should have been decoding the next track by now) - next, a
2081 directory change or end of playback will most likely happen */
2082 skip_pending = TRACK_SKIP_NONE;
2083 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2084 return;
2087 if (!playlist_delta)
2088 break;
2090 playlist_peek_offset -= playlist_delta;
2091 if (playlist_next(playlist_delta) >= 0)
2092 break;
2093 /* What!? Disappear? Hopeless bleak despair */
2095 /* Fallthrough */
2096 case TRACK_SKIP_AUTO_END_PLAYLIST:
2097 default: /* Invalid */
2098 filling = STATE_ENDED;
2099 audio_stop_playback();
2100 return;
2103 struct track_info *info = track_list_current(0);
2104 struct mp3entry *track_id3 = NULL;
2106 id3_mutex_lock();
2108 /* Update the current cuesheet if any and enabled */
2109 if (info)
2111 buf_read_cuesheet(info->cuesheet_hid);
2112 track_id3 = bufgetid3(info->id3_hid);
2115 id3_write(PLAYING_ID3, track_id3);
2117 if (delayed)
2119 /* Delayed skip where codec is ahead of user's current track */
2120 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2121 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
2122 ply_id3->elapsed = ci_id3->elapsed;
2123 ply_id3->offset = ci_id3->offset;
2126 /* The skip is technically over */
2127 skip_pending = TRACK_SKIP_NONE;
2129 /* Sync the next track information */
2130 info = track_list_current(1);
2132 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2133 id3_get(UNBUFFERED_ID3));
2135 id3_mutex_unlock();
2137 audio_playlist_track_change();
2140 /* Actually begin a transition and take care of the codec change - may complete
2141 it now or ask pcmbuf for notification depending on the type and what pcmbuf
2142 has to say */
2143 static void audio_begin_track_change(bool auto_skip, int trackstat)
2145 /* Even if the new track is bad, the old track must be finished off */
2146 bool finalised = pcmbuf_start_track_change(auto_skip);
2148 if (finalised)
2150 /* pcmbuf says that the transition happens now - complete it */
2151 audio_finalise_track_change(false);
2153 if (play_status == PLAY_STOPPED)
2154 return; /* Stopped us */
2157 if (!auto_skip)
2158 audio_clear_paused_pcm();
2160 if (trackstat >= LOAD_TRACK_OK)
2162 struct track_info *info = track_list_current(0);
2164 if (info->audio_hid < 0)
2165 return;
2167 /* Everything needed for the codec is ready - start it */
2168 if (audio_start_codec(auto_skip))
2170 if (finalised)
2171 playing_id3_sync(info, -1);
2172 return;
2175 trackstat = LOAD_TRACK_ERR_START_CODEC;
2178 audio_handle_track_load_status(trackstat);
2181 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2182 static void audio_monitor_end_of_playlist(void)
2184 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2185 filling = STATE_ENDING;
2186 pcmbuf_monitor_track_change(true);
2189 /* Codec has completed decoding the track
2190 (usually Q_AUDIO_CODEC_COMPLETE) */
2191 static void audio_on_codec_complete(int status)
2193 logf("%s(%d)", __func__, status);
2195 if (play_status == PLAY_STOPPED)
2196 return;
2198 /* If it didn't notify us first, don't expect "seek complete" message
2199 since the codec can't post it now - do things like it would have
2200 done */
2201 audio_complete_codec_seek();
2203 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2205 /* Old-hay on the ip-skay - codec has completed decoding
2207 Paused: We're not sounding it, so just remember that it happened
2208 and the resume will begin the transition
2210 Skipping: There was already a skip in progress, remember it and
2211 allow no further progress until the PCM from the previous
2212 song has finished
2214 codec_skip_pending = true;
2215 codec_skip_status = status;
2216 return;
2219 codec_skip_pending = false;
2221 #ifdef AB_REPEAT_ENABLE
2222 if (status >= 0)
2224 /* Normal automatic skip */
2225 ab_end_of_track_report();
2227 #endif
2229 int trackstat = LOAD_TRACK_OK;
2231 automatic_skip = true;
2232 skip_pending = TRACK_SKIP_AUTO;
2234 /* Does this track have an entry allocated? */
2235 struct track_info *info = track_list_advance_current(1);
2237 if (!info || info->audio_hid < 0)
2239 bool end_of_playlist = false;
2241 if (info)
2243 /* Track load is not complete - it might have stopped on a
2244 full buffer without reaching the audio handle or we just
2245 arrived at it early
2247 If this type is atomic and we couldn't get the audio,
2248 perhaps it would need to wrap to make the allocation and
2249 handles are in the way - to maximize the liklihood it can
2250 be allocated, clear all handles to reset the buffer and
2251 its indexes to 0 - for packet audio, this should not be an
2252 issue and a pointless full reload of all the track's
2253 metadata may be avoided */
2255 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2257 if (track_id3 &&
2258 get_audio_base_data_type(track_id3->codectype)
2259 == TYPE_PACKET_AUDIO)
2261 /* Continue filling after this track */
2262 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2263 audio_begin_track_change(true, trackstat);
2264 return;
2266 /* else rebuffer at this track; status applies to the track we
2267 want */
2269 else if (!playlist_peek(1, NULL, 0))
2271 /* Play sequence is complete - directory change or other playlist
2272 resequencing - the playlist must now be advanced in order to
2273 continue since a peek ahead to the next track is not possible */
2274 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2275 end_of_playlist = playlist_next(1) < 0;
2278 if (!end_of_playlist)
2280 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2281 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2283 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2285 /* Failed to find anything after all - do playlist switchover
2286 instead */
2287 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2288 end_of_playlist = playlist_next(1) < 0;
2292 if (end_of_playlist)
2294 audio_monitor_end_of_playlist();
2295 return;
2299 audio_begin_track_change(true, trackstat);
2302 /* Called when codec completes seek operation
2303 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2304 static void audio_on_codec_seek_complete(void)
2306 logf("%s()", __func__);
2307 audio_complete_codec_seek();
2308 codec_go();
2311 /* Called when PCM track change has completed
2312 (Q_AUDIO_TRACK_CHANGED) */
2313 static void audio_on_track_changed(void)
2315 /* Finish whatever is pending so that the WPS is in sync */
2316 audio_finalise_track_change(true);
2318 if (codec_skip_pending)
2320 /* Codec got ahead completing a short track - complete the
2321 codec's skip and begin the next */
2322 codec_skip_pending = false;
2323 audio_on_codec_complete(codec_skip_status);
2327 /* Begin playback from an idle state, transition to a new playlist or
2328 invalidate the buffer and resume (if playing).
2329 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2330 static void audio_start_playback(size_t offset, unsigned int flags)
2332 enum play_status old_status = play_status;
2334 if (flags & AUDIO_START_NEWBUF)
2336 /* Mark the buffer dirty - if not playing, it will be reset next
2337 time */
2338 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2339 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2342 if (old_status != PLAY_STOPPED)
2344 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2346 halt_decoding_track(true);
2348 automatic_skip = false;
2349 ff_rw_mode = false;
2351 if (flags & AUDIO_START_RESTART)
2353 /* Clear out some stuff to resume the current track where it
2354 left off */
2355 pcmbuf_play_stop();
2356 offset = id3_get(PLAYING_ID3)->offset;
2357 track_list_clear(TRACK_LIST_CLEAR_ALL);
2359 else
2361 /* This is more-or-less treated as manual track transition */
2362 /* Save resume information for current track */
2363 audio_playlist_track_finish();
2364 track_list_clear(TRACK_LIST_CLEAR_ALL);
2366 /* Indicate manual track change */
2367 pcmbuf_start_track_change(false);
2368 audio_clear_paused_pcm();
2369 wipe_track_metadata(true);
2372 /* Set after track finish event in case skip was in progress */
2373 skip_pending = TRACK_SKIP_NONE;
2375 else
2377 if (flags & AUDIO_START_RESTART)
2378 return; /* Must already be playing */
2380 /* Cold playback start from a stopped state */
2381 logf("%s(%lu): starting", __func__, offset);
2383 /* Set audio parameters */
2384 #if INPUT_SRC_CAPS != 0
2385 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2386 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2387 #endif
2388 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2389 sound_set_volume(global_settings.volume);
2390 #endif
2391 /* Be sure channel is audible */
2392 pcmbuf_fade(false, true);
2394 /* Update our state */
2395 play_status = PLAY_PLAYING;
2398 /* Start fill from beginning of playlist */
2399 playlist_peek_offset = -1;
2400 buf_set_base_handle(-1);
2402 /* Officially playing */
2403 queue_reply(&audio_queue, 1);
2405 /* Add these now - finish event for the first id3 will most likely be sent
2406 immediately */
2407 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2408 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2410 if (old_status == PLAY_STOPPED)
2412 /* Send coldstart event */
2413 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2416 /* Fill the buffer */
2417 int trackstat = audio_fill_file_buffer();
2419 if (trackstat >= LOAD_TRACK_OK)
2421 /* This is the currently playing track - get metadata, stat */
2422 playing_id3_sync(track_list_current(0), offset);
2424 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2426 /* Only if actually changing tracks... */
2427 if (!(flags & AUDIO_START_RESTART))
2428 audio_playlist_track_change();
2431 else
2433 /* Found nothing playable */
2434 audio_handle_track_load_status(trackstat);
2438 /* Stop playback and enter an idle state
2439 (usually Q_AUDIO_STOP) */
2440 static void audio_stop_playback(void)
2442 logf("%s()", __func__);
2444 if (play_status == PLAY_STOPPED)
2445 return;
2447 pcmbuf_fade(global_settings.fade_on_stop, false);
2449 /* Stop the codec and unload it */
2450 halt_decoding_track(true);
2451 pcmbuf_play_stop();
2452 codec_unload();
2454 /* Save resume information - "filling" might have been set to
2455 "STATE_ENDED" by caller in order to facilitate end of playlist */
2456 audio_playlist_track_finish();
2458 skip_pending = TRACK_SKIP_NONE;
2459 automatic_skip = false;
2461 /* Close all tracks and mark them NULL */
2462 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2463 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2464 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2466 track_list_clear(TRACK_LIST_CLEAR_ALL);
2468 /* Update our state */
2469 ff_rw_mode = false;
2470 play_status = PLAY_STOPPED;
2472 wipe_track_metadata(true);
2474 /* Go idle */
2475 filling = STATE_IDLE;
2476 cancel_cpu_boost();
2479 /* Pause the playback of the current track
2480 (Q_AUDIO_PAUSE) */
2481 static void audio_on_pause(bool pause)
2483 logf("%s(%s)", __func__, pause ? "true" : "false");
2485 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2486 return;
2488 bool const do_fade = global_settings.fade_on_stop;
2490 if (pause)
2491 pcmbuf_fade(do_fade, false);
2493 if (!ff_rw_mode)
2495 /* Not in ff/rw mode - may set the state (otherwise this could make
2496 old data play because seek hasn't completed and cleared it) */
2497 pcmbuf_pause(pause);
2500 if (!pause)
2501 pcmbuf_fade(do_fade, true);
2503 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2505 if (!pause && codec_skip_pending)
2507 /* Actually do the skip that is due - resets the status flag */
2508 audio_on_codec_complete(codec_skip_status);
2512 /* Skip a certain number of tracks forwards or backwards
2513 (Q_AUDIO_SKIP) */
2514 static void audio_on_skip(void)
2516 id3_mutex_lock();
2518 /* Eat the delta to keep it synced, even if not playing */
2519 int toskip = skip_offset;
2520 skip_offset = 0;
2522 logf("%s(): %d", __func__, toskip);
2524 id3_mutex_unlock();
2526 if (play_status == PLAY_STOPPED)
2527 return;
2529 /* Force codec to abort this track */
2530 halt_decoding_track(true);
2532 /* Kill the ff/rw halt */
2533 ff_rw_mode = false;
2535 /* Manual skip */
2536 automatic_skip = false;
2538 /* If there was an auto skip in progress, there will be residual
2539 advancement of the playlist and/or track list so compensation will be
2540 required in order to end up in the right spot */
2541 int track_list_delta = toskip;
2542 int playlist_delta = toskip;
2544 if (skip_pending != TRACK_SKIP_NONE)
2546 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2547 track_list_delta--;
2549 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2550 playlist_delta--;
2553 audio_playlist_track_finish();
2554 skip_pending = TRACK_SKIP_NONE;
2556 /* Update the playlist current track now */
2557 while (playlist_next(playlist_delta) < 0)
2559 /* Manual skip out of range (because the playlist wasn't updated
2560 yet by us and so the check in audio_skip returned 'ok') - bring
2561 back into range */
2562 int d = toskip < 0 ? 1 : -1;
2564 while (!playlist_check(playlist_delta))
2566 if (playlist_delta == d)
2568 /* Had to move the opposite direction to correct, which is
2569 wrong - this is the end */
2570 filling = STATE_ENDED;
2571 audio_stop_playback();
2572 return;
2575 playlist_delta += d;
2576 track_list_delta += d;
2580 /* Adjust things by how much the playlist was manually moved */
2581 playlist_peek_offset -= playlist_delta;
2583 struct track_info *info = track_list_advance_current(track_list_delta);
2584 int trackstat = LOAD_TRACK_OK;
2586 if (!info || info->audio_hid < 0)
2588 /* We don't know the next track thus we know we don't have it */
2589 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2592 audio_begin_track_change(false, trackstat);
2595 /* Skip to the next/previous directory
2596 (Q_AUDIO_DIR_SKIP) */
2597 static void audio_on_dir_skip(int direction)
2599 logf("%s(%d)", __func__, direction);
2601 id3_mutex_lock();
2602 skip_offset = 0;
2603 id3_mutex_unlock();
2605 if (play_status == PLAY_STOPPED)
2606 return;
2608 /* Force codec to abort this track */
2609 halt_decoding_track(true);
2611 /* Kill the ff/rw halt */
2612 ff_rw_mode = false;
2614 /* Manual skip */
2615 automatic_skip = false;
2617 audio_playlist_track_finish();
2619 /* Unless automatic and gapless, skips do not pend */
2620 skip_pending = TRACK_SKIP_NONE;
2622 /* Regardless of the return value we need to rebuffer. If it fails the old
2623 playlist will resume, else the next dir will start playing. */
2624 playlist_next_dir(direction);
2626 wipe_track_metadata(false);
2628 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2630 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2632 /* The day the music died - finish-off whatever is playing and call it
2633 quits */
2634 audio_monitor_end_of_playlist();
2635 return;
2638 audio_begin_track_change(false, trackstat);
2641 /* Enter seek mode in order to start a seek
2642 (Q_AUDIO_PRE_FF_REWIND) */
2643 static void audio_on_pre_ff_rewind(void)
2645 logf("%s()", __func__);
2647 if (play_status == PLAY_STOPPED || ff_rw_mode)
2648 return;
2650 ff_rw_mode = true;
2652 if (play_status == PLAY_PAUSED)
2653 return;
2655 pcmbuf_pause(true);
2658 /* Seek the playback of the current track to the specified time
2659 (Q_AUDIO_FF_REWIND) */
2660 static void audio_on_ff_rewind(long time)
2662 logf("%s(%ld)", __func__, time);
2664 if (play_status == PLAY_STOPPED)
2665 return;
2667 enum track_skip_type pending = skip_pending;
2669 switch (pending)
2671 case TRACK_SKIP_NONE: /* The usual case */
2672 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2673 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2675 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2676 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2678 automatic_skip = false;
2680 /* Send event before clobbering the time */
2681 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2682 then skipping back to this track resumes properly. Something else
2683 should be sent. We're not _really_ finishing the track are we? */
2684 if (time == 0)
2685 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2687 /* Prevent user codec time update - coerce to something that is
2688 innocuous concerning lookaheads */
2689 if (pending == TRACK_SKIP_NONE)
2690 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2692 id3->elapsed = time;
2693 queue_reply(&audio_queue, 1);
2695 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2697 /* Need this set in case ff/rw mode + error but _after_ the codec
2698 halt that will reset it */
2699 codec_seeking = true;
2701 if (pending == TRACK_SKIP_AUTO)
2703 if (!track_list_advance_current(-1))
2705 /* Not in list - must rebuffer at the current playlist index */
2706 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2707 < LOAD_TRACK_OK)
2709 /* Codec is stopped */
2710 break;
2715 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2716 rebuffer is needed */
2717 skip_pending = TRACK_SKIP_NONE;
2718 struct track_info *cur_info = track_list_current(0);
2720 /* Track must complete the loading _now_ since a codec and audio
2721 handle are needed in order to do the seek */
2722 if (cur_info->audio_hid < 0 &&
2723 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2725 /* Call above should push any load sequence - no need for
2726 halt_decoding_track here if no skip was pending here because
2727 there would not be a codec started if no audio handle was yet
2728 opened */
2729 break;
2732 if (pending == TRACK_SKIP_AUTO)
2734 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2735 !audio_init_codec(cur_info, ci_id3))
2737 /* We should have still been able to get it - skip it and move
2738 onto the next one - like it or not this track is broken */
2739 break;
2742 /* Set the codec API to the correct metadata and track info */
2743 ci.audio_hid = cur_info->audio_hid;
2744 ci.filesize = cur_info->filesize;
2745 buf_set_base_handle(cur_info->audio_hid);
2748 if (!haltres)
2750 /* If codec must be (re)started, reset the offset */
2751 ci_id3->offset = 0;
2754 codec_seek(time);
2755 return;
2758 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2760 /* We cannot do this because the playlist must be reversed by one
2761 and it doesn't always return the same song when going backwards
2762 across boundaries as forwards (either because of randomization
2763 or inconsistency in deciding what the previous track should be),
2764 therefore the whole operation would often end up as nonsense -
2765 lock out seeking for a couple seconds */
2767 /* Sure as heck cancel seek mode too! */
2768 audio_ff_rewind_end();
2769 return;
2772 default:
2773 /* Won't see this */
2774 return;
2777 if (play_status == PLAY_STOPPED)
2779 /* Playback ended because of an error completing a track load */
2780 return;
2783 /* Always fake it as a codec start error which will handle mode
2784 cancellations and skip to the next track */
2785 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2788 /* Invalidates all but currently playing track
2789 (Q_AUDIO_FLUSH) */
2790 static void audio_on_audio_flush(void)
2792 logf("%s", __func__);
2794 if (track_list_empty())
2795 return; /* Nothing to flush out */
2797 switch (skip_pending)
2799 case TRACK_SKIP_NONE:
2800 case TRACK_SKIP_AUTO_END_PLAYLIST:
2801 /* Remove all but the currently playing track from the list and
2802 refill after that */
2803 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2804 playlist_peek_offset = 0;
2805 id3_write_locked(UNBUFFERED_ID3, NULL);
2806 audio_update_and_announce_next_track(NULL);
2808 /* Ignore return since it's about the next track, not this one */
2809 audio_fill_file_buffer();
2811 if (skip_pending == TRACK_SKIP_NONE)
2812 break;
2814 /* There's now a track after this one now - convert to auto skip -
2815 no skip should pend right now because multiple flush messages can
2816 be fired which would cause a restart in the below cases */
2817 skip_pending = TRACK_SKIP_NONE;
2818 audio_clear_track_notifications();
2819 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2820 break;
2822 case TRACK_SKIP_AUTO:
2823 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2824 /* Precisely removing what it already decoded for the next track is
2825 not possible so a restart is required in order to continue the
2826 currently playing track without the now invalid future track
2827 playing */
2828 audio_start_playback(0, AUDIO_START_RESTART);
2829 break;
2831 default: /* Nothing else is a state */
2832 break;
2836 #ifdef AUDIO_HAVE_RECORDING
2837 /* Load the requested encoder type
2838 (Q_AUDIO_LOAD_ENCODER) */
2839 static void audio_on_load_encoder(int afmt)
2841 bool res = true;
2843 if (play_status != PLAY_STOPPED)
2844 audio_stop_playback(); /* Can't load both types at once */
2845 else
2846 codec_unload(); /* Encoder still loaded, stop and unload it */
2848 if (afmt != AFMT_UNKNOWN)
2850 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2851 if (res)
2852 codec_go(); /* These are run immediately */
2855 queue_reply(&audio_queue, res);
2857 #endif /* AUDIO_HAVE_RECORDING */
2859 static void audio_thread(void)
2861 struct queue_event ev;
2863 pcm_postinit();
2865 filling = STATE_IDLE;
2867 while (1)
2869 switch (filling)
2871 /* Active states */
2872 case STATE_FULL:
2873 case STATE_END_OF_PLAYLIST:
2874 if (buf_get_watermark() == 0)
2876 /* End of buffering for now, let's calculate the watermark,
2877 register for a low buffer event and unboost */
2878 audio_update_filebuf_watermark(0);
2879 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2880 buffer_event_buffer_low_callback);
2882 /* Fall-through */
2883 case STATE_FINISHED:
2884 /* All data was buffered */
2885 cancel_cpu_boost();
2886 /* Fall-through */
2887 case STATE_FILLING:
2888 case STATE_ENDING:
2889 if (audio_pcmbuf_track_change_scan())
2891 /* Transfer notification to audio queue event */
2892 ev.id = Q_AUDIO_TRACK_CHANGED;
2893 ev.data = 1;
2895 else
2897 /* If doing auto skip, poll pcmbuf track notifications a bit
2898 faster to promply detect the transition */
2899 queue_wait_w_tmo(&audio_queue, &ev,
2900 skip_pending == TRACK_SKIP_NONE ?
2901 HZ/2 : HZ/10);
2903 break;
2905 /* Idle states */
2906 default:
2907 queue_wait(&audio_queue, &ev);
2909 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2910 switch (ev.id)
2912 #ifdef AUDIO_HAVE_RECORDING
2913 /* Must monitor the encoder message for recording so it can remove
2914 it if we process the insertion before it does. It cannot simply
2915 be removed from under recording however. */
2916 case Q_AUDIO_LOAD_ENCODER:
2917 break;
2918 #endif
2919 case SYS_USB_DISCONNECTED:
2920 filling = STATE_IDLE;
2921 break;
2923 default:
2924 if (filling == STATE_USB)
2925 continue;
2927 #endif /* CONFIG_PLATFORM */
2930 switch (ev.id)
2932 /** Codec and track change messages **/
2933 case Q_AUDIO_CODEC_COMPLETE:
2934 /* Codec is done processing track and has gone idle */
2935 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
2936 audio_on_codec_complete(ev.data);
2937 break;
2939 case Q_AUDIO_CODEC_SEEK_COMPLETE:
2940 /* Codec is done seeking */
2941 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2942 audio_on_codec_seek_complete();
2943 break;
2945 case Q_AUDIO_TRACK_CHANGED:
2946 /* PCM track change done */
2947 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2948 audio_on_track_changed();
2949 break;
2951 /** Control messages **/
2952 case Q_AUDIO_PLAY:
2953 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2954 audio_start_playback(ev.data, 0);
2955 break;
2957 case Q_AUDIO_STOP:
2958 LOGFQUEUE("audio < Q_AUDIO_STOP");
2959 audio_stop_playback();
2960 if (ev.data != 0)
2961 queue_clear(&audio_queue);
2962 break;
2964 case Q_AUDIO_PAUSE:
2965 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2966 audio_on_pause(ev.data);
2967 break;
2969 case Q_AUDIO_SKIP:
2970 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2971 audio_on_skip();
2972 break;
2974 case Q_AUDIO_DIR_SKIP:
2975 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2976 audio_on_dir_skip(ev.data);
2977 break;
2979 case Q_AUDIO_PRE_FF_REWIND:
2980 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2981 audio_on_pre_ff_rewind();
2982 break;
2984 case Q_AUDIO_FF_REWIND:
2985 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2986 audio_on_ff_rewind(ev.data);
2987 break;
2989 case Q_AUDIO_FLUSH:
2990 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
2991 audio_on_audio_flush();
2992 break;
2994 /** Buffering messages **/
2995 case Q_AUDIO_BUFFERING:
2996 /* some buffering event */
2997 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
2998 audio_on_buffering(ev.data);
2999 break;
3001 case Q_AUDIO_FILL_BUFFER:
3002 /* continue buffering next track */
3003 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
3004 audio_on_fill_buffer();
3005 break;
3007 case Q_AUDIO_FINISH_LOAD_TRACK:
3008 /* metadata is buffered */
3009 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
3010 audio_on_finish_load_track(ev.data);
3011 break;
3013 case Q_AUDIO_HANDLE_FINISHED:
3014 /* some other type is buffered */
3015 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3016 audio_on_handle_finished(ev.data);
3017 break;
3019 /** Miscellaneous messages **/
3020 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3021 /* buffer needs to be reinitialized */
3022 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3023 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3024 break;
3026 #ifdef HAVE_DISK_STORAGE
3027 case Q_AUDIO_UPDATE_WATERMARK:
3028 /* buffering watermark needs updating */
3029 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3030 audio_update_filebuf_watermark(ev.data);
3031 break;
3032 #endif /* HAVE_DISK_STORAGE */
3034 #ifdef AUDIO_HAVE_RECORDING
3035 case Q_AUDIO_LOAD_ENCODER:
3036 /* load an encoder for recording */
3037 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3038 audio_on_load_encoder(ev.data);
3039 break;
3040 #endif /* AUDIO_HAVE_RECORDING */
3042 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3043 case SYS_USB_CONNECTED:
3044 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3045 audio_stop_playback();
3046 #ifdef PLAYBACK_VOICE
3047 voice_stop();
3048 #endif
3049 filling = STATE_USB;
3050 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3051 break;
3052 #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
3054 case SYS_TIMEOUT:
3055 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3056 break;
3058 default:
3059 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3060 break;
3061 } /* end switch */
3062 } /* end while */
3066 /* --- Buffering callbacks --- */
3068 /* Called when fullness is below the watermark level */
3069 static void buffer_event_buffer_low_callback(void *data)
3071 logf("low buffer callback");
3072 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3073 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3074 (void)data;
3077 /* Called when handles must be discarded in order to buffer new data */
3078 static void buffer_event_rebuffer_callback(void *data)
3080 logf("rebuffer callback");
3081 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3082 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3083 (void)data;
3086 /* A handle has completed buffering and all required data is available */
3087 static void buffer_event_finished_callback(void *data)
3089 int hid = *(const int *)data;
3090 const enum data_type htype = buf_handle_data_type(hid);
3092 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3094 /* Limit queue traffic */
3095 switch (htype)
3097 case TYPE_ID3:
3098 /* The metadata handle for the last loaded track has been buffered.
3099 We can ask the audio thread to load the rest of the track's data. */
3100 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3101 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3102 break;
3104 case TYPE_PACKET_AUDIO:
3105 /* Strip any useless trailing tags that are left. */
3106 strip_tags(hid);
3107 /* Fall-through */
3108 case TYPE_ATOMIC_AUDIO:
3109 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3110 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3111 break;
3113 default:
3114 /* Don't care to know about these */
3115 break;
3120 /** -- Codec callbacks -- **/
3122 /* Update elapsed times with latency-adjusted values */
3123 void audio_codec_update_elapsed(unsigned long value)
3125 #ifdef AB_REPEAT_ENABLE
3126 ab_position_report(value);
3127 #endif
3129 unsigned long latency = pcmbuf_get_latency();
3131 if (LIKELY(value >= latency))
3133 unsigned long elapsed = value - latency;
3135 if (elapsed > value || elapsed < value - 2)
3136 value = elapsed;
3138 else
3140 value = 0;
3143 /* Track codec: used later when updating the playing at the user
3144 transition */
3145 id3_get(CODEC_ID3)->elapsed = value;
3147 /* If a skip is pending, the PCM buffer is updating the time on the
3148 previous song */
3149 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3150 id3_get(PLAYING_ID3)->elapsed = value;
3153 /* Update offsets with latency-adjusted values */
3154 void audio_codec_update_offset(size_t value)
3156 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
3157 unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8;
3159 if (LIKELY(value >= latency))
3161 value -= latency;
3163 else
3165 value = 0;
3168 /* Track codec: used later when updating the playing id3 at the user
3169 transition */
3170 ci_id3->offset = value;
3172 /* If a skip is pending, the PCM buffer is updating the time on the
3173 previous song */
3174 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3175 id3_get(PLAYING_ID3)->offset = value;
3179 /** --- Pcmbuf callbacks --- **/
3181 /* Between the codec and PCM track change, we need to keep updating the
3182 * "elapsed" value of the previous (to the codec, but current to the
3183 * user/PCM/WPS) track, so that the progressbar reaches the end. */
3184 void audio_pcmbuf_position_callback(unsigned int time)
3186 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3188 time += id3->elapsed;
3190 id3->elapsed = MIN(time, id3->length);
3193 /* Post message from pcmbuf that the end of the previous track has just
3194 * been played */
3195 void audio_pcmbuf_track_change(bool pcmbuf)
3197 if (pcmbuf)
3199 /* Notify of the change in special-purpose semaphore object */
3200 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3201 audio_pcmbuf_track_change_post();
3203 else
3205 /* Safe to post directly to the queue */
3206 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3207 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3211 /* May pcmbuf start PCM playback when the buffer is full enough? */
3212 bool audio_pcmbuf_may_play(void)
3214 return play_status == PLAY_PLAYING && !ff_rw_mode;
3218 /** -- External interfaces -- **/
3220 /* Return the playback and recording status */
3221 int audio_status(void)
3223 unsigned int ret = play_status;
3225 #ifdef AUDIO_HAVE_RECORDING
3226 /* Do this here for constitency with mpeg.c version */
3227 ret |= pcm_rec_status();
3228 #endif
3230 return (int)ret;
3233 /* Clear all accumulated audio errors for playback and recording */
3234 void audio_error_clear(void)
3236 #ifdef AUDIO_HAVE_RECORDING
3237 pcm_rec_error_clear();
3238 #endif
3241 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3242 bool audio_peek_track(struct mp3entry *id3, int offset)
3244 bool retval = false;
3246 id3_mutex_lock();
3248 if (play_status != PLAY_STOPPED)
3250 id3->path[0] = '\0'; /* Null path means it should be filled now */
3251 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3252 id3->path[0] != '\0';
3255 id3_mutex_unlock();
3257 return retval;
3260 /* Return the mp3entry for the currently playing track */
3261 struct mp3entry * audio_current_track(void)
3263 struct mp3entry *id3;
3265 id3_mutex_lock();
3267 #ifdef AUDIO_FAST_SKIP_PREVIEW
3268 if (skip_offset != 0)
3270 /* This is a peekahead */
3271 id3 = id3_get(PLAYING_PEEK_ID3);
3272 audio_peek_track(id3, 0);
3274 else
3275 #endif
3277 /* Normal case */
3278 id3 = id3_get(PLAYING_ID3);
3279 audio_get_track_metadata(0, id3);
3282 id3_mutex_unlock();
3284 return id3;
3287 /* Obtains the mp3entry for the next track from the current */
3288 struct mp3entry * audio_next_track(void)
3290 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3292 id3_mutex_lock();
3294 #ifdef AUDIO_FAST_SKIP_PREVIEW
3295 if (skip_offset != 0)
3297 /* This is a peekahead */
3298 if (!audio_peek_track(id3, 1))
3299 id3 = NULL;
3301 else
3302 #endif
3304 /* Normal case */
3305 if (!audio_get_track_metadata(1, id3))
3306 id3 = NULL;
3309 id3_mutex_unlock();
3311 return id3;
3314 /* Start playback at the specified offset */
3315 void audio_play(long offset)
3317 logf("audio_play");
3319 #ifdef PLAYBACK_VOICE
3320 /* Truncate any existing voice output so we don't have spelling
3321 * etc. over the first part of the played track */
3322 talk_force_shutup();
3323 #endif
3325 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3326 audio_queue_send(Q_AUDIO_PLAY, offset);
3329 /* Stop playback if playing */
3330 void audio_stop(void)
3332 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3333 audio_queue_send(Q_AUDIO_STOP, 0);
3336 /* Pause playback if playing */
3337 void audio_pause(void)
3339 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3340 audio_queue_send(Q_AUDIO_PAUSE, true);
3343 /* This sends a stop message and the audio thread will dump all its
3344 subsequent messages */
3345 void audio_hard_stop(void)
3347 /* Stop playback */
3348 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3349 audio_queue_send(Q_AUDIO_STOP, 1);
3350 #ifdef PLAYBACK_VOICE
3351 voice_stop();
3352 #endif
3353 if (audiobuf_handle > 0)
3355 core_free(audiobuf_handle);
3356 audiobuf_handle = 0;
3360 /* Resume playback if paused */
3361 void audio_resume(void)
3363 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3364 audio_queue_send(Q_AUDIO_PAUSE, false);
3367 /* Skip the specified number of tracks forward or backward from the current */
3368 void audio_skip(int offset)
3370 id3_mutex_lock();
3372 /* If offset has to be backed-out to stay in range, no skip is done */
3373 int accum = skip_offset + offset;
3375 while (offset != 0 && !playlist_check(accum))
3377 offset += offset < 0 ? 1 : -1;
3378 accum = skip_offset + offset;
3381 if (offset != 0)
3383 /* Accumulate net manual skip count since the audio thread last
3384 processed one */
3385 skip_offset = accum;
3387 system_sound_play(SOUND_TRACK_SKIP);
3389 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3391 #ifdef AUDIO_FAST_SKIP_PREVIEW
3392 /* Do this before posting so that the audio thread can correct us
3393 when things settle down - additionally, if audio gets a message
3394 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3395 handler a skip event with the correct info but doesn't skip */
3396 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3397 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3399 /* Playback only needs the final state even if more than one is
3400 processed because it wasn't removed in time */
3401 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3402 audio_queue_post(Q_AUDIO_SKIP, 0);
3404 else
3406 /* No more tracks */
3407 system_sound_play(SOUND_TRACK_NO_MORE);
3410 id3_mutex_unlock();
3413 /* Skip one track forward from the current */
3414 void audio_next(void)
3416 audio_skip(1);
3419 /* Skip one track backward from the current */
3420 void audio_prev(void)
3422 audio_skip(-1);
3425 /* Move one directory forward */
3426 void audio_next_dir(void)
3428 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3429 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3432 /* Move one directory backward */
3433 void audio_prev_dir(void)
3435 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3436 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3439 /* Pause playback in order to start a seek that flushes the old audio */
3440 void audio_pre_ff_rewind(void)
3442 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3443 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3446 /* Seek to the new time in the current track */
3447 void audio_ff_rewind(long time)
3449 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3450 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3453 /* Clear all but the currently playing track then rebuffer */
3454 void audio_flush_and_reload_tracks(void)
3456 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3457 audio_queue_post(Q_AUDIO_FLUSH, 0);
3460 /* Return the pointer to the main audio buffer, optionally preserving
3461 voicing */
3462 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3464 unsigned char *buf;
3466 if (audio_is_initialized)
3468 audio_hard_stop();
3470 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3472 if (buffer_size == NULL)
3474 /* Special case for talk_init to use since it already knows it's
3475 trashed */
3476 buffer_state = AUDIOBUF_STATE_TRASHED;
3477 return NULL;
3480 /* make sure buffer is freed and re-allocated to simplify code below
3481 * (audio_hard_stop() likely has done that already) */
3482 if (audiobuf_handle > 0)
3484 core_free(audiobuf_handle);
3485 audiobuf_handle = 0;
3488 audiobuf_handle = core_alloc_maximum("audiobuf", buffer_size, &ops);
3489 buf = core_get_data(audiobuf_handle);
3491 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3492 || !talk_voice_required())
3494 logf("get buffer: talk, audio");
3495 /* Ok to use everything from audiobuf - voice is loaded,
3496 the talk buffer is not needed because voice isn't being used, or
3497 could be AUDIOBUF_STATE_TRASHED already. If state is
3498 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3499 written without the caller knowing what's going on. Changing certain
3500 settings may move it to a worse condition but the memory in use by
3501 something else will remain undisturbed.
3503 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3505 talk_buffer_steal();
3506 buffer_state = AUDIOBUF_STATE_TRASHED;
3509 else
3511 logf("get buffer: audio");
3512 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3513 still AUDIOBUF_STATE_INITIALIZED */
3514 /* Skip talk buffer and move pcm buffer to end to maximize available
3515 contiguous memory - no audio running means voice will not need the
3516 swap space */
3517 size_t talkbuf_size;
3518 size_t siz = *buffer_size;
3519 buf += talkbuf_size = talkbuf_init(buf);
3520 siz -= talkbuf_size + pcmbuf_init(buf + siz);
3521 siz -= voicebuf_init(buf + siz);
3522 *buffer_size = siz;
3524 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3527 return buf;
3530 #ifdef HAVE_RECORDING
3531 /* Stop audio, voice and obtain all available buffer space */
3532 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3534 audio_hard_stop();
3535 return audio_get_buffer(true, buffer_size);
3537 #endif /* HAVE_RECORDING */
3539 /* Restore audio buffer to a particular state (one more valid than the current
3540 state) */
3541 bool audio_restore_playback(int type)
3543 switch (type)
3545 case AUDIO_WANT_PLAYBACK:
3546 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3547 audio_reset_buffer();
3548 return true;
3549 case AUDIO_WANT_VOICE:
3550 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3551 audio_reset_buffer();
3552 return true;
3553 default:
3554 return false;
3558 /* Has the playback buffer been completely claimed? */
3559 bool audio_buffer_state_trashed(void)
3561 return buffer_state == AUDIOBUF_STATE_TRASHED;
3565 /** --- Miscellaneous public interfaces --- **/
3567 #ifdef HAVE_ALBUMART
3568 /* Return which album art handle is current for the user in the given slot */
3569 int playback_current_aa_hid(int slot)
3571 if ((unsigned)slot < MAX_MULTIPLE_AA)
3573 struct track_info *info = track_list_user_current(skip_offset);
3575 if (!info && abs(skip_offset) <= 1)
3577 /* Give the actual position a go */
3578 info = track_list_user_current(0);
3581 if (info)
3582 return info->aa_hid[slot];
3585 return ERR_HANDLE_NOT_FOUND;
3588 /* Find an album art slot that doesn't match the dimensions of another that
3589 is already claimed - increment the use count if it is */
3590 int playback_claim_aa_slot(struct dim *dim)
3592 int i;
3594 /* First try to find a slot already having the size to reuse it since we
3595 don't want albumart of the same size buffered multiple times */
3596 FOREACH_ALBUMART(i)
3598 struct albumart_slot *slot = &albumart_slots[i];
3600 if (slot->dim.width == dim->width &&
3601 slot->dim.height == dim->height)
3603 slot->used++;
3604 return i;
3608 /* Size is new, find a free slot */
3609 FOREACH_ALBUMART(i)
3611 if (!albumart_slots[i].used)
3613 albumart_slots[i].used++;
3614 albumart_slots[i].dim = *dim;
3615 return i;
3619 /* Sorry, no free slot */
3620 return -1;
3623 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3624 void playback_release_aa_slot(int slot)
3626 if ((unsigned)slot < MAX_MULTIPLE_AA)
3628 struct albumart_slot *aa_slot = &albumart_slots[slot];
3630 if (aa_slot->used > 0)
3631 aa_slot->used--;
3634 #endif /* HAVE_ALBUMART */
3637 #ifdef HAVE_RECORDING
3638 /* Load an encoder and run it */
3639 bool audio_load_encoder(int afmt)
3641 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3642 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3643 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3644 #else
3645 (void)afmt;
3646 return true;
3647 #endif
3650 /* Stop an encoder and unload it */
3651 void audio_remove_encoder(void)
3653 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3654 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3655 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3656 #endif
3658 #endif /* HAVE_RECORDING */
3660 /* Is an automatic skip in progress? If called outside transition callbacks,
3661 indicates the last skip type at the time it was processed and isn't very
3662 meaningful. */
3663 bool audio_automatic_skip(void)
3665 return automatic_skip;
3668 /* Would normally calculate byte offset from an elapsed time but is not
3669 used on SWCODEC */
3670 int audio_get_file_pos(void)
3672 return 0;
3675 /* Return the elapsed time of the track previous to the current */
3676 unsigned long audio_prev_elapsed(void)
3678 return prev_track_elapsed;
3681 /* Is the audio thread ready to accept commands? */
3682 bool audio_is_thread_ready(void)
3684 return filling != STATE_BOOT;
3687 /* Return total file buffer length after accounting for the talk buf */
3688 size_t audio_get_filebuflen(void)
3690 return buf_length();
3693 /* How many tracks exist on the buffer - full or partial */
3694 int audio_track_count(void)
3695 __attribute__((alias("track_list_count")));
3697 /* Return total ringbuffer space occupied - ridx to widx */
3698 long audio_filebufused(void)
3700 return buf_used();
3704 /** -- Settings -- **/
3706 /* Enable or disable cuesheet support and allocate/don't allocate the
3707 extra associated resources */
3708 void audio_set_cuesheet(int enable)
3710 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3712 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3713 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3717 #ifdef HAVE_DISK_STORAGE
3718 /* Set the audio antiskip buffer margin by index */
3719 void audio_set_buffer_margin(int setting)
3721 static const unsigned short lookup[] =
3722 { 5, 15, 30, 60, 120, 180, 300, 600 };
3724 if ((unsigned)setting >= ARRAYLEN(lookup))
3725 setting = 0;
3727 logf("buffer margin: %u", (unsigned)lookup[setting]);
3729 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3730 (unsigned)lookup[setting]);
3731 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3733 #endif /* HAVE_DISK_STORAGE */
3735 #ifdef HAVE_CROSSFADE
3736 /* Take necessary steps to enable or disable the crossfade setting */
3737 void audio_set_crossfade(int enable)
3739 /* Tell it the next setting to use */
3740 pcmbuf_request_crossfade_enable(enable);
3742 /* Return if size hasn't changed or this is too early to determine
3743 which in the second case there's no way we could be playing
3744 anything at all */
3745 if (!pcmbuf_is_same_size())
3747 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3748 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3751 #endif /* HAVE_CROSSFADE */
3754 /** -- Startup -- **/
3756 /* Initialize the audio system - called from init() in main.c */
3757 void audio_init(void)
3759 /* Can never do this twice */
3760 if (audio_is_initialized)
3762 logf("audio: already initialized");
3763 return;
3766 logf("audio: initializing");
3768 /* Initialize queues before giving control elsewhere in case it likes
3769 to send messages. Thread creation will be delayed however so nothing
3770 starts running until ready if something yields such as talk_init. */
3771 queue_init(&audio_queue, true);
3773 mutex_init(&id3_mutex);
3775 pcm_init();
3777 codec_init_codec_api();
3779 make_codec_thread();
3781 /* This thread does buffer, so match its priority */
3782 audio_thread_id = create_thread(audio_thread, audio_stack,
3783 sizeof(audio_stack), CREATE_THREAD_FROZEN,
3784 audio_thread_name
3785 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3786 IF_COP(, CPU));
3788 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3789 audio_thread_id);
3791 #ifdef PLAYBACK_VOICE
3792 voice_thread_init();
3793 #endif
3795 /* audio_reset_buffer must know the size of voice buffer so init
3796 talk first */
3797 talk_init();
3799 #ifdef HAVE_CROSSFADE
3800 /* Set crossfade setting for next buffer init which should be about... */
3801 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3802 #endif
3804 /* Initialize the buffering system */
3805 track_list_init();
3806 buffering_init();
3807 /* ...now! Set up the buffers */
3808 audio_reset_buffer();
3810 /* Probably safe to say */
3811 audio_is_initialized = true;
3813 sound_settings_apply();
3814 #ifdef HAVE_DISK_STORAGE
3815 audio_set_buffer_margin(global_settings.buffer_margin);
3816 #endif
3818 /* It's safe to let the threads run now */
3819 #ifdef PLAYBACK_VOICE
3820 voice_thread_resume();
3821 #endif
3822 codec_thread_resume();
3823 thread_thaw(audio_thread_id);