Kill a few bugs on HWCODEC
[kugel-rb.git] / apps / playback.c
blob125f22601815eecd9449d5afa04364571470084f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005-2007 Miika Pekkarinen
11 * Copyright (C) 2007-2008 Nicolas Pennequin
12 * Copyright (C) 2011 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "panic.h"
27 #include "buffer.h"
28 #include "sound.h"
29 #include "ata.h"
30 #include "usb.h"
31 #include "codecs.h"
32 #include "codec_thread.h"
33 #include "voice_thread.h"
34 #include "metadata.h"
35 #include "cuesheet.h"
36 #include "buffering.h"
37 #include "talk.h"
38 #include "playlist.h"
39 #include "abrepeat.h"
40 #include "pcmbuf.h"
41 #include "playback.h"
42 #include "misc.h"
44 #ifdef HAVE_TAGCACHE
45 #include "tagcache.h"
46 #endif
48 #ifdef AUDIO_HAVE_RECORDING
49 #include "pcm_record.h"
50 #endif
52 #ifdef HAVE_LCD_BITMAP
53 #ifdef HAVE_ALBUMART
54 #include "albumart.h"
55 #endif
56 #endif
58 /* TODO: The audio thread really is doing multitasking of acting like a
59 consumer and producer of tracks. It may be advantageous to better
60 logically separate the two functions. I won't go that far just yet. */
62 /* Internal support for voice playback */
63 #define PLAYBACK_VOICE
65 #if CONFIG_PLATFORM & PLATFORM_NATIVE
66 /* Application builds don't support direct code loading */
67 #define HAVE_CODEC_BUFFERING
68 #endif
70 /* Amount of guess-space to allow for codecs that must hunt and peck
71 * for their correct seek target, 32k seems a good size */
72 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
74 /* Define LOGF_ENABLE to enable logf output in this file */
75 /* #define LOGF_ENABLE */
76 #include "logf.h"
78 /* Macros to enable logf for queues
79 logging on SYS_TIMEOUT can be disabled */
80 #ifdef SIMULATOR
81 /* Define this for logf output of all queuing except SYS_TIMEOUT */
82 #define PLAYBACK_LOGQUEUES
83 /* Define this to logf SYS_TIMEOUT messages */
84 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
85 #endif
87 #ifdef PLAYBACK_LOGQUEUES
88 #define LOGFQUEUE logf
89 #else
90 #define LOGFQUEUE(...)
91 #endif
93 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
94 #define LOGFQUEUE_SYS_TIMEOUT logf
95 #else
96 #define LOGFQUEUE_SYS_TIMEOUT(...)
97 #endif
99 /* Variables are commented with the threads that use them:
100 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
101 * read but not updated on that thread. Audio is the only user unless otherwise
102 * specified.
105 /** Miscellaneous **/
106 bool audio_is_initialized = false; /* (A,O-) */
107 extern struct codec_api ci; /* (A,C) */
109 /** Possible arrangements of the main buffer **/
110 static enum audio_buffer_state
112 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
113 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
114 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
115 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
117 /** Main state control **/
118 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
120 enum play_status
122 PLAY_STOPPED = 0,
123 PLAY_PLAYING = AUDIO_STATUS_PLAY,
124 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
125 } play_status = PLAY_STOPPED;
127 /* Sizeable things that only need exist during playback and not when stopped */
128 static struct audio_scratch_memory
130 struct mp3entry codec_id3; /* (A,C) */
131 struct mp3entry unbuffered_id3;
132 struct cuesheet *curr_cue; /* Will follow this structure */
133 } * audio_scratch_memory = NULL;
135 /* These are used to store the current, next and optionally the peek-ahead
136 * mp3entry's - this guarantees that the pointer returned by audio_current/
137 * next_track will be valid for the full duration of the currently playing
138 * track */
139 enum audio_id3_types
141 /* These are allocated statically */
142 PLAYING_ID3 = 0,
143 NEXTTRACK_ID3,
144 #ifdef AUDIO_FAST_SKIP_PREVIEW
145 /* The real playing metadata must has to be protected since it contains
146 critical info for other features */
147 PLAYING_PEEK_ID3,
148 #endif
149 ID3_TYPE_NUM_STATIC,
150 /* These go in the scratch memory */
151 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
152 CODEC_ID3,
154 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
156 /* Peeking functions can yield and mess us up */
157 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/
160 /** For Scrobbler support **/
162 /* Previous track elapsed time */
163 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
166 /** For album art support **/
167 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
168 #ifdef HAVE_ALBUMART
170 static struct albumart_slot
172 struct dim dim; /* Holds width, height of the albumart */
173 int used; /* Counter; increments if something uses it */
174 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
176 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
177 #endif /* HAVE_ALBUMART */
180 /** Information used for tracking buffer fills **/
182 /* Buffer and thread state tracking */
183 static enum filling_state
185 STATE_BOOT = 0, /* audio thread is not ready yet */
186 STATE_IDLE, /* audio is stopped: nothing to do */
187 STATE_FILLING, /* adding tracks to the buffer */
188 STATE_FULL, /* can't add any more tracks */
189 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
190 STATE_FINISHED, /* all remaining tracks are fully buffered */
191 STATE_ENDING, /* audio playback is ending */
192 STATE_ENDED, /* audio playback is done */
193 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
194 STATE_USB, /* USB mode, ignore most messages */
195 #endif
196 } filling = STATE_BOOT;
198 /* Track info - holds information about each track in the buffer */
199 struct track_info
201 /* In per-track allocated order: */
202 int id3_hid; /* Metadata handle ID */
203 int cuesheet_hid; /* Parsed cuesheet handle ID */
204 #ifdef HAVE_ALBUMART
205 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
206 #endif
207 #ifdef HAVE_CODEC_BUFFERING
208 int codec_hid; /* Buffered codec handle ID */
209 #endif
210 int audio_hid; /* Main audio data handle ID */
211 size_t filesize; /* File total length on disk
212 TODO: This should be stored
213 in the handle or the
214 id3 and would use less
215 ram */
218 /* Track list - holds info about all buffered tracks */
219 #if MEMORYSIZE >= 32
220 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
221 #elif MEMORYSIZE >= 16
222 #define TRACK_LIST_LEN 64
223 #elif MEMORYSIZE >= 8
224 #define TRACK_LIST_LEN 32
225 #else
226 #define TRACK_LIST_LEN 16
227 #endif
229 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
231 static struct
233 /* read, write and current are maintained unwrapped, limited only by the
234 unsigned int range and wrap-safe comparisons are used */
236 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
237 if 'end' follows 'start' in this structure, track_list_count performs
238 'start - end' rather than 'end - start', giving negative count values...
239 so leave it this way for now! */
240 unsigned int end; /* Next open position */
241 unsigned int start; /* First track in list */
242 unsigned int current; /* Currently decoding track */
243 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
244 } track_list; /* (A, O-) */
247 /* Playlist steps from playlist position to next track to be buffered */
248 static int playlist_peek_offset = 0;
250 /* Metadata handle of track load in progress (meaning all handles have not
251 yet been opened for the track, id3 always exists or the track does not)
253 Tracks are keyed by their metadata handles if track list pointers are
254 insufficient to make comparisons */
255 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
257 #ifdef HAVE_DISK_STORAGE
258 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
259 static size_t buffer_margin = 5;
260 #endif
262 /* Values returned for track loading */
263 enum track_load_status
265 LOAD_TRACK_ERR_START_CODEC = -6,
266 LOAD_TRACK_ERR_FINISH_FAILED = -5,
267 LOAD_TRACK_ERR_FINISH_FULL = -4,
268 LOAD_TRACK_ERR_BUSY = -3,
269 LOAD_TRACK_ERR_NO_MORE = -2,
270 LOAD_TRACK_ERR_FAILED = -1,
271 LOAD_TRACK_OK = 0,
272 LOAD_TRACK_READY = 1,
275 /** Track change controls **/
277 /* What sort of skip is pending globally? */
278 enum track_skip_type
280 /* Relative to what user is intended to see: */
281 /* Codec: +0, Track List: +0, Playlist: +0 */
282 TRACK_SKIP_NONE = 0, /* no track skip */
283 /* Codec: +1, Track List: +1, Playlist: +0 */
284 TRACK_SKIP_AUTO, /* codec-initiated skip */
285 /* Codec: +1, Track List: +1, Playlist: +1 */
286 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
287 /* Codec: xx, Track List: +0, Playlist: +0 */
288 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
289 /* Manual skip: Never pends */
290 TRACK_SKIP_MANUAL, /* manual track skip */
291 /* Manual skip: Never pends */
292 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
293 } skip_pending = TRACK_SKIP_NONE;
295 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
296 Fixing playlist code to be able to peek into the first song of
297 the next playlist would fix any issues and this wouldn't need
298 to be a special case since pre-advancing the playlist would be
299 unneeded - it could be much more like TRACK_SKIP_AUTO and all
300 actions that require reversal during an in-progress transition
301 would work as expected */
303 /* Used to indicate status for the events. Must be separate to satisfy all
304 clients so the correct metadata is read when sending the change events
305 and also so that it is read correctly outside the events. */
306 static bool automatic_skip = false; /* (A, O-) */
308 /* Pending manual track skip offset */
309 static int skip_offset = 0; /* (A, O) */
311 /* Track change notification */
312 static struct
314 unsigned int in; /* Number of pcmbuf posts (audio isr) */
315 unsigned int out; /* Number of times audio has read the difference */
316 } track_change = { 0, 0 };
318 /** Codec status **/
319 /* Did the codec notify us it finished while we were paused or while still
320 in an automatic transition?
322 If paused, it is necessary to defer a codec-initiated skip until resuming
323 or else the track will move forward while not playing audio!
325 If in-progress, skips should not build-up ahead of where the WPS is when
326 really short tracks finish decoding.
328 If it is forgotten, it will be missed altogether and playback will just sit
329 there looking stupid and comatose until the user does something */
330 static bool codec_skip_pending = false;
331 static int codec_skip_status;
332 static bool codec_seeking = false; /* Codec seeking ack expected? */
335 /* Event queues */
336 static struct event_queue audio_queue SHAREDBSS_ATTR;
338 /* Audio thread */
339 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
340 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
341 static const char audio_thread_name[] = "audio";
342 static unsigned int audio_thread_id = 0;
344 /* Forward declarations */
345 enum audio_start_playback_flags
347 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
348 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
351 static void audio_start_playback(size_t offset, unsigned int flags);
352 static void audio_stop_playback(void);
353 static void buffer_event_buffer_low_callback(void *data);
354 static void buffer_event_rebuffer_callback(void *data);
355 static void buffer_event_finished_callback(void *data);
358 /**************************************/
360 /** --- audio_queue helpers --- **/
362 /* codec thread needs access */
363 void audio_queue_post(long id, intptr_t data)
365 queue_post(&audio_queue, id, data);
368 static intptr_t audio_queue_send(long id, intptr_t data)
370 return queue_send(&audio_queue, id, data);
374 /** --- MP3Entry --- **/
376 /* Does the mp3entry have enough info for us to use it? */
377 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
379 return id3 && (id3->length != 0 || id3->filesize != 0) &&
380 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
383 /* Return a pointer to an mp3entry on the buffer, as it is */
384 static struct mp3entry * bufgetid3(int handle_id)
386 if (handle_id < 0)
387 return NULL;
389 struct mp3entry *id3;
390 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
392 if (ret != sizeof(struct mp3entry))
393 return NULL;
395 return id3;
398 /* Read an mp3entry from the buffer, adjusted */
399 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
401 struct mp3entry *id3 = bufgetid3(handle_id);
403 if (id3)
405 copy_mp3entry(id3out, id3);
406 return true;
409 return false;
412 /* Lock the id3 mutex */
413 static void id3_mutex_lock(void)
415 mutex_lock(&id3_mutex);
418 /* Unlock the id3 mutex */
419 static void id3_mutex_unlock(void)
421 mutex_unlock(&id3_mutex);
424 /* Return one of the collection of mp3entry pointers - collect them all here */
425 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
427 switch (id3_num)
429 case UNBUFFERED_ID3:
430 return &audio_scratch_memory->unbuffered_id3;
431 case CODEC_ID3:
432 return &audio_scratch_memory->codec_id3;
433 default:
434 return &static_id3_entries[id3_num];
438 /* Copy an mp3entry into one of the mp3 entries */
439 static void id3_write(enum audio_id3_types id3_num,
440 const struct mp3entry *id3_src)
442 struct mp3entry *dest_id3 = id3_get(id3_num);
444 if (id3_src)
445 copy_mp3entry(dest_id3, id3_src);
446 else
447 wipe_mp3entry(dest_id3);
450 /* Call id3_write "safely" because peek aheads can yield, even if the fast
451 preview isn't enabled */
452 static void id3_write_locked(enum audio_id3_types id3_num,
453 const struct mp3entry *id3_src)
455 id3_mutex_lock();
456 id3_write(id3_num, id3_src);
457 id3_mutex_unlock();
461 /** --- Track info --- **/
463 /* Close a handle and mark it invalid */
464 static void track_info_close_handle(int *hid_p)
466 int hid = *hid_p;
468 /* bufclose returns true if the handle is not found, or if it is closed
469 * successfully, so these checks are safe on non-existant handles */
470 if (hid >= 0)
471 bufclose(hid);
473 /* Always reset to "no handle" in case it was something else */
474 *hid_p = ERR_HANDLE_NOT_FOUND;
477 /* Close all handles in a struct track_info and clear it */
478 static void track_info_close(struct track_info *info)
480 /* Close them in the order they are allocated on the buffer to speed up
481 the handle searching */
482 track_info_close_handle(&info->id3_hid);
483 track_info_close_handle(&info->cuesheet_hid);
484 #ifdef HAVE_ALBUMART
485 int i;
486 FOREACH_ALBUMART(i)
487 track_info_close_handle(&info->aa_hid[i]);
488 #endif
489 #ifdef HAVE_CODEC_BUFFERING
490 track_info_close_handle(&info->codec_hid);
491 #endif
492 track_info_close_handle(&info->audio_hid);
493 info->filesize = 0;
496 /* Invalidate all members to initial values - does not close handles */
497 static void track_info_wipe(struct track_info * info)
499 info->id3_hid = ERR_HANDLE_NOT_FOUND;
500 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
501 #ifdef HAVE_ALBUMART
502 int i;
503 FOREACH_ALBUMART(i)
504 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
505 #endif
506 #ifdef HAVE_CODEC_BUFFERING
507 info->codec_hid = ERR_HANDLE_NOT_FOUND;
508 #endif
509 info->audio_hid = ERR_HANDLE_NOT_FOUND;
510 info->filesize = 0;
514 /** --- Track list --- **/
516 /* Initialize the track list */
517 static void track_list_init(void)
519 int i;
520 for (i = 0; i < TRACK_LIST_LEN; i++)
521 track_info_wipe(&track_list.tracks[i]);
523 track_list.start = track_list.end = track_list.current;
526 /* Return number of items allocated in the list */
527 static unsigned int track_list_count(void)
529 return track_list.end - track_list.start;
532 /* Return true if the list is empty */
533 static inline bool track_list_empty(void)
535 return track_list.end == track_list.start;
538 /* Returns true if the list is holding the maximum number of items */
539 static bool track_list_full(void)
541 return track_list.end - track_list.start >= TRACK_LIST_LEN;
544 /* Test if the index is within the allocated range */
545 static bool track_list_in_range(int pos)
547 return (int)(pos - track_list.start) >= 0 &&
548 (int)(pos - track_list.end) < 0;
551 static struct track_info * track_list_entry(int pos)
553 return &track_list.tracks[pos & TRACK_LIST_MASK];
556 /* Return the info of the last allocation plus an offset, NULL if result is
557 out of bounds */
558 static struct track_info * track_list_last(int offset)
560 /* Last is before the end since the end isn't inclusive */
561 unsigned int pos = track_list.end + offset - 1;
563 if (!track_list_in_range(pos))
564 return NULL;
566 return track_list_entry(pos);
569 /* Allocate space at the end for another track if not full */
570 static struct track_info * track_list_alloc_track(void)
572 if (track_list_full())
573 return NULL;
575 return track_list_entry(track_list.end++);
578 /* Remove the last track entry allocated in order to support backing out
579 of a track load */
580 static void track_list_unalloc_track(void)
582 if (track_list_empty())
583 return;
585 track_list.end--;
587 if (track_list.current == track_list.end &&
588 track_list.current != track_list.start)
590 /* Current _must_ remain within bounds */
591 track_list.current--;
595 /* Return current track plus an offset, NULL if result is out of bounds */
596 static struct track_info * track_list_current(int offset)
598 unsigned int pos = track_list.current + offset;
600 if (!track_list_in_range(pos))
601 return NULL;
603 return track_list_entry(pos);
606 /* Return current based upon what's intended that the user sees - not
607 necessarily where decoding is taking place */
608 static struct track_info * track_list_user_current(int offset)
610 if (skip_pending == TRACK_SKIP_AUTO ||
611 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
613 offset--;
616 return track_list_current(offset);
619 /* Advance current track by an offset, return false if result is out of
620 bounds */
621 static struct track_info * track_list_advance_current(int offset)
623 unsigned int pos = track_list.current + offset;
625 if (!track_list_in_range(pos))
626 return NULL;
628 track_list.current = pos;
629 return track_list_entry(pos);
632 /* Clear tracks in the list, optionally preserving the current track -
633 returns 'false' if the operation was changed */
634 enum track_clear_action
636 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
637 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
638 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
641 static void track_list_clear(enum track_clear_action action)
643 logf("%s(%d)", __func__, (int)action);
645 /* Don't care now since rebuffering is imminent */
646 buf_set_watermark(0);
648 if (action != TRACK_LIST_CLEAR_ALL)
650 struct track_info *cur = track_list_current(0);
652 if (!cur || cur->id3_hid < 0)
653 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
656 /* Noone should see this progressing */
657 int start = track_list.start;
658 int current = track_list.current;
659 int end = track_list.end;
661 track_list.start = current;
663 switch (action)
665 case TRACK_LIST_CLEAR_ALL:
666 /* Result: .start = .current, .end = .current */
667 track_list.end = current;
668 break;
670 case TRACK_LIST_KEEP_CURRENT:
671 /* Result: .start = .current, .end = .current + 1 */
672 track_list.end = current + 1;
673 break;
675 case TRACK_LIST_KEEP_NEW:
676 /* Result: .start = .current, .end = .end */
677 end = current;
678 break;
681 /* Close all open handles in the range except the for the current track
682 if preserving that */
683 while (start != end)
685 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
687 struct track_info *info =
688 &track_list.tracks[start & TRACK_LIST_MASK];
690 /* If this is the in-progress load, abort it */
691 if (in_progress_id3_hid >= 0 &&
692 info->id3_hid == in_progress_id3_hid)
694 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
697 track_info_close(info);
700 start++;
705 /** --- Audio buffer -- **/
707 /* What size is needed for the scratch buffer? */
708 static size_t scratch_mem_size(void)
710 size_t size = sizeof (struct audio_scratch_memory);
712 if (global_settings.cuesheet)
713 size += sizeof (struct cuesheet);
715 return size;
718 /* Initialize the memory area where data is stored that is only used when
719 playing audio and anything depending upon it */
720 static void scratch_mem_init(void *mem)
722 audio_scratch_memory = (struct audio_scratch_memory *)mem;
723 id3_write_locked(UNBUFFERED_ID3, NULL);
724 id3_write(CODEC_ID3, NULL);
725 ci.id3 = id3_get(CODEC_ID3);
726 audio_scratch_memory->curr_cue = NULL;
728 if (global_settings.cuesheet)
730 audio_scratch_memory->curr_cue =
731 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
732 sizeof (struct audio_scratch_memory));
736 /* Set up the audio buffer for playback */
737 static void audio_reset_buffer(void)
740 * Layout audio buffer as follows:
741 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
744 /* see audio_get_recording_buffer if this is modified */
745 logf("%s()", __func__);
747 /* release the buffer on behalf of any caller of audio_get_buffer() */
748 buffer_release_buffer(0);
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 unsigned char *filebuf = buffer_get_buffer(&filebuflen);
758 /* Subtract whatever voice needs */
759 allocsize = talkbuf_init(filebuf);
760 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
761 if (allocsize > filebuflen)
762 goto bufpanic;
764 filebuf += allocsize;
765 filebuflen -= allocsize;
767 if (talk_voice_required())
769 /* Need a space for voice PCM output */
770 allocsize = voicebuf_init(filebuf + filebuflen);
772 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
773 if (allocsize > filebuflen)
774 goto bufpanic;
776 filebuflen -= allocsize;
779 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
780 allocsize = pcmbuf_init(filebuf + filebuflen);
782 /* Make sure filebuflen is a pointer sized multiple after adjustment */
783 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
784 if (allocsize > filebuflen)
785 goto bufpanic;
787 filebuflen -= allocsize;
789 /* Scratch memory */
790 allocsize = scratch_mem_size();
791 if (allocsize > filebuflen)
792 goto bufpanic;
794 scratch_mem_init(filebuf);
795 filebuf += allocsize;
796 filebuflen -= allocsize;
798 buffering_reset(filebuf, filebuflen);
800 /* Clear any references to the file buffer */
801 buffer_state = AUDIOBUF_STATE_INITIALIZED;
803 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
804 /* Make sure everything adds up - yes, some info is a bit redundant but
805 aids viewing and the summation of certain variables should add up to
806 the location of others. */
808 size_t pcmbufsize;
809 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
810 logf("fbuf: %08X", (unsigned)filebuf);
811 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
812 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
813 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
814 logf("pcmb: %08X", (unsigned)pcmbuf);
815 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
817 #endif
819 return;
821 bufpanic:
822 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
825 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
826 static void audio_update_filebuf_watermark(int seconds)
828 size_t bytes = 0;
830 #ifdef HAVE_DISK_STORAGE
831 int spinup = ata_spinup_time();
833 if (seconds == 0)
835 /* By current setting */
836 seconds = buffer_margin;
838 else
840 /* New setting */
841 buffer_margin = seconds;
843 if (buf_get_watermark() == 0)
845 /* Write a watermark only if the audio thread already did so for
846 itself or it will fail to set the event and the watermark - if
847 it hasn't yet, it will use the new setting when it does */
848 return;
852 if (spinup)
853 seconds += (spinup / HZ) + 1;
854 else
855 seconds += 5;
857 seconds += buffer_margin;
858 #else
859 /* flash storage */
860 seconds = 1;
861 #endif
863 /* Watermark is a function of the bitrate of the last track in the buffer */
864 struct mp3entry *id3 = NULL;
865 struct track_info *info = track_list_last(0);
867 if (info)
868 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
870 if (id3)
872 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
874 bytes = id3->bitrate * (1000/8) * seconds;
876 else
878 /* Bitrate has no meaning to buffering margin for atomic audio -
879 rebuffer when it's the only track left unless it's the only
880 track that fits, in which case we should avoid constant buffer
881 low events */
882 if (track_list_count() > 1)
883 bytes = info->filesize + 1;
886 else
888 /* Then set the minimum - this should not occur anyway */
889 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
890 track_list.start, track_list.current, track_list.end);
893 /* Actually setting zero disables the notification and we use that
894 to detect that it has been reset */
895 buf_set_watermark(MAX(bytes, 1));
896 logf("fwmark: %lu", (unsigned long)bytes);
900 /** -- Track change notification -- **/
902 /* Check the pcmbuf track changes and return write the message into the event
903 if there are any */
904 static inline bool audio_pcmbuf_track_change_scan(void)
906 if (track_change.out != track_change.in)
908 track_change.out++;
909 return true;
912 return false;
915 /* Clear outstanding track change posts */
916 static inline void audio_pcmbuf_track_change_clear(void)
918 track_change.out = track_change.in;
921 /* Post a track change notification - called by audio ISR */
922 static inline void audio_pcmbuf_track_change_post(void)
924 track_change.in++;
928 /** --- Helper functions --- **/
930 /* Removes messages that might end up in the queue before or while processing
931 a manual track change. Responding to them would be harmful since they
932 belong to a previous track's playback period. Anything that would generate
933 the stale messages must first be put into a state where it will not do so.
935 static void audio_clear_track_notifications(void)
937 static const long filter_list[][2] =
939 /* codec messages */
940 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
941 /* track change messages */
942 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
945 const int filter_count = ARRAYLEN(filter_list) - 1;
947 /* Remove any pcmbuf notifications */
948 pcmbuf_monitor_track_change(false);
949 audio_pcmbuf_track_change_clear();
951 /* Scrub the audio queue of the old mold */
952 while (queue_peek_ex(&audio_queue, NULL,
953 filter_count | QPEEK_REMOVE_EVENTS,
954 filter_list))
956 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
960 /* Takes actions based upon track load status codes */
961 static void audio_handle_track_load_status(int trackstat)
963 switch (trackstat)
965 case LOAD_TRACK_ERR_NO_MORE:
966 if (track_list_count() > 0)
967 break;
969 case LOAD_TRACK_ERR_START_CODEC:
970 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
971 break;
973 default:
974 break;
978 /* Announce the end of playing the current track */
979 static void audio_playlist_track_finish(void)
981 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
983 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
985 if (id3)
987 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
988 prev_track_elapsed = id3->elapsed;
990 else
992 prev_track_elapsed = 0;
996 /* Announce the beginning of the new track */
997 static void audio_playlist_track_change(void)
999 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
1001 if (id3)
1002 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
1004 playlist_update_resume_info(id3);
1007 /* Change the data for the next track and send the event */
1008 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1010 id3_write_locked(NEXTTRACK_ID3, id3_next);
1011 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1012 id3_get(NEXTTRACK_ID3));
1015 /* Bring the user current mp3entry up to date and set a new offset for the
1016 buffered metadata */
1017 static void playing_id3_sync(struct track_info *user_info, size_t offset)
1019 id3_mutex_lock();
1021 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1023 if (offset == (size_t)-1)
1025 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1026 size_t play_offset = ply_id3->offset;
1027 long play_elapsed = ply_id3->elapsed;
1028 id3_write(PLAYING_ID3, id3);
1029 ply_id3->offset = play_offset;
1030 ply_id3->elapsed = play_elapsed;
1031 offset = 0;
1033 else
1035 id3_write(PLAYING_ID3, id3);
1038 if (id3)
1039 id3->offset = offset;
1041 id3_mutex_unlock();
1044 /* Wipe-out track metadata - current is optional */
1045 static void wipe_track_metadata(bool current)
1047 id3_mutex_lock();
1049 if (current)
1050 id3_write(PLAYING_ID3, NULL);
1052 id3_write(NEXTTRACK_ID3, NULL);
1053 id3_write(UNBUFFERED_ID3, NULL);
1055 id3_mutex_unlock();
1058 /* Called when buffering is completed on the last track handle */
1059 static void filling_is_finished(void)
1061 logf("last track finished buffering");
1063 /* There's no more to load or watch for */
1064 buf_set_watermark(0);
1065 filling = STATE_FINISHED;
1068 /* Stop the codec decoding or waiting for its data to be ready - returns
1069 'false' if the codec ended up stopped */
1070 static bool halt_decoding_track(bool stop)
1072 /* If it was waiting for us to clear the buffer to make a rebuffer
1073 happen, it should cease otherwise codec_stop could deadlock waiting
1074 for the codec to go to its main loop - codec's request will now
1075 force-fail */
1076 bool retval = false;
1078 buf_signal_handle(ci.audio_hid, true);
1080 if (stop)
1081 codec_stop();
1082 else
1083 retval = codec_pause();
1085 audio_clear_track_notifications();
1087 /* We now know it's idle and not waiting for buffered data */
1088 buf_signal_handle(ci.audio_hid, false);
1090 codec_skip_pending = false;
1091 codec_seeking = false;
1093 return retval;
1096 /* Clear the PCM on a manual skip */
1097 static void audio_clear_paused_pcm(void)
1099 if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active())
1100 pcmbuf_play_stop();
1103 /* End the ff/rw mode */
1104 static void audio_ff_rewind_end(void)
1106 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1107 section */
1108 if (ff_rw_mode)
1110 ff_rw_mode = false;
1112 if (codec_seeking)
1114 /* Clear the buffer */
1115 pcmbuf_play_stop();
1118 if (play_status != PLAY_PAUSED)
1120 /* Seeking-while-playing, resume PCM playback */
1121 pcmbuf_pause(false);
1126 /* Complete the codec seek */
1127 static void audio_complete_codec_seek(void)
1129 /* If a seek completed while paused, 'paused' is true.
1130 * If seeking from seek mode, 'ff_rw_mode' is true. */
1131 if (codec_seeking)
1133 audio_ff_rewind_end();
1134 codec_seeking = false; /* set _after_ the call! */
1136 /* else it's waiting and we must repond */
1139 /* Get the current cuesheet pointer */
1140 static inline struct cuesheet * get_current_cuesheet(void)
1142 return audio_scratch_memory->curr_cue;
1145 /* Read the cuesheet from the buffer */
1146 static void buf_read_cuesheet(int handle_id)
1148 struct cuesheet *cue = get_current_cuesheet();
1150 if (!cue || handle_id < 0)
1151 return;
1153 bufread(handle_id, sizeof (struct cuesheet), cue);
1156 /* Backend to peek/current/next track metadata interface functions -
1157 fill in the mp3entry with as much information as we may obtain about
1158 the track at the specified offset from the user current track -
1159 returns false if no information exists with us */
1160 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1162 if (play_status == PLAY_STOPPED)
1163 return false;
1165 if (id3->path[0] != '\0')
1166 return true; /* Already filled */
1168 struct track_info *info = track_list_user_current(offset);
1170 if (!info)
1172 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1174 if (offset > 0 && track_list_user_current(offset - 1))
1176 /* Try the unbuffered id3 since we're moving forward */
1177 if (ub_id3->path[0] != '\0')
1179 copy_mp3entry(id3, ub_id3);
1180 return true;
1184 else if (bufreadid3(info->id3_hid, id3))
1186 return true;
1189 /* We didn't find the ID3 metadata, so we fill it with the little info we
1190 have and return that */
1192 char path[MAX_PATH+1];
1193 if (playlist_peek(offset, path, sizeof (path)))
1195 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1196 /* Try to get it from the database */
1197 if (!tagcache_fill_tags(id3, path))
1198 #endif
1200 /* By now, filename is the only source of info */
1201 fill_metadata_from_path(id3, path);
1204 return true;
1207 wipe_mp3entry(id3);
1209 return false;
1212 /* Get a resume rewind adjusted offset from the ID3 */
1213 unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1215 unsigned long offset = id3->offset;
1216 size_t resume_rewind = global_settings.resume_rewind *
1217 id3->bitrate * (1000/8);
1219 if (offset < resume_rewind)
1220 offset = 0;
1221 else
1222 offset -= resume_rewind;
1224 return offset;
1227 /* Get the codec into ram and initialize it - keep it if it's ready */
1228 static bool audio_init_codec(struct track_info *track_info,
1229 struct mp3entry *track_id3)
1231 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1232 int hid = ERR_HANDLE_NOT_FOUND;
1234 if (codt_loaded != AFMT_UNKNOWN)
1236 int codt = get_audio_base_codec_type(track_id3->codectype);
1238 if (codt == codt_loaded)
1240 /* Codec is the same base type */
1241 logf("Reusing prev. codec: %d", track_id3->codectype);
1242 #ifdef HAVE_CODEC_BUFFERING
1243 /* Close any buffered codec (we could have skipped directly to a
1244 format transistion that is the same format as the current track
1245 and the buffered one is no longer needed) */
1246 track_info_close_handle(&track_info->codec_hid);
1247 #endif
1248 return true;
1250 else
1252 /* New codec - first make sure the old one's gone */
1253 logf("Removing prev. codec: %d", codt_loaded);
1254 codec_unload();
1258 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1260 #ifdef HAVE_CODEC_BUFFERING
1261 /* Codec thread will close the handle even if it fails and will load from
1262 storage if hid is not valid or the buffer load fails */
1263 hid = track_info->codec_hid;
1264 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1265 #endif
1267 return codec_load(hid, track_id3->codectype);
1268 (void)track_info; /* When codec buffering isn't supported */
1271 /* Start the codec for the current track scheduled to be decoded */
1272 static bool audio_start_codec(bool auto_skip)
1274 struct track_info *info = track_list_current(0);
1275 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1277 if (!cur_id3)
1278 return false;
1280 buf_pin_handle(info->id3_hid, true);
1282 if (!audio_init_codec(info, cur_id3))
1284 buf_pin_handle(info->id3_hid, false);
1285 return false;
1288 #ifdef HAVE_TAGCACHE
1289 bool autoresume_enable = global_settings.autoresume_enable;
1291 if (autoresume_enable && !cur_id3->offset)
1293 /* Resume all manually selected tracks */
1294 bool resume = !auto_skip;
1296 /* Send the "buffer" event to obtain the resume position for the codec */
1297 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1299 if (!resume)
1301 /* Automatic skip - do further tests to see if we should just
1302 ignore any autoresume position */
1303 int autoresume_automatic = global_settings.autoresume_automatic;
1305 switch (autoresume_automatic)
1307 case AUTORESUME_NEXTTRACK_ALWAYS:
1308 /* Just resume unconditionally */
1309 resume = true;
1310 break;
1311 case AUTORESUME_NEXTTRACK_NEVER:
1312 /* Force-rewind it */
1313 break;
1314 default:
1315 /* Not "never resume" - pass resume filter? */
1316 resume = autoresumable(cur_id3);
1320 if (!resume)
1321 cur_id3->offset = 0;
1323 logf("%s: Set offset for %s to %lX\n", __func__,
1324 cur_id3->title, cur_id3->offset);
1326 #endif /* HAVE_TAGCACHE */
1328 /* Rewind the required amount - if an autoresume was done, this also rewinds
1329 that by the setting's amount
1331 It would be best to have bookkeeping about whether or not the track
1332 sounded or not since skipping to it or else skipping to it while paused
1333 and back again will cause accumulation of silent rewinds - that's not
1334 our job to track directly nor could it be in any reasonable way
1336 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1338 /* Update the codec API with the metadata and track info */
1339 id3_write(CODEC_ID3, cur_id3);
1341 ci.audio_hid = info->audio_hid;
1342 ci.filesize = info->filesize;
1343 buf_set_base_handle(info->audio_hid);
1345 /* All required data is now available for the codec */
1346 codec_go();
1348 #ifdef HAVE_TAGCACHE
1349 if (!autoresume_enable || cur_id3->offset)
1350 #endif
1352 /* Send the "buffer" event now */
1353 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1356 buf_pin_handle(info->id3_hid, false);
1357 return true;
1359 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1363 /** --- Audio thread --- **/
1365 /* Load and parse a cuesheet for the file - returns false if the buffer
1366 is full */
1367 static bool audio_load_cuesheet(struct track_info *info,
1368 struct mp3entry *track_id3)
1370 struct cuesheet *cue = get_current_cuesheet();
1371 track_id3->cuesheet = NULL;
1373 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1375 /* If error other than a full buffer, then mark it "unsupported" to
1376 avoid reloading attempt */
1377 int hid = ERR_UNSUPPORTED_TYPE;
1378 char cuepath[MAX_PATH];
1380 #ifdef HAVE_IO_PRIORITY
1381 buf_back_off_storage(true);
1382 #endif
1383 if (look_for_cuesheet_file(track_id3->path, cuepath))
1385 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1387 if (hid >= 0)
1389 void *cuesheet = NULL;
1390 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1392 if (parse_cuesheet(cuepath, (struct cuesheet *)cuesheet))
1394 /* Indicate cuesheet is present (while track remains
1395 buffered) */
1396 track_id3->cuesheet = cue;
1398 else
1400 bufclose(hid);
1401 hid = ERR_UNSUPPORTED_TYPE;
1406 #ifdef HAVE_IO_PRIORITY
1407 buf_back_off_storage(false);
1408 #endif
1409 if (hid == ERR_BUFFER_FULL)
1411 logf("buffer is full for now (%s)", __func__);
1412 return false;
1414 else
1416 if (hid < 0)
1417 logf("Cuesheet loading failed");
1419 info->cuesheet_hid = hid;
1423 return true;
1426 #ifdef HAVE_ALBUMART
1427 /* Load any album art for the file - returns false if the buffer is full */
1428 static bool audio_load_albumart(struct track_info *info,
1429 struct mp3entry *track_id3)
1431 int i;
1432 FOREACH_ALBUMART(i)
1434 struct bufopen_bitmap_data user_data;
1435 int *aa_hid = &info->aa_hid[i];
1436 int hid = ERR_UNSUPPORTED_TYPE;
1438 /* albumart_slots may change during a yield of bufopen,
1439 * but that's no problem */
1440 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1441 !albumart_slots[i].used)
1442 continue;
1444 memset(&user_data, 0, sizeof(user_data));
1445 user_data.dim = &albumart_slots[i].dim;
1447 #ifdef HAVE_IO_PRIORITY
1448 buf_back_off_storage(true);
1449 #endif
1451 /* We can only decode jpeg for embedded AA */
1452 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1454 user_data.embedded_albumart = &track_id3->albumart;
1455 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1458 if (hid < 0 && hid != ERR_BUFFER_FULL)
1460 /* No embedded AA or it couldn't be loaded - try other sources */
1461 char path[MAX_PATH];
1463 if (find_albumart(track_id3, path, sizeof(path),
1464 &albumart_slots[i].dim))
1466 user_data.embedded_albumart = NULL;
1467 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1471 #ifdef HAVE_IO_PRIORITY
1472 buf_back_off_storage(false);
1473 #endif
1474 if (hid == ERR_BUFFER_FULL)
1476 logf("buffer is full for now (%s)", __func__);
1477 return false;
1479 else
1481 /* If error other than a full buffer, then mark it "unsupported"
1482 to avoid reloading attempt */
1483 if (hid < 0)
1485 logf("Album art loading failed");
1486 hid = ERR_UNSUPPORTED_TYPE;
1489 *aa_hid = hid;
1493 return true;
1495 #endif /* HAVE_ALBUMART */
1497 #ifdef HAVE_CODEC_BUFFERING
1498 /* Load a codec for the file onto the buffer - assumes we're working from the
1499 currently loading track - not called for the current track */
1500 static bool audio_buffer_codec(struct track_info *track_info,
1501 struct mp3entry *track_id3)
1503 /* This will not be the current track -> it cannot be the first and the
1504 current track cannot be ahead of buffering -> there is a previous
1505 track entry which is either current or ahead of the current */
1506 struct track_info *prev_info = track_list_last(-1);
1507 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1509 /* If the previous codec is the same as this one, there is no need to
1510 put another copy of it on the file buffer (in other words, only
1511 buffer codecs at format transitions) */
1512 if (prev_id3)
1514 int codt = get_audio_base_codec_type(track_id3->codectype);
1515 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1517 if (codt == prev_codt)
1519 logf("Reusing prev. codec: %d", prev_id3->codectype);
1520 return true;
1523 /* else just load it (harmless) */
1525 /* Load the codec onto the buffer if possible */
1526 const char *codec_fn = get_codec_filename(track_id3->codectype);
1527 if (!codec_fn)
1528 return false;
1530 char codec_path[MAX_PATH+1]; /* Full path to codec */
1531 codec_get_full_path(codec_path, codec_fn);
1533 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1535 if (track_info->codec_hid >= 0)
1537 logf("Buffered codec: %d", afmt);
1538 return true;
1541 return false;
1543 #endif /* HAVE_CODEC_BUFFERING */
1545 /* Load metadata for the next track (with bufopen). The rest of the track
1546 loading will be handled by audio_finish_load_track once the metadata has
1547 been actually loaded by the buffering thread.
1549 Each track is arranged in the buffer as follows:
1550 <id3|[cuesheet|][album art|][codec|]audio>
1552 The next will not be loaded until the previous succeeds if the buffer was
1553 full at the time. To put any metadata after audio would make those handles
1554 unmovable.
1556 static int audio_load_track(void)
1558 if (in_progress_id3_hid >= 0)
1560 /* There must be an info pointer if the in-progress id3 is even there */
1561 struct track_info *info = track_list_last(0);
1563 if (info->id3_hid == in_progress_id3_hid)
1565 if (filling == STATE_FILLING)
1567 /* Haven't finished the metadata but the notification is
1568 anticipated to come soon */
1569 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1570 return LOAD_TRACK_OK;
1572 else if (filling == STATE_FULL)
1574 /* Buffer was full trying to complete the load after the
1575 metadata finished, so attempt to continue - older handles
1576 should have been cleared already */
1577 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1578 filling = STATE_FILLING;
1579 buffer_event_finished_callback(&info->id3_hid);
1580 return LOAD_TRACK_OK;
1584 /* Some old, stray buffering message */
1585 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1586 return LOAD_TRACK_ERR_BUSY;
1589 filling = STATE_FILLING;
1591 struct track_info *info = track_list_alloc_track();
1592 if (info == NULL)
1594 /* List is full so stop buffering tracks - however, attempt to obtain
1595 metadata as the unbuffered id3 */
1596 logf("No free tracks");
1597 filling = STATE_FULL;
1600 playlist_peek_offset++;
1602 logf("Buffering track: s%u/c%u/e%u/p%d",
1603 track_list.start, track_list.current, track_list.end,
1604 playlist_peek_offset);
1606 /* Get track name from current playlist read position */
1607 int fd = -1;
1608 char name_buf[MAX_PATH + 1];
1609 const char *trackname;
1611 while (1)
1614 trackname = playlist_peek(playlist_peek_offset, name_buf,
1615 sizeof (name_buf));
1617 if (!trackname)
1618 break;
1620 /* Test for broken playlists by probing for the files */
1621 fd = open(trackname, O_RDONLY);
1622 if (fd >= 0)
1623 break;
1625 logf("Open failed");
1626 /* Skip invalid entry from playlist */
1627 playlist_skip_entry(NULL, playlist_peek_offset);
1629 /* Sync the playlist if it isn't finished */
1630 if (playlist_peek(playlist_peek_offset, NULL, 0))
1631 playlist_next(0);
1634 if (!trackname)
1636 /* No track - exhausted the playlist entries */
1637 logf("End-of-playlist");
1638 id3_write_locked(UNBUFFERED_ID3, NULL);
1640 if (filling != STATE_FULL)
1641 track_list_unalloc_track(); /* Free this entry */
1643 playlist_peek_offset--; /* Maintain at last index */
1645 /* We can end up here after the real last track signals its completion
1646 and miss the transition to STATE_FINISHED esp. if dropping the last
1647 songs of a playlist late in their load (2nd stage) */
1648 info = track_list_last(0);
1650 if (info && buf_handle_remaining(info->audio_hid) == 0)
1651 filling_is_finished();
1652 else
1653 filling = STATE_END_OF_PLAYLIST;
1655 return LOAD_TRACK_ERR_NO_MORE;
1658 /* Successfully opened the file - get track metadata */
1659 if (filling == STATE_FULL ||
1660 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1662 /* Buffer or track list is full */
1663 struct mp3entry *ub_id3;
1665 playlist_peek_offset--;
1667 /* Load the metadata for the first unbuffered track */
1668 ub_id3 = id3_get(UNBUFFERED_ID3);
1669 id3_mutex_lock();
1670 get_metadata(ub_id3, fd, trackname);
1671 id3_mutex_unlock();
1673 if (filling != STATE_FULL)
1675 track_list_unalloc_track();
1676 filling = STATE_FULL;
1679 logf("%s: buffer is full for now (%u tracks)", __func__,
1680 track_list_count());
1682 else
1684 /* Successful load initiation */
1685 info->filesize = filesize(fd);
1686 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1689 close(fd);
1690 return LOAD_TRACK_OK;
1693 /* Second part of the track loading: We now have the metadata available, so we
1694 can load the codec, the album art and finally the audio data.
1695 This is called on the audio thread after the buffering thread calls the
1696 buffering_handle_finished_callback callback. */
1697 static int audio_finish_load_track(struct track_info *info)
1699 int trackstat = LOAD_TRACK_OK;
1701 if (info->id3_hid != in_progress_id3_hid)
1703 /* We must not be here if not! */
1704 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1705 in_progress_id3_hid);
1706 return LOAD_TRACK_ERR_BUSY;
1709 /* The current track for decoding (there is always one if the list is
1710 populated) */
1711 struct track_info *cur_info = track_list_current(0);
1712 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1714 if (!track_id3)
1716 /* This is an error condition. Track cannot be played without valid
1717 metadata; skip the track. */
1718 logf("No metadata for: %s", track_id3->path);
1719 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1720 goto audio_finish_load_track_exit;
1723 /* Try to load a cuesheet for the track */
1724 if (!audio_load_cuesheet(info, track_id3))
1726 /* No space for cuesheet on buffer, not an error */
1727 filling = STATE_FULL;
1728 goto audio_finish_load_track_exit;
1731 #ifdef HAVE_ALBUMART
1732 /* Try to load album art for the track */
1733 if (!audio_load_albumart(info, track_id3))
1735 /* No space for album art on buffer, not an error */
1736 filling = STATE_FULL;
1737 goto audio_finish_load_track_exit;
1739 #endif
1741 /* All handles available to external routines are ready - audio and codec
1742 information is private */
1744 if (info == track_list_user_current(0))
1746 /* Send only when the track handles could not all be opened ahead of
1747 time for the user's current track - otherwise everything is ready
1748 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1749 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1752 #ifdef HAVE_CODEC_BUFFERING
1753 /* Try to buffer a codec for the track */
1754 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1756 if (info->codec_hid == ERR_BUFFER_FULL)
1758 /* No space for codec on buffer, not an error */
1759 filling = STATE_FULL;
1760 logf("buffer is full for now (%s)", __func__);
1762 else
1764 /* This is an error condition, either no codec was found, or
1765 reading the codec file failed part way through, either way,
1766 skip the track */
1767 logf("No codec for: %s", track_id3->path);
1768 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1771 goto audio_finish_load_track_exit;
1773 #endif /* HAVE_CODEC_BUFFERING */
1775 /** Finally, load the audio **/
1776 size_t file_offset = 0;
1777 track_id3->elapsed = 0;
1779 if (track_id3->offset >= info->filesize)
1780 track_id3->offset = 0;
1782 logf("%s: set offset for %s to %lu\n", __func__,
1783 id3->title, (unsigned long)offset);
1785 /* Adjust for resume rewind so we know what to buffer - starting the codec
1786 calls it again, so we don't save it (and they shouldn't accumulate) */
1787 size_t offset = resume_rewind_adjusted_offset(track_id3);
1789 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1791 if (audiotype == TYPE_ATOMIC_AUDIO)
1792 logf("Loading atomic %d", track_id3->codectype);
1794 if (format_buffers_with_offset(track_id3->codectype))
1796 /* This format can begin buffering from any point */
1797 file_offset = offset;
1800 logf("load track: %s", track_id3->path);
1802 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1804 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1805 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1807 else
1809 /* No offset given or it is very minimal - begin at the first frame
1810 according to the metadata */
1811 file_offset = track_id3->first_frame_offset;
1814 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1816 if (hid >= 0)
1818 info->audio_hid = hid;
1820 if (info == cur_info)
1822 /* This is the current track to decode - should be started now */
1823 trackstat = LOAD_TRACK_READY;
1826 else
1828 /* Buffer could be full but not properly so if this is the only
1829 track! */
1830 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1832 filling = STATE_FULL;
1833 logf("Buffer is full for now (%s)", __func__);
1835 else
1837 /* Nothing to play if no audio handle - skip this */
1838 logf("Could not add audio data handle");
1839 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1843 audio_finish_load_track_exit:
1844 if (trackstat < LOAD_TRACK_OK)
1846 playlist_skip_entry(NULL, playlist_peek_offset);
1847 track_info_close(info);
1848 track_list_unalloc_track();
1850 if (playlist_peek(playlist_peek_offset, NULL, 0))
1851 playlist_next(0);
1853 playlist_peek_offset--;
1856 if (filling != STATE_FULL)
1858 /* Load next track - error or not */
1859 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1860 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1861 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1863 else
1865 /* Full */
1866 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1869 return trackstat;
1872 /* Start a new track load */
1873 static int audio_fill_file_buffer(void)
1875 if (play_status == PLAY_STOPPED)
1876 return LOAD_TRACK_ERR_FAILED;
1878 trigger_cpu_boost();
1880 /* Must reset the buffer before use if trashed or voice only - voice
1881 file size shouldn't have changed so we can go straight from
1882 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1883 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1884 audio_reset_buffer();
1886 logf("Starting buffer fill");
1888 int trackstat = audio_load_track();
1890 if (trackstat >= LOAD_TRACK_OK)
1892 if (track_list_current(0) == track_list_user_current(0))
1893 playlist_next(0);
1895 if (filling == STATE_FULL && !track_list_user_current(1))
1897 /* There are no user tracks on the buffer after this therefore
1898 this is the next track */
1899 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
1903 return trackstat;
1906 /* Discard unwanted tracks and start refill from after the specified playlist
1907 offset */
1908 static int audio_reset_and_rebuffer(
1909 enum track_clear_action action, int peek_offset)
1911 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
1913 id3_write_locked(UNBUFFERED_ID3, NULL);
1915 /* Remove unwanted tracks - caller must have ensured codec isn't using
1916 any */
1917 track_list_clear(action);
1919 /* Refill at specified position (-1 starts at index offset 0) */
1920 playlist_peek_offset = peek_offset;
1922 /* Fill the buffer */
1923 return audio_fill_file_buffer();
1926 /* Handle buffering events
1927 (Q_AUDIO_BUFFERING) */
1928 static void audio_on_buffering(int event)
1930 enum track_clear_action action;
1931 int peek_offset;
1933 if (track_list_empty())
1934 return;
1936 switch (event)
1938 case BUFFER_EVENT_BUFFER_LOW:
1939 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
1940 return; /* Should be nothing left to fill */
1942 /* Clear old tracks and continue buffering where it left off */
1943 action = TRACK_LIST_KEEP_NEW;
1944 peek_offset = playlist_peek_offset;
1945 break;
1947 case BUFFER_EVENT_REBUFFER:
1948 /* Remove all but the currently decoding track and redo buffering
1949 after that */
1950 action = TRACK_LIST_KEEP_CURRENT;
1951 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
1952 break;
1954 default:
1955 return;
1958 switch (skip_pending)
1960 case TRACK_SKIP_NONE:
1961 case TRACK_SKIP_AUTO:
1962 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
1963 audio_reset_and_rebuffer(action, peek_offset);
1964 break;
1966 case TRACK_SKIP_AUTO_END_PLAYLIST:
1967 /* Already finished */
1968 break;
1970 default:
1971 /* Invalid */
1972 logf("Buffering call, inv. state: %d", (int)skip_pending);
1976 /* Handle starting the next track load
1977 (Q_AUDIO_FILL_BUFFER) */
1978 static void audio_on_fill_buffer(void)
1980 audio_handle_track_load_status(audio_fill_file_buffer());
1983 /* Handle posted load track finish event
1984 (Q_AUDIO_FINISH_LOAD_TRACK) */
1985 static void audio_on_finish_load_track(int id3_hid)
1987 struct track_info *info = track_list_last(0);
1989 if (!info || !buf_is_handle(id3_hid))
1990 return;
1992 if (info == track_list_user_current(1))
1994 /* Just loaded the metadata right after the current position */
1995 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
1998 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
1999 return; /* Not current track */
2001 bool is_user_current = info == track_list_user_current(0);
2003 if (is_user_current)
2005 /* Copy cuesheet */
2006 buf_read_cuesheet(info->cuesheet_hid);
2009 if (audio_start_codec(automatic_skip))
2011 if (is_user_current)
2013 /* Be sure all tagtree info is synchronized; it will be needed for the
2014 track finish event - the sync will happen when finalizing a track
2015 change otherwise */
2016 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2018 playing_id3_sync(info, -1);
2020 if (!was_valid)
2022 /* Playing id3 hadn't been updated yet because no valid track
2023 was yet available - treat like the first track */
2024 audio_playlist_track_change();
2028 else
2030 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2034 /* Called when handles other than metadata handles have finished buffering
2035 (Q_AUDIO_HANDLE_FINISHED) */
2036 static void audio_on_handle_finished(int hid)
2038 /* Right now, only audio handles should end up calling this */
2039 if (filling == STATE_END_OF_PLAYLIST)
2041 struct track_info *info = track_list_last(0);
2043 /* Really we don't know which order the handles will actually complete
2044 to zero bytes remaining since another thread is doing it - be sure
2045 it's the right one */
2046 if (info && info->audio_hid == hid)
2048 /* This was the last track in the playlist and we now have all the
2049 data we need */
2050 filling_is_finished();
2055 /* Called to make an outstanding track skip the current track and to send the
2056 transition events */
2057 static void audio_finalise_track_change(bool delayed)
2059 switch (skip_pending)
2061 case TRACK_SKIP_NONE: /* Manual skip */
2062 break;
2064 case TRACK_SKIP_AUTO:
2065 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2067 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2068 audio_playlist_track_finish();
2070 if (!playlist_peek(playlist_delta, NULL, 0))
2072 /* Track ended up rejected - push things ahead like the codec blew
2073 it (because it was never started and now we're here where it
2074 should have been decoding the next track by now) - next, a
2075 directory change or end of playback will most likely happen */
2076 skip_pending = TRACK_SKIP_NONE;
2077 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2078 return;
2081 if (!playlist_delta)
2082 break;
2084 playlist_peek_offset -= playlist_delta;
2085 if (playlist_next(playlist_delta) >= 0)
2086 break;
2087 /* What!? Disappear? Hopeless bleak despair */
2089 /* Fallthrough */
2090 case TRACK_SKIP_AUTO_END_PLAYLIST:
2091 default: /* Invalid */
2092 filling = STATE_ENDED;
2093 audio_stop_playback();
2094 return;
2097 struct track_info *info = track_list_current(0);
2098 struct mp3entry *track_id3 = NULL;
2100 id3_mutex_lock();
2102 /* Update the current cuesheet if any and enabled */
2103 if (info)
2105 buf_read_cuesheet(info->cuesheet_hid);
2106 track_id3 = bufgetid3(info->id3_hid);
2109 id3_write(PLAYING_ID3, track_id3);
2111 if (delayed)
2113 /* Delayed skip where codec is ahead of user's current track */
2114 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2115 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
2116 ply_id3->elapsed = ci_id3->elapsed;
2117 ply_id3->offset = ci_id3->offset;
2120 /* The skip is technically over */
2121 skip_pending = TRACK_SKIP_NONE;
2123 /* Sync the next track information */
2124 info = track_list_current(1);
2126 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2127 id3_get(UNBUFFERED_ID3));
2129 id3_mutex_unlock();
2131 audio_playlist_track_change();
2134 /* Actually begin a transition and take care of the codec change - may complete
2135 it now or ask pcmbuf for notification depending on the type and what pcmbuf
2136 has to say */
2137 static void audio_begin_track_change(bool auto_skip, int trackstat)
2139 /* Even if the new track is bad, the old track must be finished off */
2140 bool finalised = pcmbuf_start_track_change(auto_skip);
2142 if (finalised)
2144 /* pcmbuf says that the transition happens now - complete it */
2145 audio_finalise_track_change(false);
2147 if (play_status == PLAY_STOPPED)
2148 return; /* Stopped us */
2151 if (!auto_skip)
2152 audio_clear_paused_pcm();
2154 if (trackstat >= LOAD_TRACK_OK)
2156 struct track_info *info = track_list_current(0);
2158 if (info->audio_hid < 0)
2159 return;
2161 /* Everything needed for the codec is ready - start it */
2162 if (audio_start_codec(auto_skip))
2164 if (finalised)
2165 playing_id3_sync(info, -1);
2166 return;
2169 trackstat = LOAD_TRACK_ERR_START_CODEC;
2172 audio_handle_track_load_status(trackstat);
2175 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2176 static void audio_monitor_end_of_playlist(void)
2178 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2179 filling = STATE_ENDING;
2180 pcmbuf_monitor_track_change(true);
2183 /* Codec has completed decoding the track
2184 (usually Q_AUDIO_CODEC_COMPLETE) */
2185 static void audio_on_codec_complete(int status)
2187 logf("%s(%d)", __func__, status);
2189 if (play_status == PLAY_STOPPED)
2190 return;
2192 /* If it didn't notify us first, don't expect "seek complete" message
2193 since the codec can't post it now - do things like it would have
2194 done */
2195 audio_complete_codec_seek();
2197 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2199 /* Old-hay on the ip-skay - codec has completed decoding
2201 Paused: We're not sounding it, so just remember that it happened
2202 and the resume will begin the transition
2204 Skipping: There was already a skip in progress, remember it and
2205 allow no further progress until the PCM from the previous
2206 song has finished
2208 codec_skip_pending = true;
2209 codec_skip_status = status;
2210 return;
2213 codec_skip_pending = false;
2215 #ifdef AB_REPEAT_ENABLE
2216 if (status >= 0)
2218 /* Normal automatic skip */
2219 ab_end_of_track_report();
2221 #endif
2223 int trackstat = LOAD_TRACK_OK;
2225 automatic_skip = true;
2226 skip_pending = TRACK_SKIP_AUTO;
2228 /* Does this track have an entry allocated? */
2229 struct track_info *info = track_list_advance_current(1);
2231 if (!info || info->audio_hid < 0)
2233 bool end_of_playlist = false;
2235 if (info)
2237 /* Track load is not complete - it might have stopped on a
2238 full buffer without reaching the audio handle or we just
2239 arrived at it early
2241 If this type is atomic and we couldn't get the audio,
2242 perhaps it would need to wrap to make the allocation and
2243 handles are in the way - to maximize the liklihood it can
2244 be allocated, clear all handles to reset the buffer and
2245 its indexes to 0 - for packet audio, this should not be an
2246 issue and a pointless full reload of all the track's
2247 metadata may be avoided */
2249 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2251 if (track_id3 &&
2252 get_audio_base_data_type(track_id3->codectype)
2253 == TYPE_PACKET_AUDIO)
2255 /* Continue filling after this track */
2256 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2257 audio_begin_track_change(true, trackstat);
2258 return;
2260 /* else rebuffer at this track; status applies to the track we
2261 want */
2263 else if (!playlist_peek(1, NULL, 0))
2265 /* Play sequence is complete - directory change or other playlist
2266 resequencing - the playlist must now be advanced in order to
2267 continue since a peek ahead to the next track is not possible */
2268 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2269 end_of_playlist = playlist_next(1) < 0;
2272 if (!end_of_playlist)
2274 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2275 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2277 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2279 /* Failed to find anything after all - do playlist switchover
2280 instead */
2281 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2282 end_of_playlist = playlist_next(1) < 0;
2286 if (end_of_playlist)
2288 audio_monitor_end_of_playlist();
2289 return;
2293 audio_begin_track_change(true, trackstat);
2296 /* Called when codec completes seek operation
2297 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2298 static void audio_on_codec_seek_complete(void)
2300 logf("%s()", __func__);
2301 audio_complete_codec_seek();
2302 codec_go();
2305 /* Called when PCM track change has completed
2306 (Q_AUDIO_TRACK_CHANGED) */
2307 static void audio_on_track_changed(void)
2309 /* Finish whatever is pending so that the WPS is in sync */
2310 audio_finalise_track_change(true);
2312 if (codec_skip_pending)
2314 /* Codec got ahead completing a short track - complete the
2315 codec's skip and begin the next */
2316 codec_skip_pending = false;
2317 audio_on_codec_complete(codec_skip_status);
2321 /* Begin playback from an idle state, transition to a new playlist or
2322 invalidate the buffer and resume (if playing).
2323 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2324 static void audio_start_playback(size_t offset, unsigned int flags)
2326 enum play_status old_status = play_status;
2328 if (flags & AUDIO_START_NEWBUF)
2330 /* Mark the buffer dirty - if not playing, it will be reset next
2331 time */
2332 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2333 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2336 if (old_status != PLAY_STOPPED)
2338 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2340 halt_decoding_track(true);
2342 automatic_skip = false;
2343 ff_rw_mode = false;
2345 if (flags & AUDIO_START_RESTART)
2347 /* Clear out some stuff to resume the current track where it
2348 left off */
2349 pcmbuf_play_stop();
2350 offset = id3_get(PLAYING_ID3)->offset;
2351 track_list_clear(TRACK_LIST_CLEAR_ALL);
2353 else
2355 /* This is more-or-less treated as manual track transition */
2356 /* Save resume information for current track */
2357 audio_playlist_track_finish();
2358 track_list_clear(TRACK_LIST_CLEAR_ALL);
2360 /* Indicate manual track change */
2361 pcmbuf_start_track_change(false);
2362 audio_clear_paused_pcm();
2363 wipe_track_metadata(true);
2366 /* Set after track finish event in case skip was in progress */
2367 skip_pending = TRACK_SKIP_NONE;
2369 else
2371 if (flags & AUDIO_START_RESTART)
2372 return; /* Must already be playing */
2374 /* Cold playback start from a stopped state */
2375 logf("%s(%lu): starting", __func__, offset);
2377 /* Set audio parameters */
2378 #if INPUT_SRC_CAPS != 0
2379 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2380 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2381 #endif
2382 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2383 sound_set_volume(global_settings.volume);
2384 #endif
2385 /* Be sure channel is audible */
2386 pcmbuf_fade(false, true);
2388 /* Update our state */
2389 play_status = PLAY_PLAYING;
2392 /* Start fill from beginning of playlist */
2393 playlist_peek_offset = -1;
2394 buf_set_base_handle(-1);
2396 /* Officially playing */
2397 queue_reply(&audio_queue, 1);
2399 /* Add these now - finish event for the first id3 will most likely be sent
2400 immediately */
2401 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2402 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2404 if (old_status == PLAY_STOPPED)
2406 /* Send coldstart event */
2407 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2410 /* Fill the buffer */
2411 int trackstat = audio_fill_file_buffer();
2413 if (trackstat >= LOAD_TRACK_OK)
2415 /* This is the currently playing track - get metadata, stat */
2416 playing_id3_sync(track_list_current(0), offset);
2418 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2420 /* Only if actually changing tracks... */
2421 if (!(flags & AUDIO_START_RESTART))
2422 audio_playlist_track_change();
2425 else
2427 /* Found nothing playable */
2428 audio_handle_track_load_status(trackstat);
2432 /* Stop playback and enter an idle state
2433 (usually Q_AUDIO_STOP) */
2434 static void audio_stop_playback(void)
2436 logf("%s()", __func__);
2438 if (play_status == PLAY_STOPPED)
2439 return;
2441 pcmbuf_fade(global_settings.fade_on_stop, false);
2443 /* Stop the codec and unload it */
2444 halt_decoding_track(true);
2445 pcmbuf_play_stop();
2446 codec_unload();
2448 /* Save resume information - "filling" might have been set to
2449 "STATE_ENDED" by caller in order to facilitate end of playlist */
2450 audio_playlist_track_finish();
2452 skip_pending = TRACK_SKIP_NONE;
2453 automatic_skip = false;
2455 /* Close all tracks and mark them NULL */
2456 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2457 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2458 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2460 track_list_clear(TRACK_LIST_CLEAR_ALL);
2462 /* Update our state */
2463 ff_rw_mode = false;
2464 play_status = PLAY_STOPPED;
2466 wipe_track_metadata(true);
2468 /* Go idle */
2469 filling = STATE_IDLE;
2470 cancel_cpu_boost();
2473 /* Pause the playback of the current track
2474 (Q_AUDIO_PAUSE) */
2475 static void audio_on_pause(bool pause)
2477 logf("%s(%s)", __func__, pause ? "true" : "false");
2479 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2480 return;
2482 bool const do_fade = global_settings.fade_on_stop;
2484 if (pause)
2485 pcmbuf_fade(do_fade, false);
2487 if (!ff_rw_mode)
2489 /* Not in ff/rw mode - may set the state (otherwise this could make
2490 old data play because seek hasn't completed and cleared it) */
2491 pcmbuf_pause(pause);
2494 if (!pause)
2495 pcmbuf_fade(do_fade, true);
2497 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2499 if (!pause && codec_skip_pending)
2501 /* Actually do the skip that is due - resets the status flag */
2502 audio_on_codec_complete(codec_skip_status);
2506 /* Skip a certain number of tracks forwards or backwards
2507 (Q_AUDIO_SKIP) */
2508 static void audio_on_skip(void)
2510 id3_mutex_lock();
2512 /* Eat the delta to keep it synced, even if not playing */
2513 int toskip = skip_offset;
2514 skip_offset = 0;
2516 logf("%s(): %d", __func__, toskip);
2518 id3_mutex_unlock();
2520 if (play_status == PLAY_STOPPED)
2521 return;
2523 /* Force codec to abort this track */
2524 halt_decoding_track(true);
2526 /* Kill the ff/rw halt */
2527 ff_rw_mode = false;
2529 /* Manual skip */
2530 automatic_skip = false;
2532 /* If there was an auto skip in progress, there will be residual
2533 advancement of the playlist and/or track list so compensation will be
2534 required in order to end up in the right spot */
2535 int track_list_delta = toskip;
2536 int playlist_delta = toskip;
2538 if (skip_pending != TRACK_SKIP_NONE)
2540 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2541 track_list_delta--;
2543 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2544 playlist_delta--;
2547 audio_playlist_track_finish();
2548 skip_pending = TRACK_SKIP_NONE;
2550 /* Update the playlist current track now */
2551 while (playlist_next(playlist_delta) < 0)
2553 /* Manual skip out of range (because the playlist wasn't updated
2554 yet by us and so the check in audio_skip returned 'ok') - bring
2555 back into range */
2556 int d = toskip < 0 ? 1 : -1;
2558 while (!playlist_check(playlist_delta))
2560 if (playlist_delta == d)
2562 /* Had to move the opposite direction to correct, which is
2563 wrong - this is the end */
2564 filling = STATE_ENDED;
2565 audio_stop_playback();
2566 return;
2569 playlist_delta += d;
2570 track_list_delta += d;
2574 /* Adjust things by how much the playlist was manually moved */
2575 playlist_peek_offset -= playlist_delta;
2577 struct track_info *info = track_list_advance_current(track_list_delta);
2578 int trackstat = LOAD_TRACK_OK;
2580 if (!info || info->audio_hid < 0)
2582 /* We don't know the next track thus we know we don't have it */
2583 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2586 audio_begin_track_change(false, trackstat);
2589 /* Skip to the next/previous directory
2590 (Q_AUDIO_DIR_SKIP) */
2591 static void audio_on_dir_skip(int direction)
2593 logf("%s(%d)", __func__, direction);
2595 id3_mutex_lock();
2596 skip_offset = 0;
2597 id3_mutex_unlock();
2599 if (play_status == PLAY_STOPPED)
2600 return;
2602 /* Force codec to abort this track */
2603 halt_decoding_track(true);
2605 /* Kill the ff/rw halt */
2606 ff_rw_mode = false;
2608 /* Manual skip */
2609 automatic_skip = false;
2611 audio_playlist_track_finish();
2613 /* Unless automatic and gapless, skips do not pend */
2614 skip_pending = TRACK_SKIP_NONE;
2616 /* Regardless of the return value we need to rebuffer. If it fails the old
2617 playlist will resume, else the next dir will start playing. */
2618 playlist_next_dir(direction);
2620 wipe_track_metadata(false);
2622 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2624 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2626 /* The day the music died - finish-off whatever is playing and call it
2627 quits */
2628 audio_monitor_end_of_playlist();
2629 return;
2632 audio_begin_track_change(false, trackstat);
2635 /* Enter seek mode in order to start a seek
2636 (Q_AUDIO_PRE_FF_REWIND) */
2637 static void audio_on_pre_ff_rewind(void)
2639 logf("%s()", __func__);
2641 if (play_status == PLAY_STOPPED || ff_rw_mode)
2642 return;
2644 ff_rw_mode = true;
2646 if (play_status == PLAY_PAUSED)
2647 return;
2649 pcmbuf_pause(true);
2652 /* Seek the playback of the current track to the specified time
2653 (Q_AUDIO_FF_REWIND) */
2654 static void audio_on_ff_rewind(long time)
2656 logf("%s(%ld)", __func__, time);
2658 if (play_status == PLAY_STOPPED)
2659 return;
2661 enum track_skip_type pending = skip_pending;
2663 switch (pending)
2665 case TRACK_SKIP_NONE: /* The usual case */
2666 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2667 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2669 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2670 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2672 automatic_skip = false;
2674 /* Send event before clobbering the time */
2675 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2676 then skipping back to this track resumes properly. Something else
2677 should be sent. We're not _really_ finishing the track are we? */
2678 if (time == 0)
2679 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2681 /* Prevent user codec time update - coerce to something that is
2682 innocuous concerning lookaheads */
2683 if (pending == TRACK_SKIP_NONE)
2684 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2686 id3->elapsed = time;
2687 queue_reply(&audio_queue, 1);
2689 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2691 /* Need this set in case ff/rw mode + error but _after_ the codec
2692 halt that will reset it */
2693 codec_seeking = true;
2695 if (pending == TRACK_SKIP_AUTO)
2697 if (!track_list_advance_current(-1))
2699 /* Not in list - must rebuffer at the current playlist index */
2700 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2701 < LOAD_TRACK_OK)
2703 /* Codec is stopped */
2704 break;
2709 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2710 rebuffer is needed */
2711 skip_pending = TRACK_SKIP_NONE;
2712 struct track_info *cur_info = track_list_current(0);
2714 /* Track must complete the loading _now_ since a codec and audio
2715 handle are needed in order to do the seek */
2716 if (cur_info->audio_hid < 0 &&
2717 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2719 /* Call above should push any load sequence - no need for
2720 halt_decoding_track here if no skip was pending here because
2721 there would not be a codec started if no audio handle was yet
2722 opened */
2723 break;
2726 if (pending == TRACK_SKIP_AUTO)
2728 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2729 !audio_init_codec(cur_info, ci_id3))
2731 /* We should have still been able to get it - skip it and move
2732 onto the next one - like it or not this track is broken */
2733 break;
2736 /* Set the codec API to the correct metadata and track info */
2737 ci.audio_hid = cur_info->audio_hid;
2738 ci.filesize = cur_info->filesize;
2739 buf_set_base_handle(cur_info->audio_hid);
2742 if (!haltres)
2744 /* If codec must be (re)started, reset the offset */
2745 ci_id3->offset = 0;
2748 codec_seek(time);
2749 return;
2752 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2754 /* We cannot do this because the playlist must be reversed by one
2755 and it doesn't always return the same song when going backwards
2756 across boundaries as forwards (either because of randomization
2757 or inconsistency in deciding what the previous track should be),
2758 therefore the whole operation would often end up as nonsense -
2759 lock out seeking for a couple seconds */
2761 /* Sure as heck cancel seek mode too! */
2762 audio_ff_rewind_end();
2763 return;
2766 default:
2767 /* Won't see this */
2768 return;
2771 if (play_status == PLAY_STOPPED)
2773 /* Playback ended because of an error completing a track load */
2774 return;
2777 /* Always fake it as a codec start error which will handle mode
2778 cancellations and skip to the next track */
2779 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2782 /* Invalidates all but currently playing track
2783 (Q_AUDIO_FLUSH) */
2784 static void audio_on_audio_flush(void)
2786 logf("%s", __func__);
2788 if (track_list_empty())
2789 return; /* Nothing to flush out */
2791 switch (skip_pending)
2793 case TRACK_SKIP_NONE:
2794 case TRACK_SKIP_AUTO_END_PLAYLIST:
2795 /* Remove all but the currently playing track from the list and
2796 refill after that */
2797 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2798 playlist_peek_offset = 0;
2799 id3_write_locked(UNBUFFERED_ID3, NULL);
2800 audio_update_and_announce_next_track(NULL);
2802 /* Ignore return since it's about the next track, not this one */
2803 audio_fill_file_buffer();
2805 if (skip_pending == TRACK_SKIP_NONE)
2806 break;
2808 /* There's now a track after this one now - convert to auto skip -
2809 no skip should pend right now because multiple flush messages can
2810 be fired which would cause a restart in the below cases */
2811 skip_pending = TRACK_SKIP_NONE;
2812 audio_clear_track_notifications();
2813 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2814 break;
2816 case TRACK_SKIP_AUTO:
2817 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2818 /* Precisely removing what it already decoded for the next track is
2819 not possible so a restart is required in order to continue the
2820 currently playing track without the now invalid future track
2821 playing */
2822 audio_start_playback(0, AUDIO_START_RESTART);
2823 break;
2825 default: /* Nothing else is a state */
2826 break;
2830 #ifdef AUDIO_HAVE_RECORDING
2831 /* Load the requested encoder type
2832 (Q_AUDIO_LOAD_ENCODER) */
2833 static void audio_on_load_encoder(int afmt)
2835 bool res = true;
2837 if (play_status != PLAY_STOPPED)
2838 audio_stop_playback(); /* Can't load both types at once */
2839 else
2840 codec_unload(); /* Encoder still loaded, stop and unload it */
2842 if (afmt != AFMT_UNKNOWN)
2844 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2845 if (res)
2846 codec_go(); /* These are run immediately */
2849 queue_reply(&audio_queue, res);
2851 #endif /* AUDIO_HAVE_RECORDING */
2853 static void audio_thread(void)
2855 struct queue_event ev;
2857 pcm_postinit();
2859 filling = STATE_IDLE;
2861 while (1)
2863 switch (filling)
2865 /* Active states */
2866 case STATE_FULL:
2867 case STATE_END_OF_PLAYLIST:
2868 if (buf_get_watermark() == 0)
2870 /* End of buffering for now, let's calculate the watermark,
2871 register for a low buffer event and unboost */
2872 audio_update_filebuf_watermark(0);
2873 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2874 buffer_event_buffer_low_callback);
2876 /* Fall-through */
2877 case STATE_FINISHED:
2878 /* All data was buffered */
2879 cancel_cpu_boost();
2880 /* Fall-through */
2881 case STATE_FILLING:
2882 case STATE_ENDING:
2883 if (audio_pcmbuf_track_change_scan())
2885 /* Transfer notification to audio queue event */
2886 ev.id = Q_AUDIO_TRACK_CHANGED;
2887 ev.data = 1;
2889 else
2891 /* If doing auto skip, poll pcmbuf track notifications a bit
2892 faster to promply detect the transition */
2893 queue_wait_w_tmo(&audio_queue, &ev,
2894 skip_pending == TRACK_SKIP_NONE ?
2895 HZ/2 : HZ/10);
2897 break;
2899 /* Idle states */
2900 default:
2901 queue_wait(&audio_queue, &ev);
2903 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2904 switch (ev.id)
2906 #ifdef AUDIO_HAVE_RECORDING
2907 /* Must monitor the encoder message for recording so it can remove
2908 it if we process the insertion before it does. It cannot simply
2909 be removed from under recording however. */
2910 case Q_AUDIO_LOAD_ENCODER:
2911 break;
2912 #endif
2913 case SYS_USB_DISCONNECTED:
2914 filling = STATE_IDLE;
2915 break;
2917 default:
2918 if (filling == STATE_USB)
2919 continue;
2921 #endif /* CONFIG_PLATFORM */
2924 switch (ev.id)
2926 /** Codec and track change messages **/
2927 case Q_AUDIO_CODEC_COMPLETE:
2928 /* Codec is done processing track and has gone idle */
2929 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
2930 audio_on_codec_complete(ev.data);
2931 break;
2933 case Q_AUDIO_CODEC_SEEK_COMPLETE:
2934 /* Codec is done seeking */
2935 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2936 audio_on_codec_seek_complete();
2937 break;
2939 case Q_AUDIO_TRACK_CHANGED:
2940 /* PCM track change done */
2941 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2942 audio_on_track_changed();
2943 break;
2945 /** Control messages **/
2946 case Q_AUDIO_PLAY:
2947 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2948 audio_start_playback(ev.data, 0);
2949 break;
2951 case Q_AUDIO_STOP:
2952 LOGFQUEUE("audio < Q_AUDIO_STOP");
2953 audio_stop_playback();
2954 if (ev.data != 0)
2955 queue_clear(&audio_queue);
2956 break;
2958 case Q_AUDIO_PAUSE:
2959 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2960 audio_on_pause(ev.data);
2961 break;
2963 case Q_AUDIO_SKIP:
2964 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2965 audio_on_skip();
2966 break;
2968 case Q_AUDIO_DIR_SKIP:
2969 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2970 audio_on_dir_skip(ev.data);
2971 break;
2973 case Q_AUDIO_PRE_FF_REWIND:
2974 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2975 audio_on_pre_ff_rewind();
2976 break;
2978 case Q_AUDIO_FF_REWIND:
2979 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2980 audio_on_ff_rewind(ev.data);
2981 break;
2983 case Q_AUDIO_FLUSH:
2984 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
2985 audio_on_audio_flush();
2986 break;
2988 /** Buffering messages **/
2989 case Q_AUDIO_BUFFERING:
2990 /* some buffering event */
2991 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
2992 audio_on_buffering(ev.data);
2993 break;
2995 case Q_AUDIO_FILL_BUFFER:
2996 /* continue buffering next track */
2997 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
2998 audio_on_fill_buffer();
2999 break;
3001 case Q_AUDIO_FINISH_LOAD_TRACK:
3002 /* metadata is buffered */
3003 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
3004 audio_on_finish_load_track(ev.data);
3005 break;
3007 case Q_AUDIO_HANDLE_FINISHED:
3008 /* some other type is buffered */
3009 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3010 audio_on_handle_finished(ev.data);
3011 break;
3013 /** Miscellaneous messages **/
3014 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3015 /* buffer needs to be reinitialized */
3016 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3017 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3018 break;
3020 #ifdef HAVE_DISK_STORAGE
3021 case Q_AUDIO_UPDATE_WATERMARK:
3022 /* buffering watermark needs updating */
3023 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3024 audio_update_filebuf_watermark(ev.data);
3025 break;
3026 #endif /* HAVE_DISK_STORAGE */
3028 #ifdef AUDIO_HAVE_RECORDING
3029 case Q_AUDIO_LOAD_ENCODER:
3030 /* load an encoder for recording */
3031 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3032 audio_on_load_encoder(ev.data);
3033 break;
3034 #endif /* AUDIO_HAVE_RECORDING */
3036 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3037 case SYS_USB_CONNECTED:
3038 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3039 audio_stop_playback();
3040 #ifdef PLAYBACK_VOICE
3041 voice_stop();
3042 #endif
3043 filling = STATE_USB;
3044 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3045 break;
3046 #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
3048 case SYS_TIMEOUT:
3049 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3050 break;
3052 default:
3053 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3054 break;
3055 } /* end switch */
3056 } /* end while */
3060 /* --- Buffering callbacks --- */
3062 /* Called when fullness is below the watermark level */
3063 static void buffer_event_buffer_low_callback(void *data)
3065 logf("low buffer callback");
3066 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3067 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3068 (void)data;
3071 /* Called when handles must be discarded in order to buffer new data */
3072 static void buffer_event_rebuffer_callback(void *data)
3074 logf("rebuffer callback");
3075 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3076 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3077 (void)data;
3080 /* A handle has completed buffering and all required data is available */
3081 static void buffer_event_finished_callback(void *data)
3083 int hid = *(const int *)data;
3084 const enum data_type htype = buf_handle_data_type(hid);
3086 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3088 /* Limit queue traffic */
3089 switch (htype)
3091 case TYPE_ID3:
3092 /* The metadata handle for the last loaded track has been buffered.
3093 We can ask the audio thread to load the rest of the track's data. */
3094 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3095 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3096 break;
3098 case TYPE_PACKET_AUDIO:
3099 /* Strip any useless trailing tags that are left. */
3100 strip_tags(hid);
3101 /* Fall-through */
3102 case TYPE_ATOMIC_AUDIO:
3103 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3104 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3105 break;
3107 default:
3108 /* Don't care to know about these */
3109 break;
3114 /** -- Codec callbacks -- **/
3116 /* Update elapsed times with latency-adjusted values */
3117 void audio_codec_update_elapsed(unsigned long value)
3119 #ifdef AB_REPEAT_ENABLE
3120 ab_position_report(value);
3121 #endif
3123 unsigned long latency = pcmbuf_get_latency();
3125 if (LIKELY(value >= latency))
3127 unsigned long elapsed = value - latency;
3129 if (elapsed > value || elapsed < value - 2)
3130 value = elapsed;
3132 else
3134 value = 0;
3137 /* Track codec: used later when updating the playing at the user
3138 transition */
3139 id3_get(CODEC_ID3)->elapsed = value;
3141 /* If a skip is pending, the PCM buffer is updating the time on the
3142 previous song */
3143 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3144 id3_get(PLAYING_ID3)->elapsed = value;
3147 /* Update offsets with latency-adjusted values */
3148 void audio_codec_update_offset(size_t value)
3150 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
3151 unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8;
3153 if (LIKELY(value >= latency))
3155 value -= latency;
3157 else
3159 value = 0;
3162 /* Track codec: used later when updating the playing id3 at the user
3163 transition */
3164 ci_id3->offset = value;
3166 /* If a skip is pending, the PCM buffer is updating the time on the
3167 previous song */
3168 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3169 id3_get(PLAYING_ID3)->offset = value;
3173 /** --- Pcmbuf callbacks --- **/
3175 /* Between the codec and PCM track change, we need to keep updating the
3176 * "elapsed" value of the previous (to the codec, but current to the
3177 * user/PCM/WPS) track, so that the progressbar reaches the end. */
3178 void audio_pcmbuf_position_callback(unsigned int time)
3180 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3182 time += id3->elapsed;
3184 id3->elapsed = MIN(time, id3->length);
3187 /* Post message from pcmbuf that the end of the previous track has just
3188 * been played */
3189 void audio_pcmbuf_track_change(bool pcmbuf)
3191 if (pcmbuf)
3193 /* Notify of the change in special-purpose semaphore object */
3194 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3195 audio_pcmbuf_track_change_post();
3197 else
3199 /* Safe to post directly to the queue */
3200 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3201 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3205 /* May pcmbuf start PCM playback when the buffer is full enough? */
3206 bool audio_pcmbuf_may_play(void)
3208 return play_status == PLAY_PLAYING && !ff_rw_mode;
3212 /** -- External interfaces -- **/
3214 /* Return the playback and recording status */
3215 int audio_status(void)
3217 unsigned int ret = play_status;
3219 #ifdef AUDIO_HAVE_RECORDING
3220 /* Do this here for constitency with mpeg.c version */
3221 ret |= pcm_rec_status();
3222 #endif
3224 return (int)ret;
3227 /* Clear all accumulated audio errors for playback and recording */
3228 void audio_error_clear(void)
3230 #ifdef AUDIO_HAVE_RECORDING
3231 pcm_rec_error_clear();
3232 #endif
3235 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3236 bool audio_peek_track(struct mp3entry *id3, int offset)
3238 bool retval = false;
3240 id3_mutex_lock();
3242 if (play_status != PLAY_STOPPED)
3244 id3->path[0] = '\0'; /* Null path means it should be filled now */
3245 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3246 id3->path[0] != '\0';
3249 id3_mutex_unlock();
3251 return retval;
3254 /* Return the mp3entry for the currently playing track */
3255 struct mp3entry * audio_current_track(void)
3257 struct mp3entry *id3;
3259 id3_mutex_lock();
3261 #ifdef AUDIO_FAST_SKIP_PREVIEW
3262 if (skip_offset != 0)
3264 /* This is a peekahead */
3265 id3 = id3_get(PLAYING_PEEK_ID3);
3266 audio_peek_track(id3, 0);
3268 else
3269 #endif
3271 /* Normal case */
3272 id3 = id3_get(PLAYING_ID3);
3273 audio_get_track_metadata(0, id3);
3276 id3_mutex_unlock();
3278 return id3;
3281 /* Obtains the mp3entry for the next track from the current */
3282 struct mp3entry * audio_next_track(void)
3284 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3286 id3_mutex_lock();
3288 #ifdef AUDIO_FAST_SKIP_PREVIEW
3289 if (skip_offset != 0)
3291 /* This is a peekahead */
3292 if (!audio_peek_track(id3, 1))
3293 id3 = NULL;
3295 else
3296 #endif
3298 /* Normal case */
3299 if (!audio_get_track_metadata(1, id3))
3300 id3 = NULL;
3303 id3_mutex_unlock();
3305 return id3;
3308 /* Start playback at the specified offset */
3309 void audio_play(long offset)
3311 logf("audio_play");
3313 #ifdef PLAYBACK_VOICE
3314 /* Truncate any existing voice output so we don't have spelling
3315 * etc. over the first part of the played track */
3316 talk_force_shutup();
3317 #endif
3319 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3320 audio_queue_send(Q_AUDIO_PLAY, offset);
3323 /* Stop playback if playing */
3324 void audio_stop(void)
3326 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3327 audio_queue_send(Q_AUDIO_STOP, 0);
3330 /* Pause playback if playing */
3331 void audio_pause(void)
3333 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3334 audio_queue_send(Q_AUDIO_PAUSE, true);
3337 /* This sends a stop message and the audio thread will dump all its
3338 subsequent messages */
3339 void audio_hard_stop(void)
3341 /* Stop playback */
3342 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3343 audio_queue_send(Q_AUDIO_STOP, 1);
3344 #ifdef PLAYBACK_VOICE
3345 voice_stop();
3346 #endif
3347 buffer_release_buffer(0);
3350 /* Resume playback if paused */
3351 void audio_resume(void)
3353 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3354 audio_queue_send(Q_AUDIO_PAUSE, false);
3357 /* Skip the specified number of tracks forward or backward from the current */
3358 void audio_skip(int offset)
3360 id3_mutex_lock();
3362 /* If offset has to be backed-out to stay in range, no skip is done */
3363 int accum = skip_offset + offset;
3365 while (offset != 0 && !playlist_check(accum))
3367 offset += offset < 0 ? 1 : -1;
3368 accum = skip_offset + offset;
3371 if (offset != 0)
3373 /* Accumulate net manual skip count since the audio thread last
3374 processed one */
3375 skip_offset = accum;
3377 system_sound_play(SOUND_TRACK_SKIP);
3379 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3381 #ifdef AUDIO_FAST_SKIP_PREVIEW
3382 /* Do this before posting so that the audio thread can correct us
3383 when things settle down - additionally, if audio gets a message
3384 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3385 handler a skip event with the correct info but doesn't skip */
3386 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3387 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3389 /* Playback only needs the final state even if more than one is
3390 processed because it wasn't removed in time */
3391 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3392 audio_queue_post(Q_AUDIO_SKIP, 0);
3394 else
3396 /* No more tracks */
3397 system_sound_play(SOUND_TRACK_NO_MORE);
3400 id3_mutex_unlock();
3403 /* Skip one track forward from the current */
3404 void audio_next(void)
3406 audio_skip(1);
3409 /* Skip one track backward from the current */
3410 void audio_prev(void)
3412 audio_skip(-1);
3415 /* Move one directory forward */
3416 void audio_next_dir(void)
3418 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3419 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3422 /* Move one directory backward */
3423 void audio_prev_dir(void)
3425 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3426 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3429 /* Pause playback in order to start a seek that flushes the old audio */
3430 void audio_pre_ff_rewind(void)
3432 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3433 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3436 /* Seek to the new time in the current track */
3437 void audio_ff_rewind(long time)
3439 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3440 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3443 /* Clear all but the currently playing track then rebuffer */
3444 void audio_flush_and_reload_tracks(void)
3446 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3447 audio_queue_post(Q_AUDIO_FLUSH, 0);
3450 /* Return the pointer to the main audio buffer, optionally preserving
3451 voicing */
3452 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3454 unsigned char *buf;
3456 if (audio_is_initialized)
3458 audio_hard_stop();
3460 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3462 if (buffer_size == NULL)
3464 /* Special case for talk_init to use since it already knows it's
3465 trashed */
3466 buffer_state = AUDIOBUF_STATE_TRASHED;
3467 return NULL;
3470 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3471 || !talk_voice_required())
3473 logf("get buffer: talk, audio");
3474 /* Ok to use everything from audiobuf - voice is loaded,
3475 the talk buffer is not needed because voice isn't being used, or
3476 could be AUDIOBUF_STATE_TRASHED already. If state is
3477 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3478 written without the caller knowing what's going on. Changing certain
3479 settings may move it to a worse condition but the memory in use by
3480 something else will remain undisturbed.
3482 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3484 talk_buffer_steal();
3485 buffer_state = AUDIOBUF_STATE_TRASHED;
3487 buf = buffer_get_buffer(buffer_size);
3489 else
3491 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3492 still AUDIOBUF_STATE_INITIALIZED */
3493 /* Skip talk buffer and move pcm buffer to end to maximize available
3494 contiguous memory - no audio running means voice will not need the
3495 swap space */
3496 size_t siz, talkbuf_size;
3497 logf("get buffer: audio");
3498 /* call buffer_get_buffer() to make use of the locking mechanism */
3499 buf = buffer_get_buffer(&siz);
3500 buf += talkbuf_size = talkbuf_init(buf);
3501 siz -= talkbuf_size + pcmbuf_init(buf + siz);
3502 siz -= voicebuf_init(buf + siz);
3503 *buffer_size = siz;
3505 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3508 return buf;
3511 #ifdef HAVE_RECORDING
3512 /* Stop audio, voice and obtain all available buffer space */
3513 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3515 talk_buffer_steal();
3516 audio_hard_stop();
3518 buffer_state = AUDIOBUF_STATE_TRASHED;
3519 return buffer_get_buffer(buffer_size);
3521 #endif /* HAVE_RECORDING */
3523 /* Restore audio buffer to a particular state (one more valid than the current
3524 state) */
3525 bool audio_restore_playback(int type)
3527 switch (type)
3529 case AUDIO_WANT_PLAYBACK:
3530 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3531 audio_reset_buffer();
3532 return true;
3533 case AUDIO_WANT_VOICE:
3534 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3535 audio_reset_buffer();
3536 return true;
3537 default:
3538 return false;
3542 /* Has the playback buffer been completely claimed? */
3543 bool audio_buffer_state_trashed(void)
3545 return buffer_state == AUDIOBUF_STATE_TRASHED;
3549 /** --- Miscellaneous public interfaces --- **/
3551 #ifdef HAVE_ALBUMART
3552 /* Return which album art handle is current for the user in the given slot */
3553 int playback_current_aa_hid(int slot)
3555 if ((unsigned)slot < MAX_MULTIPLE_AA)
3557 struct track_info *info = track_list_user_current(skip_offset);
3559 if (!info && abs(skip_offset) <= 1)
3561 /* Give the actual position a go */
3562 info = track_list_user_current(0);
3565 if (info)
3566 return info->aa_hid[slot];
3569 return ERR_HANDLE_NOT_FOUND;
3572 /* Find an album art slot that doesn't match the dimensions of another that
3573 is already claimed - increment the use count if it is */
3574 int playback_claim_aa_slot(struct dim *dim)
3576 int i;
3578 /* First try to find a slot already having the size to reuse it since we
3579 don't want albumart of the same size buffered multiple times */
3580 FOREACH_ALBUMART(i)
3582 struct albumart_slot *slot = &albumart_slots[i];
3584 if (slot->dim.width == dim->width &&
3585 slot->dim.height == dim->height)
3587 slot->used++;
3588 return i;
3592 /* Size is new, find a free slot */
3593 FOREACH_ALBUMART(i)
3595 if (!albumart_slots[i].used)
3597 albumart_slots[i].used++;
3598 albumart_slots[i].dim = *dim;
3599 return i;
3603 /* Sorry, no free slot */
3604 return -1;
3607 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3608 void playback_release_aa_slot(int slot)
3610 if ((unsigned)slot < MAX_MULTIPLE_AA)
3612 struct albumart_slot *aa_slot = &albumart_slots[slot];
3614 if (aa_slot->used > 0)
3615 aa_slot->used--;
3618 #endif /* HAVE_ALBUMART */
3621 #ifdef HAVE_RECORDING
3622 /* Load an encoder and run it */
3623 bool audio_load_encoder(int afmt)
3625 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3626 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3627 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3628 #else
3629 (void)afmt;
3630 return true;
3631 #endif
3634 /* Stop an encoder and unload it */
3635 void audio_remove_encoder(void)
3637 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3638 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3639 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3640 #endif
3642 #endif /* HAVE_RECORDING */
3644 /* Is an automatic skip in progress? If called outside transition callbacks,
3645 indicates the last skip type at the time it was processed and isn't very
3646 meaningful. */
3647 bool audio_automatic_skip(void)
3649 return automatic_skip;
3652 /* Would normally calculate byte offset from an elapsed time but is not
3653 used on SWCODEC */
3654 int audio_get_file_pos(void)
3656 return 0;
3659 /* Return the elapsed time of the track previous to the current */
3660 unsigned long audio_prev_elapsed(void)
3662 return prev_track_elapsed;
3665 /* Is the audio thread ready to accept commands? */
3666 bool audio_is_thread_ready(void)
3668 return filling != STATE_BOOT;
3671 /* Return total file buffer length after accounting for the talk buf */
3672 size_t audio_get_filebuflen(void)
3674 return buf_length();
3677 /* How many tracks exist on the buffer - full or partial */
3678 int audio_track_count(void)
3679 __attribute__((alias("track_list_count")));
3681 /* Return total ringbuffer space occupied - ridx to widx */
3682 long audio_filebufused(void)
3684 return buf_used();
3688 /** -- Settings -- **/
3690 /* Enable or disable cuesheet support and allocate/don't allocate the
3691 extra associated resources */
3692 void audio_set_cuesheet(int enable)
3694 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3696 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3697 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3701 #ifdef HAVE_DISK_STORAGE
3702 /* Set the audio antiskip buffer margin by index */
3703 void audio_set_buffer_margin(int setting)
3705 static const unsigned short lookup[] =
3706 { 5, 15, 30, 60, 120, 180, 300, 600 };
3708 if ((unsigned)setting >= ARRAYLEN(lookup))
3709 setting = 0;
3711 logf("buffer margin: %u", (unsigned)lookup[setting]);
3713 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3714 (unsigned)lookup[setting]);
3715 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3717 #endif /* HAVE_DISK_STORAGE */
3719 #ifdef HAVE_CROSSFADE
3720 /* Take necessary steps to enable or disable the crossfade setting */
3721 void audio_set_crossfade(int enable)
3723 /* Tell it the next setting to use */
3724 pcmbuf_request_crossfade_enable(enable);
3726 /* Return if size hasn't changed or this is too early to determine
3727 which in the second case there's no way we could be playing
3728 anything at all */
3729 if (!pcmbuf_is_same_size())
3731 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3732 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3735 #endif /* HAVE_CROSSFADE */
3738 /** -- Startup -- **/
3740 /* Initialize the audio system - called from init() in main.c */
3741 void audio_init(void)
3743 /* Can never do this twice */
3744 if (audio_is_initialized)
3746 logf("audio: already initialized");
3747 return;
3750 logf("audio: initializing");
3752 /* Initialize queues before giving control elsewhere in case it likes
3753 to send messages. Thread creation will be delayed however so nothing
3754 starts running until ready if something yields such as talk_init. */
3755 queue_init(&audio_queue, true);
3757 mutex_init(&id3_mutex);
3759 pcm_init();
3761 codec_init_codec_api();
3763 make_codec_thread();
3765 /* This thread does buffer, so match its priority */
3766 audio_thread_id = create_thread(audio_thread, audio_stack,
3767 sizeof(audio_stack), CREATE_THREAD_FROZEN,
3768 audio_thread_name
3769 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3770 IF_COP(, CPU));
3772 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3773 audio_thread_id);
3775 #ifdef PLAYBACK_VOICE
3776 voice_thread_init();
3777 #endif
3779 /* audio_reset_buffer must know the size of voice buffer so init
3780 talk first */
3781 talk_init();
3783 #ifdef HAVE_CROSSFADE
3784 /* Set crossfade setting for next buffer init which should be about... */
3785 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3786 #endif
3788 /* Initialize the buffering system */
3789 track_list_init();
3790 buffering_init();
3791 /* ...now! Set up the buffers */
3792 audio_reset_buffer();
3794 /* Probably safe to say */
3795 audio_is_initialized = true;
3797 sound_settings_apply();
3798 #ifdef HAVE_DISK_STORAGE
3799 audio_set_buffer_margin(global_settings.buffer_margin);
3800 #endif
3802 /* It's safe to let the threads run now */
3803 #ifdef PLAYBACK_VOICE
3804 voice_thread_resume();
3805 #endif
3806 codec_thread_resume();
3807 thread_thaw(audio_thread_id);