imx233: correctly stop charging on topoff (fix battery discharging)
[maemo-rb.git] / apps / playback.c
blob8fe43eb88475003c6c276c5660b0e9cabd8b4cc8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005-2007 Miika Pekkarinen
11 * Copyright (C) 2007-2008 Nicolas Pennequin
12 * Copyright (C) 2011 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "panic.h"
27 #include "core_alloc.h"
28 #include "sound.h"
29 #include "ata.h"
30 #include "usb.h"
31 #include "codecs.h"
32 #include "codec_thread.h"
33 #include "voice_thread.h"
34 #include "metadata.h"
35 #include "cuesheet.h"
36 #include "buffering.h"
37 #include "talk.h"
38 #include "playlist.h"
39 #include "abrepeat.h"
40 #include "pcmbuf.h"
41 #include "playback.h"
42 #include "misc.h"
43 #include "settings.h"
45 #ifdef HAVE_TAGCACHE
46 #include "tagcache.h"
47 #endif
49 #ifdef AUDIO_HAVE_RECORDING
50 #include "pcm_record.h"
51 #endif
53 #ifdef HAVE_LCD_BITMAP
54 #ifdef HAVE_ALBUMART
55 #include "albumart.h"
56 #endif
57 #endif
59 /* TODO: The audio thread really is doing multitasking of acting like a
60 consumer and producer of tracks. It may be advantageous to better
61 logically separate the two functions. I won't go that far just yet. */
63 /* Internal support for voice playback */
64 #define PLAYBACK_VOICE
66 #if CONFIG_PLATFORM & PLATFORM_NATIVE
67 /* Application builds don't support direct code loading */
68 #define HAVE_CODEC_BUFFERING
69 #endif
71 /* Amount of guess-space to allow for codecs that must hunt and peck
72 * for their correct seek target, 32k seems a good size */
73 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
75 /* Define LOGF_ENABLE to enable logf output in this file */
76 /* #define LOGF_ENABLE */
77 #include "logf.h"
79 /* Macros to enable logf for queues
80 logging on SYS_TIMEOUT can be disabled */
81 #ifdef SIMULATOR
82 /* Define this for logf output of all queuing except SYS_TIMEOUT */
83 #define PLAYBACK_LOGQUEUES
84 /* Define this to logf SYS_TIMEOUT messages */
85 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
86 #endif
88 #ifdef PLAYBACK_LOGQUEUES
89 #define LOGFQUEUE logf
90 #else
91 #define LOGFQUEUE(...)
92 #endif
94 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
95 #define LOGFQUEUE_SYS_TIMEOUT logf
96 #else
97 #define LOGFQUEUE_SYS_TIMEOUT(...)
98 #endif
100 /* Variables are commented with the threads that use them:
101 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
102 * read but not updated on that thread. Audio is the only user unless otherwise
103 * specified.
106 /** Miscellaneous **/
107 bool audio_is_initialized = false; /* (A,O-) */
108 extern struct codec_api ci; /* (A,C) */
110 /** Possible arrangements of the main buffer **/
111 static enum audio_buffer_state
113 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
114 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
115 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
116 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
118 /** Main state control **/
119 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
121 enum play_status
123 PLAY_STOPPED = 0,
124 PLAY_PLAYING = AUDIO_STATUS_PLAY,
125 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
126 } play_status = PLAY_STOPPED;
128 /* Sizeable things that only need exist during playback and not when stopped */
129 static struct audio_scratch_memory
131 struct mp3entry codec_id3; /* (A,C) */
132 struct mp3entry unbuffered_id3;
133 struct cuesheet *curr_cue; /* Will follow this structure */
134 } * audio_scratch_memory = NULL;
136 /* These are used to store the current, next and optionally the peek-ahead
137 * mp3entry's - this guarantees that the pointer returned by audio_current/
138 * next_track will be valid for the full duration of the currently playing
139 * track */
140 enum audio_id3_types
142 /* These are allocated statically */
143 PLAYING_ID3 = 0,
144 NEXTTRACK_ID3,
145 #ifdef AUDIO_FAST_SKIP_PREVIEW
146 /* The real playing metadata must has to be protected since it contains
147 critical info for other features */
148 PLAYING_PEEK_ID3,
149 #endif
150 ID3_TYPE_NUM_STATIC,
151 /* These go in the scratch memory */
152 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
153 CODEC_ID3,
155 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
157 /* Peeking functions can yield and mess us up */
158 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/
161 /** For Scrobbler support **/
163 /* Previous track elapsed time */
164 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
167 /** For album art support **/
168 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
169 #ifdef HAVE_ALBUMART
171 static struct albumart_slot
173 struct dim dim; /* Holds width, height of the albumart */
174 int used; /* Counter; increments if something uses it */
175 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
177 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
178 #endif /* HAVE_ALBUMART */
181 /** Information used for tracking buffer fills **/
183 /* Buffer and thread state tracking */
184 static enum filling_state
186 STATE_IDLE = 0, /* 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 STATE_USB, /* USB mode, ignore most messages */
194 } filling = STATE_IDLE;
196 /* Track info - holds information about each track in the buffer */
197 struct track_info
199 /* In per-track allocated order: */
200 int id3_hid; /* Metadata handle ID */
201 int cuesheet_hid; /* Parsed cuesheet handle ID */
202 #ifdef HAVE_ALBUMART
203 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
204 #endif
205 #ifdef HAVE_CODEC_BUFFERING
206 int codec_hid; /* Buffered codec handle ID */
207 #endif
208 int audio_hid; /* Main audio data handle ID */
209 size_t filesize; /* File total length on disk
210 TODO: This should be stored
211 in the handle or the
212 id3 and would use less
213 ram */
216 /* Track list - holds info about all buffered tracks */
217 #if MEMORYSIZE >= 32
218 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
219 #elif MEMORYSIZE >= 16
220 #define TRACK_LIST_LEN 64
221 #elif MEMORYSIZE >= 8
222 #define TRACK_LIST_LEN 32
223 #else
224 #define TRACK_LIST_LEN 16
225 #endif
227 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
229 static struct
231 /* read, write and current are maintained unwrapped, limited only by the
232 unsigned int range and wrap-safe comparisons are used */
234 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
235 if 'end' follows 'start' in this structure, track_list_count performs
236 'start - end' rather than 'end - start', giving negative count values...
237 so leave it this way for now! */
238 unsigned int end; /* Next open position */
239 unsigned int start; /* First track in list */
240 unsigned int current; /* Currently decoding track */
241 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
242 } track_list; /* (A, O-) */
245 /* Playlist steps from playlist position to next track to be buffered */
246 static int playlist_peek_offset = 0;
248 /* Metadata handle of track load in progress (meaning all handles have not
249 yet been opened for the track, id3 always exists or the track does not)
251 Tracks are keyed by their metadata handles if track list pointers are
252 insufficient to make comparisons */
253 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
255 #ifdef HAVE_DISK_STORAGE
256 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
257 static size_t buffer_margin = 5;
258 #endif
260 /* Values returned for track loading */
261 enum track_load_status
263 LOAD_TRACK_ERR_START_CODEC = -6,
264 LOAD_TRACK_ERR_FINISH_FAILED = -5,
265 LOAD_TRACK_ERR_FINISH_FULL = -4,
266 LOAD_TRACK_ERR_BUSY = -3,
267 LOAD_TRACK_ERR_NO_MORE = -2,
268 LOAD_TRACK_ERR_FAILED = -1,
269 LOAD_TRACK_OK = 0,
270 LOAD_TRACK_READY = 1,
273 /** Track change controls **/
275 /* What sort of skip is pending globally? */
276 enum track_skip_type
278 /* Relative to what user is intended to see: */
279 /* Codec: +0, Track List: +0, Playlist: +0 */
280 TRACK_SKIP_NONE = 0, /* no track skip */
281 /* Codec: +1, Track List: +1, Playlist: +0 */
282 TRACK_SKIP_AUTO, /* codec-initiated skip */
283 /* Codec: +1, Track List: +1, Playlist: +1 */
284 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
285 /* Codec: xx, Track List: +0, Playlist: +0 */
286 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
287 /* Manual skip: Never pends */
288 TRACK_SKIP_MANUAL, /* manual track skip */
289 /* Manual skip: Never pends */
290 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
291 } skip_pending = TRACK_SKIP_NONE;
293 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
294 Fixing playlist code to be able to peek into the first song of
295 the next playlist would fix any issues and this wouldn't need
296 to be a special case since pre-advancing the playlist would be
297 unneeded - it could be much more like TRACK_SKIP_AUTO and all
298 actions that require reversal during an in-progress transition
299 would work as expected */
301 /* Used to indicate status for the events. Must be separate to satisfy all
302 clients so the correct metadata is read when sending the change events
303 and also so that it is read correctly outside the events. */
304 static bool automatic_skip = false; /* (A, O-) */
306 /* Pending manual track skip offset */
307 static int skip_offset = 0; /* (A, O) */
309 /* Track change notification */
310 static struct
312 unsigned int in; /* Number of pcmbuf posts (audio isr) */
313 unsigned int out; /* Number of times audio has read the difference */
314 } track_change = { 0, 0 };
316 /** Codec status **/
317 /* Did the codec notify us it finished while we were paused or while still
318 in an automatic transition?
320 If paused, it is necessary to defer a codec-initiated skip until resuming
321 or else the track will move forward while not playing audio!
323 If in-progress, skips should not build-up ahead of where the WPS is when
324 really short tracks finish decoding.
326 If it is forgotten, it will be missed altogether and playback will just sit
327 there looking stupid and comatose until the user does something */
328 static bool codec_skip_pending = false;
329 static int codec_skip_status;
330 static bool codec_seeking = false; /* Codec seeking ack expected? */
331 static unsigned int position_key = 0;
333 /* Event queues */
334 static struct event_queue audio_queue SHAREDBSS_ATTR;
336 /* Audio thread */
337 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
338 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
339 static const char audio_thread_name[] = "audio";
340 static unsigned int audio_thread_id = 0;
342 /* Forward declarations */
343 enum audio_start_playback_flags
345 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
346 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
349 static void audio_start_playback(size_t offset, unsigned int flags);
350 static void audio_stop_playback(void);
351 static void buffer_event_buffer_low_callback(void *data);
352 static void buffer_event_rebuffer_callback(void *data);
353 static void buffer_event_finished_callback(void *data);
354 void audio_pcmbuf_sync_position(void);
357 /**************************************/
359 /** --- audio_queue helpers --- **/
360 static void audio_queue_post(long id, intptr_t data)
362 queue_post(&audio_queue, id, data);
365 static intptr_t audio_queue_send(long id, intptr_t data)
367 return queue_send(&audio_queue, id, data);
371 /** --- MP3Entry --- **/
373 /* Does the mp3entry have enough info for us to use it? */
374 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
376 return id3 && (id3->length != 0 || id3->filesize != 0) &&
377 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
380 /* Return a pointer to an mp3entry on the buffer, as it is */
381 static struct mp3entry * bufgetid3(int handle_id)
383 if (handle_id < 0)
384 return NULL;
386 struct mp3entry *id3;
387 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
389 if (ret != sizeof(struct mp3entry))
390 return NULL;
392 return id3;
395 /* Read an mp3entry from the buffer, adjusted */
396 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
398 struct mp3entry *id3 = bufgetid3(handle_id);
400 if (id3)
402 copy_mp3entry(id3out, id3);
403 return true;
406 return false;
409 /* Lock the id3 mutex */
410 static void id3_mutex_lock(void)
412 mutex_lock(&id3_mutex);
415 /* Unlock the id3 mutex */
416 static void id3_mutex_unlock(void)
418 mutex_unlock(&id3_mutex);
421 /* Return one of the collection of mp3entry pointers - collect them all here */
422 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
424 switch (id3_num)
426 case UNBUFFERED_ID3:
427 return &audio_scratch_memory->unbuffered_id3;
428 case CODEC_ID3:
429 return &audio_scratch_memory->codec_id3;
430 default:
431 return &static_id3_entries[id3_num];
435 /* Copy an mp3entry into one of the mp3 entries */
436 static void id3_write(enum audio_id3_types id3_num,
437 const struct mp3entry *id3_src)
439 struct mp3entry *dest_id3 = id3_get(id3_num);
441 if (id3_src)
442 copy_mp3entry(dest_id3, id3_src);
443 else
444 wipe_mp3entry(dest_id3);
447 /* Call id3_write "safely" because peek aheads can yield, even if the fast
448 preview isn't enabled */
449 static void id3_write_locked(enum audio_id3_types id3_num,
450 const struct mp3entry *id3_src)
452 id3_mutex_lock();
453 id3_write(id3_num, id3_src);
454 id3_mutex_unlock();
458 /** --- Track info --- **/
460 /* Close a handle and mark it invalid */
461 static void track_info_close_handle(int *hid_p)
463 int hid = *hid_p;
465 /* bufclose returns true if the handle is not found, or if it is closed
466 * successfully, so these checks are safe on non-existant handles */
467 if (hid >= 0)
468 bufclose(hid);
470 /* Always reset to "no handle" in case it was something else */
471 *hid_p = ERR_HANDLE_NOT_FOUND;
474 /* Close all handles in a struct track_info and clear it */
475 static void track_info_close(struct track_info *info)
477 /* Close them in the order they are allocated on the buffer to speed up
478 the handle searching */
479 track_info_close_handle(&info->id3_hid);
480 track_info_close_handle(&info->cuesheet_hid);
481 #ifdef HAVE_ALBUMART
482 int i;
483 FOREACH_ALBUMART(i)
484 track_info_close_handle(&info->aa_hid[i]);
485 #endif
486 #ifdef HAVE_CODEC_BUFFERING
487 track_info_close_handle(&info->codec_hid);
488 #endif
489 track_info_close_handle(&info->audio_hid);
490 info->filesize = 0;
493 /* Invalidate all members to initial values - does not close handles */
494 static void track_info_wipe(struct track_info * info)
496 info->id3_hid = ERR_HANDLE_NOT_FOUND;
497 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
498 #ifdef HAVE_ALBUMART
499 int i;
500 FOREACH_ALBUMART(i)
501 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
502 #endif
503 #ifdef HAVE_CODEC_BUFFERING
504 info->codec_hid = ERR_HANDLE_NOT_FOUND;
505 #endif
506 info->audio_hid = ERR_HANDLE_NOT_FOUND;
507 info->filesize = 0;
511 /** --- Track list --- **/
513 /* Initialize the track list */
514 static void track_list_init(void)
516 int i;
517 for (i = 0; i < TRACK_LIST_LEN; i++)
518 track_info_wipe(&track_list.tracks[i]);
520 track_list.start = track_list.end = track_list.current;
523 /* Return number of items allocated in the list */
524 static unsigned int track_list_count(void)
526 return track_list.end - track_list.start;
529 /* Return true if the list is empty */
530 static inline bool track_list_empty(void)
532 return track_list.end == track_list.start;
535 /* Returns true if the list is holding the maximum number of items */
536 static bool track_list_full(void)
538 return track_list.end - track_list.start >= TRACK_LIST_LEN;
541 /* Test if the index is within the allocated range */
542 static bool track_list_in_range(int pos)
544 return (int)(pos - track_list.start) >= 0 &&
545 (int)(pos - track_list.end) < 0;
548 static struct track_info * track_list_entry(int pos)
550 return &track_list.tracks[pos & TRACK_LIST_MASK];
553 /* Return the info of the last allocation plus an offset, NULL if result is
554 out of bounds */
555 static struct track_info * track_list_last(int offset)
557 /* Last is before the end since the end isn't inclusive */
558 unsigned int pos = track_list.end + offset - 1;
560 if (!track_list_in_range(pos))
561 return NULL;
563 return track_list_entry(pos);
566 /* Allocate space at the end for another track if not full */
567 static struct track_info * track_list_alloc_track(void)
569 if (track_list_full())
570 return NULL;
572 return track_list_entry(track_list.end++);
575 /* Remove the last track entry allocated in order to support backing out
576 of a track load */
577 static void track_list_unalloc_track(void)
579 if (track_list_empty())
580 return;
582 track_list.end--;
584 if (track_list.current == track_list.end &&
585 track_list.current != track_list.start)
587 /* Current _must_ remain within bounds */
588 track_list.current--;
592 /* Return current track plus an offset, NULL if result is out of bounds */
593 static struct track_info * track_list_current(int offset)
595 unsigned int pos = track_list.current + offset;
597 if (!track_list_in_range(pos))
598 return NULL;
600 return track_list_entry(pos);
603 /* Return current based upon what's intended that the user sees - not
604 necessarily where decoding is taking place */
605 static struct track_info * track_list_user_current(int offset)
607 if (skip_pending == TRACK_SKIP_AUTO ||
608 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
610 offset--;
613 return track_list_current(offset);
616 /* Advance current track by an offset, return false if result is out of
617 bounds */
618 static struct track_info * track_list_advance_current(int offset)
620 unsigned int pos = track_list.current + offset;
622 if (!track_list_in_range(pos))
623 return NULL;
625 track_list.current = pos;
626 return track_list_entry(pos);
629 /* Clear tracks in the list, optionally preserving the current track -
630 returns 'false' if the operation was changed */
631 enum track_clear_action
633 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
634 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
635 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
638 static void track_list_clear(enum track_clear_action action)
640 logf("%s(%d)", __func__, (int)action);
642 /* Don't care now since rebuffering is imminent */
643 buf_set_watermark(0);
645 if (action != TRACK_LIST_CLEAR_ALL)
647 struct track_info *cur = track_list_current(0);
649 if (!cur || cur->id3_hid < 0)
650 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
653 /* Noone should see this progressing */
654 int start = track_list.start;
655 int current = track_list.current;
656 int end = track_list.end;
658 track_list.start = current;
660 switch (action)
662 case TRACK_LIST_CLEAR_ALL:
663 /* Result: .start = .current, .end = .current */
664 track_list.end = current;
665 break;
667 case TRACK_LIST_KEEP_CURRENT:
668 /* Result: .start = .current, .end = .current + 1 */
669 track_list.end = current + 1;
670 break;
672 case TRACK_LIST_KEEP_NEW:
673 /* Result: .start = .current, .end = .end */
674 end = current;
675 break;
678 /* Close all open handles in the range except the for the current track
679 if preserving that */
680 while (start != end)
682 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
684 struct track_info *info =
685 &track_list.tracks[start & TRACK_LIST_MASK];
687 /* If this is the in-progress load, abort it */
688 if (in_progress_id3_hid >= 0 &&
689 info->id3_hid == in_progress_id3_hid)
691 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
694 track_info_close(info);
697 start++;
702 /** --- Audio buffer -- **/
704 /* What size is needed for the scratch buffer? */
705 static size_t scratch_mem_size(void)
707 size_t size = sizeof (struct audio_scratch_memory);
709 if (global_settings.cuesheet)
710 size += sizeof (struct cuesheet);
712 return size;
715 /* Initialize the memory area where data is stored that is only used when
716 playing audio and anything depending upon it */
717 static void scratch_mem_init(void *mem)
719 audio_scratch_memory = (struct audio_scratch_memory *)mem;
720 id3_write_locked(UNBUFFERED_ID3, NULL);
721 id3_write(CODEC_ID3, NULL);
722 ci.id3 = id3_get(CODEC_ID3);
723 audio_scratch_memory->curr_cue = NULL;
725 if (global_settings.cuesheet)
727 audio_scratch_memory->curr_cue =
728 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
729 sizeof (struct audio_scratch_memory));
733 static int audiobuf_handle;
734 #define AUDIO_BUFFER_RESERVE (256*1024)
735 static size_t filebuflen;
738 size_t audio_buffer_size(void)
740 if (audiobuf_handle > 0)
741 return filebuflen - AUDIO_BUFFER_RESERVE;
742 return 0;
745 size_t audio_buffer_available(void)
747 size_t size = 0;
748 size_t core_size = core_available();
749 if (audiobuf_handle > 0) /* if allocated return what we can give */
750 size = filebuflen - AUDIO_BUFFER_RESERVE - 128;
751 return MAX(core_size, size);
754 /* Set up the audio buffer for playback
755 * filebuflen must be pre-initialized with the maximum size */
756 static void audio_reset_buffer_noalloc(void* filebuf)
759 * Layout audio buffer as follows:
760 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
763 /* see audio_get_recording_buffer if this is modified */
764 logf("%s()", __func__);
766 /* If the setup of anything allocated before the file buffer is
767 changed, do check the adjustments after the buffer_alloc call
768 as it will likely be affected and need sliding over */
770 /* Initially set up file buffer as all space available */
771 size_t allocsize;
773 /* Subtract whatever voice needs */
774 allocsize = talkbuf_init(filebuf);
775 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
776 if (allocsize > filebuflen)
777 goto bufpanic;
779 filebuf += allocsize;
780 filebuflen -= allocsize;
782 if (talk_voice_required())
784 /* Need a space for voice PCM output */
785 allocsize = voicebuf_init(filebuf + filebuflen);
787 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
788 if (allocsize > filebuflen)
789 goto bufpanic;
791 filebuflen -= allocsize;
794 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
795 allocsize = pcmbuf_init(filebuf + filebuflen);
797 /* Make sure filebuflen is a pointer sized multiple after adjustment */
798 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
799 if (allocsize > filebuflen)
800 goto bufpanic;
802 filebuflen -= allocsize;
804 /* Scratch memory */
805 allocsize = scratch_mem_size();
806 if (allocsize > filebuflen)
807 goto bufpanic;
809 scratch_mem_init(filebuf);
810 filebuf += allocsize;
811 filebuflen -= allocsize;
813 buffering_reset(filebuf, filebuflen);
815 /* Clear any references to the file buffer */
816 buffer_state = AUDIOBUF_STATE_INITIALIZED;
818 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
819 /* Make sure everything adds up - yes, some info is a bit redundant but
820 aids viewing and the summation of certain variables should add up to
821 the location of others. */
823 logf("fbuf: %08X", (unsigned)filebuf);
824 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
825 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
826 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
828 #endif
830 return;
832 bufpanic:
833 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
836 /* Buffer must not move. */
837 static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
839 struct queue_event ev;
840 static const long filter_list[][2] =
842 /* codec messages */
843 { Q_AUDIO_PLAY, Q_AUDIO_PLAY },
845 /* filebuflen is, at this point, the buffering.c buffer size,
846 * i.e. the audiobuf except voice, scratch mem, pcm, ... */
847 ssize_t extradata_size = old_size - filebuflen;
848 /* check what buflib requests */
849 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
850 ssize_t size = (ssize_t)old_size - wanted_size;
851 /* keep at least 256K for the buffering */
852 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE)
853 return BUFLIB_CB_CANNOT_SHRINK;
856 /* TODO: Do it without stopping playback, if possible */
857 long offset = audio_current_track()->offset;
858 bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
859 /* There's one problem with stoping and resuming: If it happens in a too
860 * frequent fashion, the codecs lose the resume postion and playback
861 * begins from the beginning.
862 * To work around use queue_post() to effectively delay the resume in case
863 * we're called another time. However this has another problem: id3->offset
864 * gets zero since playback is stopped. Therefore, try to peek at the
865 * queue_post from the last call to get the correct offset. This also
866 * lets us conviniently remove the queue event so Q_AUDIO_PLAY is only
867 * processed once. */
868 bool play_queued = queue_peek_ex(&audio_queue, &ev, QPEEK_REMOVE_EVENTS, filter_list);
870 if (playing && offset > 0) /* current id3->offset is king */
871 ev.data = offset;
873 /* don't call audio_hard_stop() as it frees this handle */
874 if (thread_self() == audio_thread_id)
875 { /* inline case Q_AUDIO_STOP (audio_hard_stop() response
876 * if we're in the audio thread */
877 audio_stop_playback();
878 queue_clear(&audio_queue);
880 else
881 audio_queue_send(Q_AUDIO_STOP, 1);
882 #ifdef PLAYBACK_VOICE
883 voice_stop();
884 #endif
885 /* we should be free to change the buffer now
886 * set final buffer size before calling audio_reset_buffer_noalloc()
887 * (now it's the total size, the call will subtract voice etc) */
888 filebuflen = size;
889 switch (hints & BUFLIB_SHRINK_POS_MASK)
891 case BUFLIB_SHRINK_POS_BACK:
892 core_shrink(handle, start, size);
893 audio_reset_buffer_noalloc(start);
894 break;
895 case BUFLIB_SHRINK_POS_FRONT:
896 core_shrink(handle, start + wanted_size, size);
897 audio_reset_buffer_noalloc(start + wanted_size);
898 break;
900 if (playing || play_queued)
902 /* post, to make subsequent calls not break the resume position */
903 audio_queue_post(Q_AUDIO_PLAY, ev.data);
906 return BUFLIB_CB_OK;
909 static struct buflib_callbacks ops = {
910 .move_callback = NULL,
911 .shrink_callback = shrink_callback,
914 static void audio_reset_buffer(void)
916 if (audiobuf_handle > 0)
918 core_free(audiobuf_handle);
919 audiobuf_handle = 0;
921 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
922 unsigned char *filebuf = core_get_data(audiobuf_handle);
924 audio_reset_buffer_noalloc(filebuf);
927 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
928 static void audio_update_filebuf_watermark(int seconds)
930 size_t bytes = 0;
932 #ifdef HAVE_DISK_STORAGE
933 int spinup = ata_spinup_time();
935 if (seconds == 0)
937 /* By current setting */
938 seconds = buffer_margin;
940 else
942 /* New setting */
943 buffer_margin = seconds;
945 if (buf_get_watermark() == 0)
947 /* Write a watermark only if the audio thread already did so for
948 itself or it will fail to set the event and the watermark - if
949 it hasn't yet, it will use the new setting when it does */
950 return;
954 if (spinup)
955 seconds += (spinup / HZ) + 1;
956 else
957 seconds += 5;
959 seconds += buffer_margin;
960 #else
961 /* flash storage */
962 seconds = 1;
963 #endif
965 /* Watermark is a function of the bitrate of the last track in the buffer */
966 struct mp3entry *id3 = NULL;
967 struct track_info *info = track_list_last(0);
969 if (info)
970 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
972 if (id3)
974 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
976 bytes = id3->bitrate * (1000/8) * seconds;
978 else
980 /* Bitrate has no meaning to buffering margin for atomic audio -
981 rebuffer when it's the only track left unless it's the only
982 track that fits, in which case we should avoid constant buffer
983 low events */
984 if (track_list_count() > 1)
985 bytes = info->filesize + 1;
988 else
990 /* Then set the minimum - this should not occur anyway */
991 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
992 track_list.start, track_list.current, track_list.end);
995 /* Actually setting zero disables the notification and we use that
996 to detect that it has been reset */
997 buf_set_watermark(MAX(bytes, 1));
998 logf("fwmark: %lu", (unsigned long)bytes);
1002 /** -- Track change notification -- **/
1004 /* Check the pcmbuf track changes and return write the message into the event
1005 if there are any */
1006 static inline bool audio_pcmbuf_track_change_scan(void)
1008 if (track_change.out != track_change.in)
1010 track_change.out++;
1011 return true;
1014 return false;
1017 /* Clear outstanding track change posts */
1018 static inline void audio_pcmbuf_track_change_clear(void)
1020 track_change.out = track_change.in;
1023 /* Post a track change notification - called by audio ISR */
1024 static inline void audio_pcmbuf_track_change_post(void)
1026 track_change.in++;
1030 /** --- Helper functions --- **/
1032 /* Removes messages that might end up in the queue before or while processing
1033 a manual track change. Responding to them would be harmful since they
1034 belong to a previous track's playback period. Anything that would generate
1035 the stale messages must first be put into a state where it will not do so.
1037 static void audio_clear_track_notifications(void)
1039 static const long filter_list[][2] =
1041 /* codec messages */
1042 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
1043 /* track change messages */
1044 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
1047 const int filter_count = ARRAYLEN(filter_list) - 1;
1049 /* Remove any pcmbuf notifications */
1050 pcmbuf_monitor_track_change(false);
1051 audio_pcmbuf_track_change_clear();
1053 /* Scrub the audio queue of the old mold */
1054 while (queue_peek_ex(&audio_queue, NULL,
1055 filter_count | QPEEK_REMOVE_EVENTS,
1056 filter_list))
1058 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
1062 /* Takes actions based upon track load status codes */
1063 static void audio_handle_track_load_status(int trackstat)
1065 switch (trackstat)
1067 case LOAD_TRACK_ERR_NO_MORE:
1068 if (track_list_count() > 0)
1069 break;
1071 case LOAD_TRACK_ERR_START_CODEC:
1072 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
1073 break;
1075 default:
1076 break;
1080 /* Announce the end of playing the current track */
1081 static void audio_playlist_track_finish(void)
1083 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1084 struct mp3entry *id3 = valid_mp3entry(ply_id3);
1086 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
1088 if (id3)
1090 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
1091 prev_track_elapsed = id3->elapsed;
1093 else
1095 prev_track_elapsed = 0;
1099 /* Announce the beginning of the new track */
1100 static void audio_playlist_track_change(void)
1102 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
1104 if (id3)
1105 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
1107 position_key = pcmbuf_get_position_key();
1109 playlist_update_resume_info(id3);
1112 /* Change the data for the next track and send the event */
1113 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1115 id3_write_locked(NEXTTRACK_ID3, id3_next);
1116 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1117 id3_get(NEXTTRACK_ID3));
1120 /* Bring the user current mp3entry up to date and set a new offset for the
1121 buffered metadata */
1122 static void playing_id3_sync(struct track_info *user_info, off_t offset)
1124 id3_mutex_lock();
1126 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1127 struct mp3entry *playing_id3 = id3_get(PLAYING_ID3);
1129 pcm_play_lock();
1131 unsigned long e = playing_id3->elapsed;
1132 unsigned long o = playing_id3->offset;
1134 id3_write(PLAYING_ID3, id3);
1136 if (offset < 0)
1138 playing_id3->elapsed = e;
1139 playing_id3->offset = o;
1140 offset = 0;
1143 pcm_play_unlock();
1145 if (id3)
1146 id3->offset = offset;
1148 id3_mutex_unlock();
1151 /* Wipe-out track metadata - current is optional */
1152 static void wipe_track_metadata(bool current)
1154 id3_mutex_lock();
1156 if (current)
1157 id3_write(PLAYING_ID3, NULL);
1159 id3_write(NEXTTRACK_ID3, NULL);
1160 id3_write(UNBUFFERED_ID3, NULL);
1162 id3_mutex_unlock();
1165 /* Called when buffering is completed on the last track handle */
1166 static void filling_is_finished(void)
1168 logf("last track finished buffering");
1170 /* There's no more to load or watch for */
1171 buf_set_watermark(0);
1172 filling = STATE_FINISHED;
1175 /* Stop the codec decoding or waiting for its data to be ready - returns
1176 'false' if the codec ended up stopped */
1177 static bool halt_decoding_track(bool stop)
1179 /* If it was waiting for us to clear the buffer to make a rebuffer
1180 happen, it should cease otherwise codec_stop could deadlock waiting
1181 for the codec to go to its main loop - codec's request will now
1182 force-fail */
1183 bool retval = false;
1185 buf_signal_handle(ci.audio_hid, true);
1187 if (stop)
1188 codec_stop();
1189 else
1190 retval = codec_pause();
1192 audio_clear_track_notifications();
1194 /* We now know it's idle and not waiting for buffered data */
1195 buf_signal_handle(ci.audio_hid, false);
1197 codec_skip_pending = false;
1198 codec_seeking = false;
1200 return retval;
1203 /* Wait for any in-progress fade to complete */
1204 static void audio_wait_fade_complete(void)
1206 /* Just loop until it's done */
1207 while (pcmbuf_fading())
1208 sleep(0);
1211 /* End the ff/rw mode */
1212 static void audio_ff_rewind_end(void)
1214 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1215 section */
1216 if (ff_rw_mode)
1218 ff_rw_mode = false;
1220 if (codec_seeking)
1222 /* Clear the buffer */
1223 pcmbuf_play_stop();
1224 audio_pcmbuf_sync_position();
1227 if (play_status != PLAY_PAUSED)
1229 /* Seeking-while-playing, resume PCM playback */
1230 pcmbuf_pause(false);
1235 /* Complete the codec seek */
1236 static void audio_complete_codec_seek(void)
1238 /* If a seek completed while paused, 'paused' is true.
1239 * If seeking from seek mode, 'ff_rw_mode' is true. */
1240 if (codec_seeking)
1242 audio_ff_rewind_end();
1243 codec_seeking = false; /* set _after_ the call! */
1245 /* else it's waiting and we must repond */
1248 /* Get the current cuesheet pointer */
1249 static inline struct cuesheet * get_current_cuesheet(void)
1251 return audio_scratch_memory->curr_cue;
1254 /* Read the cuesheet from the buffer */
1255 static void buf_read_cuesheet(int handle_id)
1257 struct cuesheet *cue = get_current_cuesheet();
1259 if (!cue || handle_id < 0)
1260 return;
1262 bufread(handle_id, sizeof (struct cuesheet), cue);
1265 /* Backend to peek/current/next track metadata interface functions -
1266 fill in the mp3entry with as much information as we may obtain about
1267 the track at the specified offset from the user current track -
1268 returns false if no information exists with us */
1269 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1271 if (play_status == PLAY_STOPPED)
1272 return false;
1274 if (id3->path[0] != '\0')
1275 return true; /* Already filled */
1277 struct track_info *info = track_list_user_current(offset);
1279 if (!info)
1281 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1283 if (offset > 0 && track_list_user_current(offset - 1))
1285 /* Try the unbuffered id3 since we're moving forward */
1286 if (ub_id3->path[0] != '\0')
1288 copy_mp3entry(id3, ub_id3);
1289 return true;
1293 else if (bufreadid3(info->id3_hid, id3))
1295 id3->cuesheet = NULL;
1296 return true;
1299 /* We didn't find the ID3 metadata, so we fill it with the little info we
1300 have and return that */
1302 char path[MAX_PATH+1];
1303 if (playlist_peek(offset, path, sizeof (path)))
1305 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1306 /* Try to get it from the database */
1307 if (!tagcache_fill_tags(id3, path))
1308 #endif
1310 /* By now, filename is the only source of info */
1311 fill_metadata_from_path(id3, path);
1314 return true;
1317 wipe_mp3entry(id3);
1319 return false;
1322 /* Get a resume rewind adjusted offset from the ID3 */
1323 static unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1325 unsigned long offset = id3->offset;
1326 size_t resume_rewind = global_settings.resume_rewind *
1327 id3->bitrate * (1000/8);
1329 if (offset < resume_rewind)
1330 offset = 0;
1331 else
1332 offset -= resume_rewind;
1334 return offset;
1337 /* Get the codec into ram and initialize it - keep it if it's ready */
1338 static bool audio_init_codec(struct track_info *track_info,
1339 struct mp3entry *track_id3)
1341 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1342 int hid = ERR_HANDLE_NOT_FOUND;
1344 if (codt_loaded != AFMT_UNKNOWN)
1346 int codt = get_audio_base_codec_type(track_id3->codectype);
1348 if (codt == codt_loaded)
1350 /* Codec is the same base type */
1351 logf("Reusing prev. codec: %d", track_id3->codectype);
1352 #ifdef HAVE_CODEC_BUFFERING
1353 /* Close any buffered codec (we could have skipped directly to a
1354 format transistion that is the same format as the current track
1355 and the buffered one is no longer needed) */
1356 track_info_close_handle(&track_info->codec_hid);
1357 #endif
1358 return true;
1360 else
1362 /* New codec - first make sure the old one's gone */
1363 logf("Removing prev. codec: %d", codt_loaded);
1364 codec_unload();
1368 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1370 #ifdef HAVE_CODEC_BUFFERING
1371 /* Codec thread will close the handle even if it fails and will load from
1372 storage if hid is not valid or the buffer load fails */
1373 hid = track_info->codec_hid;
1374 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1375 #endif
1377 return codec_load(hid, track_id3->codectype);
1378 (void)track_info; /* When codec buffering isn't supported */
1381 /* Start the codec for the current track scheduled to be decoded */
1382 static bool audio_start_codec(bool auto_skip)
1384 struct track_info *info = track_list_current(0);
1385 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1387 if (!cur_id3)
1388 return false;
1390 buf_pin_handle(info->id3_hid, true);
1392 if (!audio_init_codec(info, cur_id3))
1394 buf_pin_handle(info->id3_hid, false);
1395 return false;
1398 #ifdef HAVE_TAGCACHE
1399 bool autoresume_enable = global_settings.autoresume_enable;
1401 if (autoresume_enable && !cur_id3->offset)
1403 /* Resume all manually selected tracks */
1404 bool resume = !auto_skip;
1406 /* Send the "buffer" event to obtain the resume position for the codec */
1407 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1409 if (!resume)
1411 /* Automatic skip - do further tests to see if we should just
1412 ignore any autoresume position */
1413 int autoresume_automatic = global_settings.autoresume_automatic;
1415 switch (autoresume_automatic)
1417 case AUTORESUME_NEXTTRACK_ALWAYS:
1418 /* Just resume unconditionally */
1419 resume = true;
1420 break;
1421 case AUTORESUME_NEXTTRACK_NEVER:
1422 /* Force-rewind it */
1423 break;
1424 default:
1425 /* Not "never resume" - pass resume filter? */
1426 resume = autoresumable(cur_id3);
1430 if (!resume)
1431 cur_id3->offset = 0;
1433 logf("%s: Set offset for %s to %lX\n", __func__,
1434 cur_id3->title, cur_id3->offset);
1436 #endif /* HAVE_TAGCACHE */
1438 /* Rewind the required amount - if an autoresume was done, this also rewinds
1439 that by the setting's amount
1441 It would be best to have bookkeeping about whether or not the track
1442 sounded or not since skipping to it or else skipping to it while paused
1443 and back again will cause accumulation of silent rewinds - that's not
1444 our job to track directly nor could it be in any reasonable way
1446 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1448 /* Update the codec API with the metadata and track info */
1449 id3_write(CODEC_ID3, cur_id3);
1451 ci.audio_hid = info->audio_hid;
1452 ci.filesize = info->filesize;
1453 buf_set_base_handle(info->audio_hid);
1455 /* All required data is now available for the codec */
1456 codec_go();
1458 #ifdef HAVE_TAGCACHE
1459 if (!autoresume_enable || cur_id3->offset)
1460 #endif
1462 /* Send the "buffer" event now */
1463 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1466 buf_pin_handle(info->id3_hid, false);
1467 return true;
1469 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1473 /** --- Audio thread --- **/
1475 /* Load and parse a cuesheet for the file - returns false if the buffer
1476 is full */
1477 static bool audio_load_cuesheet(struct track_info *info,
1478 struct mp3entry *track_id3)
1480 struct cuesheet *cue = get_current_cuesheet();
1481 track_id3->cuesheet = NULL;
1483 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1485 /* If error other than a full buffer, then mark it "unsupported" to
1486 avoid reloading attempt */
1487 int hid = ERR_UNSUPPORTED_TYPE;
1488 struct cuesheet_file cue_file;
1490 #ifdef HAVE_IO_PRIORITY
1491 buf_back_off_storage(true);
1492 #endif
1493 if (look_for_cuesheet_file(track_id3, &cue_file))
1495 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1497 if (hid >= 0)
1499 void *cuesheet = NULL;
1500 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1502 if (parse_cuesheet(&cue_file, (struct cuesheet *)cuesheet))
1504 /* Indicate cuesheet is present (while track remains
1505 buffered) */
1506 track_id3->cuesheet = cue;
1508 else
1510 bufclose(hid);
1511 hid = ERR_UNSUPPORTED_TYPE;
1516 #ifdef HAVE_IO_PRIORITY
1517 buf_back_off_storage(false);
1518 #endif
1519 if (hid == ERR_BUFFER_FULL)
1521 logf("buffer is full for now (%s)", __func__);
1522 return false;
1524 else
1526 if (hid < 0)
1527 logf("Cuesheet loading failed");
1529 info->cuesheet_hid = hid;
1533 return true;
1536 #ifdef HAVE_ALBUMART
1537 /* Load any album art for the file - returns false if the buffer is full */
1538 static bool audio_load_albumart(struct track_info *info,
1539 struct mp3entry *track_id3)
1541 int i;
1542 FOREACH_ALBUMART(i)
1544 struct bufopen_bitmap_data user_data;
1545 int *aa_hid = &info->aa_hid[i];
1546 int hid = ERR_UNSUPPORTED_TYPE;
1548 /* albumart_slots may change during a yield of bufopen,
1549 * but that's no problem */
1550 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1551 !albumart_slots[i].used)
1552 continue;
1554 memset(&user_data, 0, sizeof(user_data));
1555 user_data.dim = &albumart_slots[i].dim;
1557 #ifdef HAVE_IO_PRIORITY
1558 buf_back_off_storage(true);
1559 #endif
1561 /* We can only decode jpeg for embedded AA */
1562 if (track_id3->has_embedded_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1564 user_data.embedded_albumart = &track_id3->albumart;
1565 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1568 if (hid < 0 && hid != ERR_BUFFER_FULL)
1570 /* No embedded AA or it couldn't be loaded - try other sources */
1571 char path[MAX_PATH];
1573 if (find_albumart(track_id3, path, sizeof(path),
1574 &albumart_slots[i].dim))
1576 user_data.embedded_albumart = NULL;
1577 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1581 #ifdef HAVE_IO_PRIORITY
1582 buf_back_off_storage(false);
1583 #endif
1584 if (hid == ERR_BUFFER_FULL)
1586 logf("buffer is full for now (%s)", __func__);
1587 return false;
1589 else
1591 /* If error other than a full buffer, then mark it "unsupported"
1592 to avoid reloading attempt */
1593 if (hid < 0)
1595 logf("Album art loading failed");
1596 hid = ERR_UNSUPPORTED_TYPE;
1599 *aa_hid = hid;
1603 return true;
1605 #endif /* HAVE_ALBUMART */
1607 #ifdef HAVE_CODEC_BUFFERING
1608 /* Load a codec for the file onto the buffer - assumes we're working from the
1609 currently loading track - not called for the current track */
1610 static bool audio_buffer_codec(struct track_info *track_info,
1611 struct mp3entry *track_id3)
1613 /* This will not be the current track -> it cannot be the first and the
1614 current track cannot be ahead of buffering -> there is a previous
1615 track entry which is either current or ahead of the current */
1616 struct track_info *prev_info = track_list_last(-1);
1617 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1619 /* If the previous codec is the same as this one, there is no need to
1620 put another copy of it on the file buffer (in other words, only
1621 buffer codecs at format transitions) */
1622 if (prev_id3)
1624 int codt = get_audio_base_codec_type(track_id3->codectype);
1625 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1627 if (codt == prev_codt)
1629 logf("Reusing prev. codec: %d", prev_id3->codectype);
1630 return true;
1633 /* else just load it (harmless) */
1635 /* Load the codec onto the buffer if possible */
1636 const char *codec_fn = get_codec_filename(track_id3->codectype);
1637 if (!codec_fn)
1638 return false;
1640 char codec_path[MAX_PATH+1]; /* Full path to codec */
1641 codec_get_full_path(codec_path, codec_fn);
1643 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1645 if (track_info->codec_hid >= 0)
1647 logf("Buffered codec: %d", afmt);
1648 return true;
1651 return false;
1653 #endif /* HAVE_CODEC_BUFFERING */
1655 /* Load metadata for the next track (with bufopen). The rest of the track
1656 loading will be handled by audio_finish_load_track once the metadata has
1657 been actually loaded by the buffering thread.
1659 Each track is arranged in the buffer as follows:
1660 <id3|[cuesheet|][album art|][codec|]audio>
1662 The next will not be loaded until the previous succeeds if the buffer was
1663 full at the time. To put any metadata after audio would make those handles
1664 unmovable.
1666 static int audio_load_track(void)
1668 if (in_progress_id3_hid >= 0)
1670 /* There must be an info pointer if the in-progress id3 is even there */
1671 struct track_info *info = track_list_last(0);
1673 if (info->id3_hid == in_progress_id3_hid)
1675 if (filling == STATE_FILLING)
1677 /* Haven't finished the metadata but the notification is
1678 anticipated to come soon */
1679 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1680 return LOAD_TRACK_OK;
1682 else if (filling == STATE_FULL)
1684 /* Buffer was full trying to complete the load after the
1685 metadata finished, so attempt to continue - older handles
1686 should have been cleared already */
1687 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1688 filling = STATE_FILLING;
1689 buffer_event_finished_callback(&info->id3_hid);
1690 return LOAD_TRACK_OK;
1694 /* Some old, stray buffering message */
1695 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1696 return LOAD_TRACK_ERR_BUSY;
1699 filling = STATE_FILLING;
1701 struct track_info *info = track_list_alloc_track();
1702 if (info == NULL)
1704 /* List is full so stop buffering tracks - however, attempt to obtain
1705 metadata as the unbuffered id3 */
1706 logf("No free tracks");
1707 filling = STATE_FULL;
1710 playlist_peek_offset++;
1712 logf("Buffering track: s%u/c%u/e%u/p%d",
1713 track_list.start, track_list.current, track_list.end,
1714 playlist_peek_offset);
1716 /* Get track name from current playlist read position */
1717 int fd = -1;
1718 char name_buf[MAX_PATH + 1];
1719 const char *trackname;
1721 while (1)
1724 trackname = playlist_peek(playlist_peek_offset, name_buf,
1725 sizeof (name_buf));
1727 if (!trackname)
1728 break;
1730 /* Test for broken playlists by probing for the files */
1731 fd = open(trackname, O_RDONLY);
1732 if (fd >= 0)
1733 break;
1735 logf("Open failed");
1736 /* Skip invalid entry from playlist */
1737 playlist_skip_entry(NULL, playlist_peek_offset);
1739 /* Sync the playlist if it isn't finished */
1740 if (playlist_peek(playlist_peek_offset, NULL, 0))
1741 playlist_next(0);
1744 if (!trackname)
1746 /* No track - exhausted the playlist entries */
1747 logf("End-of-playlist");
1748 id3_write_locked(UNBUFFERED_ID3, NULL);
1750 if (filling != STATE_FULL)
1751 track_list_unalloc_track(); /* Free this entry */
1753 playlist_peek_offset--; /* Maintain at last index */
1755 /* We can end up here after the real last track signals its completion
1756 and miss the transition to STATE_FINISHED esp. if dropping the last
1757 songs of a playlist late in their load (2nd stage) */
1758 info = track_list_last(0);
1760 if (info && buf_handle_remaining(info->audio_hid) == 0)
1761 filling_is_finished();
1762 else
1763 filling = STATE_END_OF_PLAYLIST;
1765 return LOAD_TRACK_ERR_NO_MORE;
1768 /* Successfully opened the file - get track metadata */
1769 if (filling == STATE_FULL ||
1770 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1772 /* Buffer or track list is full */
1773 struct mp3entry *ub_id3;
1775 playlist_peek_offset--;
1777 /* Load the metadata for the first unbuffered track */
1778 ub_id3 = id3_get(UNBUFFERED_ID3);
1779 id3_mutex_lock();
1780 get_metadata(ub_id3, fd, trackname);
1781 id3_mutex_unlock();
1783 if (filling != STATE_FULL)
1785 track_list_unalloc_track();
1786 filling = STATE_FULL;
1789 logf("%s: buffer is full for now (%u tracks)", __func__,
1790 track_list_count());
1792 else
1794 /* Successful load initiation */
1795 info->filesize = filesize(fd);
1796 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1799 close(fd);
1800 return LOAD_TRACK_OK;
1803 /* Second part of the track loading: We now have the metadata available, so we
1804 can load the codec, the album art and finally the audio data.
1805 This is called on the audio thread after the buffering thread calls the
1806 buffering_handle_finished_callback callback. */
1807 static int audio_finish_load_track(struct track_info *info)
1809 int trackstat = LOAD_TRACK_OK;
1811 if (info->id3_hid != in_progress_id3_hid)
1813 /* We must not be here if not! */
1814 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1815 in_progress_id3_hid);
1816 return LOAD_TRACK_ERR_BUSY;
1819 /* The current track for decoding (there is always one if the list is
1820 populated) */
1821 struct track_info *cur_info = track_list_current(0);
1822 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1824 if (!track_id3)
1826 /* This is an error condition. Track cannot be played without valid
1827 metadata; skip the track. */
1828 logf("No metadata");
1829 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1830 goto audio_finish_load_track_exit;
1833 /* Try to load a cuesheet for the track */
1834 if (!audio_load_cuesheet(info, track_id3))
1836 /* No space for cuesheet on buffer, not an error */
1837 filling = STATE_FULL;
1838 goto audio_finish_load_track_exit;
1841 #ifdef HAVE_ALBUMART
1842 /* Try to load album art for the track */
1843 if (!audio_load_albumart(info, track_id3))
1845 /* No space for album art on buffer, not an error */
1846 filling = STATE_FULL;
1847 goto audio_finish_load_track_exit;
1849 #endif
1851 /* All handles available to external routines are ready - audio and codec
1852 information is private */
1854 if (info == track_list_user_current(0))
1856 /* Send only when the track handles could not all be opened ahead of
1857 time for the user's current track - otherwise everything is ready
1858 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1859 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1862 #ifdef HAVE_CODEC_BUFFERING
1863 /* Try to buffer a codec for the track */
1864 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1866 if (info->codec_hid == ERR_BUFFER_FULL)
1868 /* No space for codec on buffer, not an error */
1869 filling = STATE_FULL;
1870 logf("buffer is full for now (%s)", __func__);
1872 else
1874 /* This is an error condition, either no codec was found, or
1875 reading the codec file failed part way through, either way,
1876 skip the track */
1877 logf("No codec for: %s", track_id3->path);
1878 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1881 goto audio_finish_load_track_exit;
1883 #endif /* HAVE_CODEC_BUFFERING */
1885 /** Finally, load the audio **/
1886 size_t file_offset = 0;
1887 track_id3->elapsed = 0;
1889 if (track_id3->offset >= info->filesize)
1890 track_id3->offset = 0;
1892 logf("%s: set offset for %s to %lu\n", __func__,
1893 id3->title, (unsigned long)offset);
1895 /* Adjust for resume rewind so we know what to buffer - starting the codec
1896 calls it again, so we don't save it (and they shouldn't accumulate) */
1897 size_t offset = resume_rewind_adjusted_offset(track_id3);
1899 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1901 if (audiotype == TYPE_ATOMIC_AUDIO)
1902 logf("Loading atomic %d", track_id3->codectype);
1904 if (format_buffers_with_offset(track_id3->codectype))
1906 /* This format can begin buffering from any point */
1907 file_offset = offset;
1910 logf("load track: %s", track_id3->path);
1912 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1914 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1915 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1917 else
1919 /* No offset given or it is very minimal - begin at the first frame
1920 according to the metadata */
1921 file_offset = track_id3->first_frame_offset;
1924 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1926 if (hid >= 0)
1928 info->audio_hid = hid;
1930 if (info == cur_info)
1932 /* This is the current track to decode - should be started now */
1933 trackstat = LOAD_TRACK_READY;
1936 else
1938 /* Buffer could be full but not properly so if this is the only
1939 track! */
1940 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1942 filling = STATE_FULL;
1943 logf("Buffer is full for now (%s)", __func__);
1945 else
1947 /* Nothing to play if no audio handle - skip this */
1948 logf("Could not add audio data handle");
1949 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1953 audio_finish_load_track_exit:
1954 if (trackstat < LOAD_TRACK_OK)
1956 playlist_skip_entry(NULL, playlist_peek_offset);
1957 track_info_close(info);
1958 track_list_unalloc_track();
1960 if (playlist_peek(playlist_peek_offset, NULL, 0))
1961 playlist_next(0);
1963 playlist_peek_offset--;
1966 if (filling != STATE_FULL)
1968 /* Load next track - error or not */
1969 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1970 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1971 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1973 else
1975 /* Full */
1976 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1979 return trackstat;
1982 /* Start a new track load */
1983 static int audio_fill_file_buffer(void)
1985 if (play_status == PLAY_STOPPED)
1986 return LOAD_TRACK_ERR_FAILED;
1988 trigger_cpu_boost();
1990 /* Must reset the buffer before use if trashed or voice only - voice
1991 file size shouldn't have changed so we can go straight from
1992 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1993 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1994 audio_reset_buffer();
1996 logf("Starting buffer fill");
1998 int trackstat = audio_load_track();
2000 if (trackstat >= LOAD_TRACK_OK)
2002 if (track_list_current(0) == track_list_user_current(0))
2003 playlist_next(0);
2005 if (filling == STATE_FULL && !track_list_user_current(1))
2007 /* There are no user tracks on the buffer after this therefore
2008 this is the next track */
2009 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
2013 return trackstat;
2016 /* Discard unwanted tracks and start refill from after the specified playlist
2017 offset */
2018 static int audio_reset_and_rebuffer(
2019 enum track_clear_action action, int peek_offset)
2021 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
2023 id3_write_locked(UNBUFFERED_ID3, NULL);
2025 /* Remove unwanted tracks - caller must have ensured codec isn't using
2026 any */
2027 track_list_clear(action);
2029 /* Refill at specified position (-1 starts at index offset 0) */
2030 playlist_peek_offset = peek_offset;
2032 /* Fill the buffer */
2033 return audio_fill_file_buffer();
2036 /* Handle buffering events
2037 (Q_AUDIO_BUFFERING) */
2038 static void audio_on_buffering(int event)
2040 enum track_clear_action action;
2041 int peek_offset;
2043 if (track_list_empty())
2044 return;
2046 switch (event)
2048 case BUFFER_EVENT_BUFFER_LOW:
2049 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
2050 return; /* Should be nothing left to fill */
2052 /* Clear old tracks and continue buffering where it left off */
2053 action = TRACK_LIST_KEEP_NEW;
2054 peek_offset = playlist_peek_offset;
2055 break;
2057 case BUFFER_EVENT_REBUFFER:
2058 /* Remove all but the currently decoding track and redo buffering
2059 after that */
2060 action = TRACK_LIST_KEEP_CURRENT;
2061 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
2062 break;
2064 default:
2065 return;
2068 switch (skip_pending)
2070 case TRACK_SKIP_NONE:
2071 case TRACK_SKIP_AUTO:
2072 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2073 audio_reset_and_rebuffer(action, peek_offset);
2074 break;
2076 case TRACK_SKIP_AUTO_END_PLAYLIST:
2077 /* Already finished */
2078 break;
2080 default:
2081 /* Invalid */
2082 logf("Buffering call, inv. state: %d", (int)skip_pending);
2086 /* Handle starting the next track load
2087 (Q_AUDIO_FILL_BUFFER) */
2088 static void audio_on_fill_buffer(void)
2090 audio_handle_track_load_status(audio_fill_file_buffer());
2093 /* Handle posted load track finish event
2094 (Q_AUDIO_FINISH_LOAD_TRACK) */
2095 static void audio_on_finish_load_track(int id3_hid)
2097 struct track_info *info = track_list_last(0);
2099 if (!info || !buf_is_handle(id3_hid))
2100 return;
2102 if (info == track_list_user_current(1))
2104 /* Just loaded the metadata right after the current position */
2105 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
2108 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
2109 return; /* Not current track */
2111 bool is_user_current = info == track_list_user_current(0);
2113 if (is_user_current)
2115 /* Copy cuesheet */
2116 buf_read_cuesheet(info->cuesheet_hid);
2119 if (audio_start_codec(automatic_skip))
2121 if (is_user_current)
2123 /* Be sure all tagtree info is synchronized; it will be needed for the
2124 track finish event - the sync will happen when finalizing a track
2125 change otherwise */
2126 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2128 playing_id3_sync(info, -1);
2130 if (!was_valid)
2132 /* Playing id3 hadn't been updated yet because no valid track
2133 was yet available - treat like the first track */
2134 audio_playlist_track_change();
2138 else
2140 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2144 /* Called when handles other than metadata handles have finished buffering
2145 (Q_AUDIO_HANDLE_FINISHED) */
2146 static void audio_on_handle_finished(int hid)
2148 /* Right now, only audio handles should end up calling this */
2149 if (filling == STATE_END_OF_PLAYLIST)
2151 struct track_info *info = track_list_last(0);
2153 /* Really we don't know which order the handles will actually complete
2154 to zero bytes remaining since another thread is doing it - be sure
2155 it's the right one */
2156 if (info && info->audio_hid == hid)
2158 /* This was the last track in the playlist and we now have all the
2159 data we need */
2160 filling_is_finished();
2165 /* Called to make an outstanding track skip the current track and to send the
2166 transition events */
2167 static void audio_finalise_track_change(void)
2169 switch (skip_pending)
2171 case TRACK_SKIP_NONE: /* Manual skip */
2172 break;
2174 case TRACK_SKIP_AUTO:
2175 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2177 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2178 audio_playlist_track_finish();
2180 if (!playlist_peek(playlist_delta, NULL, 0))
2182 /* Track ended up rejected - push things ahead like the codec blew
2183 it (because it was never started and now we're here where it
2184 should have been decoding the next track by now) - next, a
2185 directory change or end of playback will most likely happen */
2186 skip_pending = TRACK_SKIP_NONE;
2187 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2188 return;
2191 if (!playlist_delta)
2192 break;
2194 playlist_peek_offset -= playlist_delta;
2195 if (playlist_next(playlist_delta) >= 0)
2196 break;
2197 /* What!? Disappear? Hopeless bleak despair */
2199 /* Fallthrough */
2200 case TRACK_SKIP_AUTO_END_PLAYLIST:
2201 default: /* Invalid */
2202 filling = STATE_ENDED;
2203 audio_stop_playback();
2204 return;
2207 struct track_info *info = track_list_current(0);
2208 struct mp3entry *track_id3 = NULL;
2210 id3_mutex_lock();
2212 /* Update the current cuesheet if any and enabled */
2213 if (info)
2215 buf_read_cuesheet(info->cuesheet_hid);
2216 track_id3 = bufgetid3(info->id3_hid);
2219 id3_write(PLAYING_ID3, track_id3);
2221 /* The skip is technically over */
2222 skip_pending = TRACK_SKIP_NONE;
2224 /* Sync the next track information */
2225 info = track_list_current(1);
2227 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2228 id3_get(UNBUFFERED_ID3));
2230 id3_mutex_unlock();
2232 audio_playlist_track_change();
2235 /* Actually begin a transition and take care of the codec change - may complete
2236 it now or ask pcmbuf for notification depending on the type */
2237 static void audio_begin_track_change(enum pcm_track_change_type type,
2238 int trackstat)
2240 /* Even if the new track is bad, the old track must be finished off */
2241 pcmbuf_start_track_change(type);
2243 bool auto_skip = type != TRACK_CHANGE_MANUAL;
2245 if (!auto_skip)
2247 /* Manual track change happens now */
2248 audio_finalise_track_change();
2249 pcmbuf_sync_position_update();
2251 if (play_status == PLAY_STOPPED)
2252 return; /* Stopped us */
2255 if (trackstat >= LOAD_TRACK_OK)
2257 struct track_info *info = track_list_current(0);
2259 if (info->audio_hid < 0)
2260 return;
2262 /* Everything needed for the codec is ready - start it */
2263 if (audio_start_codec(auto_skip))
2265 if (!auto_skip)
2266 playing_id3_sync(info, -1);
2267 return;
2270 trackstat = LOAD_TRACK_ERR_START_CODEC;
2273 audio_handle_track_load_status(trackstat);
2276 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2277 static void audio_monitor_end_of_playlist(void)
2279 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2280 filling = STATE_ENDING;
2281 pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA);
2284 /* Codec has completed decoding the track
2285 (usually Q_AUDIO_CODEC_COMPLETE) */
2286 static void audio_on_codec_complete(int status)
2288 logf("%s(%d)", __func__, status);
2290 if (play_status == PLAY_STOPPED)
2291 return;
2293 /* If it didn't notify us first, don't expect "seek complete" message
2294 since the codec can't post it now - do things like it would have
2295 done */
2296 audio_complete_codec_seek();
2298 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2300 /* Old-hay on the ip-skay - codec has completed decoding
2302 Paused: We're not sounding it, so just remember that it happened
2303 and the resume will begin the transition
2305 Skipping: There was already a skip in progress, remember it and
2306 allow no further progress until the PCM from the previous
2307 song has finished
2309 codec_skip_pending = true;
2310 codec_skip_status = status;
2311 return;
2314 codec_skip_pending = false;
2316 int trackstat = LOAD_TRACK_OK;
2318 automatic_skip = true;
2319 skip_pending = TRACK_SKIP_AUTO;
2321 /* Does this track have an entry allocated? */
2322 struct track_info *info = track_list_advance_current(1);
2324 if (!info || info->audio_hid < 0)
2326 bool end_of_playlist = false;
2328 if (info)
2330 /* Track load is not complete - it might have stopped on a
2331 full buffer without reaching the audio handle or we just
2332 arrived at it early
2334 If this type is atomic and we couldn't get the audio,
2335 perhaps it would need to wrap to make the allocation and
2336 handles are in the way - to maximize the liklihood it can
2337 be allocated, clear all handles to reset the buffer and
2338 its indexes to 0 - for packet audio, this should not be an
2339 issue and a pointless full reload of all the track's
2340 metadata may be avoided */
2342 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2344 if (track_id3 &&
2345 get_audio_base_data_type(track_id3->codectype)
2346 == TYPE_PACKET_AUDIO)
2348 /* Continue filling after this track */
2349 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2350 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat);
2351 return;
2353 /* else rebuffer at this track; status applies to the track we
2354 want */
2356 else if (!playlist_peek(1, NULL, 0))
2358 /* Play sequence is complete - directory change or other playlist
2359 resequencing - the playlist must now be advanced in order to
2360 continue since a peek ahead to the next track is not possible */
2361 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2362 end_of_playlist = playlist_next(1) < 0;
2365 if (!end_of_playlist)
2367 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2368 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2370 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2372 /* Failed to find anything after all - do playlist switchover
2373 instead */
2374 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2375 end_of_playlist = playlist_next(1) < 0;
2379 if (end_of_playlist)
2381 audio_monitor_end_of_playlist();
2382 return;
2386 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat);
2389 /* Called when codec completes seek operation
2390 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2391 static void audio_on_codec_seek_complete(void)
2393 logf("%s()", __func__);
2394 audio_complete_codec_seek();
2395 codec_go();
2398 /* Called when PCM track change has completed
2399 (Q_AUDIO_TRACK_CHANGED) */
2400 static void audio_on_track_changed(void)
2402 /* Finish whatever is pending so that the WPS is in sync */
2403 audio_finalise_track_change();
2405 if (codec_skip_pending)
2407 /* Codec got ahead completing a short track - complete the
2408 codec's skip and begin the next */
2409 codec_skip_pending = false;
2410 audio_on_codec_complete(codec_skip_status);
2414 /* Begin playback from an idle state, transition to a new playlist or
2415 invalidate the buffer and resume (if playing).
2416 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2417 static void audio_start_playback(size_t offset, unsigned int flags)
2419 enum play_status old_status = play_status;
2421 if (flags & AUDIO_START_NEWBUF)
2423 /* Mark the buffer dirty - if not playing, it will be reset next
2424 time */
2425 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2426 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2429 if (old_status != PLAY_STOPPED)
2431 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2433 halt_decoding_track(true);
2435 automatic_skip = false;
2436 ff_rw_mode = false;
2438 if (flags & AUDIO_START_RESTART)
2440 /* Clear out some stuff to resume the current track where it
2441 left off */
2442 pcmbuf_play_stop();
2443 offset = id3_get(PLAYING_ID3)->offset;
2444 track_list_clear(TRACK_LIST_CLEAR_ALL);
2446 else
2448 /* This is more-or-less treated as manual track transition */
2449 /* Save resume information for current track */
2450 audio_playlist_track_finish();
2451 track_list_clear(TRACK_LIST_CLEAR_ALL);
2453 /* Indicate manual track change */
2454 pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
2455 wipe_track_metadata(true);
2458 /* Set after track finish event in case skip was in progress */
2459 skip_pending = TRACK_SKIP_NONE;
2461 else
2463 if (flags & AUDIO_START_RESTART)
2464 return; /* Must already be playing */
2466 /* Cold playback start from a stopped state */
2467 logf("%s(%lu): starting", __func__, offset);
2469 /* Set audio parameters */
2470 #if INPUT_SRC_CAPS != 0
2471 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2472 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2473 #endif
2474 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2475 sound_set_volume(global_settings.volume);
2476 #endif
2477 /* Be sure channel is audible */
2478 pcmbuf_fade(false, true);
2480 /* Update our state */
2481 play_status = PLAY_PLAYING;
2484 /* Codec's position should be available as soon as it knows it */
2485 position_key = pcmbuf_get_position_key();
2486 pcmbuf_sync_position_update();
2488 /* Start fill from beginning of playlist */
2489 playlist_peek_offset = -1;
2490 buf_set_base_handle(-1);
2492 /* Officially playing */
2493 queue_reply(&audio_queue, 1);
2495 /* Add these now - finish event for the first id3 will most likely be sent
2496 immediately */
2497 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2498 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2500 if (old_status == PLAY_STOPPED)
2502 /* Send coldstart event */
2503 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2506 /* Fill the buffer */
2507 int trackstat = audio_fill_file_buffer();
2509 if (trackstat >= LOAD_TRACK_OK)
2511 /* This is the currently playing track - get metadata, stat */
2512 playing_id3_sync(track_list_current(0), offset);
2514 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2516 /* Only if actually changing tracks... */
2517 if (!(flags & AUDIO_START_RESTART))
2518 audio_playlist_track_change();
2521 else
2523 /* Found nothing playable */
2524 audio_handle_track_load_status(trackstat);
2528 /* Stop playback and enter an idle state
2529 (usually Q_AUDIO_STOP) */
2530 static void audio_stop_playback(void)
2532 logf("%s()", __func__);
2534 if (play_status == PLAY_STOPPED)
2535 return;
2537 bool do_fade = global_settings.fade_on_stop && filling != STATE_ENDED;
2539 pcmbuf_fade(do_fade, false);
2541 /* Wait for fade-out */
2542 audio_wait_fade_complete();
2544 /* Stop the codec and unload it */
2545 halt_decoding_track(true);
2546 pcmbuf_play_stop();
2547 codec_unload();
2549 /* Save resume information - "filling" might have been set to
2550 "STATE_ENDED" by caller in order to facilitate end of playlist */
2551 audio_playlist_track_finish();
2553 skip_pending = TRACK_SKIP_NONE;
2554 automatic_skip = false;
2556 /* Close all tracks and mark them NULL */
2557 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2558 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2559 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2561 track_list_clear(TRACK_LIST_CLEAR_ALL);
2563 /* Update our state */
2564 ff_rw_mode = false;
2565 play_status = PLAY_STOPPED;
2567 wipe_track_metadata(true);
2569 /* Go idle */
2570 filling = STATE_IDLE;
2571 cancel_cpu_boost();
2574 /* Pause the playback of the current track
2575 (Q_AUDIO_PAUSE) */
2576 static void audio_on_pause(bool pause)
2578 logf("%s(%s)", __func__, pause ? "true" : "false");
2580 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2581 return;
2583 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2585 if (!pause && codec_skip_pending)
2587 /* Actually do the skip that is due - resets the status flag */
2588 audio_on_codec_complete(codec_skip_status);
2591 bool do_fade = global_settings.fade_on_stop;
2593 pcmbuf_fade(do_fade, !pause);
2595 if (!ff_rw_mode && !(do_fade && pause))
2597 /* Not in ff/rw mode - can actually change the audio state now */
2598 pcmbuf_pause(pause);
2602 /* Skip a certain number of tracks forwards or backwards
2603 (Q_AUDIO_SKIP) */
2604 static void audio_on_skip(void)
2606 id3_mutex_lock();
2608 /* Eat the delta to keep it synced, even if not playing */
2609 int toskip = skip_offset;
2610 skip_offset = 0;
2612 logf("%s(): %d", __func__, toskip);
2614 id3_mutex_unlock();
2616 if (play_status == PLAY_STOPPED)
2617 return;
2619 /* Force codec to abort this track */
2620 halt_decoding_track(true);
2622 /* Kill the ff/rw halt */
2623 ff_rw_mode = false;
2625 /* Manual skip */
2626 automatic_skip = false;
2628 /* If there was an auto skip in progress, there will be residual
2629 advancement of the playlist and/or track list so compensation will be
2630 required in order to end up in the right spot */
2631 int track_list_delta = toskip;
2632 int playlist_delta = toskip;
2634 if (skip_pending != TRACK_SKIP_NONE)
2636 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2637 track_list_delta--;
2639 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2640 playlist_delta--;
2643 audio_playlist_track_finish();
2644 skip_pending = TRACK_SKIP_NONE;
2646 /* Update the playlist current track now */
2647 while (playlist_next(playlist_delta) < 0)
2649 /* Manual skip out of range (because the playlist wasn't updated
2650 yet by us and so the check in audio_skip returned 'ok') - bring
2651 back into range */
2652 int d = toskip < 0 ? 1 : -1;
2654 while (!playlist_check(playlist_delta))
2656 if (playlist_delta == d)
2658 /* Had to move the opposite direction to correct, which is
2659 wrong - this is the end */
2660 filling = STATE_ENDED;
2661 audio_stop_playback();
2662 return;
2665 playlist_delta += d;
2666 track_list_delta += d;
2670 /* Adjust things by how much the playlist was manually moved */
2671 playlist_peek_offset -= playlist_delta;
2673 struct track_info *info = track_list_advance_current(track_list_delta);
2674 int trackstat = LOAD_TRACK_OK;
2676 if (!info || info->audio_hid < 0)
2678 /* We don't know the next track thus we know we don't have it */
2679 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2682 audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat);
2685 /* Skip to the next/previous directory
2686 (Q_AUDIO_DIR_SKIP) */
2687 static void audio_on_dir_skip(int direction)
2689 logf("%s(%d)", __func__, direction);
2691 id3_mutex_lock();
2692 skip_offset = 0;
2693 id3_mutex_unlock();
2695 if (play_status == PLAY_STOPPED)
2696 return;
2698 /* Force codec to abort this track */
2699 halt_decoding_track(true);
2701 /* Kill the ff/rw halt */
2702 ff_rw_mode = false;
2704 /* Manual skip */
2705 automatic_skip = false;
2707 audio_playlist_track_finish();
2709 /* Unless automatic and gapless, skips do not pend */
2710 skip_pending = TRACK_SKIP_NONE;
2712 /* Regardless of the return value we need to rebuffer. If it fails the old
2713 playlist will resume, else the next dir will start playing. */
2714 playlist_next_dir(direction);
2716 wipe_track_metadata(false);
2718 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2720 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2722 /* The day the music died - finish-off whatever is playing and call it
2723 quits */
2724 audio_monitor_end_of_playlist();
2725 return;
2728 audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat);
2731 /* Enter seek mode in order to start a seek
2732 (Q_AUDIO_PRE_FF_REWIND) */
2733 static void audio_on_pre_ff_rewind(void)
2735 logf("%s()", __func__);
2737 if (play_status == PLAY_STOPPED || ff_rw_mode)
2738 return;
2740 ff_rw_mode = true;
2742 audio_wait_fade_complete();
2744 if (play_status == PLAY_PAUSED)
2745 return;
2747 pcmbuf_pause(true);
2750 /* Seek the playback of the current track to the specified time
2751 (Q_AUDIO_FF_REWIND) */
2752 static void audio_on_ff_rewind(long time)
2754 logf("%s(%ld)", __func__, time);
2756 if (play_status == PLAY_STOPPED)
2757 return;
2759 enum track_skip_type pending = skip_pending;
2761 switch (pending)
2763 case TRACK_SKIP_NONE: /* The usual case */
2764 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2765 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2767 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2768 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2770 automatic_skip = false;
2772 /* Send event before clobbering the time */
2773 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2774 then skipping back to this track resumes properly. Something else
2775 should be sent. We're not _really_ finishing the track are we? */
2776 if (time == 0)
2777 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2779 id3->elapsed = time;
2780 queue_reply(&audio_queue, 1);
2782 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2784 /* Need this set in case ff/rw mode + error but _after_ the codec
2785 halt that will reset it */
2786 codec_seeking = true;
2788 /* If in transition, key will have changed - sync to it */
2789 position_key = pcmbuf_get_position_key();
2791 if (pending == TRACK_SKIP_AUTO)
2793 if (!track_list_advance_current(-1))
2795 /* Not in list - must rebuffer at the current playlist index */
2796 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2797 < LOAD_TRACK_OK)
2799 /* Codec is stopped */
2800 break;
2805 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2806 rebuffer is needed */
2807 skip_pending = TRACK_SKIP_NONE;
2808 struct track_info *cur_info = track_list_current(0);
2810 /* Track must complete the loading _now_ since a codec and audio
2811 handle are needed in order to do the seek */
2812 if (cur_info->audio_hid < 0 &&
2813 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2815 /* Call above should push any load sequence - no need for
2816 halt_decoding_track here if no skip was pending here because
2817 there would not be a codec started if no audio handle was yet
2818 opened */
2819 break;
2822 if (pending == TRACK_SKIP_AUTO)
2824 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2825 !audio_init_codec(cur_info, ci_id3))
2827 /* We should have still been able to get it - skip it and move
2828 onto the next one - like it or not this track is broken */
2829 break;
2832 /* Set the codec API to the correct metadata and track info */
2833 ci.audio_hid = cur_info->audio_hid;
2834 ci.filesize = cur_info->filesize;
2835 buf_set_base_handle(cur_info->audio_hid);
2838 if (!haltres)
2840 /* If codec must be (re)started, reset the offset */
2841 ci_id3->offset = 0;
2844 codec_seek(time);
2845 return;
2848 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2850 /* We cannot do this because the playlist must be reversed by one
2851 and it doesn't always return the same song when going backwards
2852 across boundaries as forwards (either because of randomization
2853 or inconsistency in deciding what the previous track should be),
2854 therefore the whole operation would often end up as nonsense -
2855 lock out seeking for a couple seconds */
2857 /* Sure as heck cancel seek mode too! */
2858 audio_ff_rewind_end();
2859 return;
2862 default:
2863 /* Won't see this */
2864 return;
2867 if (play_status == PLAY_STOPPED)
2869 /* Playback ended because of an error completing a track load */
2870 return;
2873 /* Always fake it as a codec start error which will handle mode
2874 cancellations and skip to the next track */
2875 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2878 /* Invalidates all but currently playing track
2879 (Q_AUDIO_FLUSH) */
2880 static void audio_on_audio_flush(void)
2882 logf("%s", __func__);
2884 if (track_list_empty())
2885 return; /* Nothing to flush out */
2887 switch (skip_pending)
2889 case TRACK_SKIP_NONE:
2890 case TRACK_SKIP_AUTO_END_PLAYLIST:
2891 /* Remove all but the currently playing track from the list and
2892 refill after that */
2893 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2894 playlist_peek_offset = 0;
2895 id3_write_locked(UNBUFFERED_ID3, NULL);
2896 audio_update_and_announce_next_track(NULL);
2898 /* Ignore return since it's about the next track, not this one */
2899 audio_fill_file_buffer();
2901 if (skip_pending == TRACK_SKIP_NONE)
2902 break;
2904 /* There's now a track after this one now - convert to auto skip -
2905 no skip should pend right now because multiple flush messages can
2906 be fired which would cause a restart in the below cases */
2907 skip_pending = TRACK_SKIP_NONE;
2908 audio_clear_track_notifications();
2909 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2910 break;
2912 case TRACK_SKIP_AUTO:
2913 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2914 /* Precisely removing what it already decoded for the next track is
2915 not possible so a restart is required in order to continue the
2916 currently playing track without the now invalid future track
2917 playing */
2918 audio_start_playback(0, AUDIO_START_RESTART);
2919 break;
2921 default: /* Nothing else is a state */
2922 break;
2926 #ifdef AUDIO_HAVE_RECORDING
2927 /* Load the requested encoder type
2928 (Q_AUDIO_LOAD_ENCODER) */
2929 static void audio_on_load_encoder(int afmt)
2931 bool res = true;
2933 if (play_status != PLAY_STOPPED)
2934 audio_stop_playback(); /* Can't load both types at once */
2935 else
2936 codec_unload(); /* Encoder still loaded, stop and unload it */
2938 if (afmt != AFMT_UNKNOWN)
2940 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2941 if (res)
2942 codec_go(); /* These are run immediately */
2945 queue_reply(&audio_queue, res);
2947 #endif /* AUDIO_HAVE_RECORDING */
2949 static void audio_thread(void)
2951 struct queue_event ev;
2953 pcm_postinit();
2955 while (1)
2957 switch (filling)
2959 /* Active states */
2960 case STATE_FULL:
2961 case STATE_END_OF_PLAYLIST:
2962 if (buf_get_watermark() == 0)
2964 /* End of buffering for now, let's calculate the watermark,
2965 register for a low buffer event and unboost */
2966 audio_update_filebuf_watermark(0);
2967 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2968 buffer_event_buffer_low_callback);
2970 /* Fall-through */
2971 case STATE_FINISHED:
2972 /* All data was buffered */
2973 cancel_cpu_boost();
2974 /* Fall-through */
2975 case STATE_FILLING:
2976 case STATE_ENDING:
2977 if (audio_pcmbuf_track_change_scan())
2979 /* Transfer notification to audio queue event */
2980 ev.id = Q_AUDIO_TRACK_CHANGED;
2981 ev.data = 1;
2983 else
2985 /* If doing auto skip, poll pcmbuf track notifications a bit
2986 faster to promply detect the transition */
2987 queue_wait_w_tmo(&audio_queue, &ev,
2988 skip_pending == TRACK_SKIP_NONE ?
2989 HZ/2 : HZ/10);
2991 break;
2993 /* Idle states */
2994 default:
2995 queue_wait(&audio_queue, &ev);
2997 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2998 switch (ev.id)
3000 #ifdef AUDIO_HAVE_RECORDING
3001 /* Must monitor the encoder message for recording so it can remove
3002 it if we process the insertion before it does. It cannot simply
3003 be removed from under recording however. */
3004 case Q_AUDIO_LOAD_ENCODER:
3005 break;
3006 #endif
3007 case SYS_USB_DISCONNECTED:
3008 filling = STATE_IDLE;
3009 break;
3011 default:
3012 if (filling == STATE_USB)
3013 continue;
3015 #endif /* CONFIG_PLATFORM */
3018 switch (ev.id)
3020 /** Codec and track change messages **/
3021 case Q_AUDIO_CODEC_COMPLETE:
3022 /* Codec is done processing track and has gone idle */
3023 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
3024 audio_on_codec_complete(ev.data);
3025 break;
3027 case Q_AUDIO_CODEC_SEEK_COMPLETE:
3028 /* Codec is done seeking */
3029 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
3030 audio_on_codec_seek_complete();
3031 break;
3033 case Q_AUDIO_TRACK_CHANGED:
3034 /* PCM track change done */
3035 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
3036 audio_on_track_changed();
3037 break;
3039 /** Control messages **/
3040 case Q_AUDIO_PLAY:
3041 LOGFQUEUE("audio < Q_AUDIO_PLAY");
3042 audio_start_playback(ev.data, 0);
3043 break;
3045 case Q_AUDIO_STOP:
3046 LOGFQUEUE("audio < Q_AUDIO_STOP");
3047 audio_stop_playback();
3048 if (ev.data != 0)
3049 queue_clear(&audio_queue);
3050 break;
3052 case Q_AUDIO_PAUSE:
3053 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
3054 audio_on_pause(ev.data);
3055 break;
3057 case Q_AUDIO_SKIP:
3058 LOGFQUEUE("audio < Q_AUDIO_SKIP");
3059 audio_on_skip();
3060 break;
3062 case Q_AUDIO_DIR_SKIP:
3063 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
3064 audio_on_dir_skip(ev.data);
3065 break;
3067 case Q_AUDIO_PRE_FF_REWIND:
3068 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
3069 audio_on_pre_ff_rewind();
3070 break;
3072 case Q_AUDIO_FF_REWIND:
3073 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
3074 audio_on_ff_rewind(ev.data);
3075 break;
3077 case Q_AUDIO_FLUSH:
3078 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
3079 audio_on_audio_flush();
3080 break;
3082 /** Buffering messages **/
3083 case Q_AUDIO_BUFFERING:
3084 /* some buffering event */
3085 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
3086 audio_on_buffering(ev.data);
3087 break;
3089 case Q_AUDIO_FILL_BUFFER:
3090 /* continue buffering next track */
3091 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
3092 audio_on_fill_buffer();
3093 break;
3095 case Q_AUDIO_FINISH_LOAD_TRACK:
3096 /* metadata is buffered */
3097 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
3098 audio_on_finish_load_track(ev.data);
3099 break;
3101 case Q_AUDIO_HANDLE_FINISHED:
3102 /* some other type is buffered */
3103 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3104 audio_on_handle_finished(ev.data);
3105 break;
3107 /** Miscellaneous messages **/
3108 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3109 /* buffer needs to be reinitialized */
3110 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3111 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3112 break;
3114 #ifdef HAVE_DISK_STORAGE
3115 case Q_AUDIO_UPDATE_WATERMARK:
3116 /* buffering watermark needs updating */
3117 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3118 audio_update_filebuf_watermark(ev.data);
3119 break;
3120 #endif /* HAVE_DISK_STORAGE */
3122 #ifdef AUDIO_HAVE_RECORDING
3123 case Q_AUDIO_LOAD_ENCODER:
3124 /* load an encoder for recording */
3125 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3126 audio_on_load_encoder(ev.data);
3127 break;
3128 #endif /* AUDIO_HAVE_RECORDING */
3130 case SYS_USB_CONNECTED:
3131 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3132 audio_stop_playback();
3133 #ifdef PLAYBACK_VOICE
3134 voice_stop();
3135 #endif
3136 filling = STATE_USB;
3137 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3138 break;
3140 case SYS_TIMEOUT:
3141 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3142 break;
3144 default:
3145 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3146 break;
3147 } /* end switch */
3148 } /* end while */
3152 /* --- Buffering callbacks --- */
3154 /* Called when fullness is below the watermark level */
3155 static void buffer_event_buffer_low_callback(void *data)
3157 logf("low buffer callback");
3158 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3159 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3160 (void)data;
3163 /* Called when handles must be discarded in order to buffer new data */
3164 static void buffer_event_rebuffer_callback(void *data)
3166 logf("rebuffer callback");
3167 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3168 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3169 (void)data;
3172 /* A handle has completed buffering and all required data is available */
3173 static void buffer_event_finished_callback(void *data)
3175 int hid = *(const int *)data;
3176 const enum data_type htype = buf_handle_data_type(hid);
3178 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3180 /* Limit queue traffic */
3181 switch (htype)
3183 case TYPE_ID3:
3184 /* The metadata handle for the last loaded track has been buffered.
3185 We can ask the audio thread to load the rest of the track's data. */
3186 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3187 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3188 break;
3190 case TYPE_PACKET_AUDIO:
3191 /* Strip any useless trailing tags that are left. */
3192 strip_tags(hid);
3193 /* Fall-through */
3194 case TYPE_ATOMIC_AUDIO:
3195 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3196 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3197 break;
3199 default:
3200 /* Don't care to know about these */
3201 break;
3206 /** -- Codec callbacks -- **/
3208 /* Update elapsed time for next PCM insert */
3209 void audio_codec_update_elapsed(unsigned long elapsed)
3211 #ifdef AB_REPEAT_ENABLE
3212 ab_position_report(elapsed);
3213 #endif
3214 /* Save in codec's id3 where it is used at next pcm insert */
3215 id3_get(CODEC_ID3)->elapsed = elapsed;
3218 /* Update offset for next PCM insert */
3219 void audio_codec_update_offset(size_t offset)
3221 /* Save in codec's id3 where it is used at next pcm insert */
3222 id3_get(CODEC_ID3)->offset = offset;
3225 /* Codec has finished running */
3226 void audio_codec_complete(int status)
3228 #ifdef AB_REPEAT_ENABLE
3229 if (status >= CODEC_OK)
3231 /* Normal automatic skip */
3232 ab_end_of_track_report();
3234 #endif
3236 LOGFQUEUE("codec > audio Q_AUDIO_CODEC_COMPLETE: %d", status);
3237 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, status);
3240 /* Codec has finished seeking */
3241 void audio_codec_seek_complete(void)
3243 LOGFQUEUE("codec > audio Q_AUDIO_CODEC_SEEK_COMPLETE");
3244 audio_queue_post(Q_AUDIO_CODEC_SEEK_COMPLETE, 0);
3248 /** --- Pcmbuf callbacks --- **/
3250 /* Update the elapsed and offset from the information cached during the
3251 PCM buffer insert */
3252 void audio_pcmbuf_position_callback(unsigned long elapsed, off_t offset,
3253 unsigned int key)
3255 if (key == position_key)
3257 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3258 id3->elapsed = elapsed;
3259 id3->offset = offset;
3263 /* Synchronize position info to the codec's */
3264 void audio_pcmbuf_sync_position(void)
3266 audio_pcmbuf_position_callback(ci.id3->elapsed, ci.id3->offset,
3267 pcmbuf_get_position_key());
3270 /* Post message from pcmbuf that the end of the previous track has just
3271 * been played */
3272 void audio_pcmbuf_track_change(bool pcmbuf)
3274 if (pcmbuf)
3276 /* Notify of the change in special-purpose semaphore object */
3277 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3278 audio_pcmbuf_track_change_post();
3280 else
3282 /* Safe to post directly to the queue */
3283 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3284 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3288 /* May pcmbuf start PCM playback when the buffer is full enough? */
3289 bool audio_pcmbuf_may_play(void)
3291 return play_status == PLAY_PLAYING && !ff_rw_mode;
3295 /** -- External interfaces -- **/
3297 /* Return the playback and recording status */
3298 int audio_status(void)
3300 unsigned int ret = play_status;
3302 #ifdef AUDIO_HAVE_RECORDING
3303 /* Do this here for constitency with mpeg.c version */
3304 ret |= pcm_rec_status();
3305 #endif
3307 return (int)ret;
3310 /* Clear all accumulated audio errors for playback and recording */
3311 void audio_error_clear(void)
3313 #ifdef AUDIO_HAVE_RECORDING
3314 pcm_rec_error_clear();
3315 #endif
3318 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3319 bool audio_peek_track(struct mp3entry *id3, int offset)
3321 bool retval = false;
3323 id3_mutex_lock();
3325 if (play_status != PLAY_STOPPED)
3327 id3->path[0] = '\0'; /* Null path means it should be filled now */
3328 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3329 id3->path[0] != '\0';
3332 id3_mutex_unlock();
3334 return retval;
3337 /* Return the mp3entry for the currently playing track */
3338 struct mp3entry * audio_current_track(void)
3340 struct mp3entry *id3;
3342 id3_mutex_lock();
3344 #ifdef AUDIO_FAST_SKIP_PREVIEW
3345 if (skip_offset != 0)
3347 /* This is a peekahead */
3348 id3 = id3_get(PLAYING_PEEK_ID3);
3349 audio_peek_track(id3, 0);
3351 else
3352 #endif
3354 /* Normal case */
3355 id3 = id3_get(PLAYING_ID3);
3356 audio_get_track_metadata(0, id3);
3359 id3_mutex_unlock();
3361 return id3;
3364 /* Obtains the mp3entry for the next track from the current */
3365 struct mp3entry * audio_next_track(void)
3367 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3369 id3_mutex_lock();
3371 #ifdef AUDIO_FAST_SKIP_PREVIEW
3372 if (skip_offset != 0)
3374 /* This is a peekahead */
3375 if (!audio_peek_track(id3, 1))
3376 id3 = NULL;
3378 else
3379 #endif
3381 /* Normal case */
3382 if (!audio_get_track_metadata(1, id3))
3383 id3 = NULL;
3386 id3_mutex_unlock();
3388 return id3;
3391 /* Start playback at the specified offset */
3392 void audio_play(long offset)
3394 logf("audio_play");
3396 #ifdef PLAYBACK_VOICE
3397 /* Truncate any existing voice output so we don't have spelling
3398 * etc. over the first part of the played track */
3399 talk_force_shutup();
3400 #endif
3402 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3403 audio_queue_send(Q_AUDIO_PLAY, offset);
3406 /* Stop playback if playing */
3407 void audio_stop(void)
3409 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3410 audio_queue_send(Q_AUDIO_STOP, 0);
3413 /* Pause playback if playing */
3414 void audio_pause(void)
3416 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3417 audio_queue_send(Q_AUDIO_PAUSE, true);
3420 /* This sends a stop message and the audio thread will dump all its
3421 subsequent messages */
3422 void audio_hard_stop(void)
3424 /* Stop playback */
3425 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3426 audio_queue_send(Q_AUDIO_STOP, 1);
3427 #ifdef PLAYBACK_VOICE
3428 voice_stop();
3429 #endif
3430 if (audiobuf_handle > 0)
3431 audiobuf_handle = core_free(audiobuf_handle);
3434 /* Resume playback if paused */
3435 void audio_resume(void)
3437 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3438 audio_queue_send(Q_AUDIO_PAUSE, false);
3441 /* Skip the specified number of tracks forward or backward from the current */
3442 void audio_skip(int offset)
3444 id3_mutex_lock();
3446 /* If offset has to be backed-out to stay in range, no skip is done */
3447 int accum = skip_offset + offset;
3449 while (offset != 0 && !playlist_check(accum))
3451 offset += offset < 0 ? 1 : -1;
3452 accum = skip_offset + offset;
3455 if (offset != 0)
3457 /* Accumulate net manual skip count since the audio thread last
3458 processed one */
3459 skip_offset = accum;
3461 system_sound_play(SOUND_TRACK_SKIP);
3463 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3465 #ifdef AUDIO_FAST_SKIP_PREVIEW
3466 /* Do this before posting so that the audio thread can correct us
3467 when things settle down - additionally, if audio gets a message
3468 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3469 handler a skip event with the correct info but doesn't skip */
3470 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3471 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3473 /* Playback only needs the final state even if more than one is
3474 processed because it wasn't removed in time */
3475 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3476 audio_queue_post(Q_AUDIO_SKIP, 0);
3478 else
3480 /* No more tracks */
3481 system_sound_play(SOUND_TRACK_NO_MORE);
3484 id3_mutex_unlock();
3487 /* Skip one track forward from the current */
3488 void audio_next(void)
3490 audio_skip(1);
3493 /* Skip one track backward from the current */
3494 void audio_prev(void)
3496 audio_skip(-1);
3499 /* Move one directory forward */
3500 void audio_next_dir(void)
3502 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3503 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3506 /* Move one directory backward */
3507 void audio_prev_dir(void)
3509 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3510 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3513 /* Pause playback in order to start a seek that flushes the old audio */
3514 void audio_pre_ff_rewind(void)
3516 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3517 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3520 /* Seek to the new time in the current track */
3521 void audio_ff_rewind(long time)
3523 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3524 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3527 /* Clear all but the currently playing track then rebuffer */
3528 void audio_flush_and_reload_tracks(void)
3530 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3531 audio_queue_post(Q_AUDIO_FLUSH, 0);
3534 /* Return the pointer to the main audio buffer, optionally preserving
3535 voicing */
3536 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3538 unsigned char *buf;
3540 if (audio_is_initialized)
3542 audio_hard_stop();
3544 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3546 if (buffer_size == NULL)
3548 /* Special case for talk_init to use since it already knows it's
3549 trashed */
3550 buffer_state = AUDIOBUF_STATE_TRASHED;
3551 return NULL;
3554 /* make sure buffer is freed and re-allocated to simplify code below
3555 * (audio_hard_stop() likely has done that already) */
3556 if (audiobuf_handle > 0)
3557 audiobuf_handle = core_free(audiobuf_handle);
3559 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
3560 buf = core_get_data(audiobuf_handle);
3562 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3563 || !talk_voice_required())
3565 logf("get buffer: talk, audio");
3566 /* Ok to use everything from audiobuf - voice is loaded,
3567 the talk buffer is not needed because voice isn't being used, or
3568 could be AUDIOBUF_STATE_TRASHED already. If state is
3569 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3570 written without the caller knowing what's going on. Changing certain
3571 settings may move it to a worse condition but the memory in use by
3572 something else will remain undisturbed.
3574 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3576 talk_buffer_steal();
3577 buffer_state = AUDIOBUF_STATE_TRASHED;
3580 else
3582 logf("get buffer: audio");
3583 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3584 still AUDIOBUF_STATE_INITIALIZED */
3585 /* Skip talk buffer and move pcm buffer to end to maximize available
3586 contiguous memory - no audio running means voice will not need the
3587 swap space */
3588 size_t talkbuf_size;
3589 buf += talkbuf_size = talkbuf_init(buf);
3590 filebuflen -= talkbuf_size;
3591 filebuflen -= voicebuf_init(buf + filebuflen);
3593 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3596 *buffer_size = filebuflen;
3597 return buf;
3600 #ifdef HAVE_RECORDING
3601 /* Stop audio, voice and obtain all available buffer space */
3602 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3604 audio_hard_stop();
3605 return audio_get_buffer(true, buffer_size);
3607 #endif /* HAVE_RECORDING */
3609 /* Restore audio buffer to a particular state (one more valid than the current
3610 state) */
3611 bool audio_restore_playback(int type)
3613 switch (type)
3615 case AUDIO_WANT_PLAYBACK:
3616 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3617 audio_reset_buffer();
3618 return true;
3619 case AUDIO_WANT_VOICE:
3620 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3621 audio_reset_buffer();
3622 return true;
3623 default:
3624 return false;
3629 /** --- Miscellaneous public interfaces --- **/
3631 #ifdef HAVE_ALBUMART
3632 /* Return which album art handle is current for the user in the given slot */
3633 int playback_current_aa_hid(int slot)
3635 if ((unsigned)slot < MAX_MULTIPLE_AA)
3637 struct track_info *info = track_list_user_current(skip_offset);
3639 if (!info && abs(skip_offset) <= 1)
3641 /* Give the actual position a go */
3642 info = track_list_user_current(0);
3645 if (info)
3646 return info->aa_hid[slot];
3649 return ERR_HANDLE_NOT_FOUND;
3652 /* Find an album art slot that doesn't match the dimensions of another that
3653 is already claimed - increment the use count if it is */
3654 int playback_claim_aa_slot(struct dim *dim)
3656 int i;
3658 /* First try to find a slot already having the size to reuse it since we
3659 don't want albumart of the same size buffered multiple times */
3660 FOREACH_ALBUMART(i)
3662 struct albumart_slot *slot = &albumart_slots[i];
3664 if (slot->dim.width == dim->width &&
3665 slot->dim.height == dim->height)
3667 slot->used++;
3668 return i;
3672 /* Size is new, find a free slot */
3673 FOREACH_ALBUMART(i)
3675 if (!albumart_slots[i].used)
3677 albumart_slots[i].used++;
3678 albumart_slots[i].dim = *dim;
3679 return i;
3683 /* Sorry, no free slot */
3684 return -1;
3687 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3688 void playback_release_aa_slot(int slot)
3690 if ((unsigned)slot < MAX_MULTIPLE_AA)
3692 struct albumart_slot *aa_slot = &albumart_slots[slot];
3694 if (aa_slot->used > 0)
3695 aa_slot->used--;
3698 #endif /* HAVE_ALBUMART */
3701 #ifdef HAVE_RECORDING
3702 /* Load an encoder and run it */
3703 bool audio_load_encoder(int afmt)
3705 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3706 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3707 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3708 #else
3709 (void)afmt;
3710 return true;
3711 #endif
3714 /* Stop an encoder and unload it */
3715 void audio_remove_encoder(void)
3717 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3718 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3719 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3720 #endif
3722 #endif /* HAVE_RECORDING */
3724 /* Is an automatic skip in progress? If called outside transition callbacks,
3725 indicates the last skip type at the time it was processed and isn't very
3726 meaningful. */
3727 bool audio_automatic_skip(void)
3729 return automatic_skip;
3732 /* Would normally calculate byte offset from an elapsed time but is not
3733 used on SWCODEC */
3734 int audio_get_file_pos(void)
3736 return 0;
3739 /* Return the elapsed time of the track previous to the current */
3740 unsigned long audio_prev_elapsed(void)
3742 return prev_track_elapsed;
3745 /* Return total file buffer length after accounting for the talk buf */
3746 size_t audio_get_filebuflen(void)
3748 return buf_length();
3751 /* How many tracks exist on the buffer - full or partial */
3752 int audio_track_count(void)
3753 __attribute__((alias("track_list_count")));
3755 /* Return total ringbuffer space occupied - ridx to widx */
3756 long audio_filebufused(void)
3758 return buf_used();
3762 /** -- Settings -- **/
3764 /* Enable or disable cuesheet support and allocate/don't allocate the
3765 extra associated resources */
3766 void audio_set_cuesheet(int enable)
3768 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3770 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3771 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3775 #ifdef HAVE_DISK_STORAGE
3776 /* Set the audio antiskip buffer margin by index */
3777 void audio_set_buffer_margin(int setting)
3779 static const unsigned short lookup[] =
3780 { 5, 15, 30, 60, 120, 180, 300, 600 };
3782 if ((unsigned)setting >= ARRAYLEN(lookup))
3783 setting = 0;
3785 logf("buffer margin: %u", (unsigned)lookup[setting]);
3787 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3788 (unsigned)lookup[setting]);
3789 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3791 #endif /* HAVE_DISK_STORAGE */
3793 #ifdef HAVE_CROSSFADE
3794 /* Take necessary steps to enable or disable the crossfade setting */
3795 void audio_set_crossfade(int enable)
3797 /* Tell it the next setting to use */
3798 pcmbuf_request_crossfade_enable(enable);
3800 /* Return if size hasn't changed or this is too early to determine
3801 which in the second case there's no way we could be playing
3802 anything at all */
3803 if (!pcmbuf_is_same_size())
3805 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3806 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3809 #endif /* HAVE_CROSSFADE */
3812 /** -- Startup -- **/
3814 /* Initialize the audio system - called from init() in main.c */
3815 void audio_init(void)
3817 /* Can never do this twice */
3818 if (audio_is_initialized)
3820 logf("audio: already initialized");
3821 return;
3824 logf("audio: initializing");
3826 /* Initialize queues before giving control elsewhere in case it likes
3827 to send messages. Thread creation will be delayed however so nothing
3828 starts running until ready if something yields such as talk_init. */
3829 queue_init(&audio_queue, true);
3831 mutex_init(&id3_mutex);
3833 pcm_init();
3835 codec_thread_init();
3837 /* This thread does buffer, so match its priority */
3838 audio_thread_id = create_thread(audio_thread, audio_stack,
3839 sizeof(audio_stack), 0, audio_thread_name
3840 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3841 IF_COP(, CPU));
3843 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3844 audio_thread_id);
3846 #ifdef PLAYBACK_VOICE
3847 voice_thread_init();
3848 #endif
3850 /* audio_reset_buffer must know the size of voice buffer so init
3851 talk first */
3852 talk_init();
3854 #ifdef HAVE_CROSSFADE
3855 /* Set crossfade setting for next buffer init which should be about... */
3856 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3857 #endif
3859 /* Initialize the buffering system */
3860 track_list_init();
3861 buffering_init();
3862 /* ...now! Set up the buffers */
3863 audio_reset_buffer();
3865 /* Probably safe to say */
3866 audio_is_initialized = true;
3868 sound_settings_apply();
3869 #ifdef HAVE_DISK_STORAGE
3870 audio_set_buffer_margin(global_settings.buffer_margin);
3871 #endif