Remove now unneeded variable
[maemo-rb.git] / apps / playback.c
blob3adf6f6a4957f12df0e1bbbf8a6b1c177baebbb7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005-2007 Miika Pekkarinen
11 * Copyright (C) 2007-2008 Nicolas Pennequin
12 * Copyright (C) 2011 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "panic.h"
27 #include "buffer.h"
28 #include "sound.h"
29 #include "ata.h"
30 #include "usb.h"
31 #include "codecs.h"
32 #include "codec_thread.h"
33 #include "voice_thread.h"
34 #include "metadata.h"
35 #include "cuesheet.h"
36 #include "buffering.h"
37 #include "talk.h"
38 #include "playlist.h"
39 #include "abrepeat.h"
40 #include "pcmbuf.h"
41 #include "playback.h"
42 #include "misc.h"
44 #ifdef HAVE_TAGCACHE
45 #include "tagcache.h"
46 #endif
48 #ifdef AUDIO_HAVE_RECORDING
49 #include "pcm_record.h"
50 #endif
52 #ifdef HAVE_LCD_BITMAP
53 #ifdef HAVE_ALBUMART
54 #include "albumart.h"
55 #endif
56 #endif
58 /* TODO: The audio thread really is doing multitasking of acting like a
59 consumer and producer of tracks. It may be advantageous to better
60 logically separate the two functions. I won't go that far just yet. */
62 /* Internal support for voice playback */
63 #define PLAYBACK_VOICE
65 #if CONFIG_PLATFORM & PLATFORM_NATIVE
66 /* Application builds don't support direct code loading */
67 #define HAVE_CODEC_BUFFERING
68 #endif
70 /* Amount of guess-space to allow for codecs that must hunt and peck
71 * for their correct seek target, 32k seems a good size */
72 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
74 /* Define LOGF_ENABLE to enable logf output in this file */
75 /* #define LOGF_ENABLE */
76 #include "logf.h"
78 /* Macros to enable logf for queues
79 logging on SYS_TIMEOUT can be disabled */
80 #ifdef SIMULATOR
81 /* Define this for logf output of all queuing except SYS_TIMEOUT */
82 #define PLAYBACK_LOGQUEUES
83 /* Define this to logf SYS_TIMEOUT messages */
84 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
85 #endif
87 #ifdef PLAYBACK_LOGQUEUES
88 #define LOGFQUEUE logf
89 #else
90 #define LOGFQUEUE(...)
91 #endif
93 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
94 #define LOGFQUEUE_SYS_TIMEOUT logf
95 #else
96 #define LOGFQUEUE_SYS_TIMEOUT(...)
97 #endif
99 /* Variables are commented with the threads that use them:
100 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
101 * read but not updated on that thread. Audio is the only user unless otherwise
102 * specified.
105 /** Miscellaneous **/
106 bool audio_is_initialized = false; /* (A,O-) */
107 extern struct codec_api ci; /* (A,C) */
109 /** Possible arrangements of the main buffer **/
110 static enum audio_buffer_state
112 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
113 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
114 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
115 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
117 /** Main state control **/
118 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
120 enum play_status
122 PLAY_STOPPED = 0,
123 PLAY_PLAYING = AUDIO_STATUS_PLAY,
124 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
125 } play_status = PLAY_STOPPED;
127 /* Sizeable things that only need exist during playback and not when stopped */
128 static struct audio_scratch_memory
130 struct mp3entry codec_id3; /* (A,C) */
131 struct mp3entry unbuffered_id3;
132 struct cuesheet *curr_cue; /* Will follow this structure */
133 } * audio_scratch_memory = NULL;
135 /* These are used to store the current, next and optionally the peek-ahead
136 * mp3entry's - this guarantees that the pointer returned by audio_current/
137 * next_track will be valid for the full duration of the currently playing
138 * track */
139 enum audio_id3_types
141 /* These are allocated statically */
142 PLAYING_ID3 = 0,
143 NEXTTRACK_ID3,
144 #ifdef AUDIO_FAST_SKIP_PREVIEW
145 /* The real playing metadata must has to be protected since it contains
146 critical info for other features */
147 PLAYING_PEEK_ID3,
148 #endif
149 ID3_TYPE_NUM_STATIC,
150 /* These go in the scratch memory */
151 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
152 CODEC_ID3,
154 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
156 /* Peeking functions can yield and mess us up */
157 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/
160 /** For Scrobbler support **/
162 /* Previous track elapsed time */
163 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
166 /** For album art support **/
167 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
168 #ifdef HAVE_ALBUMART
170 static struct albumart_slot
172 struct dim dim; /* Holds width, height of the albumart */
173 int used; /* Counter; increments if something uses it */
174 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
176 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
177 #endif /* HAVE_ALBUMART */
180 /** Information used for tracking buffer fills **/
182 /* Buffer and thread state tracking */
183 static enum filling_state
185 STATE_BOOT = 0, /* audio thread is not ready yet */
186 STATE_IDLE, /* audio is stopped: nothing to do */
187 STATE_FILLING, /* adding tracks to the buffer */
188 STATE_FULL, /* can't add any more tracks */
189 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
190 STATE_FINISHED, /* all remaining tracks are fully buffered */
191 STATE_ENDING, /* audio playback is ending */
192 STATE_ENDED, /* audio playback is done */
193 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
194 STATE_USB, /* USB mode, ignore most messages */
195 #endif
196 } filling = STATE_BOOT;
198 /* Track info - holds information about each track in the buffer */
199 struct track_info
201 /* In per-track allocated order: */
202 int id3_hid; /* Metadata handle ID */
203 int cuesheet_hid; /* Parsed cuesheet handle ID */
204 #ifdef HAVE_ALBUMART
205 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
206 #endif
207 #ifdef HAVE_CODEC_BUFFERING
208 int codec_hid; /* Buffered codec handle ID */
209 #endif
210 int audio_hid; /* Main audio data handle ID */
211 size_t filesize; /* File total length on disk
212 TODO: This should be stored
213 in the handle or the
214 id3 and would use less
215 ram */
218 /* Track list - holds info about all buffered tracks */
219 #if MEMORYSIZE >= 32
220 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
221 #elif MEMORYSIZE >= 16
222 #define TRACK_LIST_LEN 64
223 #elif MEMORYSIZE >= 8
224 #define TRACK_LIST_LEN 32
225 #else
226 #define TRACK_LIST_LEN 16
227 #endif
229 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
231 static struct
233 /* read, write and current are maintained unwrapped, limited only by the
234 unsigned int range and wrap-safe comparisons are used */
236 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
237 if 'end' follows 'start' in this structure, track_list_count performs
238 'start - end' rather than 'end - start', giving negative count values...
239 so leave it this way for now! */
240 unsigned int end; /* Next open position */
241 unsigned int start; /* First track in list */
242 unsigned int current; /* Currently decoding track */
243 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
244 } track_list; /* (A, O-) */
247 /* Playlist steps from playlist position to next track to be buffered */
248 static int playlist_peek_offset = 0;
250 /* Metadata handle of track load in progress (meaning all handles have not
251 yet been opened for the track, id3 always exists or the track does not)
253 Tracks are keyed by their metadata handles if track list pointers are
254 insufficient to make comparisons */
255 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
257 #ifdef HAVE_DISK_STORAGE
258 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
259 static size_t buffer_margin = 5;
260 #endif
262 /* Values returned for track loading */
263 enum track_load_status
265 LOAD_TRACK_ERR_START_CODEC = -6,
266 LOAD_TRACK_ERR_FINISH_FAILED = -5,
267 LOAD_TRACK_ERR_FINISH_FULL = -4,
268 LOAD_TRACK_ERR_BUSY = -3,
269 LOAD_TRACK_ERR_NO_MORE = -2,
270 LOAD_TRACK_ERR_FAILED = -1,
271 LOAD_TRACK_OK = 0,
272 LOAD_TRACK_READY = 1,
275 /** Track change controls **/
277 /* What sort of skip is pending globally? */
278 enum track_skip_type
280 /* Relative to what user is intended to see: */
281 /* Codec: +0, Track List: +0, Playlist: +0 */
282 TRACK_SKIP_NONE = 0, /* no track skip */
283 /* Codec: +1, Track List: +1, Playlist: +0 */
284 TRACK_SKIP_AUTO, /* codec-initiated skip */
285 /* Codec: +1, Track List: +1, Playlist: +1 */
286 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
287 /* Codec: xx, Track List: +0, Playlist: +0 */
288 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
289 /* Manual skip: Never pends */
290 TRACK_SKIP_MANUAL, /* manual track skip */
291 /* Manual skip: Never pends */
292 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
293 } skip_pending = TRACK_SKIP_NONE;
295 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
296 Fixing playlist code to be able to peek into the first song of
297 the next playlist would fix any issues and this wouldn't need
298 to be a special case since pre-advancing the playlist would be
299 unneeded - it could be much more like TRACK_SKIP_AUTO and all
300 actions that require reversal during an in-progress transition
301 would work as expected */
303 /* Used to indicate status for the events. Must be separate to satisfy all
304 clients so the correct metadata is read when sending the change events
305 and also so that it is read correctly outside the events. */
306 static bool automatic_skip = false; /* (A, O-) */
308 /* Pending manual track skip offset */
309 static int skip_offset = 0; /* (A, O) */
311 /* Track change notification */
312 static struct
314 unsigned int in; /* Number of pcmbuf posts (audio isr) */
315 unsigned int out; /* Number of times audio has read the difference */
316 } track_change = { 0, 0 };
318 /** Codec status **/
319 /* Did the codec notify us it finished while we were paused or while still
320 in an automatic transition?
322 If paused, it is necessary to defer a codec-initiated skip until resuming
323 or else the track will move forward while not playing audio!
325 If in-progress, skips should not build-up ahead of where the WPS is when
326 really short tracks finish decoding.
328 If it is forgotten, it will be missed altogether and playback will just sit
329 there looking stupid and comatose until the user does something */
330 static bool codec_skip_pending = false;
331 static int codec_skip_status;
332 static bool codec_seeking = false; /* Codec seeking ack expected? */
335 /* Event queues */
336 static struct event_queue audio_queue SHAREDBSS_ATTR;
338 /* Audio thread */
339 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
340 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
341 static const char audio_thread_name[] = "audio";
342 static unsigned int audio_thread_id = 0;
344 /* Forward declarations */
345 enum audio_start_playback_flags
347 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
348 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
351 static void audio_start_playback(size_t offset, unsigned int flags);
352 static void audio_stop_playback(void);
353 static void buffer_event_buffer_low_callback(void *data);
354 static void buffer_event_rebuffer_callback(void *data);
355 static void buffer_event_finished_callback(void *data);
358 /**************************************/
360 /** --- audio_queue helpers --- **/
362 /* codec thread needs access */
363 void audio_queue_post(long id, intptr_t data)
365 queue_post(&audio_queue, id, data);
368 static intptr_t audio_queue_send(long id, intptr_t data)
370 return queue_send(&audio_queue, id, data);
374 /** --- MP3Entry --- **/
376 /* Does the mp3entry have enough info for us to use it? */
377 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
379 return id3 && (id3->length != 0 || id3->filesize != 0) &&
380 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
383 /* Return a pointer to an mp3entry on the buffer, as it is */
384 static struct mp3entry * bufgetid3(int handle_id)
386 if (handle_id < 0)
387 return NULL;
389 struct mp3entry *id3;
390 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
392 if (ret != sizeof(struct mp3entry))
393 return NULL;
395 return id3;
398 /* Read an mp3entry from the buffer, adjusted */
399 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
401 struct mp3entry *id3 = bufgetid3(handle_id);
403 if (id3)
405 copy_mp3entry(id3out, id3);
406 return true;
409 return false;
412 /* Lock the id3 mutex */
413 static void id3_mutex_lock(void)
415 mutex_lock(&id3_mutex);
418 /* Unlock the id3 mutex */
419 static void id3_mutex_unlock(void)
421 mutex_unlock(&id3_mutex);
424 /* Return one of the collection of mp3entry pointers - collect them all here */
425 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
427 switch (id3_num)
429 case UNBUFFERED_ID3:
430 return &audio_scratch_memory->unbuffered_id3;
431 case CODEC_ID3:
432 return &audio_scratch_memory->codec_id3;
433 default:
434 return &static_id3_entries[id3_num];
438 /* Copy an mp3entry into one of the mp3 entries */
439 static void id3_write(enum audio_id3_types id3_num,
440 const struct mp3entry *id3_src)
442 struct mp3entry *dest_id3 = id3_get(id3_num);
444 if (id3_src)
445 copy_mp3entry(dest_id3, id3_src);
446 else
447 wipe_mp3entry(dest_id3);
450 /* Call id3_write "safely" because peek aheads can yield, even if the fast
451 preview isn't enabled */
452 static void id3_write_locked(enum audio_id3_types id3_num,
453 const struct mp3entry *id3_src)
455 id3_mutex_lock();
456 id3_write(id3_num, id3_src);
457 id3_mutex_unlock();
461 /** --- Track info --- **/
463 /* Close a handle and mark it invalid */
464 static void track_info_close_handle(int *hid_p)
466 int hid = *hid_p;
468 /* bufclose returns true if the handle is not found, or if it is closed
469 * successfully, so these checks are safe on non-existant handles */
470 if (hid >= 0)
471 bufclose(hid);
473 /* Always reset to "no handle" in case it was something else */
474 *hid_p = ERR_HANDLE_NOT_FOUND;
477 /* Close all handles in a struct track_info and clear it */
478 static void track_info_close(struct track_info *info)
480 /* Close them in the order they are allocated on the buffer to speed up
481 the handle searching */
482 track_info_close_handle(&info->id3_hid);
483 track_info_close_handle(&info->cuesheet_hid);
484 #ifdef HAVE_ALBUMART
485 int i;
486 FOREACH_ALBUMART(i)
487 track_info_close_handle(&info->aa_hid[i]);
488 #endif
489 #ifdef HAVE_CODEC_BUFFERING
490 track_info_close_handle(&info->codec_hid);
491 #endif
492 track_info_close_handle(&info->audio_hid);
493 info->filesize = 0;
496 /* Invalidate all members to initial values - does not close handles */
497 static void track_info_wipe(struct track_info * info)
499 info->id3_hid = ERR_HANDLE_NOT_FOUND;
500 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
501 #ifdef HAVE_ALBUMART
502 int i;
503 FOREACH_ALBUMART(i)
504 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
505 #endif
506 #ifdef HAVE_CODEC_BUFFERING
507 info->codec_hid = ERR_HANDLE_NOT_FOUND;
508 #endif
509 info->audio_hid = ERR_HANDLE_NOT_FOUND;
510 info->filesize = 0;
514 /** --- Track list --- **/
516 /* Initialize the track list */
517 static void track_list_init(void)
519 int i;
520 for (i = 0; i < TRACK_LIST_LEN; i++)
521 track_info_wipe(&track_list.tracks[i]);
523 track_list.start = track_list.end = track_list.current;
526 /* Return number of items allocated in the list */
527 static unsigned int track_list_count(void)
529 return track_list.end - track_list.start;
532 /* Return true if the list is empty */
533 static inline bool track_list_empty(void)
535 return track_list.end == track_list.start;
538 /* Returns true if the list is holding the maximum number of items */
539 static bool track_list_full(void)
541 return track_list.end - track_list.start >= TRACK_LIST_LEN;
544 /* Test if the index is within the allocated range */
545 static bool track_list_in_range(int pos)
547 return (int)(pos - track_list.start) >= 0 &&
548 (int)(pos - track_list.end) < 0;
551 static struct track_info * track_list_entry(int pos)
553 return &track_list.tracks[pos & TRACK_LIST_MASK];
556 /* Return the info of the last allocation plus an offset, NULL if result is
557 out of bounds */
558 static struct track_info * track_list_last(int offset)
560 /* Last is before the end since the end isn't inclusive */
561 unsigned int pos = track_list.end + offset - 1;
563 if (!track_list_in_range(pos))
564 return NULL;
566 return track_list_entry(pos);
569 /* Allocate space at the end for another track if not full */
570 static struct track_info * track_list_alloc_track(void)
572 if (track_list_full())
573 return NULL;
575 return track_list_entry(track_list.end++);
578 /* Remove the last track entry allocated in order to support backing out
579 of a track load */
580 static void track_list_unalloc_track(void)
582 if (track_list_empty())
583 return;
585 track_list.end--;
587 if (track_list.current == track_list.end &&
588 track_list.current != track_list.start)
590 /* Current _must_ remain within bounds */
591 track_list.current--;
595 /* Return current track plus an offset, NULL if result is out of bounds */
596 static struct track_info * track_list_current(int offset)
598 unsigned int pos = track_list.current + offset;
600 if (!track_list_in_range(pos))
601 return NULL;
603 return track_list_entry(pos);
606 /* Return current based upon what's intended that the user sees - not
607 necessarily where decoding is taking place */
608 static struct track_info * track_list_user_current(int offset)
610 if (skip_pending == TRACK_SKIP_AUTO ||
611 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
613 offset--;
616 return track_list_current(offset);
619 /* Advance current track by an offset, return false if result is out of
620 bounds */
621 static struct track_info * track_list_advance_current(int offset)
623 unsigned int pos = track_list.current + offset;
625 if (!track_list_in_range(pos))
626 return NULL;
628 track_list.current = pos;
629 return track_list_entry(pos);
632 /* Clear tracks in the list, optionally preserving the current track -
633 returns 'false' if the operation was changed */
634 enum track_clear_action
636 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
637 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
638 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
641 static void track_list_clear(enum track_clear_action action)
643 logf("%s(%d)", __func__, (int)action);
645 /* Don't care now since rebuffering is imminent */
646 buf_set_watermark(0);
648 if (action != TRACK_LIST_CLEAR_ALL)
650 struct track_info *cur = track_list_current(0);
652 if (!cur || cur->id3_hid < 0)
653 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
656 /* Noone should see this progressing */
657 int start = track_list.start;
658 int current = track_list.current;
659 int end = track_list.end;
661 track_list.start = current;
663 switch (action)
665 case TRACK_LIST_CLEAR_ALL:
666 /* Result: .start = .current, .end = .current */
667 track_list.end = current;
668 break;
670 case TRACK_LIST_KEEP_CURRENT:
671 /* Result: .start = .current, .end = .current + 1 */
672 track_list.end = current + 1;
673 break;
675 case TRACK_LIST_KEEP_NEW:
676 /* Result: .start = .current, .end = .end */
677 end = current;
678 break;
681 /* Close all open handles in the range except the for the current track
682 if preserving that */
683 while (start != end)
685 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
687 struct track_info *info =
688 &track_list.tracks[start & TRACK_LIST_MASK];
690 /* If this is the in-progress load, abort it */
691 if (in_progress_id3_hid >= 0 &&
692 info->id3_hid == in_progress_id3_hid)
694 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
697 track_info_close(info);
700 start++;
705 /** --- Audio buffer -- **/
707 /* What size is needed for the scratch buffer? */
708 static size_t scratch_mem_size(void)
710 size_t size = sizeof (struct audio_scratch_memory);
712 if (global_settings.cuesheet)
713 size += sizeof (struct cuesheet);
715 return size;
718 /* Initialize the memory area where data is stored that is only used when
719 playing audio and anything depending upon it */
720 static void scratch_mem_init(void *mem)
722 audio_scratch_memory = (struct audio_scratch_memory *)mem;
723 id3_write_locked(UNBUFFERED_ID3, NULL);
724 id3_write(CODEC_ID3, NULL);
725 ci.id3 = id3_get(CODEC_ID3);
726 audio_scratch_memory->curr_cue = NULL;
728 if (global_settings.cuesheet)
730 audio_scratch_memory->curr_cue =
731 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
732 sizeof (struct audio_scratch_memory));
736 /* Set up the audio buffer for playback */
737 static void audio_reset_buffer(void)
740 * Layout audio buffer as follows:
741 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
744 /* see audio_get_recording_buffer if this is modified */
745 logf("%s()", __func__);
747 /* release the buffer on behalf of any caller of audio_get_buffer() */
748 buffer_release_buffer(0);
750 /* If the setup of anything allocated before the file buffer is
751 changed, do check the adjustments after the buffer_alloc call
752 as it will likely be affected and need sliding over */
754 /* Initially set up file buffer as all space available */
755 size_t filebuflen, allocsize;
756 unsigned char *filebuf = buffer_get_buffer(&filebuflen);
758 /* Subtract whatever voice needs */
759 allocsize = talkbuf_init(filebuf);
760 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
761 if (allocsize > filebuflen)
762 goto bufpanic;
764 filebuf += allocsize;
765 filebuflen -= allocsize;
767 if (talk_voice_required())
769 /* Need a space for voice PCM output */
770 allocsize = voicebuf_init(filebuf + filebuflen);
772 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
773 if (allocsize > filebuflen)
774 goto bufpanic;
776 filebuflen -= allocsize;
779 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
780 allocsize = pcmbuf_init(filebuf + filebuflen);
782 /* Make sure filebuflen is a pointer sized multiple after adjustment */
783 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
784 if (allocsize > filebuflen)
785 goto bufpanic;
787 filebuflen -= allocsize;
789 /* Scratch memory */
790 allocsize = scratch_mem_size();
791 if (allocsize > filebuflen)
792 goto bufpanic;
794 scratch_mem_init(filebuf);
795 filebuf += allocsize;
796 filebuflen -= allocsize;
798 buffering_reset(filebuf, filebuflen);
800 /* Clear any references to the file buffer */
801 buffer_state = AUDIOBUF_STATE_INITIALIZED;
803 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
804 /* Make sure everything adds up - yes, some info is a bit redundant but
805 aids viewing and the summation of certain variables should add up to
806 the location of others. */
808 size_t pcmbufsize;
809 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
810 logf("fbuf: %08X", (unsigned)filebuf);
811 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
812 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
813 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
814 logf("pcmb: %08X", (unsigned)pcmbuf);
815 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
817 #endif
819 return;
821 bufpanic:
822 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
825 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
826 static void audio_update_filebuf_watermark(int seconds)
828 size_t bytes = 0;
830 #ifdef HAVE_DISK_STORAGE
831 int spinup = ata_spinup_time();
833 if (seconds == 0)
835 /* By current setting */
836 seconds = buffer_margin;
838 else
840 /* New setting */
841 buffer_margin = seconds;
843 if (buf_get_watermark() == 0)
845 /* Write a watermark only if the audio thread already did so for
846 itself or it will fail to set the event and the watermark - if
847 it hasn't yet, it will use the new setting when it does */
848 return;
852 if (spinup)
853 seconds += (spinup / HZ) + 1;
854 else
855 seconds += 5;
857 seconds += buffer_margin;
858 #else
859 /* flash storage */
860 seconds = 1;
861 #endif
863 /* Watermark is a function of the bitrate of the last track in the buffer */
864 struct mp3entry *id3 = NULL;
865 struct track_info *info = track_list_last(0);
867 if (info)
868 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
870 if (id3)
872 if (get_audio_base_data_type(id3->codectype) == TYPE_PACKET_AUDIO)
874 bytes = id3->bitrate * (1000/8) * seconds;
876 else
878 /* Bitrate has no meaning to buffering margin for atomic audio -
879 rebuffer when it's the only track left unless it's the only
880 track that fits, in which case we should avoid constant buffer
881 low events */
882 if (track_list_count() > 1)
883 bytes = info->filesize + 1;
886 else
888 /* Then set the minimum - this should not occur anyway */
889 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
890 track_list.start, track_list.current, track_list.end);
893 /* Actually setting zero disables the notification and we use that
894 to detect that it has been reset */
895 buf_set_watermark(MAX(bytes, 1));
896 logf("fwmark: %lu", (unsigned long)bytes);
900 /** -- Track change notification -- **/
902 /* Check the pcmbuf track changes and return write the message into the event
903 if there are any */
904 static inline bool audio_pcmbuf_track_change_scan(void)
906 if (track_change.out != track_change.in)
908 track_change.out++;
909 return true;
912 return false;
915 /* Clear outstanding track change posts */
916 static inline void audio_pcmbuf_track_change_clear(void)
918 track_change.out = track_change.in;
921 /* Post a track change notification - called by audio ISR */
922 static inline void audio_pcmbuf_track_change_post(void)
924 track_change.in++;
928 /** --- Helper functions --- **/
930 /* Removes messages that might end up in the queue before or while processing
931 a manual track change. Responding to them would be harmful since they
932 belong to a previous track's playback period. Anything that would generate
933 the stale messages must first be put into a state where it will not do so.
935 static void audio_clear_track_notifications(void)
937 static const long filter_list[][2] =
939 /* codec messages */
940 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
941 /* track change messages */
942 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
945 const int filter_count = ARRAYLEN(filter_list) - 1;
947 /* Remove any pcmbuf notifications */
948 pcmbuf_monitor_track_change(false);
949 audio_pcmbuf_track_change_clear();
951 /* Scrub the audio queue of the old mold */
952 while (queue_peek_ex(&audio_queue, NULL,
953 filter_count | QPEEK_REMOVE_EVENTS,
954 filter_list))
956 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
960 /* Takes actions based upon track load status codes */
961 static void audio_handle_track_load_status(int trackstat)
963 switch (trackstat)
965 case LOAD_TRACK_ERR_NO_MORE:
966 if (track_list_count() > 0)
967 break;
969 case LOAD_TRACK_ERR_START_CODEC:
970 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
971 break;
973 default:
974 break;
978 /* Announce the end of playing the current track */
979 static void audio_playlist_track_finish(void)
981 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
983 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
985 if (id3)
987 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
988 prev_track_elapsed = id3->elapsed;
990 else
992 prev_track_elapsed = 0;
996 /* Announce the beginning of the new track */
997 static void audio_playlist_track_change(void)
999 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
1001 if (id3)
1002 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
1004 playlist_update_resume_info(id3);
1007 /* Change the data for the next track and send the event */
1008 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1010 id3_write_locked(NEXTTRACK_ID3, id3_next);
1011 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1012 id3_get(NEXTTRACK_ID3));
1015 /* Bring the user current mp3entry up to date and set a new offset for the
1016 buffered metadata */
1017 static void playing_id3_sync(struct track_info *user_info, size_t offset)
1019 id3_mutex_lock();
1021 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1023 if (offset == (size_t)-1)
1025 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1026 size_t play_offset = ply_id3->offset;
1027 long play_elapsed = ply_id3->elapsed;
1028 id3_write(PLAYING_ID3, id3);
1029 ply_id3->offset = play_offset;
1030 ply_id3->elapsed = play_elapsed;
1031 offset = 0;
1033 else
1035 id3_write(PLAYING_ID3, id3);
1038 if (id3)
1039 id3->offset = offset;
1041 id3_mutex_unlock();
1044 /* Wipe-out track metadata - current is optional */
1045 static void wipe_track_metadata(bool current)
1047 id3_mutex_lock();
1049 if (current)
1050 id3_write(PLAYING_ID3, NULL);
1052 id3_write(NEXTTRACK_ID3, NULL);
1053 id3_write(UNBUFFERED_ID3, NULL);
1055 id3_mutex_unlock();
1058 /* Called when buffering is completed on the last track handle */
1059 static void filling_is_finished(void)
1061 logf("last track finished buffering");
1063 /* There's no more to load or watch for */
1064 buf_set_watermark(0);
1065 filling = STATE_FINISHED;
1068 /* Stop the codec decoding or waiting for its data to be ready - returns
1069 'false' if the codec ended up stopped */
1070 static bool halt_decoding_track(bool stop)
1072 /* If it was waiting for us to clear the buffer to make a rebuffer
1073 happen, it should cease otherwise codec_stop could deadlock waiting
1074 for the codec to go to its main loop - codec's request will now
1075 force-fail */
1076 bool retval = false;
1078 buf_signal_handle(ci.audio_hid, true);
1080 if (stop)
1081 codec_stop();
1082 else
1083 retval = codec_pause();
1085 audio_clear_track_notifications();
1087 /* We now know it's idle and not waiting for buffered data */
1088 buf_signal_handle(ci.audio_hid, false);
1090 codec_skip_pending = false;
1091 codec_seeking = false;
1093 return retval;
1096 /* Clear the PCM on a manual skip */
1097 static void audio_clear_paused_pcm(void)
1099 if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active())
1100 pcmbuf_play_stop();
1103 /* Wait for any in-progress fade to complete */
1104 static void audio_wait_fade_complete(void)
1106 /* Just loop until it's done */
1107 while (pcmbuf_fading())
1108 sleep(0);
1111 /* End the ff/rw mode */
1112 static void audio_ff_rewind_end(void)
1114 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1115 section */
1116 if (ff_rw_mode)
1118 ff_rw_mode = false;
1120 if (codec_seeking)
1122 /* Clear the buffer */
1123 pcmbuf_play_stop();
1126 if (play_status != PLAY_PAUSED)
1128 /* Seeking-while-playing, resume PCM playback */
1129 pcmbuf_pause(false);
1134 /* Complete the codec seek */
1135 static void audio_complete_codec_seek(void)
1137 /* If a seek completed while paused, 'paused' is true.
1138 * If seeking from seek mode, 'ff_rw_mode' is true. */
1139 if (codec_seeking)
1141 audio_ff_rewind_end();
1142 codec_seeking = false; /* set _after_ the call! */
1144 /* else it's waiting and we must repond */
1147 /* Get the current cuesheet pointer */
1148 static inline struct cuesheet * get_current_cuesheet(void)
1150 return audio_scratch_memory->curr_cue;
1153 /* Read the cuesheet from the buffer */
1154 static void buf_read_cuesheet(int handle_id)
1156 struct cuesheet *cue = get_current_cuesheet();
1158 if (!cue || handle_id < 0)
1159 return;
1161 bufread(handle_id, sizeof (struct cuesheet), cue);
1164 /* Backend to peek/current/next track metadata interface functions -
1165 fill in the mp3entry with as much information as we may obtain about
1166 the track at the specified offset from the user current track -
1167 returns false if no information exists with us */
1168 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1170 if (play_status == PLAY_STOPPED)
1171 return false;
1173 if (id3->path[0] != '\0')
1174 return true; /* Already filled */
1176 struct track_info *info = track_list_user_current(offset);
1178 if (!info)
1180 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1182 if (offset > 0 && track_list_user_current(offset - 1))
1184 /* Try the unbuffered id3 since we're moving forward */
1185 if (ub_id3->path[0] != '\0')
1187 copy_mp3entry(id3, ub_id3);
1188 return true;
1192 else if (bufreadid3(info->id3_hid, id3))
1194 id3->cuesheet = NULL;
1195 return true;
1198 /* We didn't find the ID3 metadata, so we fill it with the little info we
1199 have and return that */
1201 char path[MAX_PATH+1];
1202 if (playlist_peek(offset, path, sizeof (path)))
1204 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1205 /* Try to get it from the database */
1206 if (!tagcache_fill_tags(id3, path))
1207 #endif
1209 /* By now, filename is the only source of info */
1210 fill_metadata_from_path(id3, path);
1213 return true;
1216 wipe_mp3entry(id3);
1218 return false;
1221 /* Get a resume rewind adjusted offset from the ID3 */
1222 unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1224 unsigned long offset = id3->offset;
1225 size_t resume_rewind = global_settings.resume_rewind *
1226 id3->bitrate * (1000/8);
1228 if (offset < resume_rewind)
1229 offset = 0;
1230 else
1231 offset -= resume_rewind;
1233 return offset;
1236 /* Get the codec into ram and initialize it - keep it if it's ready */
1237 static bool audio_init_codec(struct track_info *track_info,
1238 struct mp3entry *track_id3)
1240 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1241 int hid = ERR_HANDLE_NOT_FOUND;
1243 if (codt_loaded != AFMT_UNKNOWN)
1245 int codt = get_audio_base_codec_type(track_id3->codectype);
1247 if (codt == codt_loaded)
1249 /* Codec is the same base type */
1250 logf("Reusing prev. codec: %d", track_id3->codectype);
1251 #ifdef HAVE_CODEC_BUFFERING
1252 /* Close any buffered codec (we could have skipped directly to a
1253 format transistion that is the same format as the current track
1254 and the buffered one is no longer needed) */
1255 track_info_close_handle(&track_info->codec_hid);
1256 #endif
1257 return true;
1259 else
1261 /* New codec - first make sure the old one's gone */
1262 logf("Removing prev. codec: %d", codt_loaded);
1263 codec_unload();
1267 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1269 #ifdef HAVE_CODEC_BUFFERING
1270 /* Codec thread will close the handle even if it fails and will load from
1271 storage if hid is not valid or the buffer load fails */
1272 hid = track_info->codec_hid;
1273 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1274 #endif
1276 return codec_load(hid, track_id3->codectype);
1277 (void)track_info; /* When codec buffering isn't supported */
1280 /* Start the codec for the current track scheduled to be decoded */
1281 static bool audio_start_codec(bool auto_skip)
1283 struct track_info *info = track_list_current(0);
1284 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1286 if (!cur_id3)
1287 return false;
1289 buf_pin_handle(info->id3_hid, true);
1291 if (!audio_init_codec(info, cur_id3))
1293 buf_pin_handle(info->id3_hid, false);
1294 return false;
1297 #ifdef HAVE_TAGCACHE
1298 bool autoresume_enable = global_settings.autoresume_enable;
1300 if (autoresume_enable && !cur_id3->offset)
1302 /* Resume all manually selected tracks */
1303 bool resume = !auto_skip;
1305 /* Send the "buffer" event to obtain the resume position for the codec */
1306 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1308 if (!resume)
1310 /* Automatic skip - do further tests to see if we should just
1311 ignore any autoresume position */
1312 int autoresume_automatic = global_settings.autoresume_automatic;
1314 switch (autoresume_automatic)
1316 case AUTORESUME_NEXTTRACK_ALWAYS:
1317 /* Just resume unconditionally */
1318 resume = true;
1319 break;
1320 case AUTORESUME_NEXTTRACK_NEVER:
1321 /* Force-rewind it */
1322 break;
1323 default:
1324 /* Not "never resume" - pass resume filter? */
1325 resume = autoresumable(cur_id3);
1329 if (!resume)
1330 cur_id3->offset = 0;
1332 logf("%s: Set offset for %s to %lX\n", __func__,
1333 cur_id3->title, cur_id3->offset);
1335 #endif /* HAVE_TAGCACHE */
1337 /* Rewind the required amount - if an autoresume was done, this also rewinds
1338 that by the setting's amount
1340 It would be best to have bookkeeping about whether or not the track
1341 sounded or not since skipping to it or else skipping to it while paused
1342 and back again will cause accumulation of silent rewinds - that's not
1343 our job to track directly nor could it be in any reasonable way
1345 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1347 /* Update the codec API with the metadata and track info */
1348 id3_write(CODEC_ID3, cur_id3);
1350 ci.audio_hid = info->audio_hid;
1351 ci.filesize = info->filesize;
1352 buf_set_base_handle(info->audio_hid);
1354 /* All required data is now available for the codec */
1355 codec_go();
1357 #ifdef HAVE_TAGCACHE
1358 if (!autoresume_enable || cur_id3->offset)
1359 #endif
1361 /* Send the "buffer" event now */
1362 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1365 buf_pin_handle(info->id3_hid, false);
1366 return true;
1368 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1372 /** --- Audio thread --- **/
1374 /* Load and parse a cuesheet for the file - returns false if the buffer
1375 is full */
1376 static bool audio_load_cuesheet(struct track_info *info,
1377 struct mp3entry *track_id3)
1379 struct cuesheet *cue = get_current_cuesheet();
1380 track_id3->cuesheet = NULL;
1382 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1384 /* If error other than a full buffer, then mark it "unsupported" to
1385 avoid reloading attempt */
1386 int hid = ERR_UNSUPPORTED_TYPE;
1387 char cuepath[MAX_PATH];
1389 #ifdef HAVE_IO_PRIORITY
1390 buf_back_off_storage(true);
1391 #endif
1392 if (look_for_cuesheet_file(track_id3->path, cuepath))
1394 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1396 if (hid >= 0)
1398 void *cuesheet = NULL;
1399 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1401 if (parse_cuesheet(cuepath, (struct cuesheet *)cuesheet))
1403 /* Indicate cuesheet is present (while track remains
1404 buffered) */
1405 track_id3->cuesheet = cue;
1407 else
1409 bufclose(hid);
1410 hid = ERR_UNSUPPORTED_TYPE;
1415 #ifdef HAVE_IO_PRIORITY
1416 buf_back_off_storage(false);
1417 #endif
1418 if (hid == ERR_BUFFER_FULL)
1420 logf("buffer is full for now (%s)", __func__);
1421 return false;
1423 else
1425 if (hid < 0)
1426 logf("Cuesheet loading failed");
1428 info->cuesheet_hid = hid;
1432 return true;
1435 #ifdef HAVE_ALBUMART
1436 /* Load any album art for the file - returns false if the buffer is full */
1437 static bool audio_load_albumart(struct track_info *info,
1438 struct mp3entry *track_id3)
1440 int i;
1441 FOREACH_ALBUMART(i)
1443 struct bufopen_bitmap_data user_data;
1444 int *aa_hid = &info->aa_hid[i];
1445 int hid = ERR_UNSUPPORTED_TYPE;
1447 /* albumart_slots may change during a yield of bufopen,
1448 * but that's no problem */
1449 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1450 !albumart_slots[i].used)
1451 continue;
1453 memset(&user_data, 0, sizeof(user_data));
1454 user_data.dim = &albumart_slots[i].dim;
1456 #ifdef HAVE_IO_PRIORITY
1457 buf_back_off_storage(true);
1458 #endif
1460 /* We can only decode jpeg for embedded AA */
1461 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1463 user_data.embedded_albumart = &track_id3->albumart;
1464 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1467 if (hid < 0 && hid != ERR_BUFFER_FULL)
1469 /* No embedded AA or it couldn't be loaded - try other sources */
1470 char path[MAX_PATH];
1472 if (find_albumart(track_id3, path, sizeof(path),
1473 &albumart_slots[i].dim))
1475 user_data.embedded_albumart = NULL;
1476 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1480 #ifdef HAVE_IO_PRIORITY
1481 buf_back_off_storage(false);
1482 #endif
1483 if (hid == ERR_BUFFER_FULL)
1485 logf("buffer is full for now (%s)", __func__);
1486 return false;
1488 else
1490 /* If error other than a full buffer, then mark it "unsupported"
1491 to avoid reloading attempt */
1492 if (hid < 0)
1494 logf("Album art loading failed");
1495 hid = ERR_UNSUPPORTED_TYPE;
1498 *aa_hid = hid;
1502 return true;
1504 #endif /* HAVE_ALBUMART */
1506 #ifdef HAVE_CODEC_BUFFERING
1507 /* Load a codec for the file onto the buffer - assumes we're working from the
1508 currently loading track - not called for the current track */
1509 static bool audio_buffer_codec(struct track_info *track_info,
1510 struct mp3entry *track_id3)
1512 /* This will not be the current track -> it cannot be the first and the
1513 current track cannot be ahead of buffering -> there is a previous
1514 track entry which is either current or ahead of the current */
1515 struct track_info *prev_info = track_list_last(-1);
1516 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1518 /* If the previous codec is the same as this one, there is no need to
1519 put another copy of it on the file buffer (in other words, only
1520 buffer codecs at format transitions) */
1521 if (prev_id3)
1523 int codt = get_audio_base_codec_type(track_id3->codectype);
1524 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1526 if (codt == prev_codt)
1528 logf("Reusing prev. codec: %d", prev_id3->codectype);
1529 return true;
1532 /* else just load it (harmless) */
1534 /* Load the codec onto the buffer if possible */
1535 const char *codec_fn = get_codec_filename(track_id3->codectype);
1536 if (!codec_fn)
1537 return false;
1539 char codec_path[MAX_PATH+1]; /* Full path to codec */
1540 codec_get_full_path(codec_path, codec_fn);
1542 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1544 if (track_info->codec_hid >= 0)
1546 logf("Buffered codec: %d", afmt);
1547 return true;
1550 return false;
1552 #endif /* HAVE_CODEC_BUFFERING */
1554 /* Load metadata for the next track (with bufopen). The rest of the track
1555 loading will be handled by audio_finish_load_track once the metadata has
1556 been actually loaded by the buffering thread.
1558 Each track is arranged in the buffer as follows:
1559 <id3|[cuesheet|][album art|][codec|]audio>
1561 The next will not be loaded until the previous succeeds if the buffer was
1562 full at the time. To put any metadata after audio would make those handles
1563 unmovable.
1565 static int audio_load_track(void)
1567 if (in_progress_id3_hid >= 0)
1569 /* There must be an info pointer if the in-progress id3 is even there */
1570 struct track_info *info = track_list_last(0);
1572 if (info->id3_hid == in_progress_id3_hid)
1574 if (filling == STATE_FILLING)
1576 /* Haven't finished the metadata but the notification is
1577 anticipated to come soon */
1578 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1579 return LOAD_TRACK_OK;
1581 else if (filling == STATE_FULL)
1583 /* Buffer was full trying to complete the load after the
1584 metadata finished, so attempt to continue - older handles
1585 should have been cleared already */
1586 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1587 filling = STATE_FILLING;
1588 buffer_event_finished_callback(&info->id3_hid);
1589 return LOAD_TRACK_OK;
1593 /* Some old, stray buffering message */
1594 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1595 return LOAD_TRACK_ERR_BUSY;
1598 filling = STATE_FILLING;
1600 struct track_info *info = track_list_alloc_track();
1601 if (info == NULL)
1603 /* List is full so stop buffering tracks - however, attempt to obtain
1604 metadata as the unbuffered id3 */
1605 logf("No free tracks");
1606 filling = STATE_FULL;
1609 playlist_peek_offset++;
1611 logf("Buffering track: s%u/c%u/e%u/p%d",
1612 track_list.start, track_list.current, track_list.end,
1613 playlist_peek_offset);
1615 /* Get track name from current playlist read position */
1616 int fd = -1;
1617 char name_buf[MAX_PATH + 1];
1618 const char *trackname;
1620 while (1)
1623 trackname = playlist_peek(playlist_peek_offset, name_buf,
1624 sizeof (name_buf));
1626 if (!trackname)
1627 break;
1629 /* Test for broken playlists by probing for the files */
1630 fd = open(trackname, O_RDONLY);
1631 if (fd >= 0)
1632 break;
1634 logf("Open failed");
1635 /* Skip invalid entry from playlist */
1636 playlist_skip_entry(NULL, playlist_peek_offset);
1638 /* Sync the playlist if it isn't finished */
1639 if (playlist_peek(playlist_peek_offset, NULL, 0))
1640 playlist_next(0);
1643 if (!trackname)
1645 /* No track - exhausted the playlist entries */
1646 logf("End-of-playlist");
1647 id3_write_locked(UNBUFFERED_ID3, NULL);
1649 if (filling != STATE_FULL)
1650 track_list_unalloc_track(); /* Free this entry */
1652 playlist_peek_offset--; /* Maintain at last index */
1654 /* We can end up here after the real last track signals its completion
1655 and miss the transition to STATE_FINISHED esp. if dropping the last
1656 songs of a playlist late in their load (2nd stage) */
1657 info = track_list_last(0);
1659 if (info && buf_handle_remaining(info->audio_hid) == 0)
1660 filling_is_finished();
1661 else
1662 filling = STATE_END_OF_PLAYLIST;
1664 return LOAD_TRACK_ERR_NO_MORE;
1667 /* Successfully opened the file - get track metadata */
1668 if (filling == STATE_FULL ||
1669 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1671 /* Buffer or track list is full */
1672 struct mp3entry *ub_id3;
1674 playlist_peek_offset--;
1676 /* Load the metadata for the first unbuffered track */
1677 ub_id3 = id3_get(UNBUFFERED_ID3);
1678 id3_mutex_lock();
1679 get_metadata(ub_id3, fd, trackname);
1680 id3_mutex_unlock();
1682 if (filling != STATE_FULL)
1684 track_list_unalloc_track();
1685 filling = STATE_FULL;
1688 logf("%s: buffer is full for now (%u tracks)", __func__,
1689 track_list_count());
1691 else
1693 /* Successful load initiation */
1694 info->filesize = filesize(fd);
1695 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1698 close(fd);
1699 return LOAD_TRACK_OK;
1702 /* Second part of the track loading: We now have the metadata available, so we
1703 can load the codec, the album art and finally the audio data.
1704 This is called on the audio thread after the buffering thread calls the
1705 buffering_handle_finished_callback callback. */
1706 static int audio_finish_load_track(struct track_info *info)
1708 int trackstat = LOAD_TRACK_OK;
1710 if (info->id3_hid != in_progress_id3_hid)
1712 /* We must not be here if not! */
1713 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1714 in_progress_id3_hid);
1715 return LOAD_TRACK_ERR_BUSY;
1718 /* The current track for decoding (there is always one if the list is
1719 populated) */
1720 struct track_info *cur_info = track_list_current(0);
1721 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1723 if (!track_id3)
1725 /* This is an error condition. Track cannot be played without valid
1726 metadata; skip the track. */
1727 logf("No metadata for: %s", track_id3->path);
1728 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1729 goto audio_finish_load_track_exit;
1732 /* Try to load a cuesheet for the track */
1733 if (!audio_load_cuesheet(info, track_id3))
1735 /* No space for cuesheet on buffer, not an error */
1736 filling = STATE_FULL;
1737 goto audio_finish_load_track_exit;
1740 #ifdef HAVE_ALBUMART
1741 /* Try to load album art for the track */
1742 if (!audio_load_albumart(info, track_id3))
1744 /* No space for album art on buffer, not an error */
1745 filling = STATE_FULL;
1746 goto audio_finish_load_track_exit;
1748 #endif
1750 /* All handles available to external routines are ready - audio and codec
1751 information is private */
1753 if (info == track_list_user_current(0))
1755 /* Send only when the track handles could not all be opened ahead of
1756 time for the user's current track - otherwise everything is ready
1757 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1758 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1761 #ifdef HAVE_CODEC_BUFFERING
1762 /* Try to buffer a codec for the track */
1763 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1765 if (info->codec_hid == ERR_BUFFER_FULL)
1767 /* No space for codec on buffer, not an error */
1768 filling = STATE_FULL;
1769 logf("buffer is full for now (%s)", __func__);
1771 else
1773 /* This is an error condition, either no codec was found, or
1774 reading the codec file failed part way through, either way,
1775 skip the track */
1776 logf("No codec for: %s", track_id3->path);
1777 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1780 goto audio_finish_load_track_exit;
1782 #endif /* HAVE_CODEC_BUFFERING */
1784 /** Finally, load the audio **/
1785 size_t file_offset = 0;
1786 track_id3->elapsed = 0;
1788 if (track_id3->offset >= info->filesize)
1789 track_id3->offset = 0;
1791 logf("%s: set offset for %s to %lu\n", __func__,
1792 id3->title, (unsigned long)offset);
1794 /* Adjust for resume rewind so we know what to buffer - starting the codec
1795 calls it again, so we don't save it (and they shouldn't accumulate) */
1796 size_t offset = resume_rewind_adjusted_offset(track_id3);
1798 enum data_type audiotype = get_audio_base_data_type(track_id3->codectype);
1800 if (audiotype == TYPE_ATOMIC_AUDIO)
1801 logf("Loading atomic %d", track_id3->codectype);
1803 if (format_buffers_with_offset(track_id3->codectype))
1805 /* This format can begin buffering from any point */
1806 file_offset = offset;
1809 logf("load track: %s", track_id3->path);
1811 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1813 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1814 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1816 else
1818 /* No offset given or it is very minimal - begin at the first frame
1819 according to the metadata */
1820 file_offset = track_id3->first_frame_offset;
1823 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1825 if (hid >= 0)
1827 info->audio_hid = hid;
1829 if (info == cur_info)
1831 /* This is the current track to decode - should be started now */
1832 trackstat = LOAD_TRACK_READY;
1835 else
1837 /* Buffer could be full but not properly so if this is the only
1838 track! */
1839 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
1841 filling = STATE_FULL;
1842 logf("Buffer is full for now (%s)", __func__);
1844 else
1846 /* Nothing to play if no audio handle - skip this */
1847 logf("Could not add audio data handle");
1848 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1852 audio_finish_load_track_exit:
1853 if (trackstat < LOAD_TRACK_OK)
1855 playlist_skip_entry(NULL, playlist_peek_offset);
1856 track_info_close(info);
1857 track_list_unalloc_track();
1859 if (playlist_peek(playlist_peek_offset, NULL, 0))
1860 playlist_next(0);
1862 playlist_peek_offset--;
1865 if (filling != STATE_FULL)
1867 /* Load next track - error or not */
1868 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
1869 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1870 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
1872 else
1874 /* Full */
1875 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
1878 return trackstat;
1881 /* Start a new track load */
1882 static int audio_fill_file_buffer(void)
1884 if (play_status == PLAY_STOPPED)
1885 return LOAD_TRACK_ERR_FAILED;
1887 trigger_cpu_boost();
1889 /* Must reset the buffer before use if trashed or voice only - voice
1890 file size shouldn't have changed so we can go straight from
1891 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1892 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1893 audio_reset_buffer();
1895 logf("Starting buffer fill");
1897 int trackstat = audio_load_track();
1899 if (trackstat >= LOAD_TRACK_OK)
1901 if (track_list_current(0) == track_list_user_current(0))
1902 playlist_next(0);
1904 if (filling == STATE_FULL && !track_list_user_current(1))
1906 /* There are no user tracks on the buffer after this therefore
1907 this is the next track */
1908 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
1912 return trackstat;
1915 /* Discard unwanted tracks and start refill from after the specified playlist
1916 offset */
1917 static int audio_reset_and_rebuffer(
1918 enum track_clear_action action, int peek_offset)
1920 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
1922 id3_write_locked(UNBUFFERED_ID3, NULL);
1924 /* Remove unwanted tracks - caller must have ensured codec isn't using
1925 any */
1926 track_list_clear(action);
1928 /* Refill at specified position (-1 starts at index offset 0) */
1929 playlist_peek_offset = peek_offset;
1931 /* Fill the buffer */
1932 return audio_fill_file_buffer();
1935 /* Handle buffering events
1936 (Q_AUDIO_BUFFERING) */
1937 static void audio_on_buffering(int event)
1939 enum track_clear_action action;
1940 int peek_offset;
1942 if (track_list_empty())
1943 return;
1945 switch (event)
1947 case BUFFER_EVENT_BUFFER_LOW:
1948 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
1949 return; /* Should be nothing left to fill */
1951 /* Clear old tracks and continue buffering where it left off */
1952 action = TRACK_LIST_KEEP_NEW;
1953 peek_offset = playlist_peek_offset;
1954 break;
1956 case BUFFER_EVENT_REBUFFER:
1957 /* Remove all but the currently decoding track and redo buffering
1958 after that */
1959 action = TRACK_LIST_KEEP_CURRENT;
1960 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
1961 break;
1963 default:
1964 return;
1967 switch (skip_pending)
1969 case TRACK_SKIP_NONE:
1970 case TRACK_SKIP_AUTO:
1971 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
1972 audio_reset_and_rebuffer(action, peek_offset);
1973 break;
1975 case TRACK_SKIP_AUTO_END_PLAYLIST:
1976 /* Already finished */
1977 break;
1979 default:
1980 /* Invalid */
1981 logf("Buffering call, inv. state: %d", (int)skip_pending);
1985 /* Handle starting the next track load
1986 (Q_AUDIO_FILL_BUFFER) */
1987 static void audio_on_fill_buffer(void)
1989 audio_handle_track_load_status(audio_fill_file_buffer());
1992 /* Handle posted load track finish event
1993 (Q_AUDIO_FINISH_LOAD_TRACK) */
1994 static void audio_on_finish_load_track(int id3_hid)
1996 struct track_info *info = track_list_last(0);
1998 if (!info || !buf_is_handle(id3_hid))
1999 return;
2001 if (info == track_list_user_current(1))
2003 /* Just loaded the metadata right after the current position */
2004 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
2007 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
2008 return; /* Not current track */
2010 bool is_user_current = info == track_list_user_current(0);
2012 if (is_user_current)
2014 /* Copy cuesheet */
2015 buf_read_cuesheet(info->cuesheet_hid);
2018 if (audio_start_codec(automatic_skip))
2020 if (is_user_current)
2022 /* Be sure all tagtree info is synchronized; it will be needed for the
2023 track finish event - the sync will happen when finalizing a track
2024 change otherwise */
2025 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2027 playing_id3_sync(info, -1);
2029 if (!was_valid)
2031 /* Playing id3 hadn't been updated yet because no valid track
2032 was yet available - treat like the first track */
2033 audio_playlist_track_change();
2037 else
2039 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2043 /* Called when handles other than metadata handles have finished buffering
2044 (Q_AUDIO_HANDLE_FINISHED) */
2045 static void audio_on_handle_finished(int hid)
2047 /* Right now, only audio handles should end up calling this */
2048 if (filling == STATE_END_OF_PLAYLIST)
2050 struct track_info *info = track_list_last(0);
2052 /* Really we don't know which order the handles will actually complete
2053 to zero bytes remaining since another thread is doing it - be sure
2054 it's the right one */
2055 if (info && info->audio_hid == hid)
2057 /* This was the last track in the playlist and we now have all the
2058 data we need */
2059 filling_is_finished();
2064 /* Called to make an outstanding track skip the current track and to send the
2065 transition events */
2066 static void audio_finalise_track_change(bool delayed)
2068 switch (skip_pending)
2070 case TRACK_SKIP_NONE: /* Manual skip */
2071 break;
2073 case TRACK_SKIP_AUTO:
2074 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2076 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2077 audio_playlist_track_finish();
2079 if (!playlist_peek(playlist_delta, NULL, 0))
2081 /* Track ended up rejected - push things ahead like the codec blew
2082 it (because it was never started and now we're here where it
2083 should have been decoding the next track by now) - next, a
2084 directory change or end of playback will most likely happen */
2085 skip_pending = TRACK_SKIP_NONE;
2086 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2087 return;
2090 if (!playlist_delta)
2091 break;
2093 playlist_peek_offset -= playlist_delta;
2094 if (playlist_next(playlist_delta) >= 0)
2095 break;
2096 /* What!? Disappear? Hopeless bleak despair */
2098 /* Fallthrough */
2099 case TRACK_SKIP_AUTO_END_PLAYLIST:
2100 default: /* Invalid */
2101 filling = STATE_ENDED;
2102 audio_stop_playback();
2103 return;
2106 struct track_info *info = track_list_current(0);
2107 struct mp3entry *track_id3 = NULL;
2109 id3_mutex_lock();
2111 /* Update the current cuesheet if any and enabled */
2112 if (info)
2114 buf_read_cuesheet(info->cuesheet_hid);
2115 track_id3 = bufgetid3(info->id3_hid);
2118 id3_write(PLAYING_ID3, track_id3);
2120 if (delayed)
2122 /* Delayed skip where codec is ahead of user's current track */
2123 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2124 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
2125 ply_id3->elapsed = ci_id3->elapsed;
2126 ply_id3->offset = ci_id3->offset;
2129 /* The skip is technically over */
2130 skip_pending = TRACK_SKIP_NONE;
2132 /* Sync the next track information */
2133 info = track_list_current(1);
2135 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2136 id3_get(UNBUFFERED_ID3));
2138 id3_mutex_unlock();
2140 audio_playlist_track_change();
2143 /* Actually begin a transition and take care of the codec change - may complete
2144 it now or ask pcmbuf for notification depending on the type and what pcmbuf
2145 has to say */
2146 static void audio_begin_track_change(bool auto_skip, int trackstat)
2148 /* Even if the new track is bad, the old track must be finished off */
2149 bool finalised = pcmbuf_start_track_change(auto_skip);
2151 if (finalised)
2153 /* pcmbuf says that the transition happens now - complete it */
2154 audio_finalise_track_change(false);
2156 if (play_status == PLAY_STOPPED)
2157 return; /* Stopped us */
2160 if (!auto_skip)
2161 audio_clear_paused_pcm();
2163 if (trackstat >= LOAD_TRACK_OK)
2165 struct track_info *info = track_list_current(0);
2167 if (info->audio_hid < 0)
2168 return;
2170 /* Everything needed for the codec is ready - start it */
2171 if (audio_start_codec(auto_skip))
2173 if (finalised)
2174 playing_id3_sync(info, -1);
2175 return;
2178 trackstat = LOAD_TRACK_ERR_START_CODEC;
2181 audio_handle_track_load_status(trackstat);
2184 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2185 static void audio_monitor_end_of_playlist(void)
2187 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2188 filling = STATE_ENDING;
2189 pcmbuf_monitor_track_change(true);
2192 /* Codec has completed decoding the track
2193 (usually Q_AUDIO_CODEC_COMPLETE) */
2194 static void audio_on_codec_complete(int status)
2196 logf("%s(%d)", __func__, status);
2198 if (play_status == PLAY_STOPPED)
2199 return;
2201 /* If it didn't notify us first, don't expect "seek complete" message
2202 since the codec can't post it now - do things like it would have
2203 done */
2204 audio_complete_codec_seek();
2206 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2208 /* Old-hay on the ip-skay - codec has completed decoding
2210 Paused: We're not sounding it, so just remember that it happened
2211 and the resume will begin the transition
2213 Skipping: There was already a skip in progress, remember it and
2214 allow no further progress until the PCM from the previous
2215 song has finished
2217 codec_skip_pending = true;
2218 codec_skip_status = status;
2219 return;
2222 codec_skip_pending = false;
2224 #ifdef AB_REPEAT_ENABLE
2225 if (status >= 0)
2227 /* Normal automatic skip */
2228 ab_end_of_track_report();
2230 #endif
2232 int trackstat = LOAD_TRACK_OK;
2234 automatic_skip = true;
2235 skip_pending = TRACK_SKIP_AUTO;
2237 /* Does this track have an entry allocated? */
2238 struct track_info *info = track_list_advance_current(1);
2240 if (!info || info->audio_hid < 0)
2242 bool end_of_playlist = false;
2244 if (info)
2246 /* Track load is not complete - it might have stopped on a
2247 full buffer without reaching the audio handle or we just
2248 arrived at it early
2250 If this type is atomic and we couldn't get the audio,
2251 perhaps it would need to wrap to make the allocation and
2252 handles are in the way - to maximize the liklihood it can
2253 be allocated, clear all handles to reset the buffer and
2254 its indexes to 0 - for packet audio, this should not be an
2255 issue and a pointless full reload of all the track's
2256 metadata may be avoided */
2258 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2260 if (track_id3 &&
2261 get_audio_base_data_type(track_id3->codectype)
2262 == TYPE_PACKET_AUDIO)
2264 /* Continue filling after this track */
2265 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2266 audio_begin_track_change(true, trackstat);
2267 return;
2269 /* else rebuffer at this track; status applies to the track we
2270 want */
2272 else if (!playlist_peek(1, NULL, 0))
2274 /* Play sequence is complete - directory change or other playlist
2275 resequencing - the playlist must now be advanced in order to
2276 continue since a peek ahead to the next track is not possible */
2277 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2278 end_of_playlist = playlist_next(1) < 0;
2281 if (!end_of_playlist)
2283 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2284 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2286 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2288 /* Failed to find anything after all - do playlist switchover
2289 instead */
2290 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2291 end_of_playlist = playlist_next(1) < 0;
2295 if (end_of_playlist)
2297 audio_monitor_end_of_playlist();
2298 return;
2302 audio_begin_track_change(true, trackstat);
2305 /* Called when codec completes seek operation
2306 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2307 static void audio_on_codec_seek_complete(void)
2309 logf("%s()", __func__);
2310 audio_complete_codec_seek();
2311 codec_go();
2314 /* Called when PCM track change has completed
2315 (Q_AUDIO_TRACK_CHANGED) */
2316 static void audio_on_track_changed(void)
2318 /* Finish whatever is pending so that the WPS is in sync */
2319 audio_finalise_track_change(true);
2321 if (codec_skip_pending)
2323 /* Codec got ahead completing a short track - complete the
2324 codec's skip and begin the next */
2325 codec_skip_pending = false;
2326 audio_on_codec_complete(codec_skip_status);
2330 /* Begin playback from an idle state, transition to a new playlist or
2331 invalidate the buffer and resume (if playing).
2332 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2333 static void audio_start_playback(size_t offset, unsigned int flags)
2335 enum play_status old_status = play_status;
2337 if (flags & AUDIO_START_NEWBUF)
2339 /* Mark the buffer dirty - if not playing, it will be reset next
2340 time */
2341 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2342 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2345 if (old_status != PLAY_STOPPED)
2347 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2349 halt_decoding_track(true);
2351 automatic_skip = false;
2352 ff_rw_mode = false;
2354 if (flags & AUDIO_START_RESTART)
2356 /* Clear out some stuff to resume the current track where it
2357 left off */
2358 pcmbuf_play_stop();
2359 offset = id3_get(PLAYING_ID3)->offset;
2360 track_list_clear(TRACK_LIST_CLEAR_ALL);
2362 else
2364 /* This is more-or-less treated as manual track transition */
2365 /* Save resume information for current track */
2366 audio_playlist_track_finish();
2367 track_list_clear(TRACK_LIST_CLEAR_ALL);
2369 /* Indicate manual track change */
2370 pcmbuf_start_track_change(false);
2371 audio_clear_paused_pcm();
2372 wipe_track_metadata(true);
2375 /* Set after track finish event in case skip was in progress */
2376 skip_pending = TRACK_SKIP_NONE;
2378 else
2380 if (flags & AUDIO_START_RESTART)
2381 return; /* Must already be playing */
2383 /* Cold playback start from a stopped state */
2384 logf("%s(%lu): starting", __func__, offset);
2386 /* Set audio parameters */
2387 #if INPUT_SRC_CAPS != 0
2388 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2389 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2390 #endif
2391 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2392 sound_set_volume(global_settings.volume);
2393 #endif
2394 /* Be sure channel is audible */
2395 pcmbuf_fade(false, true);
2397 /* Update our state */
2398 play_status = PLAY_PLAYING;
2401 /* Start fill from beginning of playlist */
2402 playlist_peek_offset = -1;
2403 buf_set_base_handle(-1);
2405 /* Officially playing */
2406 queue_reply(&audio_queue, 1);
2408 /* Add these now - finish event for the first id3 will most likely be sent
2409 immediately */
2410 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2411 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2413 if (old_status == PLAY_STOPPED)
2415 /* Send coldstart event */
2416 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2419 /* Fill the buffer */
2420 int trackstat = audio_fill_file_buffer();
2422 if (trackstat >= LOAD_TRACK_OK)
2424 /* This is the currently playing track - get metadata, stat */
2425 playing_id3_sync(track_list_current(0), offset);
2427 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2429 /* Only if actually changing tracks... */
2430 if (!(flags & AUDIO_START_RESTART))
2431 audio_playlist_track_change();
2434 else
2436 /* Found nothing playable */
2437 audio_handle_track_load_status(trackstat);
2441 /* Stop playback and enter an idle state
2442 (usually Q_AUDIO_STOP) */
2443 static void audio_stop_playback(void)
2445 logf("%s()", __func__);
2447 if (play_status == PLAY_STOPPED)
2448 return;
2450 bool do_fade = global_settings.fade_on_stop && filling != STATE_ENDED;
2452 pcmbuf_fade(do_fade, false);
2454 /* Wait for fade-out */
2455 audio_wait_fade_complete();
2457 /* Stop the codec and unload it */
2458 halt_decoding_track(true);
2459 pcmbuf_play_stop();
2460 codec_unload();
2462 /* Save resume information - "filling" might have been set to
2463 "STATE_ENDED" by caller in order to facilitate end of playlist */
2464 audio_playlist_track_finish();
2466 skip_pending = TRACK_SKIP_NONE;
2467 automatic_skip = false;
2469 /* Close all tracks and mark them NULL */
2470 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2471 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2472 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2474 track_list_clear(TRACK_LIST_CLEAR_ALL);
2476 /* Update our state */
2477 ff_rw_mode = false;
2478 play_status = PLAY_STOPPED;
2480 wipe_track_metadata(true);
2482 /* Go idle */
2483 filling = STATE_IDLE;
2484 cancel_cpu_boost();
2487 /* Pause the playback of the current track
2488 (Q_AUDIO_PAUSE) */
2489 static void audio_on_pause(bool pause)
2491 logf("%s(%s)", __func__, pause ? "true" : "false");
2493 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2494 return;
2496 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2498 if (!pause && codec_skip_pending)
2500 /* Actually do the skip that is due - resets the status flag */
2501 audio_on_codec_complete(codec_skip_status);
2504 bool do_fade = global_settings.fade_on_stop;
2506 pcmbuf_fade(do_fade, !pause);
2508 if (!ff_rw_mode && !(do_fade && pause))
2510 /* Not in ff/rw mode - can actually change the audio state now */
2511 pcmbuf_pause(pause);
2515 /* Skip a certain number of tracks forwards or backwards
2516 (Q_AUDIO_SKIP) */
2517 static void audio_on_skip(void)
2519 id3_mutex_lock();
2521 /* Eat the delta to keep it synced, even if not playing */
2522 int toskip = skip_offset;
2523 skip_offset = 0;
2525 logf("%s(): %d", __func__, toskip);
2527 id3_mutex_unlock();
2529 if (play_status == PLAY_STOPPED)
2530 return;
2532 /* Force codec to abort this track */
2533 halt_decoding_track(true);
2535 /* Kill the ff/rw halt */
2536 ff_rw_mode = false;
2538 /* Manual skip */
2539 automatic_skip = false;
2541 /* If there was an auto skip in progress, there will be residual
2542 advancement of the playlist and/or track list so compensation will be
2543 required in order to end up in the right spot */
2544 int track_list_delta = toskip;
2545 int playlist_delta = toskip;
2547 if (skip_pending != TRACK_SKIP_NONE)
2549 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2550 track_list_delta--;
2552 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2553 playlist_delta--;
2556 audio_playlist_track_finish();
2557 skip_pending = TRACK_SKIP_NONE;
2559 /* Update the playlist current track now */
2560 while (playlist_next(playlist_delta) < 0)
2562 /* Manual skip out of range (because the playlist wasn't updated
2563 yet by us and so the check in audio_skip returned 'ok') - bring
2564 back into range */
2565 int d = toskip < 0 ? 1 : -1;
2567 while (!playlist_check(playlist_delta))
2569 if (playlist_delta == d)
2571 /* Had to move the opposite direction to correct, which is
2572 wrong - this is the end */
2573 filling = STATE_ENDED;
2574 audio_stop_playback();
2575 return;
2578 playlist_delta += d;
2579 track_list_delta += d;
2583 /* Adjust things by how much the playlist was manually moved */
2584 playlist_peek_offset -= playlist_delta;
2586 struct track_info *info = track_list_advance_current(track_list_delta);
2587 int trackstat = LOAD_TRACK_OK;
2589 if (!info || info->audio_hid < 0)
2591 /* We don't know the next track thus we know we don't have it */
2592 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2595 audio_begin_track_change(false, trackstat);
2598 /* Skip to the next/previous directory
2599 (Q_AUDIO_DIR_SKIP) */
2600 static void audio_on_dir_skip(int direction)
2602 logf("%s(%d)", __func__, direction);
2604 id3_mutex_lock();
2605 skip_offset = 0;
2606 id3_mutex_unlock();
2608 if (play_status == PLAY_STOPPED)
2609 return;
2611 /* Force codec to abort this track */
2612 halt_decoding_track(true);
2614 /* Kill the ff/rw halt */
2615 ff_rw_mode = false;
2617 /* Manual skip */
2618 automatic_skip = false;
2620 audio_playlist_track_finish();
2622 /* Unless automatic and gapless, skips do not pend */
2623 skip_pending = TRACK_SKIP_NONE;
2625 /* Regardless of the return value we need to rebuffer. If it fails the old
2626 playlist will resume, else the next dir will start playing. */
2627 playlist_next_dir(direction);
2629 wipe_track_metadata(false);
2631 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2633 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2635 /* The day the music died - finish-off whatever is playing and call it
2636 quits */
2637 audio_monitor_end_of_playlist();
2638 return;
2641 audio_begin_track_change(false, trackstat);
2644 /* Enter seek mode in order to start a seek
2645 (Q_AUDIO_PRE_FF_REWIND) */
2646 static void audio_on_pre_ff_rewind(void)
2648 logf("%s()", __func__);
2650 if (play_status == PLAY_STOPPED || ff_rw_mode)
2651 return;
2653 ff_rw_mode = true;
2655 audio_wait_fade_complete();
2657 if (play_status == PLAY_PAUSED)
2658 return;
2660 pcmbuf_pause(true);
2663 /* Seek the playback of the current track to the specified time
2664 (Q_AUDIO_FF_REWIND) */
2665 static void audio_on_ff_rewind(long time)
2667 logf("%s(%ld)", __func__, time);
2669 if (play_status == PLAY_STOPPED)
2670 return;
2672 enum track_skip_type pending = skip_pending;
2674 switch (pending)
2676 case TRACK_SKIP_NONE: /* The usual case */
2677 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2678 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2680 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2681 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2683 automatic_skip = false;
2685 /* Send event before clobbering the time */
2686 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2687 then skipping back to this track resumes properly. Something else
2688 should be sent. We're not _really_ finishing the track are we? */
2689 if (time == 0)
2690 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2692 /* Prevent user codec time update - coerce to something that is
2693 innocuous concerning lookaheads */
2694 if (pending == TRACK_SKIP_NONE)
2695 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2697 id3->elapsed = time;
2698 queue_reply(&audio_queue, 1);
2700 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2702 /* Need this set in case ff/rw mode + error but _after_ the codec
2703 halt that will reset it */
2704 codec_seeking = true;
2706 if (pending == TRACK_SKIP_AUTO)
2708 if (!track_list_advance_current(-1))
2710 /* Not in list - must rebuffer at the current playlist index */
2711 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2712 < LOAD_TRACK_OK)
2714 /* Codec is stopped */
2715 break;
2720 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2721 rebuffer is needed */
2722 skip_pending = TRACK_SKIP_NONE;
2723 struct track_info *cur_info = track_list_current(0);
2725 /* Track must complete the loading _now_ since a codec and audio
2726 handle are needed in order to do the seek */
2727 if (cur_info->audio_hid < 0 &&
2728 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2730 /* Call above should push any load sequence - no need for
2731 halt_decoding_track here if no skip was pending here because
2732 there would not be a codec started if no audio handle was yet
2733 opened */
2734 break;
2737 if (pending == TRACK_SKIP_AUTO)
2739 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2740 !audio_init_codec(cur_info, ci_id3))
2742 /* We should have still been able to get it - skip it and move
2743 onto the next one - like it or not this track is broken */
2744 break;
2747 /* Set the codec API to the correct metadata and track info */
2748 ci.audio_hid = cur_info->audio_hid;
2749 ci.filesize = cur_info->filesize;
2750 buf_set_base_handle(cur_info->audio_hid);
2753 if (!haltres)
2755 /* If codec must be (re)started, reset the offset */
2756 ci_id3->offset = 0;
2759 codec_seek(time);
2760 return;
2763 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2765 /* We cannot do this because the playlist must be reversed by one
2766 and it doesn't always return the same song when going backwards
2767 across boundaries as forwards (either because of randomization
2768 or inconsistency in deciding what the previous track should be),
2769 therefore the whole operation would often end up as nonsense -
2770 lock out seeking for a couple seconds */
2772 /* Sure as heck cancel seek mode too! */
2773 audio_ff_rewind_end();
2774 return;
2777 default:
2778 /* Won't see this */
2779 return;
2782 if (play_status == PLAY_STOPPED)
2784 /* Playback ended because of an error completing a track load */
2785 return;
2788 /* Always fake it as a codec start error which will handle mode
2789 cancellations and skip to the next track */
2790 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2793 /* Invalidates all but currently playing track
2794 (Q_AUDIO_FLUSH) */
2795 static void audio_on_audio_flush(void)
2797 logf("%s", __func__);
2799 if (track_list_empty())
2800 return; /* Nothing to flush out */
2802 switch (skip_pending)
2804 case TRACK_SKIP_NONE:
2805 case TRACK_SKIP_AUTO_END_PLAYLIST:
2806 /* Remove all but the currently playing track from the list and
2807 refill after that */
2808 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2809 playlist_peek_offset = 0;
2810 id3_write_locked(UNBUFFERED_ID3, NULL);
2811 audio_update_and_announce_next_track(NULL);
2813 /* Ignore return since it's about the next track, not this one */
2814 audio_fill_file_buffer();
2816 if (skip_pending == TRACK_SKIP_NONE)
2817 break;
2819 /* There's now a track after this one now - convert to auto skip -
2820 no skip should pend right now because multiple flush messages can
2821 be fired which would cause a restart in the below cases */
2822 skip_pending = TRACK_SKIP_NONE;
2823 audio_clear_track_notifications();
2824 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2825 break;
2827 case TRACK_SKIP_AUTO:
2828 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2829 /* Precisely removing what it already decoded for the next track is
2830 not possible so a restart is required in order to continue the
2831 currently playing track without the now invalid future track
2832 playing */
2833 audio_start_playback(0, AUDIO_START_RESTART);
2834 break;
2836 default: /* Nothing else is a state */
2837 break;
2841 #ifdef AUDIO_HAVE_RECORDING
2842 /* Load the requested encoder type
2843 (Q_AUDIO_LOAD_ENCODER) */
2844 static void audio_on_load_encoder(int afmt)
2846 bool res = true;
2848 if (play_status != PLAY_STOPPED)
2849 audio_stop_playback(); /* Can't load both types at once */
2850 else
2851 codec_unload(); /* Encoder still loaded, stop and unload it */
2853 if (afmt != AFMT_UNKNOWN)
2855 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
2856 if (res)
2857 codec_go(); /* These are run immediately */
2860 queue_reply(&audio_queue, res);
2862 #endif /* AUDIO_HAVE_RECORDING */
2864 static void audio_thread(void)
2866 struct queue_event ev;
2868 pcm_postinit();
2870 filling = STATE_IDLE;
2872 while (1)
2874 switch (filling)
2876 /* Active states */
2877 case STATE_FULL:
2878 case STATE_END_OF_PLAYLIST:
2879 if (buf_get_watermark() == 0)
2881 /* End of buffering for now, let's calculate the watermark,
2882 register for a low buffer event and unboost */
2883 audio_update_filebuf_watermark(0);
2884 add_event(BUFFER_EVENT_BUFFER_LOW, true,
2885 buffer_event_buffer_low_callback);
2887 /* Fall-through */
2888 case STATE_FINISHED:
2889 /* All data was buffered */
2890 cancel_cpu_boost();
2891 /* Fall-through */
2892 case STATE_FILLING:
2893 case STATE_ENDING:
2894 if (audio_pcmbuf_track_change_scan())
2896 /* Transfer notification to audio queue event */
2897 ev.id = Q_AUDIO_TRACK_CHANGED;
2898 ev.data = 1;
2900 else
2902 /* If doing auto skip, poll pcmbuf track notifications a bit
2903 faster to promply detect the transition */
2904 queue_wait_w_tmo(&audio_queue, &ev,
2905 skip_pending == TRACK_SKIP_NONE ?
2906 HZ/2 : HZ/10);
2908 break;
2910 /* Idle states */
2911 default:
2912 queue_wait(&audio_queue, &ev);
2914 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2915 switch (ev.id)
2917 #ifdef AUDIO_HAVE_RECORDING
2918 /* Must monitor the encoder message for recording so it can remove
2919 it if we process the insertion before it does. It cannot simply
2920 be removed from under recording however. */
2921 case Q_AUDIO_LOAD_ENCODER:
2922 break;
2923 #endif
2924 case SYS_USB_DISCONNECTED:
2925 filling = STATE_IDLE;
2926 break;
2928 default:
2929 if (filling == STATE_USB)
2930 continue;
2932 #endif /* CONFIG_PLATFORM */
2935 switch (ev.id)
2937 /** Codec and track change messages **/
2938 case Q_AUDIO_CODEC_COMPLETE:
2939 /* Codec is done processing track and has gone idle */
2940 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
2941 audio_on_codec_complete(ev.data);
2942 break;
2944 case Q_AUDIO_CODEC_SEEK_COMPLETE:
2945 /* Codec is done seeking */
2946 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2947 audio_on_codec_seek_complete();
2948 break;
2950 case Q_AUDIO_TRACK_CHANGED:
2951 /* PCM track change done */
2952 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2953 audio_on_track_changed();
2954 break;
2956 /** Control messages **/
2957 case Q_AUDIO_PLAY:
2958 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2959 audio_start_playback(ev.data, 0);
2960 break;
2962 case Q_AUDIO_STOP:
2963 LOGFQUEUE("audio < Q_AUDIO_STOP");
2964 audio_stop_playback();
2965 if (ev.data != 0)
2966 queue_clear(&audio_queue);
2967 break;
2969 case Q_AUDIO_PAUSE:
2970 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2971 audio_on_pause(ev.data);
2972 break;
2974 case Q_AUDIO_SKIP:
2975 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2976 audio_on_skip();
2977 break;
2979 case Q_AUDIO_DIR_SKIP:
2980 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2981 audio_on_dir_skip(ev.data);
2982 break;
2984 case Q_AUDIO_PRE_FF_REWIND:
2985 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2986 audio_on_pre_ff_rewind();
2987 break;
2989 case Q_AUDIO_FF_REWIND:
2990 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2991 audio_on_ff_rewind(ev.data);
2992 break;
2994 case Q_AUDIO_FLUSH:
2995 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
2996 audio_on_audio_flush();
2997 break;
2999 /** Buffering messages **/
3000 case Q_AUDIO_BUFFERING:
3001 /* some buffering event */
3002 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
3003 audio_on_buffering(ev.data);
3004 break;
3006 case Q_AUDIO_FILL_BUFFER:
3007 /* continue buffering next track */
3008 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
3009 audio_on_fill_buffer();
3010 break;
3012 case Q_AUDIO_FINISH_LOAD_TRACK:
3013 /* metadata is buffered */
3014 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
3015 audio_on_finish_load_track(ev.data);
3016 break;
3018 case Q_AUDIO_HANDLE_FINISHED:
3019 /* some other type is buffered */
3020 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3021 audio_on_handle_finished(ev.data);
3022 break;
3024 /** Miscellaneous messages **/
3025 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3026 /* buffer needs to be reinitialized */
3027 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3028 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3029 break;
3031 #ifdef HAVE_DISK_STORAGE
3032 case Q_AUDIO_UPDATE_WATERMARK:
3033 /* buffering watermark needs updating */
3034 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3035 audio_update_filebuf_watermark(ev.data);
3036 break;
3037 #endif /* HAVE_DISK_STORAGE */
3039 #ifdef AUDIO_HAVE_RECORDING
3040 case Q_AUDIO_LOAD_ENCODER:
3041 /* load an encoder for recording */
3042 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3043 audio_on_load_encoder(ev.data);
3044 break;
3045 #endif /* AUDIO_HAVE_RECORDING */
3047 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3048 case SYS_USB_CONNECTED:
3049 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3050 audio_stop_playback();
3051 #ifdef PLAYBACK_VOICE
3052 voice_stop();
3053 #endif
3054 filling = STATE_USB;
3055 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3056 break;
3057 #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
3059 case SYS_TIMEOUT:
3060 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3061 break;
3063 default:
3064 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3065 break;
3066 } /* end switch */
3067 } /* end while */
3071 /* --- Buffering callbacks --- */
3073 /* Called when fullness is below the watermark level */
3074 static void buffer_event_buffer_low_callback(void *data)
3076 logf("low buffer callback");
3077 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3078 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3079 (void)data;
3082 /* Called when handles must be discarded in order to buffer new data */
3083 static void buffer_event_rebuffer_callback(void *data)
3085 logf("rebuffer callback");
3086 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3087 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3088 (void)data;
3091 /* A handle has completed buffering and all required data is available */
3092 static void buffer_event_finished_callback(void *data)
3094 int hid = *(const int *)data;
3095 const enum data_type htype = buf_handle_data_type(hid);
3097 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3099 /* Limit queue traffic */
3100 switch (htype)
3102 case TYPE_ID3:
3103 /* The metadata handle for the last loaded track has been buffered.
3104 We can ask the audio thread to load the rest of the track's data. */
3105 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3106 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3107 break;
3109 case TYPE_PACKET_AUDIO:
3110 /* Strip any useless trailing tags that are left. */
3111 strip_tags(hid);
3112 /* Fall-through */
3113 case TYPE_ATOMIC_AUDIO:
3114 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3115 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3116 break;
3118 default:
3119 /* Don't care to know about these */
3120 break;
3125 /** -- Codec callbacks -- **/
3127 /* Update elapsed times with latency-adjusted values */
3128 void audio_codec_update_elapsed(unsigned long value)
3130 #ifdef AB_REPEAT_ENABLE
3131 ab_position_report(value);
3132 #endif
3134 unsigned long latency = pcmbuf_get_latency();
3136 if (LIKELY(value >= latency))
3138 unsigned long elapsed = value - latency;
3140 if (elapsed > value || elapsed < value - 2)
3141 value = elapsed;
3143 else
3145 value = 0;
3148 /* Track codec: used later when updating the playing at the user
3149 transition */
3150 id3_get(CODEC_ID3)->elapsed = value;
3152 /* If a skip is pending, the PCM buffer is updating the time on the
3153 previous song */
3154 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3155 id3_get(PLAYING_ID3)->elapsed = value;
3158 /* Update offsets with latency-adjusted values */
3159 void audio_codec_update_offset(size_t value)
3161 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
3162 unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8;
3164 if (LIKELY(value >= latency))
3166 value -= latency;
3168 else
3170 value = 0;
3173 /* Track codec: used later when updating the playing id3 at the user
3174 transition */
3175 ci_id3->offset = value;
3177 /* If a skip is pending, the PCM buffer is updating the time on the
3178 previous song */
3179 if (LIKELY(skip_pending == TRACK_SKIP_NONE))
3180 id3_get(PLAYING_ID3)->offset = value;
3184 /** --- Pcmbuf callbacks --- **/
3186 /* Between the codec and PCM track change, we need to keep updating the
3187 * "elapsed" value of the previous (to the codec, but current to the
3188 * user/PCM/WPS) track, so that the progressbar reaches the end. */
3189 void audio_pcmbuf_position_callback(unsigned int time)
3191 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3193 time += id3->elapsed;
3195 id3->elapsed = MIN(time, id3->length);
3198 /* Post message from pcmbuf that the end of the previous track has just
3199 * been played */
3200 void audio_pcmbuf_track_change(bool pcmbuf)
3202 if (pcmbuf)
3204 /* Notify of the change in special-purpose semaphore object */
3205 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3206 audio_pcmbuf_track_change_post();
3208 else
3210 /* Safe to post directly to the queue */
3211 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3212 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3216 /* May pcmbuf start PCM playback when the buffer is full enough? */
3217 bool audio_pcmbuf_may_play(void)
3219 return play_status == PLAY_PLAYING && !ff_rw_mode;
3223 /** -- External interfaces -- **/
3225 /* Return the playback and recording status */
3226 int audio_status(void)
3228 unsigned int ret = play_status;
3230 #ifdef AUDIO_HAVE_RECORDING
3231 /* Do this here for constitency with mpeg.c version */
3232 ret |= pcm_rec_status();
3233 #endif
3235 return (int)ret;
3238 /* Clear all accumulated audio errors for playback and recording */
3239 void audio_error_clear(void)
3241 #ifdef AUDIO_HAVE_RECORDING
3242 pcm_rec_error_clear();
3243 #endif
3246 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3247 bool audio_peek_track(struct mp3entry *id3, int offset)
3249 bool retval = false;
3251 id3_mutex_lock();
3253 if (play_status != PLAY_STOPPED)
3255 id3->path[0] = '\0'; /* Null path means it should be filled now */
3256 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3257 id3->path[0] != '\0';
3260 id3_mutex_unlock();
3262 return retval;
3265 /* Return the mp3entry for the currently playing track */
3266 struct mp3entry * audio_current_track(void)
3268 struct mp3entry *id3;
3270 id3_mutex_lock();
3272 #ifdef AUDIO_FAST_SKIP_PREVIEW
3273 if (skip_offset != 0)
3275 /* This is a peekahead */
3276 id3 = id3_get(PLAYING_PEEK_ID3);
3277 audio_peek_track(id3, 0);
3279 else
3280 #endif
3282 /* Normal case */
3283 id3 = id3_get(PLAYING_ID3);
3284 audio_get_track_metadata(0, id3);
3287 id3_mutex_unlock();
3289 return id3;
3292 /* Obtains the mp3entry for the next track from the current */
3293 struct mp3entry * audio_next_track(void)
3295 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3297 id3_mutex_lock();
3299 #ifdef AUDIO_FAST_SKIP_PREVIEW
3300 if (skip_offset != 0)
3302 /* This is a peekahead */
3303 if (!audio_peek_track(id3, 1))
3304 id3 = NULL;
3306 else
3307 #endif
3309 /* Normal case */
3310 if (!audio_get_track_metadata(1, id3))
3311 id3 = NULL;
3314 id3_mutex_unlock();
3316 return id3;
3319 /* Start playback at the specified offset */
3320 void audio_play(long offset)
3322 logf("audio_play");
3324 #ifdef PLAYBACK_VOICE
3325 /* Truncate any existing voice output so we don't have spelling
3326 * etc. over the first part of the played track */
3327 talk_force_shutup();
3328 #endif
3330 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3331 audio_queue_send(Q_AUDIO_PLAY, offset);
3334 /* Stop playback if playing */
3335 void audio_stop(void)
3337 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3338 audio_queue_send(Q_AUDIO_STOP, 0);
3341 /* Pause playback if playing */
3342 void audio_pause(void)
3344 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3345 audio_queue_send(Q_AUDIO_PAUSE, true);
3348 /* This sends a stop message and the audio thread will dump all its
3349 subsequent messages */
3350 void audio_hard_stop(void)
3352 /* Stop playback */
3353 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3354 audio_queue_send(Q_AUDIO_STOP, 1);
3355 #ifdef PLAYBACK_VOICE
3356 voice_stop();
3357 #endif
3358 buffer_release_buffer(0);
3361 /* Resume playback if paused */
3362 void audio_resume(void)
3364 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3365 audio_queue_send(Q_AUDIO_PAUSE, false);
3368 /* Skip the specified number of tracks forward or backward from the current */
3369 void audio_skip(int offset)
3371 id3_mutex_lock();
3373 /* If offset has to be backed-out to stay in range, no skip is done */
3374 int accum = skip_offset + offset;
3376 while (offset != 0 && !playlist_check(accum))
3378 offset += offset < 0 ? 1 : -1;
3379 accum = skip_offset + offset;
3382 if (offset != 0)
3384 /* Accumulate net manual skip count since the audio thread last
3385 processed one */
3386 skip_offset = accum;
3388 system_sound_play(SOUND_TRACK_SKIP);
3390 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3392 #ifdef AUDIO_FAST_SKIP_PREVIEW
3393 /* Do this before posting so that the audio thread can correct us
3394 when things settle down - additionally, if audio gets a message
3395 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3396 handler a skip event with the correct info but doesn't skip */
3397 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3398 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3400 /* Playback only needs the final state even if more than one is
3401 processed because it wasn't removed in time */
3402 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3403 audio_queue_post(Q_AUDIO_SKIP, 0);
3405 else
3407 /* No more tracks */
3408 system_sound_play(SOUND_TRACK_NO_MORE);
3411 id3_mutex_unlock();
3414 /* Skip one track forward from the current */
3415 void audio_next(void)
3417 audio_skip(1);
3420 /* Skip one track backward from the current */
3421 void audio_prev(void)
3423 audio_skip(-1);
3426 /* Move one directory forward */
3427 void audio_next_dir(void)
3429 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3430 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3433 /* Move one directory backward */
3434 void audio_prev_dir(void)
3436 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3437 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3440 /* Pause playback in order to start a seek that flushes the old audio */
3441 void audio_pre_ff_rewind(void)
3443 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3444 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3447 /* Seek to the new time in the current track */
3448 void audio_ff_rewind(long time)
3450 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3451 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3454 /* Clear all but the currently playing track then rebuffer */
3455 void audio_flush_and_reload_tracks(void)
3457 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3458 audio_queue_post(Q_AUDIO_FLUSH, 0);
3461 /* Return the pointer to the main audio buffer, optionally preserving
3462 voicing */
3463 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3465 unsigned char *buf;
3467 if (audio_is_initialized)
3469 audio_hard_stop();
3471 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3473 if (buffer_size == NULL)
3475 /* Special case for talk_init to use since it already knows it's
3476 trashed */
3477 buffer_state = AUDIOBUF_STATE_TRASHED;
3478 return NULL;
3481 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3482 || !talk_voice_required())
3484 logf("get buffer: talk, audio");
3485 /* Ok to use everything from audiobuf - voice is loaded,
3486 the talk buffer is not needed because voice isn't being used, or
3487 could be AUDIOBUF_STATE_TRASHED already. If state is
3488 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3489 written without the caller knowing what's going on. Changing certain
3490 settings may move it to a worse condition but the memory in use by
3491 something else will remain undisturbed.
3493 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3495 talk_buffer_steal();
3496 buffer_state = AUDIOBUF_STATE_TRASHED;
3498 buf = buffer_get_buffer(buffer_size);
3500 else
3502 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3503 still AUDIOBUF_STATE_INITIALIZED */
3504 /* Skip talk buffer and move pcm buffer to end to maximize available
3505 contiguous memory - no audio running means voice will not need the
3506 swap space */
3507 size_t siz, talkbuf_size;
3508 logf("get buffer: audio");
3509 /* call buffer_get_buffer() to make use of the locking mechanism */
3510 buf = buffer_get_buffer(&siz);
3511 buf += talkbuf_size = talkbuf_init(buf);
3512 siz -= talkbuf_size;
3513 siz -= voicebuf_init(buf + siz);
3514 *buffer_size = siz;
3516 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3519 return buf;
3522 #ifdef HAVE_RECORDING
3523 /* Stop audio, voice and obtain all available buffer space */
3524 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3526 talk_buffer_steal();
3527 audio_hard_stop();
3529 buffer_state = AUDIOBUF_STATE_TRASHED;
3530 return buffer_get_buffer(buffer_size);
3532 #endif /* HAVE_RECORDING */
3534 /* Restore audio buffer to a particular state (one more valid than the current
3535 state) */
3536 bool audio_restore_playback(int type)
3538 switch (type)
3540 case AUDIO_WANT_PLAYBACK:
3541 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3542 audio_reset_buffer();
3543 return true;
3544 case AUDIO_WANT_VOICE:
3545 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3546 audio_reset_buffer();
3547 return true;
3548 default:
3549 return false;
3553 /* Has the playback buffer been completely claimed? */
3554 bool audio_buffer_state_trashed(void)
3556 return buffer_state == AUDIOBUF_STATE_TRASHED;
3560 /** --- Miscellaneous public interfaces --- **/
3562 #ifdef HAVE_ALBUMART
3563 /* Return which album art handle is current for the user in the given slot */
3564 int playback_current_aa_hid(int slot)
3566 if ((unsigned)slot < MAX_MULTIPLE_AA)
3568 struct track_info *info = track_list_user_current(skip_offset);
3570 if (!info && abs(skip_offset) <= 1)
3572 /* Give the actual position a go */
3573 info = track_list_user_current(0);
3576 if (info)
3577 return info->aa_hid[slot];
3580 return ERR_HANDLE_NOT_FOUND;
3583 /* Find an album art slot that doesn't match the dimensions of another that
3584 is already claimed - increment the use count if it is */
3585 int playback_claim_aa_slot(struct dim *dim)
3587 int i;
3589 /* First try to find a slot already having the size to reuse it since we
3590 don't want albumart of the same size buffered multiple times */
3591 FOREACH_ALBUMART(i)
3593 struct albumart_slot *slot = &albumart_slots[i];
3595 if (slot->dim.width == dim->width &&
3596 slot->dim.height == dim->height)
3598 slot->used++;
3599 return i;
3603 /* Size is new, find a free slot */
3604 FOREACH_ALBUMART(i)
3606 if (!albumart_slots[i].used)
3608 albumart_slots[i].used++;
3609 albumart_slots[i].dim = *dim;
3610 return i;
3614 /* Sorry, no free slot */
3615 return -1;
3618 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3619 void playback_release_aa_slot(int slot)
3621 if ((unsigned)slot < MAX_MULTIPLE_AA)
3623 struct albumart_slot *aa_slot = &albumart_slots[slot];
3625 if (aa_slot->used > 0)
3626 aa_slot->used--;
3629 #endif /* HAVE_ALBUMART */
3632 #ifdef HAVE_RECORDING
3633 /* Load an encoder and run it */
3634 bool audio_load_encoder(int afmt)
3636 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3637 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3638 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3639 #else
3640 (void)afmt;
3641 return true;
3642 #endif
3645 /* Stop an encoder and unload it */
3646 void audio_remove_encoder(void)
3648 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3649 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3650 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3651 #endif
3653 #endif /* HAVE_RECORDING */
3655 /* Is an automatic skip in progress? If called outside transition callbacks,
3656 indicates the last skip type at the time it was processed and isn't very
3657 meaningful. */
3658 bool audio_automatic_skip(void)
3660 return automatic_skip;
3663 /* Would normally calculate byte offset from an elapsed time but is not
3664 used on SWCODEC */
3665 int audio_get_file_pos(void)
3667 return 0;
3670 /* Return the elapsed time of the track previous to the current */
3671 unsigned long audio_prev_elapsed(void)
3673 return prev_track_elapsed;
3676 /* Is the audio thread ready to accept commands? */
3677 bool audio_is_thread_ready(void)
3679 return filling != STATE_BOOT;
3682 /* Return total file buffer length after accounting for the talk buf */
3683 size_t audio_get_filebuflen(void)
3685 return buf_length();
3688 /* How many tracks exist on the buffer - full or partial */
3689 int audio_track_count(void)
3690 __attribute__((alias("track_list_count")));
3692 /* Return total ringbuffer space occupied - ridx to widx */
3693 long audio_filebufused(void)
3695 return buf_used();
3699 /** -- Settings -- **/
3701 /* Enable or disable cuesheet support and allocate/don't allocate the
3702 extra associated resources */
3703 void audio_set_cuesheet(int enable)
3705 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3707 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3708 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3712 #ifdef HAVE_DISK_STORAGE
3713 /* Set the audio antiskip buffer margin by index */
3714 void audio_set_buffer_margin(int setting)
3716 static const unsigned short lookup[] =
3717 { 5, 15, 30, 60, 120, 180, 300, 600 };
3719 if ((unsigned)setting >= ARRAYLEN(lookup))
3720 setting = 0;
3722 logf("buffer margin: %u", (unsigned)lookup[setting]);
3724 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3725 (unsigned)lookup[setting]);
3726 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3728 #endif /* HAVE_DISK_STORAGE */
3730 #ifdef HAVE_CROSSFADE
3731 /* Take necessary steps to enable or disable the crossfade setting */
3732 void audio_set_crossfade(int enable)
3734 /* Tell it the next setting to use */
3735 pcmbuf_request_crossfade_enable(enable);
3737 /* Return if size hasn't changed or this is too early to determine
3738 which in the second case there's no way we could be playing
3739 anything at all */
3740 if (!pcmbuf_is_same_size())
3742 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3743 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3746 #endif /* HAVE_CROSSFADE */
3749 /** -- Startup -- **/
3751 /* Initialize the audio system - called from init() in main.c */
3752 void audio_init(void)
3754 /* Can never do this twice */
3755 if (audio_is_initialized)
3757 logf("audio: already initialized");
3758 return;
3761 logf("audio: initializing");
3763 /* Initialize queues before giving control elsewhere in case it likes
3764 to send messages. Thread creation will be delayed however so nothing
3765 starts running until ready if something yields such as talk_init. */
3766 queue_init(&audio_queue, true);
3768 mutex_init(&id3_mutex);
3770 pcm_init();
3772 codec_init_codec_api();
3774 make_codec_thread();
3776 /* This thread does buffer, so match its priority */
3777 audio_thread_id = create_thread(audio_thread, audio_stack,
3778 sizeof(audio_stack), CREATE_THREAD_FROZEN,
3779 audio_thread_name
3780 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3781 IF_COP(, CPU));
3783 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3784 audio_thread_id);
3786 #ifdef PLAYBACK_VOICE
3787 voice_thread_init();
3788 #endif
3790 /* audio_reset_buffer must know the size of voice buffer so init
3791 talk first */
3792 talk_init();
3794 #ifdef HAVE_CROSSFADE
3795 /* Set crossfade setting for next buffer init which should be about... */
3796 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3797 #endif
3799 /* Initialize the buffering system */
3800 track_list_init();
3801 buffering_init();
3802 /* ...now! Set up the buffers */
3803 audio_reset_buffer();
3805 /* Probably safe to say */
3806 audio_is_initialized = true;
3808 sound_settings_apply();
3809 #ifdef HAVE_DISK_STORAGE
3810 audio_set_buffer_margin(global_settings.buffer_margin);
3811 #endif
3813 /* It's safe to let the threads run now */
3814 #ifdef PLAYBACK_VOICE
3815 voice_thread_resume();
3816 #endif
3817 codec_thread_resume();
3818 thread_thaw(audio_thread_id);