hm801: Tweak keymap.
[maemo-rb.git] / apps / playback.c
blob997a374410be041b6d5102effbc1fc2339a5f58f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005-2007 Miika Pekkarinen
11 * Copyright (C) 2007-2008 Nicolas Pennequin
12 * Copyright (C) 2011 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "config.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "panic.h"
27 #include "core_alloc.h"
28 #include "sound.h"
29 #include "ata.h"
30 #include "usb.h"
31 #include "codecs.h"
32 #include "codec_thread.h"
33 #include "voice_thread.h"
34 #include "metadata.h"
35 #include "cuesheet.h"
36 #include "buffering.h"
37 #include "talk.h"
38 #include "playlist.h"
39 #include "abrepeat.h"
40 #include "pcmbuf.h"
41 #include "playback.h"
42 #include "misc.h"
43 #include "settings.h"
45 #ifdef HAVE_TAGCACHE
46 #include "tagcache.h"
47 #endif
49 #ifdef AUDIO_HAVE_RECORDING
50 #include "pcm_record.h"
51 #endif
53 #ifdef HAVE_LCD_BITMAP
54 #ifdef HAVE_ALBUMART
55 #include "albumart.h"
56 #endif
57 #endif
59 /* TODO: The audio thread really is doing multitasking of acting like a
60 consumer and producer of tracks. It may be advantageous to better
61 logically separate the two functions. I won't go that far just yet. */
63 /* Internal support for voice playback */
64 #define PLAYBACK_VOICE
66 #if CONFIG_PLATFORM & PLATFORM_NATIVE
67 /* Application builds don't support direct code loading */
68 #define HAVE_CODEC_BUFFERING
69 #endif
71 /* Amount of guess-space to allow for codecs that must hunt and peck
72 * for their correct seek target, 32k seems a good size */
73 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
75 /* Define LOGF_ENABLE to enable logf output in this file */
76 /* #define LOGF_ENABLE */
77 #include "logf.h"
79 /* Macros to enable logf for queues
80 logging on SYS_TIMEOUT can be disabled */
81 #ifdef SIMULATOR
82 /* Define this for logf output of all queuing except SYS_TIMEOUT */
83 #define PLAYBACK_LOGQUEUES
84 /* Define this to logf SYS_TIMEOUT messages */
85 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
86 #endif
88 #ifdef PLAYBACK_LOGQUEUES
89 #define LOGFQUEUE logf
90 #else
91 #define LOGFQUEUE(...)
92 #endif
94 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
95 #define LOGFQUEUE_SYS_TIMEOUT logf
96 #else
97 #define LOGFQUEUE_SYS_TIMEOUT(...)
98 #endif
100 /* Variables are commented with the threads that use them:
101 * A=audio, C=codec, O=other. A suffix of "-" indicates that the variable is
102 * read but not updated on that thread. Audio is the only user unless otherwise
103 * specified.
106 /** Miscellaneous **/
107 bool audio_is_initialized = false; /* (A,O-) */
108 extern struct codec_api ci; /* (A,C) */
110 /** Possible arrangements of the main buffer **/
111 static enum audio_buffer_state
113 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
114 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
115 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
116 } buffer_state = AUDIOBUF_STATE_TRASHED; /* (A,O) */
118 /** Main state control **/
119 static bool ff_rw_mode SHAREDBSS_ATTR = false; /* Pre-ff-rewind mode (A,O-) */
121 enum play_status
123 PLAY_STOPPED = 0,
124 PLAY_PLAYING = AUDIO_STATUS_PLAY,
125 PLAY_PAUSED = AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE,
126 } play_status = PLAY_STOPPED;
128 /* Sizeable things that only need exist during playback and not when stopped */
129 static struct audio_scratch_memory
131 struct mp3entry codec_id3; /* (A,C) */
132 struct mp3entry unbuffered_id3;
133 struct cuesheet *curr_cue; /* Will follow this structure */
134 } * audio_scratch_memory = NULL;
136 /* These are used to store the current, next and optionally the peek-ahead
137 * mp3entry's - this guarantees that the pointer returned by audio_current/
138 * next_track will be valid for the full duration of the currently playing
139 * track */
140 enum audio_id3_types
142 /* These are allocated statically */
143 PLAYING_ID3 = 0,
144 NEXTTRACK_ID3,
145 #ifdef AUDIO_FAST_SKIP_PREVIEW
146 /* The real playing metadata must has to be protected since it contains
147 critical info for other features */
148 PLAYING_PEEK_ID3,
149 #endif
150 ID3_TYPE_NUM_STATIC,
151 /* These go in the scratch memory */
152 UNBUFFERED_ID3 = ID3_TYPE_NUM_STATIC,
153 CODEC_ID3,
155 static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */
157 /* Peeking functions can yield and mess us up */
158 static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/
161 /** For Scrobbler support **/
163 /* Previous track elapsed time */
164 static unsigned long prev_track_elapsed = 0; /* (A,O-) */
167 /** For album art support **/
168 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
169 #ifdef HAVE_ALBUMART
171 static struct albumart_slot
173 struct dim dim; /* Holds width, height of the albumart */
174 int used; /* Counter; increments if something uses it */
175 } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */
177 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
178 #endif /* HAVE_ALBUMART */
181 /** Information used for tracking buffer fills **/
183 /* Buffer and thread state tracking */
184 static enum filling_state
186 STATE_IDLE = 0, /* audio is stopped: nothing to do */
187 STATE_FILLING, /* adding tracks to the buffer */
188 STATE_FULL, /* can't add any more tracks */
189 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
190 STATE_FINISHED, /* all remaining tracks are fully buffered */
191 STATE_ENDING, /* audio playback is ending */
192 STATE_ENDED, /* audio playback is done */
193 STATE_USB, /* USB mode, ignore most messages */
194 } filling = STATE_IDLE;
196 /* Track info - holds information about each track in the buffer */
197 struct track_info
199 /* In per-track allocated order: */
200 int id3_hid; /* Metadata handle ID */
201 int cuesheet_hid; /* Parsed cuesheet handle ID */
202 #ifdef HAVE_ALBUMART
203 int aa_hid[MAX_MULTIPLE_AA];/* Album art handle IDs */
204 #endif
205 #ifdef HAVE_CODEC_BUFFERING
206 int codec_hid; /* Buffered codec handle ID */
207 #endif
208 int audio_hid; /* Main audio data handle ID */
209 size_t filesize; /* File total length on disk
210 TODO: This should be stored
211 in the handle or the
212 id3 and would use less
213 ram */
216 /* Track list - holds info about all buffered tracks */
217 #if MEMORYSIZE >= 32
218 #define TRACK_LIST_LEN 128 /* Must be 2^int(+n) */
219 #elif MEMORYSIZE >= 16
220 #define TRACK_LIST_LEN 64
221 #elif MEMORYSIZE >= 8
222 #define TRACK_LIST_LEN 32
223 #else
224 #define TRACK_LIST_LEN 16
225 #endif
227 #define TRACK_LIST_MASK (TRACK_LIST_LEN-1)
229 static struct
231 /* read, write and current are maintained unwrapped, limited only by the
232 unsigned int range and wrap-safe comparisons are used */
234 /* NOTE: there appears to be a bug in arm-elf-eabi-gcc 4.4.4 for ARMv4 where
235 if 'end' follows 'start' in this structure, track_list_count performs
236 'start - end' rather than 'end - start', giving negative count values...
237 so leave it this way for now! */
238 unsigned int end; /* Next open position */
239 unsigned int start; /* First track in list */
240 unsigned int current; /* Currently decoding track */
241 struct track_info tracks[TRACK_LIST_LEN]; /* Buffered track information */
242 } track_list; /* (A, O-) */
245 /* Playlist steps from playlist position to next track to be buffered */
246 static int playlist_peek_offset = 0;
248 /* Metadata handle of track load in progress (meaning all handles have not
249 yet been opened for the track, id3 always exists or the track does not)
251 Tracks are keyed by their metadata handles if track list pointers are
252 insufficient to make comparisons */
253 static int in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
255 #ifdef HAVE_DISK_STORAGE
256 /* Buffer margin A.K.A. anti-skip buffer (in seconds) */
257 static size_t buffer_margin = 5;
258 #endif
260 /* Values returned for track loading */
261 enum track_load_status
263 LOAD_TRACK_ERR_START_CODEC = -6,
264 LOAD_TRACK_ERR_FINISH_FAILED = -5,
265 LOAD_TRACK_ERR_FINISH_FULL = -4,
266 LOAD_TRACK_ERR_BUSY = -3,
267 LOAD_TRACK_ERR_NO_MORE = -2,
268 LOAD_TRACK_ERR_FAILED = -1,
269 LOAD_TRACK_OK = 0,
270 LOAD_TRACK_READY = 1,
273 /** Track change controls **/
275 /* What sort of skip is pending globally? */
276 enum track_skip_type
278 /* Relative to what user is intended to see: */
279 /* Codec: +0, Track List: +0, Playlist: +0 */
280 TRACK_SKIP_NONE = 0, /* no track skip */
281 /* Codec: +1, Track List: +1, Playlist: +0 */
282 TRACK_SKIP_AUTO, /* codec-initiated skip */
283 /* Codec: +1, Track List: +1, Playlist: +1 */
284 TRACK_SKIP_AUTO_NEW_PLAYLIST, /* codec-initiated skip is new playlist */
285 /* Codec: xx, Track List: +0, Playlist: +0 */
286 TRACK_SKIP_AUTO_END_PLAYLIST, /* codec-initiated end of playlist */
287 /* Manual skip: Never pends */
288 TRACK_SKIP_MANUAL, /* manual track skip */
289 /* Manual skip: Never pends */
290 TRACK_SKIP_DIR_CHANGE, /* manual directory skip */
291 } skip_pending = TRACK_SKIP_NONE;
293 /* Note about TRACK_SKIP_AUTO_NEW_PLAYLIST:
294 Fixing playlist code to be able to peek into the first song of
295 the next playlist would fix any issues and this wouldn't need
296 to be a special case since pre-advancing the playlist would be
297 unneeded - it could be much more like TRACK_SKIP_AUTO and all
298 actions that require reversal during an in-progress transition
299 would work as expected */
301 /* Used to indicate status for the events. Must be separate to satisfy all
302 clients so the correct metadata is read when sending the change events
303 and also so that it is read correctly outside the events. */
304 static bool automatic_skip = false; /* (A, O-) */
306 /* Pending manual track skip offset */
307 static int skip_offset = 0; /* (A, O) */
309 /* Track change notification */
310 static struct
312 unsigned int in; /* Number of pcmbuf posts (audio isr) */
313 unsigned int out; /* Number of times audio has read the difference */
314 } track_change = { 0, 0 };
316 /** Codec status **/
317 /* Did the codec notify us it finished while we were paused or while still
318 in an automatic transition?
320 If paused, it is necessary to defer a codec-initiated skip until resuming
321 or else the track will move forward while not playing audio!
323 If in-progress, skips should not build-up ahead of where the WPS is when
324 really short tracks finish decoding.
326 If it is forgotten, it will be missed altogether and playback will just sit
327 there looking stupid and comatose until the user does something */
328 static bool codec_skip_pending = false;
329 static int codec_skip_status;
330 static bool codec_seeking = false; /* Codec seeking ack expected? */
331 static unsigned int position_key = 0;
333 /* Event queues */
334 static struct event_queue audio_queue SHAREDBSS_ATTR;
336 /* Audio thread */
337 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
338 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
339 static const char audio_thread_name[] = "audio";
340 static unsigned int audio_thread_id = 0;
342 /* Forward declarations */
343 enum audio_start_playback_flags
345 AUDIO_START_RESTART = 0x1, /* "Restart" playback (flush _all_ tracks) */
346 AUDIO_START_NEWBUF = 0x2, /* Mark the audiobuffer as invalid */
349 static void audio_start_playback(size_t offset, unsigned int flags);
350 static void audio_stop_playback(void);
351 static void buffer_event_buffer_low_callback(void *data);
352 static void buffer_event_rebuffer_callback(void *data);
353 static void buffer_event_finished_callback(void *data);
354 void audio_pcmbuf_sync_position(void);
357 /**************************************/
359 /** --- audio_queue helpers --- **/
360 static void audio_queue_post(long id, intptr_t data)
362 queue_post(&audio_queue, id, data);
365 static intptr_t audio_queue_send(long id, intptr_t data)
367 return queue_send(&audio_queue, id, data);
371 /** --- MP3Entry --- **/
373 /* Does the mp3entry have enough info for us to use it? */
374 static struct mp3entry * valid_mp3entry(const struct mp3entry *id3)
376 return id3 && (id3->length != 0 || id3->filesize != 0) &&
377 id3->codectype != AFMT_UNKNOWN ? (struct mp3entry *)id3 : NULL;
380 /* Return a pointer to an mp3entry on the buffer, as it is */
381 static struct mp3entry * bufgetid3(int handle_id)
383 if (handle_id < 0)
384 return NULL;
386 struct mp3entry *id3;
387 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
389 if (ret != sizeof(struct mp3entry))
390 return NULL;
392 return id3;
395 /* Read an mp3entry from the buffer, adjusted */
396 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
398 struct mp3entry *id3 = bufgetid3(handle_id);
400 if (id3)
402 copy_mp3entry(id3out, id3);
403 return true;
406 return false;
409 /* Lock the id3 mutex */
410 static void id3_mutex_lock(void)
412 mutex_lock(&id3_mutex);
415 /* Unlock the id3 mutex */
416 static void id3_mutex_unlock(void)
418 mutex_unlock(&id3_mutex);
421 /* Return one of the collection of mp3entry pointers - collect them all here */
422 static inline struct mp3entry * id3_get(enum audio_id3_types id3_num)
424 switch (id3_num)
426 case UNBUFFERED_ID3:
427 return &audio_scratch_memory->unbuffered_id3;
428 case CODEC_ID3:
429 return &audio_scratch_memory->codec_id3;
430 default:
431 return &static_id3_entries[id3_num];
435 /* Copy an mp3entry into one of the mp3 entries */
436 static void id3_write(enum audio_id3_types id3_num,
437 const struct mp3entry *id3_src)
439 struct mp3entry *dest_id3 = id3_get(id3_num);
441 if (id3_src)
442 copy_mp3entry(dest_id3, id3_src);
443 else
444 wipe_mp3entry(dest_id3);
447 /* Call id3_write "safely" because peek aheads can yield, even if the fast
448 preview isn't enabled */
449 static void id3_write_locked(enum audio_id3_types id3_num,
450 const struct mp3entry *id3_src)
452 id3_mutex_lock();
453 id3_write(id3_num, id3_src);
454 id3_mutex_unlock();
458 /** --- Track info --- **/
460 /* Close a handle and mark it invalid */
461 static void track_info_close_handle(int *hid_p)
463 int hid = *hid_p;
465 /* bufclose returns true if the handle is not found, or if it is closed
466 * successfully, so these checks are safe on non-existant handles */
467 if (hid >= 0)
468 bufclose(hid);
470 /* Always reset to "no handle" in case it was something else */
471 *hid_p = ERR_HANDLE_NOT_FOUND;
474 /* Close all handles in a struct track_info and clear it */
475 static void track_info_close(struct track_info *info)
477 /* Close them in the order they are allocated on the buffer to speed up
478 the handle searching */
479 track_info_close_handle(&info->id3_hid);
480 track_info_close_handle(&info->cuesheet_hid);
481 #ifdef HAVE_ALBUMART
482 int i;
483 FOREACH_ALBUMART(i)
484 track_info_close_handle(&info->aa_hid[i]);
485 #endif
486 #ifdef HAVE_CODEC_BUFFERING
487 track_info_close_handle(&info->codec_hid);
488 #endif
489 track_info_close_handle(&info->audio_hid);
490 info->filesize = 0;
493 /* Invalidate all members to initial values - does not close handles */
494 static void track_info_wipe(struct track_info * info)
496 info->id3_hid = ERR_HANDLE_NOT_FOUND;
497 info->cuesheet_hid = ERR_HANDLE_NOT_FOUND;
498 #ifdef HAVE_ALBUMART
499 int i;
500 FOREACH_ALBUMART(i)
501 info->aa_hid[i] = ERR_HANDLE_NOT_FOUND;
502 #endif
503 #ifdef HAVE_CODEC_BUFFERING
504 info->codec_hid = ERR_HANDLE_NOT_FOUND;
505 #endif
506 info->audio_hid = ERR_HANDLE_NOT_FOUND;
507 info->filesize = 0;
511 /** --- Track list --- **/
513 /* Initialize the track list */
514 static void track_list_init(void)
516 int i;
517 for (i = 0; i < TRACK_LIST_LEN; i++)
518 track_info_wipe(&track_list.tracks[i]);
520 track_list.start = track_list.end = track_list.current;
523 /* Return number of items allocated in the list */
524 static unsigned int track_list_count(void)
526 return track_list.end - track_list.start;
529 /* Return true if the list is empty */
530 static inline bool track_list_empty(void)
532 return track_list.end == track_list.start;
535 /* Returns true if the list is holding the maximum number of items */
536 static bool track_list_full(void)
538 return track_list.end - track_list.start >= TRACK_LIST_LEN;
541 /* Test if the index is within the allocated range */
542 static bool track_list_in_range(int pos)
544 return (int)(pos - track_list.start) >= 0 &&
545 (int)(pos - track_list.end) < 0;
548 static struct track_info * track_list_entry(int pos)
550 return &track_list.tracks[pos & TRACK_LIST_MASK];
553 /* Return the info of the last allocation plus an offset, NULL if result is
554 out of bounds */
555 static struct track_info * track_list_last(int offset)
557 /* Last is before the end since the end isn't inclusive */
558 unsigned int pos = track_list.end + offset - 1;
560 if (!track_list_in_range(pos))
561 return NULL;
563 return track_list_entry(pos);
566 /* Allocate space at the end for another track if not full */
567 static struct track_info * track_list_alloc_track(void)
569 if (track_list_full())
570 return NULL;
572 return track_list_entry(track_list.end++);
575 /* Remove the last track entry allocated in order to support backing out
576 of a track load */
577 static void track_list_unalloc_track(void)
579 if (track_list_empty())
580 return;
582 track_list.end--;
584 if (track_list.current == track_list.end &&
585 track_list.current != track_list.start)
587 /* Current _must_ remain within bounds */
588 track_list.current--;
592 /* Return current track plus an offset, NULL if result is out of bounds */
593 static struct track_info * track_list_current(int offset)
595 unsigned int pos = track_list.current + offset;
597 if (!track_list_in_range(pos))
598 return NULL;
600 return track_list_entry(pos);
603 /* Return current based upon what's intended that the user sees - not
604 necessarily where decoding is taking place */
605 static struct track_info * track_list_user_current(int offset)
607 if (skip_pending == TRACK_SKIP_AUTO ||
608 skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
610 offset--;
613 return track_list_current(offset);
616 /* Advance current track by an offset, return false if result is out of
617 bounds */
618 static struct track_info * track_list_advance_current(int offset)
620 unsigned int pos = track_list.current + offset;
622 if (!track_list_in_range(pos))
623 return NULL;
625 track_list.current = pos;
626 return track_list_entry(pos);
629 /* Clear tracks in the list, optionally preserving the current track -
630 returns 'false' if the operation was changed */
631 enum track_clear_action
633 TRACK_LIST_CLEAR_ALL = 0, /* Clear all tracks */
634 TRACK_LIST_KEEP_CURRENT, /* Keep current only; clear before + after */
635 TRACK_LIST_KEEP_NEW /* Keep current and those that follow */
638 static void track_list_clear(enum track_clear_action action)
640 logf("%s(%d)", __func__, (int)action);
642 /* Don't care now since rebuffering is imminent */
643 buf_set_watermark(0);
645 if (action != TRACK_LIST_CLEAR_ALL)
647 struct track_info *cur = track_list_current(0);
649 if (!cur || cur->id3_hid < 0)
650 action = TRACK_LIST_CLEAR_ALL; /* Nothing worthwhile keeping */
653 /* Noone should see this progressing */
654 int start = track_list.start;
655 int current = track_list.current;
656 int end = track_list.end;
658 track_list.start = current;
660 switch (action)
662 case TRACK_LIST_CLEAR_ALL:
663 /* Result: .start = .current, .end = .current */
664 track_list.end = current;
665 break;
667 case TRACK_LIST_KEEP_CURRENT:
668 /* Result: .start = .current, .end = .current + 1 */
669 track_list.end = current + 1;
670 break;
672 case TRACK_LIST_KEEP_NEW:
673 /* Result: .start = .current, .end = .end */
674 end = current;
675 break;
678 /* Close all open handles in the range except the for the current track
679 if preserving that */
680 while (start != end)
682 if (action != TRACK_LIST_KEEP_CURRENT || start != current)
684 struct track_info *info =
685 &track_list.tracks[start & TRACK_LIST_MASK];
687 /* If this is the in-progress load, abort it */
688 if (in_progress_id3_hid >= 0 &&
689 info->id3_hid == in_progress_id3_hid)
691 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
694 track_info_close(info);
697 start++;
702 /** --- Audio buffer -- **/
704 /* What size is needed for the scratch buffer? */
705 static size_t scratch_mem_size(void)
707 size_t size = sizeof (struct audio_scratch_memory);
709 if (global_settings.cuesheet)
710 size += sizeof (struct cuesheet);
712 return size;
715 /* Initialize the memory area where data is stored that is only used when
716 playing audio and anything depending upon it */
717 static void scratch_mem_init(void *mem)
719 audio_scratch_memory = (struct audio_scratch_memory *)mem;
720 id3_write_locked(UNBUFFERED_ID3, NULL);
721 id3_write(CODEC_ID3, NULL);
722 ci.id3 = id3_get(CODEC_ID3);
723 audio_scratch_memory->curr_cue = NULL;
725 if (global_settings.cuesheet)
727 audio_scratch_memory->curr_cue =
728 SKIPBYTES((struct cuesheet *)audio_scratch_memory,
729 sizeof (struct audio_scratch_memory));
733 static int audiobuf_handle;
734 #define AUDIO_BUFFER_RESERVE (256*1024)
735 static size_t filebuflen;
738 size_t audio_buffer_size(void)
740 if (audiobuf_handle > 0)
741 return filebuflen - AUDIO_BUFFER_RESERVE;
742 return 0;
745 size_t audio_buffer_available(void)
747 size_t size = 0;
748 size_t core_size = core_available();
749 if (audiobuf_handle > 0) /* if allocated return what we can give */
750 size = filebuflen - AUDIO_BUFFER_RESERVE - 128;
751 return MAX(core_size, size);
754 /* Set up the audio buffer for playback
755 * filebuflen must be pre-initialized with the maximum size */
756 static void audio_reset_buffer_noalloc(void* filebuf)
759 * Layout audio buffer as follows:
760 * [[|TALK]|SCRATCH|BUFFERING|PCM|[VOICE|]]
763 /* see audio_get_recording_buffer if this is modified */
764 logf("%s()", __func__);
766 /* If the setup of anything allocated before the file buffer is
767 changed, do check the adjustments after the buffer_alloc call
768 as it will likely be affected and need sliding over */
770 /* Initially set up file buffer as all space available */
771 size_t allocsize;
773 /* Subtract whatever voice needs */
774 allocsize = talkbuf_init(filebuf);
775 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
776 if (allocsize > filebuflen)
777 goto bufpanic;
779 filebuf += allocsize;
780 filebuflen -= allocsize;
782 if (talk_voice_required())
784 /* Need a space for voice PCM output */
785 allocsize = voicebuf_init(filebuf + filebuflen);
787 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
788 if (allocsize > filebuflen)
789 goto bufpanic;
791 filebuflen -= allocsize;
794 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
795 allocsize = pcmbuf_init(filebuf + filebuflen);
797 /* Make sure filebuflen is a pointer sized multiple after adjustment */
798 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
799 if (allocsize > filebuflen)
800 goto bufpanic;
802 filebuflen -= allocsize;
804 /* Scratch memory */
805 allocsize = scratch_mem_size();
806 if (allocsize > filebuflen)
807 goto bufpanic;
809 scratch_mem_init(filebuf);
810 filebuf += allocsize;
811 filebuflen -= allocsize;
813 buffering_reset(filebuf, filebuflen);
815 /* Clear any references to the file buffer */
816 buffer_state = AUDIOBUF_STATE_INITIALIZED;
818 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
819 /* Make sure everything adds up - yes, some info is a bit redundant but
820 aids viewing and the summation of certain variables should add up to
821 the location of others. */
823 logf("fbuf: %08X", (unsigned)filebuf);
824 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
825 logf("sbuf: %08X", (unsigned)audio_scratch_memory);
826 logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize));
828 #endif
830 return;
832 bufpanic:
833 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
836 /* Buffer must not move. */
837 static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
839 struct queue_event ev;
840 static const long filter_list[][2] =
842 /* codec messages */
843 { Q_AUDIO_PLAY, Q_AUDIO_PLAY },
845 /* filebuflen is, at this point, the buffering.c buffer size,
846 * i.e. the audiobuf except voice, scratch mem, pcm, ... */
847 ssize_t extradata_size = old_size - filebuflen;
848 /* check what buflib requests */
849 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
850 ssize_t size = (ssize_t)old_size - wanted_size;
851 /* keep at least 256K for the buffering */
852 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE)
853 return BUFLIB_CB_CANNOT_SHRINK;
856 /* TODO: Do it without stopping playback, if possible */
857 long offset = audio_current_track()->offset;
858 /* resume if playing */
859 bool playing = (audio_status() == AUDIO_STATUS_PLAY);
860 /* There's one problem with stoping and resuming: If it happens in a too
861 * frequent fashion, the codecs lose the resume postion and playback
862 * begins from the beginning.
863 * To work around use queue_post() to effectively delay the resume in case
864 * we're called another time. However this has another problem: id3->offset
865 * gets zero since playback is stopped. Therefore, try to peek at the
866 * queue_post from the last call to get the correct offset. This also
867 * lets us conviniently remove the queue event so Q_AUDIO_PLAY is only
868 * processed once. */
869 bool play_queued = queue_peek_ex(&audio_queue, &ev, QPEEK_REMOVE_EVENTS, filter_list);
871 if (playing && offset > 0) /* current id3->offset is king */
872 ev.data = offset;
874 /* don't call audio_hard_stop() as it frees this handle */
875 if (thread_self() == audio_thread_id)
876 { /* inline case Q_AUDIO_STOP (audio_hard_stop() response
877 * if we're in the audio thread */
878 audio_stop_playback();
879 queue_clear(&audio_queue);
881 else
882 audio_queue_send(Q_AUDIO_STOP, 1);
883 #ifdef PLAYBACK_VOICE
884 voice_stop();
885 #endif
886 /* we should be free to change the buffer now
887 * set final buffer size before calling audio_reset_buffer_noalloc()
888 * (now it's the total size, the call will subtract voice etc) */
889 filebuflen = size;
890 switch (hints & BUFLIB_SHRINK_POS_MASK)
892 case BUFLIB_SHRINK_POS_BACK:
893 core_shrink(handle, start, size);
894 audio_reset_buffer_noalloc(start);
895 break;
896 case BUFLIB_SHRINK_POS_FRONT:
897 core_shrink(handle, start + wanted_size, size);
898 audio_reset_buffer_noalloc(start + wanted_size);
899 break;
901 if (playing || play_queued)
903 /* post, to make subsequent calls not break the resume position */
904 audio_queue_post(Q_AUDIO_PLAY, ev.data);
907 return BUFLIB_CB_OK;
910 static struct buflib_callbacks ops = {
911 .move_callback = NULL,
912 .shrink_callback = shrink_callback,
915 static void audio_reset_buffer(void)
917 if (audiobuf_handle > 0)
919 core_free(audiobuf_handle);
920 audiobuf_handle = 0;
922 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
923 unsigned char *filebuf = core_get_data(audiobuf_handle);
925 audio_reset_buffer_noalloc(filebuf);
928 /* Set the buffer margin to begin rebuffering when 'seconds' from empty */
929 static void audio_update_filebuf_watermark(int seconds)
931 size_t bytes = 0;
933 #ifdef HAVE_DISK_STORAGE
934 int spinup = ata_spinup_time();
936 if (seconds == 0)
938 /* By current setting */
939 seconds = buffer_margin;
941 else
943 /* New setting */
944 buffer_margin = seconds;
946 if (buf_get_watermark() == 0)
948 /* Write a watermark only if the audio thread already did so for
949 itself or it will fail to set the event and the watermark - if
950 it hasn't yet, it will use the new setting when it does */
951 return;
955 if (spinup)
956 seconds += (spinup / HZ) + 1;
957 else
958 seconds += 5;
960 seconds += buffer_margin;
961 #else
962 /* flash storage */
963 seconds = 1;
964 #endif
966 /* Watermark is a function of the bitrate of the last track in the buffer */
967 struct mp3entry *id3 = NULL;
968 struct track_info *info = track_list_last(0);
970 if (info)
971 id3 = valid_mp3entry(bufgetid3(info->id3_hid));
973 if (id3)
975 if (!rbcodec_format_is_atomic(id3->codectype))
977 bytes = id3->bitrate * (1000/8) * seconds;
979 else
981 /* Bitrate has no meaning to buffering margin for atomic audio -
982 rebuffer when it's the only track left unless it's the only
983 track that fits, in which case we should avoid constant buffer
984 low events */
985 if (track_list_count() > 1)
986 bytes = info->filesize + 1;
989 else
991 /* Then set the minimum - this should not occur anyway */
992 logf("fwmark: No id3 for last track (s%u/c%u/e%u)",
993 track_list.start, track_list.current, track_list.end);
996 /* Actually setting zero disables the notification and we use that
997 to detect that it has been reset */
998 buf_set_watermark(MAX(bytes, 1));
999 logf("fwmark: %lu", (unsigned long)bytes);
1003 /** -- Track change notification -- **/
1005 /* Check the pcmbuf track changes and return write the message into the event
1006 if there are any */
1007 static inline bool audio_pcmbuf_track_change_scan(void)
1009 if (track_change.out != track_change.in)
1011 track_change.out++;
1012 return true;
1015 return false;
1018 /* Clear outstanding track change posts */
1019 static inline void audio_pcmbuf_track_change_clear(void)
1021 track_change.out = track_change.in;
1024 /* Post a track change notification - called by audio ISR */
1025 static inline void audio_pcmbuf_track_change_post(void)
1027 track_change.in++;
1031 /** --- Helper functions --- **/
1033 /* Removes messages that might end up in the queue before or while processing
1034 a manual track change. Responding to them would be harmful since they
1035 belong to a previous track's playback period. Anything that would generate
1036 the stale messages must first be put into a state where it will not do so.
1038 static void audio_clear_track_notifications(void)
1040 static const long filter_list[][2] =
1042 /* codec messages */
1043 { Q_AUDIO_CODEC_SEEK_COMPLETE, Q_AUDIO_CODEC_COMPLETE },
1044 /* track change messages */
1045 { Q_AUDIO_TRACK_CHANGED, Q_AUDIO_TRACK_CHANGED },
1048 const int filter_count = ARRAYLEN(filter_list) - 1;
1050 /* Remove any pcmbuf notifications */
1051 pcmbuf_monitor_track_change(false);
1052 audio_pcmbuf_track_change_clear();
1054 /* Scrub the audio queue of the old mold */
1055 while (queue_peek_ex(&audio_queue, NULL,
1056 filter_count | QPEEK_REMOVE_EVENTS,
1057 filter_list))
1059 yield(); /* Not strictly needed, per se, ad infinitum, ra, ra */
1063 /* Takes actions based upon track load status codes */
1064 static void audio_handle_track_load_status(int trackstat)
1066 switch (trackstat)
1068 case LOAD_TRACK_ERR_NO_MORE:
1069 if (track_list_count() > 0)
1070 break;
1072 case LOAD_TRACK_ERR_START_CODEC:
1073 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_ERROR);
1074 break;
1076 default:
1077 break;
1081 /* Announce the end of playing the current track */
1082 static void audio_playlist_track_finish(void)
1084 struct mp3entry *ply_id3 = id3_get(PLAYING_ID3);
1085 struct mp3entry *id3 = valid_mp3entry(ply_id3);
1087 playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3);
1089 if (id3)
1091 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
1092 prev_track_elapsed = id3->elapsed;
1094 else
1096 prev_track_elapsed = 0;
1100 /* Announce the beginning of the new track */
1101 static void audio_playlist_track_change(void)
1103 struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3));
1105 if (id3)
1106 send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3);
1108 position_key = pcmbuf_get_position_key();
1110 playlist_update_resume_info(id3);
1113 /* Change the data for the next track and send the event */
1114 static void audio_update_and_announce_next_track(const struct mp3entry *id3_next)
1116 id3_write_locked(NEXTTRACK_ID3, id3_next);
1117 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
1118 id3_get(NEXTTRACK_ID3));
1121 /* Bring the user current mp3entry up to date and set a new offset for the
1122 buffered metadata */
1123 static void playing_id3_sync(struct track_info *user_info, off_t offset)
1125 id3_mutex_lock();
1127 struct mp3entry *id3 = bufgetid3(user_info->id3_hid);
1128 struct mp3entry *playing_id3 = id3_get(PLAYING_ID3);
1130 pcm_play_lock();
1132 unsigned long e = playing_id3->elapsed;
1133 unsigned long o = playing_id3->offset;
1135 id3_write(PLAYING_ID3, id3);
1137 if (offset < 0)
1139 playing_id3->elapsed = e;
1140 playing_id3->offset = o;
1141 offset = 0;
1144 pcm_play_unlock();
1146 if (id3)
1147 id3->offset = offset;
1149 id3_mutex_unlock();
1152 /* Wipe-out track metadata - current is optional */
1153 static void wipe_track_metadata(bool current)
1155 id3_mutex_lock();
1157 if (current)
1158 id3_write(PLAYING_ID3, NULL);
1160 id3_write(NEXTTRACK_ID3, NULL);
1161 id3_write(UNBUFFERED_ID3, NULL);
1163 id3_mutex_unlock();
1166 /* Called when buffering is completed on the last track handle */
1167 static void filling_is_finished(void)
1169 logf("last track finished buffering");
1171 /* There's no more to load or watch for */
1172 buf_set_watermark(0);
1173 filling = STATE_FINISHED;
1176 /* Stop the codec decoding or waiting for its data to be ready - returns
1177 'false' if the codec ended up stopped */
1178 static bool halt_decoding_track(bool stop)
1180 /* If it was waiting for us to clear the buffer to make a rebuffer
1181 happen, it should cease otherwise codec_stop could deadlock waiting
1182 for the codec to go to its main loop - codec's request will now
1183 force-fail */
1184 bool retval = false;
1186 buf_signal_handle(ci.audio_hid, true);
1188 if (stop)
1189 codec_stop();
1190 else
1191 retval = codec_pause();
1193 audio_clear_track_notifications();
1195 /* We now know it's idle and not waiting for buffered data */
1196 buf_signal_handle(ci.audio_hid, false);
1198 codec_skip_pending = false;
1199 codec_seeking = false;
1201 return retval;
1204 /* Wait for any in-progress fade to complete */
1205 static void audio_wait_fade_complete(void)
1207 /* Just loop until it's done */
1208 while (pcmbuf_fading())
1209 sleep(0);
1212 /* End the ff/rw mode */
1213 static void audio_ff_rewind_end(void)
1215 /* A seamless seek (not calling audio_pre_ff_rewind) skips this
1216 section */
1217 if (ff_rw_mode)
1219 ff_rw_mode = false;
1221 if (codec_seeking)
1223 /* Clear the buffer */
1224 pcmbuf_play_stop();
1225 audio_pcmbuf_sync_position();
1228 if (play_status != PLAY_PAUSED)
1230 /* Seeking-while-playing, resume PCM playback */
1231 pcmbuf_pause(false);
1236 /* Complete the codec seek */
1237 static void audio_complete_codec_seek(void)
1239 /* If a seek completed while paused, 'paused' is true.
1240 * If seeking from seek mode, 'ff_rw_mode' is true. */
1241 if (codec_seeking)
1243 audio_ff_rewind_end();
1244 codec_seeking = false; /* set _after_ the call! */
1246 /* else it's waiting and we must repond */
1249 /* Get the current cuesheet pointer */
1250 static inline struct cuesheet * get_current_cuesheet(void)
1252 return audio_scratch_memory->curr_cue;
1255 /* Read the cuesheet from the buffer */
1256 static void buf_read_cuesheet(int handle_id)
1258 struct cuesheet *cue = get_current_cuesheet();
1260 if (!cue || handle_id < 0)
1261 return;
1263 bufread(handle_id, sizeof (struct cuesheet), cue);
1266 /* Backend to peek/current/next track metadata interface functions -
1267 fill in the mp3entry with as much information as we may obtain about
1268 the track at the specified offset from the user current track -
1269 returns false if no information exists with us */
1270 static bool audio_get_track_metadata(int offset, struct mp3entry *id3)
1272 if (play_status == PLAY_STOPPED)
1273 return false;
1275 if (id3->path[0] != '\0')
1276 return true; /* Already filled */
1278 struct track_info *info = track_list_user_current(offset);
1280 if (!info)
1282 struct mp3entry *ub_id3 = id3_get(UNBUFFERED_ID3);
1284 if (offset > 0 && track_list_user_current(offset - 1))
1286 /* Try the unbuffered id3 since we're moving forward */
1287 if (ub_id3->path[0] != '\0')
1289 copy_mp3entry(id3, ub_id3);
1290 return true;
1294 else if (bufreadid3(info->id3_hid, id3))
1296 id3->cuesheet = NULL;
1297 return true;
1300 /* We didn't find the ID3 metadata, so we fill it with the little info we
1301 have and return that */
1303 char path[MAX_PATH+1];
1304 if (playlist_peek(offset, path, sizeof (path)))
1306 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1307 /* Try to get it from the database */
1308 if (!tagcache_fill_tags(id3, path))
1309 #endif
1311 /* By now, filename is the only source of info */
1312 fill_metadata_from_path(id3, path);
1315 return true;
1318 wipe_mp3entry(id3);
1320 return false;
1323 /* Get a resume rewind adjusted offset from the ID3 */
1324 static unsigned long resume_rewind_adjusted_offset(const struct mp3entry *id3)
1326 unsigned long offset = id3->offset;
1327 size_t resume_rewind = global_settings.resume_rewind *
1328 id3->bitrate * (1000/8);
1330 if (offset < resume_rewind)
1331 offset = 0;
1332 else
1333 offset -= resume_rewind;
1335 return offset;
1338 /* Get the codec into ram and initialize it - keep it if it's ready */
1339 static bool audio_init_codec(struct track_info *track_info,
1340 struct mp3entry *track_id3)
1342 int codt_loaded = get_audio_base_codec_type(codec_loaded());
1343 int hid = ERR_HANDLE_NOT_FOUND;
1345 if (codt_loaded != AFMT_UNKNOWN)
1347 int codt = get_audio_base_codec_type(track_id3->codectype);
1349 if (codt == codt_loaded)
1351 /* Codec is the same base type */
1352 logf("Reusing prev. codec: %d", track_id3->codectype);
1353 #ifdef HAVE_CODEC_BUFFERING
1354 /* Close any buffered codec (we could have skipped directly to a
1355 format transistion that is the same format as the current track
1356 and the buffered one is no longer needed) */
1357 track_info_close_handle(&track_info->codec_hid);
1358 #endif
1359 return true;
1361 else
1363 /* New codec - first make sure the old one's gone */
1364 logf("Removing prev. codec: %d", codt_loaded);
1365 codec_unload();
1369 logf("New codec: %d/%d", track_id3->codectype, codec_loaded());
1371 #ifdef HAVE_CODEC_BUFFERING
1372 /* Codec thread will close the handle even if it fails and will load from
1373 storage if hid is not valid or the buffer load fails */
1374 hid = track_info->codec_hid;
1375 track_info->codec_hid = ERR_HANDLE_NOT_FOUND;
1376 #endif
1378 return codec_load(hid, track_id3->codectype);
1379 (void)track_info; /* When codec buffering isn't supported */
1382 #ifdef HAVE_TAGCACHE
1383 /* Check settings for whether the file should be autoresumed */
1384 enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE };
1385 static bool autoresumable(struct mp3entry *id3)
1387 char *endp, *path;
1388 size_t len;
1389 bool is_resumable;
1391 if (id3->autoresumable) /* result cached? */
1392 return id3->autoresumable == AUTORESUMABLE_TRUE;
1394 is_resumable = false;
1396 if (id3->path)
1398 for (path = global_settings.autoresume_paths;
1399 *path; /* search terms left? */
1400 path++)
1402 if (*path == ':') /* Skip empty search patterns */
1403 continue;
1405 /* FIXME: As soon as strcspn or strchrnul are made available in
1406 the core, the following can be made more efficient. */
1407 endp = strchr(path, ':');
1408 if (endp)
1409 len = endp - path;
1410 else
1411 len = strlen(path);
1413 /* Note: At this point, len is always > 0 */
1415 if (strncasecmp(id3->path, path, len) == 0)
1417 /* Full directory-name matches only. Trailing '/' in
1418 search path OK. */
1419 if (id3->path[len] == '/' || id3->path[len - 1] == '/')
1421 is_resumable = true;
1422 break;
1425 path += len - 1;
1429 /* cache result */
1430 id3->autoresumable =
1431 is_resumable ? AUTORESUMABLE_TRUE : AUTORESUMABLE_FALSE;
1433 logf("autoresumable: %s is%s resumable",
1434 id3->path, is_resumable ? "" : " not");
1436 return is_resumable;
1438 #endif /* HAVE_TAGCACHE */
1440 /* Start the codec for the current track scheduled to be decoded */
1441 static bool audio_start_codec(bool auto_skip)
1443 struct track_info *info = track_list_current(0);
1444 struct mp3entry *cur_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1446 if (!cur_id3)
1447 return false;
1449 buf_pin_handle(info->id3_hid, true);
1451 if (!audio_init_codec(info, cur_id3))
1453 buf_pin_handle(info->id3_hid, false);
1454 return false;
1457 #ifdef HAVE_TAGCACHE
1458 bool autoresume_enable = global_settings.autoresume_enable;
1460 if (autoresume_enable && !cur_id3->offset)
1462 /* Resume all manually selected tracks */
1463 bool resume = !auto_skip;
1465 /* Send the "buffer" event to obtain the resume position for the codec */
1466 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1468 if (!resume)
1470 /* Automatic skip - do further tests to see if we should just
1471 ignore any autoresume position */
1472 int autoresume_automatic = global_settings.autoresume_automatic;
1474 switch (autoresume_automatic)
1476 case AUTORESUME_NEXTTRACK_ALWAYS:
1477 /* Just resume unconditionally */
1478 resume = true;
1479 break;
1480 case AUTORESUME_NEXTTRACK_NEVER:
1481 /* Force-rewind it */
1482 break;
1483 default:
1484 /* Not "never resume" - pass resume filter? */
1485 resume = autoresumable(cur_id3);
1489 if (!resume)
1490 cur_id3->offset = 0;
1492 logf("%s: Set offset for %s to %lX\n", __func__,
1493 cur_id3->title, cur_id3->offset);
1495 #endif /* HAVE_TAGCACHE */
1497 /* Rewind the required amount - if an autoresume was done, this also rewinds
1498 that by the setting's amount
1500 It would be best to have bookkeeping about whether or not the track
1501 sounded or not since skipping to it or else skipping to it while paused
1502 and back again will cause accumulation of silent rewinds - that's not
1503 our job to track directly nor could it be in any reasonable way
1505 cur_id3->offset = resume_rewind_adjusted_offset(cur_id3);
1507 /* Update the codec API with the metadata and track info */
1508 id3_write(CODEC_ID3, cur_id3);
1510 ci.audio_hid = info->audio_hid;
1511 ci.filesize = info->filesize;
1512 buf_set_base_handle(info->audio_hid);
1514 /* All required data is now available for the codec */
1515 codec_go();
1517 #ifdef HAVE_TAGCACHE
1518 if (!autoresume_enable || cur_id3->offset)
1519 #endif
1521 /* Send the "buffer" event now */
1522 send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3);
1525 buf_pin_handle(info->id3_hid, false);
1526 return true;
1528 (void)auto_skip; /* ifndef HAVE_TAGCACHE */
1532 /** --- Audio thread --- **/
1534 /* Load and parse a cuesheet for the file - returns false if the buffer
1535 is full */
1536 static bool audio_load_cuesheet(struct track_info *info,
1537 struct mp3entry *track_id3)
1539 struct cuesheet *cue = get_current_cuesheet();
1540 track_id3->cuesheet = NULL;
1542 if (cue && info->cuesheet_hid == ERR_HANDLE_NOT_FOUND)
1544 /* If error other than a full buffer, then mark it "unsupported" to
1545 avoid reloading attempt */
1546 int hid = ERR_UNSUPPORTED_TYPE;
1547 struct cuesheet_file cue_file;
1549 #ifdef HAVE_IO_PRIORITY
1550 buf_back_off_storage(true);
1551 #endif
1552 if (look_for_cuesheet_file(track_id3, &cue_file))
1554 hid = bufalloc(NULL, sizeof (struct cuesheet), TYPE_CUESHEET);
1556 if (hid >= 0)
1558 void *cuesheet = NULL;
1559 bufgetdata(hid, sizeof (struct cuesheet), &cuesheet);
1561 if (parse_cuesheet(&cue_file, (struct cuesheet *)cuesheet))
1563 /* Indicate cuesheet is present (while track remains
1564 buffered) */
1565 track_id3->cuesheet = cue;
1567 else
1569 bufclose(hid);
1570 hid = ERR_UNSUPPORTED_TYPE;
1575 #ifdef HAVE_IO_PRIORITY
1576 buf_back_off_storage(false);
1577 #endif
1578 if (hid == ERR_BUFFER_FULL)
1580 logf("buffer is full for now (%s)", __func__);
1581 return false;
1583 else
1585 if (hid < 0)
1586 logf("Cuesheet loading failed");
1588 info->cuesheet_hid = hid;
1592 return true;
1595 #ifdef HAVE_ALBUMART
1596 /* Load any album art for the file - returns false if the buffer is full */
1597 static bool audio_load_albumart(struct track_info *info,
1598 struct mp3entry *track_id3)
1600 int i;
1601 FOREACH_ALBUMART(i)
1603 struct bufopen_bitmap_data user_data;
1604 int *aa_hid = &info->aa_hid[i];
1605 int hid = ERR_UNSUPPORTED_TYPE;
1607 /* albumart_slots may change during a yield of bufopen,
1608 * but that's no problem */
1609 if (*aa_hid >= 0 || *aa_hid == ERR_UNSUPPORTED_TYPE ||
1610 !albumart_slots[i].used)
1611 continue;
1613 memset(&user_data, 0, sizeof(user_data));
1614 user_data.dim = &albumart_slots[i].dim;
1616 #ifdef HAVE_IO_PRIORITY
1617 buf_back_off_storage(true);
1618 #endif
1620 /* We can only decode jpeg for embedded AA */
1621 if (track_id3->has_embedded_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1623 user_data.embedded_albumart = &track_id3->albumart;
1624 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1627 if (hid < 0 && hid != ERR_BUFFER_FULL)
1629 /* No embedded AA or it couldn't be loaded - try other sources */
1630 char path[MAX_PATH];
1632 if (find_albumart(track_id3, path, sizeof(path),
1633 &albumart_slots[i].dim))
1635 user_data.embedded_albumart = NULL;
1636 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1640 #ifdef HAVE_IO_PRIORITY
1641 buf_back_off_storage(false);
1642 #endif
1643 if (hid == ERR_BUFFER_FULL)
1645 logf("buffer is full for now (%s)", __func__);
1646 return false;
1648 else
1650 /* If error other than a full buffer, then mark it "unsupported"
1651 to avoid reloading attempt */
1652 if (hid < 0)
1654 logf("Album art loading failed");
1655 hid = ERR_UNSUPPORTED_TYPE;
1658 *aa_hid = hid;
1662 return true;
1664 #endif /* HAVE_ALBUMART */
1666 #ifdef HAVE_CODEC_BUFFERING
1667 /* Load a codec for the file onto the buffer - assumes we're working from the
1668 currently loading track - not called for the current track */
1669 static bool audio_buffer_codec(struct track_info *track_info,
1670 struct mp3entry *track_id3)
1672 /* This will not be the current track -> it cannot be the first and the
1673 current track cannot be ahead of buffering -> there is a previous
1674 track entry which is either current or ahead of the current */
1675 struct track_info *prev_info = track_list_last(-1);
1676 struct mp3entry *prev_id3 = bufgetid3(prev_info->id3_hid);
1678 /* If the previous codec is the same as this one, there is no need to
1679 put another copy of it on the file buffer (in other words, only
1680 buffer codecs at format transitions) */
1681 if (prev_id3)
1683 int codt = get_audio_base_codec_type(track_id3->codectype);
1684 int prev_codt = get_audio_base_codec_type(prev_id3->codectype);
1686 if (codt == prev_codt)
1688 logf("Reusing prev. codec: %d", prev_id3->codectype);
1689 return true;
1692 /* else just load it (harmless) */
1694 /* Load the codec onto the buffer if possible */
1695 const char *codec_fn = get_codec_filename(track_id3->codectype);
1696 if (!codec_fn)
1697 return false;
1699 char codec_path[MAX_PATH+1]; /* Full path to codec */
1700 codec_get_full_path(codec_path, codec_fn);
1702 track_info->codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1704 if (track_info->codec_hid >= 0)
1706 logf("Buffered codec: %d", afmt);
1707 return true;
1710 return false;
1712 #endif /* HAVE_CODEC_BUFFERING */
1714 /* Load metadata for the next track (with bufopen). The rest of the track
1715 loading will be handled by audio_finish_load_track once the metadata has
1716 been actually loaded by the buffering thread.
1718 Each track is arranged in the buffer as follows:
1719 <id3|[cuesheet|][album art|][codec|]audio>
1721 The next will not be loaded until the previous succeeds if the buffer was
1722 full at the time. To put any metadata after audio would make those handles
1723 unmovable.
1725 static int audio_load_track(void)
1727 if (in_progress_id3_hid >= 0)
1729 /* There must be an info pointer if the in-progress id3 is even there */
1730 struct track_info *info = track_list_last(0);
1732 if (info->id3_hid == in_progress_id3_hid)
1734 if (filling == STATE_FILLING)
1736 /* Haven't finished the metadata but the notification is
1737 anticipated to come soon */
1738 logf("%s(): in progress ok: %d". __func__, info->id3_hid);
1739 return LOAD_TRACK_OK;
1741 else if (filling == STATE_FULL)
1743 /* Buffer was full trying to complete the load after the
1744 metadata finished, so attempt to continue - older handles
1745 should have been cleared already */
1746 logf("%s(): finishing load: %d". __func__, info->id3_hid);
1747 filling = STATE_FILLING;
1748 buffer_event_finished_callback(&info->id3_hid);
1749 return LOAD_TRACK_OK;
1753 /* Some old, stray buffering message */
1754 logf("%s(): already in progress: %d". __func__, info->id3_hid);
1755 return LOAD_TRACK_ERR_BUSY;
1758 filling = STATE_FILLING;
1760 struct track_info *info = track_list_alloc_track();
1761 if (info == NULL)
1763 /* List is full so stop buffering tracks - however, attempt to obtain
1764 metadata as the unbuffered id3 */
1765 logf("No free tracks");
1766 filling = STATE_FULL;
1769 playlist_peek_offset++;
1771 logf("Buffering track: s%u/c%u/e%u/p%d",
1772 track_list.start, track_list.current, track_list.end,
1773 playlist_peek_offset);
1775 /* Get track name from current playlist read position */
1776 int fd = -1;
1777 char name_buf[MAX_PATH + 1];
1778 const char *trackname;
1780 while (1)
1783 trackname = playlist_peek(playlist_peek_offset, name_buf,
1784 sizeof (name_buf));
1786 if (!trackname)
1787 break;
1789 /* Test for broken playlists by probing for the files */
1790 fd = open(trackname, O_RDONLY);
1791 if (fd >= 0)
1792 break;
1794 logf("Open failed");
1795 /* Skip invalid entry from playlist */
1796 playlist_skip_entry(NULL, playlist_peek_offset);
1798 /* Sync the playlist if it isn't finished */
1799 if (playlist_peek(playlist_peek_offset, NULL, 0))
1800 playlist_next(0);
1803 if (!trackname)
1805 /* No track - exhausted the playlist entries */
1806 logf("End-of-playlist");
1807 id3_write_locked(UNBUFFERED_ID3, NULL);
1809 if (filling != STATE_FULL)
1810 track_list_unalloc_track(); /* Free this entry */
1812 playlist_peek_offset--; /* Maintain at last index */
1814 /* We can end up here after the real last track signals its completion
1815 and miss the transition to STATE_FINISHED esp. if dropping the last
1816 songs of a playlist late in their load (2nd stage) */
1817 info = track_list_last(0);
1819 if (info && buf_handle_remaining(info->audio_hid) == 0)
1820 filling_is_finished();
1821 else
1822 filling = STATE_END_OF_PLAYLIST;
1824 return LOAD_TRACK_ERR_NO_MORE;
1827 /* Successfully opened the file - get track metadata */
1828 if (filling == STATE_FULL ||
1829 (info->id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL)) < 0)
1831 /* Buffer or track list is full */
1832 struct mp3entry *ub_id3;
1834 playlist_peek_offset--;
1836 /* Load the metadata for the first unbuffered track */
1837 ub_id3 = id3_get(UNBUFFERED_ID3);
1838 id3_mutex_lock();
1839 get_metadata(ub_id3, fd, trackname);
1840 id3_mutex_unlock();
1842 if (filling != STATE_FULL)
1844 track_list_unalloc_track();
1845 filling = STATE_FULL;
1848 logf("%s: buffer is full for now (%u tracks)", __func__,
1849 track_list_count());
1851 else
1853 /* Successful load initiation */
1854 info->filesize = filesize(fd);
1855 in_progress_id3_hid = info->id3_hid; /* Remember what's in-progress */
1858 close(fd);
1859 return LOAD_TRACK_OK;
1862 /* Second part of the track loading: We now have the metadata available, so we
1863 can load the codec, the album art and finally the audio data.
1864 This is called on the audio thread after the buffering thread calls the
1865 buffering_handle_finished_callback callback. */
1866 static int audio_finish_load_track(struct track_info *info)
1868 int trackstat = LOAD_TRACK_OK;
1870 if (info->id3_hid != in_progress_id3_hid)
1872 /* We must not be here if not! */
1873 logf("%s: wrong track %d/%d", __func__, info->id3_hid,
1874 in_progress_id3_hid);
1875 return LOAD_TRACK_ERR_BUSY;
1878 /* The current track for decoding (there is always one if the list is
1879 populated) */
1880 struct track_info *cur_info = track_list_current(0);
1881 struct mp3entry *track_id3 = valid_mp3entry(bufgetid3(info->id3_hid));
1883 if (!track_id3)
1885 /* This is an error condition. Track cannot be played without valid
1886 metadata; skip the track. */
1887 logf("No metadata");
1888 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1889 goto audio_finish_load_track_exit;
1892 /* Try to load a cuesheet for the track */
1893 if (!audio_load_cuesheet(info, track_id3))
1895 /* No space for cuesheet on buffer, not an error */
1896 filling = STATE_FULL;
1897 goto audio_finish_load_track_exit;
1900 #ifdef HAVE_ALBUMART
1901 /* Try to load album art for the track */
1902 if (!audio_load_albumart(info, track_id3))
1904 /* No space for album art on buffer, not an error */
1905 filling = STATE_FULL;
1906 goto audio_finish_load_track_exit;
1908 #endif
1910 /* All handles available to external routines are ready - audio and codec
1911 information is private */
1913 if (info == track_list_user_current(0))
1915 /* Send only when the track handles could not all be opened ahead of
1916 time for the user's current track - otherwise everything is ready
1917 by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */
1918 send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3));
1921 #ifdef HAVE_CODEC_BUFFERING
1922 /* Try to buffer a codec for the track */
1923 if (info != cur_info && !audio_buffer_codec(info, track_id3))
1925 if (info->codec_hid == ERR_BUFFER_FULL)
1927 /* No space for codec on buffer, not an error */
1928 filling = STATE_FULL;
1929 logf("buffer is full for now (%s)", __func__);
1931 else
1933 /* This is an error condition, either no codec was found, or
1934 reading the codec file failed part way through, either way,
1935 skip the track */
1936 logf("No codec for: %s", track_id3->path);
1937 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
1940 goto audio_finish_load_track_exit;
1942 #endif /* HAVE_CODEC_BUFFERING */
1944 /** Finally, load the audio **/
1945 size_t file_offset = 0;
1946 track_id3->elapsed = 0;
1948 if (track_id3->offset >= info->filesize)
1949 track_id3->offset = 0;
1951 logf("%s: set offset for %s to %lu\n", __func__,
1952 id3->title, (unsigned long)offset);
1954 /* Adjust for resume rewind so we know what to buffer - starting the codec
1955 calls it again, so we don't save it (and they shouldn't accumulate) */
1956 size_t offset = resume_rewind_adjusted_offset(track_id3);
1958 enum data_type audiotype = rbcodec_format_is_atomic(track_id3->codectype) ?
1959 TYPE_ATOMIC_AUDIO : TYPE_PACKET_AUDIO;
1961 if (audiotype == TYPE_ATOMIC_AUDIO)
1962 logf("Loading atomic %d", track_id3->codectype);
1964 if (format_buffers_with_offset(track_id3->codectype))
1966 /* This format can begin buffering from any point */
1967 file_offset = offset;
1970 logf("load track: %s", track_id3->path);
1972 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1974 /* We can buffer later in the file, adjust the hunt-and-peck margin */
1975 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1977 else
1979 /* No offset given or it is very minimal - begin at the first frame
1980 according to the metadata */
1981 file_offset = track_id3->first_frame_offset;
1984 int hid = bufopen(track_id3->path, file_offset, audiotype, NULL);
1986 if (hid >= 0)
1988 info->audio_hid = hid;
1990 if (info == cur_info)
1992 /* This is the current track to decode - should be started now */
1993 trackstat = LOAD_TRACK_READY;
1996 else
1998 /* Buffer could be full but not properly so if this is the only
1999 track! */
2000 if (hid == ERR_BUFFER_FULL && audio_track_count() > 1)
2002 filling = STATE_FULL;
2003 logf("Buffer is full for now (%s)", __func__);
2005 else
2007 /* Nothing to play if no audio handle - skip this */
2008 logf("Could not add audio data handle");
2009 trackstat = LOAD_TRACK_ERR_FINISH_FAILED;
2013 audio_finish_load_track_exit:
2014 if (trackstat < LOAD_TRACK_OK)
2016 playlist_skip_entry(NULL, playlist_peek_offset);
2017 track_info_close(info);
2018 track_list_unalloc_track();
2020 if (playlist_peek(playlist_peek_offset, NULL, 0))
2021 playlist_next(0);
2023 playlist_peek_offset--;
2026 if (filling != STATE_FULL)
2028 /* Load next track - error or not */
2029 in_progress_id3_hid = ERR_HANDLE_NOT_FOUND;
2030 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
2031 audio_queue_post(Q_AUDIO_FILL_BUFFER, 0);
2033 else
2035 /* Full */
2036 trackstat = LOAD_TRACK_ERR_FINISH_FULL;
2039 return trackstat;
2042 /* Start a new track load */
2043 static int audio_fill_file_buffer(void)
2045 if (play_status == PLAY_STOPPED)
2046 return LOAD_TRACK_ERR_FAILED;
2048 trigger_cpu_boost();
2050 /* Must reset the buffer before use if trashed or voice only - voice
2051 file size shouldn't have changed so we can go straight from
2052 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
2053 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
2054 audio_reset_buffer();
2056 logf("Starting buffer fill");
2058 int trackstat = audio_load_track();
2060 if (trackstat >= LOAD_TRACK_OK)
2062 if (track_list_current(0) == track_list_user_current(0))
2063 playlist_next(0);
2065 if (filling == STATE_FULL && !track_list_user_current(1))
2067 /* There are no user tracks on the buffer after this therefore
2068 this is the next track */
2069 audio_update_and_announce_next_track(id3_get(UNBUFFERED_ID3));
2073 return trackstat;
2076 /* Discard unwanted tracks and start refill from after the specified playlist
2077 offset */
2078 static int audio_reset_and_rebuffer(
2079 enum track_clear_action action, int peek_offset)
2081 logf("Forcing rebuffer: 0x%X, %d", flags, peek_offset);
2083 id3_write_locked(UNBUFFERED_ID3, NULL);
2085 /* Remove unwanted tracks - caller must have ensured codec isn't using
2086 any */
2087 track_list_clear(action);
2089 /* Refill at specified position (-1 starts at index offset 0) */
2090 playlist_peek_offset = peek_offset;
2092 /* Fill the buffer */
2093 return audio_fill_file_buffer();
2096 /* Handle buffering events
2097 (Q_AUDIO_BUFFERING) */
2098 static void audio_on_buffering(int event)
2100 enum track_clear_action action;
2101 int peek_offset;
2103 if (track_list_empty())
2104 return;
2106 switch (event)
2108 case BUFFER_EVENT_BUFFER_LOW:
2109 if (filling != STATE_FULL && filling != STATE_END_OF_PLAYLIST)
2110 return; /* Should be nothing left to fill */
2112 /* Clear old tracks and continue buffering where it left off */
2113 action = TRACK_LIST_KEEP_NEW;
2114 peek_offset = playlist_peek_offset;
2115 break;
2117 case BUFFER_EVENT_REBUFFER:
2118 /* Remove all but the currently decoding track and redo buffering
2119 after that */
2120 action = TRACK_LIST_KEEP_CURRENT;
2121 peek_offset = (skip_pending == TRACK_SKIP_AUTO) ? 1 : 0;
2122 break;
2124 default:
2125 return;
2128 switch (skip_pending)
2130 case TRACK_SKIP_NONE:
2131 case TRACK_SKIP_AUTO:
2132 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2133 audio_reset_and_rebuffer(action, peek_offset);
2134 break;
2136 case TRACK_SKIP_AUTO_END_PLAYLIST:
2137 /* Already finished */
2138 break;
2140 default:
2141 /* Invalid */
2142 logf("Buffering call, inv. state: %d", (int)skip_pending);
2146 /* Handle starting the next track load
2147 (Q_AUDIO_FILL_BUFFER) */
2148 static void audio_on_fill_buffer(void)
2150 audio_handle_track_load_status(audio_fill_file_buffer());
2153 /* Handle posted load track finish event
2154 (Q_AUDIO_FINISH_LOAD_TRACK) */
2155 static void audio_on_finish_load_track(int id3_hid)
2157 struct track_info *info = track_list_last(0);
2159 if (!info || !buf_is_handle(id3_hid))
2160 return;
2162 if (info == track_list_user_current(1))
2164 /* Just loaded the metadata right after the current position */
2165 audio_update_and_announce_next_track(bufgetid3(info->id3_hid));
2168 if (audio_finish_load_track(info) != LOAD_TRACK_READY)
2169 return; /* Not current track */
2171 bool is_user_current = info == track_list_user_current(0);
2173 if (is_user_current)
2175 /* Copy cuesheet */
2176 buf_read_cuesheet(info->cuesheet_hid);
2179 if (audio_start_codec(automatic_skip))
2181 if (is_user_current)
2183 /* Be sure all tagtree info is synchronized; it will be needed for the
2184 track finish event - the sync will happen when finalizing a track
2185 change otherwise */
2186 bool was_valid = valid_mp3entry(id3_get(PLAYING_ID3));
2188 playing_id3_sync(info, -1);
2190 if (!was_valid)
2192 /* Playing id3 hadn't been updated yet because no valid track
2193 was yet available - treat like the first track */
2194 audio_playlist_track_change();
2198 else
2200 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2204 /* Called when handles other than metadata handles have finished buffering
2205 (Q_AUDIO_HANDLE_FINISHED) */
2206 static void audio_on_handle_finished(int hid)
2208 /* Right now, only audio handles should end up calling this */
2209 if (filling == STATE_END_OF_PLAYLIST)
2211 struct track_info *info = track_list_last(0);
2213 /* Really we don't know which order the handles will actually complete
2214 to zero bytes remaining since another thread is doing it - be sure
2215 it's the right one */
2216 if (info && info->audio_hid == hid)
2218 /* This was the last track in the playlist and we now have all the
2219 data we need */
2220 filling_is_finished();
2225 /* Called to make an outstanding track skip the current track and to send the
2226 transition events */
2227 static void audio_finalise_track_change(void)
2229 switch (skip_pending)
2231 case TRACK_SKIP_NONE: /* Manual skip */
2232 break;
2234 case TRACK_SKIP_AUTO:
2235 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2237 int playlist_delta = skip_pending == TRACK_SKIP_AUTO ? 1 : 0;
2238 audio_playlist_track_finish();
2240 if (!playlist_peek(playlist_delta, NULL, 0))
2242 /* Track ended up rejected - push things ahead like the codec blew
2243 it (because it was never started and now we're here where it
2244 should have been decoding the next track by now) - next, a
2245 directory change or end of playback will most likely happen */
2246 skip_pending = TRACK_SKIP_NONE;
2247 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2248 return;
2251 if (!playlist_delta)
2252 break;
2254 playlist_peek_offset -= playlist_delta;
2255 if (playlist_next(playlist_delta) >= 0)
2256 break;
2257 /* What!? Disappear? Hopeless bleak despair */
2259 /* Fallthrough */
2260 case TRACK_SKIP_AUTO_END_PLAYLIST:
2261 default: /* Invalid */
2262 filling = STATE_ENDED;
2263 audio_stop_playback();
2264 return;
2267 struct track_info *info = track_list_current(0);
2268 struct mp3entry *track_id3 = NULL;
2270 id3_mutex_lock();
2272 /* Update the current cuesheet if any and enabled */
2273 if (info)
2275 buf_read_cuesheet(info->cuesheet_hid);
2276 track_id3 = bufgetid3(info->id3_hid);
2279 id3_write(PLAYING_ID3, track_id3);
2281 /* The skip is technically over */
2282 skip_pending = TRACK_SKIP_NONE;
2284 /* Sync the next track information */
2285 info = track_list_current(1);
2287 id3_write(NEXTTRACK_ID3, info ? bufgetid3(info->id3_hid) :
2288 id3_get(UNBUFFERED_ID3));
2290 id3_mutex_unlock();
2292 audio_playlist_track_change();
2295 /* Actually begin a transition and take care of the codec change - may complete
2296 it now or ask pcmbuf for notification depending on the type */
2297 static void audio_begin_track_change(enum pcm_track_change_type type,
2298 int trackstat)
2300 /* Even if the new track is bad, the old track must be finished off */
2301 pcmbuf_start_track_change(type);
2303 bool auto_skip = type != TRACK_CHANGE_MANUAL;
2305 if (!auto_skip)
2307 /* Manual track change happens now */
2308 audio_finalise_track_change();
2309 pcmbuf_sync_position_update();
2311 if (play_status == PLAY_STOPPED)
2312 return; /* Stopped us */
2315 if (trackstat >= LOAD_TRACK_OK)
2317 struct track_info *info = track_list_current(0);
2319 if (info->audio_hid < 0)
2320 return;
2322 /* Everything needed for the codec is ready - start it */
2323 if (audio_start_codec(auto_skip))
2325 if (!auto_skip)
2326 playing_id3_sync(info, -1);
2327 return;
2330 trackstat = LOAD_TRACK_ERR_START_CODEC;
2333 audio_handle_track_load_status(trackstat);
2336 /* Transition to end-of-playlist state and begin wait for PCM to finish */
2337 static void audio_monitor_end_of_playlist(void)
2339 skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST;
2340 filling = STATE_ENDING;
2341 pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA);
2344 /* Codec has completed decoding the track
2345 (usually Q_AUDIO_CODEC_COMPLETE) */
2346 static void audio_on_codec_complete(int status)
2348 logf("%s(%d)", __func__, status);
2350 if (play_status == PLAY_STOPPED)
2351 return;
2353 /* If it didn't notify us first, don't expect "seek complete" message
2354 since the codec can't post it now - do things like it would have
2355 done */
2356 audio_complete_codec_seek();
2358 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2360 /* Old-hay on the ip-skay - codec has completed decoding
2362 Paused: We're not sounding it, so just remember that it happened
2363 and the resume will begin the transition
2365 Skipping: There was already a skip in progress, remember it and
2366 allow no further progress until the PCM from the previous
2367 song has finished
2369 codec_skip_pending = true;
2370 codec_skip_status = status;
2371 return;
2374 codec_skip_pending = false;
2376 int trackstat = LOAD_TRACK_OK;
2378 automatic_skip = true;
2379 skip_pending = TRACK_SKIP_AUTO;
2381 /* Does this track have an entry allocated? */
2382 struct track_info *info = track_list_advance_current(1);
2384 if (!info || info->audio_hid < 0)
2386 bool end_of_playlist = false;
2388 if (info)
2390 /* Track load is not complete - it might have stopped on a
2391 full buffer without reaching the audio handle or we just
2392 arrived at it early
2394 If this type is atomic and we couldn't get the audio,
2395 perhaps it would need to wrap to make the allocation and
2396 handles are in the way - to maximize the liklihood it can
2397 be allocated, clear all handles to reset the buffer and
2398 its indexes to 0 - for packet audio, this should not be an
2399 issue and a pointless full reload of all the track's
2400 metadata may be avoided */
2402 struct mp3entry *track_id3 = bufgetid3(info->id3_hid);
2404 if (track_id3 && !rbcodec_format_is_atomic(track_id3->codectype))
2406 /* Continue filling after this track */
2407 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2408 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat);
2409 return;
2411 /* else rebuffer at this track; status applies to the track we
2412 want */
2414 else if (!playlist_peek(1, NULL, 0))
2416 /* Play sequence is complete - directory change or other playlist
2417 resequencing - the playlist must now be advanced in order to
2418 continue since a peek ahead to the next track is not possible */
2419 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2420 end_of_playlist = playlist_next(1) < 0;
2423 if (!end_of_playlist)
2425 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2426 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2428 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2430 /* Failed to find anything after all - do playlist switchover
2431 instead */
2432 skip_pending = TRACK_SKIP_AUTO_NEW_PLAYLIST;
2433 end_of_playlist = playlist_next(1) < 0;
2437 if (end_of_playlist)
2439 audio_monitor_end_of_playlist();
2440 return;
2444 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat);
2447 /* Called when codec completes seek operation
2448 (usually Q_AUDIO_CODEC_SEEK_COMPLETE) */
2449 static void audio_on_codec_seek_complete(void)
2451 logf("%s()", __func__);
2452 audio_complete_codec_seek();
2453 codec_go();
2456 /* Called when PCM track change has completed
2457 (Q_AUDIO_TRACK_CHANGED) */
2458 static void audio_on_track_changed(void)
2460 /* Finish whatever is pending so that the WPS is in sync */
2461 audio_finalise_track_change();
2463 if (codec_skip_pending)
2465 /* Codec got ahead completing a short track - complete the
2466 codec's skip and begin the next */
2467 codec_skip_pending = false;
2468 audio_on_codec_complete(codec_skip_status);
2472 /* Begin playback from an idle state, transition to a new playlist or
2473 invalidate the buffer and resume (if playing).
2474 (usually Q_AUDIO_PLAY, Q_AUDIO_REMAKE_AUDIO_BUFFER) */
2475 static void audio_start_playback(size_t offset, unsigned int flags)
2477 enum play_status old_status = play_status;
2479 if (flags & AUDIO_START_NEWBUF)
2481 /* Mark the buffer dirty - if not playing, it will be reset next
2482 time */
2483 if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
2484 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
2487 if (old_status != PLAY_STOPPED)
2489 logf("%s(%lu): skipping", __func__, (unsigned long)offset);
2491 halt_decoding_track(true);
2493 automatic_skip = false;
2494 ff_rw_mode = false;
2496 if (flags & AUDIO_START_RESTART)
2498 /* Clear out some stuff to resume the current track where it
2499 left off */
2500 pcmbuf_play_stop();
2501 offset = id3_get(PLAYING_ID3)->offset;
2502 track_list_clear(TRACK_LIST_CLEAR_ALL);
2504 else
2506 /* This is more-or-less treated as manual track transition */
2507 /* Save resume information for current track */
2508 audio_playlist_track_finish();
2509 track_list_clear(TRACK_LIST_CLEAR_ALL);
2511 /* Indicate manual track change */
2512 pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
2513 wipe_track_metadata(true);
2516 /* Set after track finish event in case skip was in progress */
2517 skip_pending = TRACK_SKIP_NONE;
2519 else
2521 if (flags & AUDIO_START_RESTART)
2522 return; /* Must already be playing */
2524 /* Cold playback start from a stopped state */
2525 logf("%s(%lu): starting", __func__, offset);
2527 /* Set audio parameters */
2528 #if INPUT_SRC_CAPS != 0
2529 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
2530 audio_set_output_source(AUDIO_SRC_PLAYBACK);
2531 #endif
2532 #ifndef PLATFORM_HAS_VOLUME_CHANGE
2533 sound_set_volume(global_settings.volume);
2534 #endif
2535 /* Be sure channel is audible */
2536 pcmbuf_fade(false, true);
2538 /* Update our state */
2539 play_status = PLAY_PLAYING;
2542 /* Codec's position should be available as soon as it knows it */
2543 position_key = pcmbuf_get_position_key();
2544 pcmbuf_sync_position_update();
2546 /* Start fill from beginning of playlist */
2547 playlist_peek_offset = -1;
2548 buf_set_base_handle(-1);
2550 /* Officially playing */
2551 queue_reply(&audio_queue, 1);
2553 /* Add these now - finish event for the first id3 will most likely be sent
2554 immediately */
2555 add_event(BUFFER_EVENT_REBUFFER, false, buffer_event_rebuffer_callback);
2556 add_event(BUFFER_EVENT_FINISHED, false, buffer_event_finished_callback);
2558 if (old_status == PLAY_STOPPED)
2560 /* Send coldstart event */
2561 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2564 /* Fill the buffer */
2565 int trackstat = audio_fill_file_buffer();
2567 if (trackstat >= LOAD_TRACK_OK)
2569 /* This is the currently playing track - get metadata, stat */
2570 playing_id3_sync(track_list_current(0), offset);
2572 if (valid_mp3entry(id3_get(PLAYING_ID3)))
2574 /* Only if actually changing tracks... */
2575 if (!(flags & AUDIO_START_RESTART))
2576 audio_playlist_track_change();
2579 else
2581 /* Found nothing playable */
2582 audio_handle_track_load_status(trackstat);
2586 /* Stop playback and enter an idle state
2587 (usually Q_AUDIO_STOP) */
2588 static void audio_stop_playback(void)
2590 logf("%s()", __func__);
2592 if (play_status == PLAY_STOPPED)
2593 return;
2595 bool do_fade = global_settings.fade_on_stop && filling != STATE_ENDED;
2597 pcmbuf_fade(do_fade, false);
2599 /* Wait for fade-out */
2600 audio_wait_fade_complete();
2602 /* Stop the codec and unload it */
2603 halt_decoding_track(true);
2604 pcmbuf_play_stop();
2605 codec_unload();
2607 /* Save resume information - "filling" might have been set to
2608 "STATE_ENDED" by caller in order to facilitate end of playlist */
2609 audio_playlist_track_finish();
2611 skip_pending = TRACK_SKIP_NONE;
2612 automatic_skip = false;
2614 /* Close all tracks and mark them NULL */
2615 remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback);
2616 remove_event(BUFFER_EVENT_FINISHED, buffer_event_finished_callback);
2617 remove_event(BUFFER_EVENT_BUFFER_LOW, buffer_event_buffer_low_callback);
2619 track_list_clear(TRACK_LIST_CLEAR_ALL);
2621 /* Update our state */
2622 ff_rw_mode = false;
2623 play_status = PLAY_STOPPED;
2625 wipe_track_metadata(true);
2627 /* Go idle */
2628 filling = STATE_IDLE;
2629 cancel_cpu_boost();
2632 /* Pause the playback of the current track
2633 (Q_AUDIO_PAUSE) */
2634 static void audio_on_pause(bool pause)
2636 logf("%s(%s)", __func__, pause ? "true" : "false");
2638 if (play_status == PLAY_STOPPED || pause == (play_status == PLAY_PAUSED))
2639 return;
2641 play_status = pause ? PLAY_PAUSED : PLAY_PLAYING;
2643 if (!pause && codec_skip_pending)
2645 /* Actually do the skip that is due - resets the status flag */
2646 audio_on_codec_complete(codec_skip_status);
2649 bool do_fade = global_settings.fade_on_stop;
2651 pcmbuf_fade(do_fade, !pause);
2653 if (!ff_rw_mode && !(do_fade && pause))
2655 /* Not in ff/rw mode - can actually change the audio state now */
2656 pcmbuf_pause(pause);
2660 /* Skip a certain number of tracks forwards or backwards
2661 (Q_AUDIO_SKIP) */
2662 static void audio_on_skip(void)
2664 id3_mutex_lock();
2666 /* Eat the delta to keep it synced, even if not playing */
2667 int toskip = skip_offset;
2668 skip_offset = 0;
2670 logf("%s(): %d", __func__, toskip);
2672 id3_mutex_unlock();
2674 if (play_status == PLAY_STOPPED)
2675 return;
2677 /* Force codec to abort this track */
2678 halt_decoding_track(true);
2680 /* Kill the ff/rw halt */
2681 ff_rw_mode = false;
2683 /* Manual skip */
2684 automatic_skip = false;
2686 /* If there was an auto skip in progress, there will be residual
2687 advancement of the playlist and/or track list so compensation will be
2688 required in order to end up in the right spot */
2689 int track_list_delta = toskip;
2690 int playlist_delta = toskip;
2692 if (skip_pending != TRACK_SKIP_NONE)
2694 if (skip_pending != TRACK_SKIP_AUTO_END_PLAYLIST)
2695 track_list_delta--;
2697 if (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)
2698 playlist_delta--;
2701 audio_playlist_track_finish();
2702 skip_pending = TRACK_SKIP_NONE;
2704 /* Update the playlist current track now */
2705 int pl_retval;
2706 while ((pl_retval = playlist_next(playlist_delta)) < 0)
2708 if (pl_retval < -1)
2710 /* Some variety of fatal error while updating playlist */
2711 filling = STATE_ENDED;
2712 audio_stop_playback();
2713 return;
2716 /* Manual skip out of range (because the playlist wasn't updated
2717 yet by us and so the check in audio_skip returned 'ok') - bring
2718 back into range */
2719 int d = toskip < 0 ? 1 : -1;
2721 while (!playlist_check(playlist_delta))
2723 if (playlist_delta == d)
2725 /* Had to move the opposite direction to correct, which is
2726 wrong - this is the end */
2727 filling = STATE_ENDED;
2728 audio_stop_playback();
2729 return;
2732 playlist_delta += d;
2733 track_list_delta += d;
2737 /* Adjust things by how much the playlist was manually moved */
2738 playlist_peek_offset -= playlist_delta;
2740 struct track_info *info = track_list_advance_current(track_list_delta);
2741 int trackstat = LOAD_TRACK_OK;
2743 if (!info || info->audio_hid < 0)
2745 /* We don't know the next track thus we know we don't have it */
2746 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2749 audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat);
2752 /* Skip to the next/previous directory
2753 (Q_AUDIO_DIR_SKIP) */
2754 static void audio_on_dir_skip(int direction)
2756 logf("%s(%d)", __func__, direction);
2758 id3_mutex_lock();
2759 skip_offset = 0;
2760 id3_mutex_unlock();
2762 if (play_status == PLAY_STOPPED)
2763 return;
2765 /* Force codec to abort this track */
2766 halt_decoding_track(true);
2768 /* Kill the ff/rw halt */
2769 ff_rw_mode = false;
2771 /* Manual skip */
2772 automatic_skip = false;
2774 audio_playlist_track_finish();
2776 /* Unless automatic and gapless, skips do not pend */
2777 skip_pending = TRACK_SKIP_NONE;
2779 /* Regardless of the return value we need to rebuffer. If it fails the old
2780 playlist will resume, else the next dir will start playing. */
2781 playlist_next_dir(direction);
2783 wipe_track_metadata(false);
2785 int trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1);
2787 if (trackstat == LOAD_TRACK_ERR_NO_MORE)
2789 /* The day the music died - finish-off whatever is playing and call it
2790 quits */
2791 audio_monitor_end_of_playlist();
2792 return;
2795 audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat);
2798 /* Enter seek mode in order to start a seek
2799 (Q_AUDIO_PRE_FF_REWIND) */
2800 static void audio_on_pre_ff_rewind(void)
2802 logf("%s()", __func__);
2804 if (play_status == PLAY_STOPPED || ff_rw_mode)
2805 return;
2807 ff_rw_mode = true;
2809 audio_wait_fade_complete();
2811 if (play_status == PLAY_PAUSED)
2812 return;
2814 pcmbuf_pause(true);
2817 /* Seek the playback of the current track to the specified time
2818 (Q_AUDIO_FF_REWIND) */
2819 static void audio_on_ff_rewind(long time)
2821 logf("%s(%ld)", __func__, time);
2823 if (play_status == PLAY_STOPPED)
2824 return;
2826 enum track_skip_type pending = skip_pending;
2828 switch (pending)
2830 case TRACK_SKIP_NONE: /* The usual case */
2831 case TRACK_SKIP_AUTO: /* Have to back it out (fun!) */
2832 case TRACK_SKIP_AUTO_END_PLAYLIST: /* Still have the last codec used */
2834 struct mp3entry *id3 = id3_get(PLAYING_ID3);
2835 struct mp3entry *ci_id3 = id3_get(CODEC_ID3);
2837 automatic_skip = false;
2839 /* Send event before clobbering the time */
2840 /* FIXME: Nasty, but the tagtree expects this so that rewinding and
2841 then skipping back to this track resumes properly. Something else
2842 should be sent. We're not _really_ finishing the track are we? */
2843 if (time == 0)
2844 send_event(PLAYBACK_EVENT_TRACK_FINISH, id3);
2846 id3->elapsed = time;
2847 queue_reply(&audio_queue, 1);
2849 bool haltres = halt_decoding_track(pending == TRACK_SKIP_AUTO);
2851 /* Need this set in case ff/rw mode + error but _after_ the codec
2852 halt that will reset it */
2853 codec_seeking = true;
2855 /* If in transition, key will have changed - sync to it */
2856 position_key = pcmbuf_get_position_key();
2858 if (pending == TRACK_SKIP_AUTO)
2860 if (!track_list_advance_current(-1))
2862 /* Not in list - must rebuffer at the current playlist index */
2863 if (audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1)
2864 < LOAD_TRACK_OK)
2866 /* Codec is stopped */
2867 break;
2872 /* Set after audio_fill_file_buffer to disable playing id3 clobber if
2873 rebuffer is needed */
2874 skip_pending = TRACK_SKIP_NONE;
2875 struct track_info *cur_info = track_list_current(0);
2877 /* Track must complete the loading _now_ since a codec and audio
2878 handle are needed in order to do the seek */
2879 if (cur_info->audio_hid < 0 &&
2880 audio_finish_load_track(cur_info) != LOAD_TRACK_READY)
2882 /* Call above should push any load sequence - no need for
2883 halt_decoding_track here if no skip was pending here because
2884 there would not be a codec started if no audio handle was yet
2885 opened */
2886 break;
2889 if (pending == TRACK_SKIP_AUTO)
2891 if (!bufreadid3(cur_info->id3_hid, ci_id3) ||
2892 !audio_init_codec(cur_info, ci_id3))
2894 /* We should have still been able to get it - skip it and move
2895 onto the next one - like it or not this track is broken */
2896 break;
2899 /* Set the codec API to the correct metadata and track info */
2900 ci.audio_hid = cur_info->audio_hid;
2901 ci.filesize = cur_info->filesize;
2902 buf_set_base_handle(cur_info->audio_hid);
2905 if (!haltres)
2907 /* If codec must be (re)started, reset the offset */
2908 ci_id3->offset = 0;
2911 codec_seek(time);
2912 return;
2915 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2917 /* We cannot do this because the playlist must be reversed by one
2918 and it doesn't always return the same song when going backwards
2919 across boundaries as forwards (either because of randomization
2920 or inconsistency in deciding what the previous track should be),
2921 therefore the whole operation would often end up as nonsense -
2922 lock out seeking for a couple seconds */
2924 /* Sure as heck cancel seek mode too! */
2925 audio_ff_rewind_end();
2926 return;
2929 default:
2930 /* Won't see this */
2931 return;
2934 if (play_status == PLAY_STOPPED)
2936 /* Playback ended because of an error completing a track load */
2937 return;
2940 /* Always fake it as a codec start error which will handle mode
2941 cancellations and skip to the next track */
2942 audio_handle_track_load_status(LOAD_TRACK_ERR_START_CODEC);
2945 /* Invalidates all but currently playing track
2946 (Q_AUDIO_FLUSH) */
2947 static void audio_on_audio_flush(void)
2949 logf("%s", __func__);
2951 if (track_list_empty())
2952 return; /* Nothing to flush out */
2954 switch (skip_pending)
2956 case TRACK_SKIP_NONE:
2957 case TRACK_SKIP_AUTO_END_PLAYLIST:
2958 /* Remove all but the currently playing track from the list and
2959 refill after that */
2960 track_list_clear(TRACK_LIST_KEEP_CURRENT);
2961 playlist_peek_offset = 0;
2962 id3_write_locked(UNBUFFERED_ID3, NULL);
2963 audio_update_and_announce_next_track(NULL);
2965 /* Ignore return since it's about the next track, not this one */
2966 audio_fill_file_buffer();
2968 if (skip_pending == TRACK_SKIP_NONE)
2969 break;
2971 /* There's now a track after this one now - convert to auto skip -
2972 no skip should pend right now because multiple flush messages can
2973 be fired which would cause a restart in the below cases */
2974 skip_pending = TRACK_SKIP_NONE;
2975 audio_clear_track_notifications();
2976 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, CODEC_OK);
2977 break;
2979 case TRACK_SKIP_AUTO:
2980 case TRACK_SKIP_AUTO_NEW_PLAYLIST:
2981 /* Precisely removing what it already decoded for the next track is
2982 not possible so a restart is required in order to continue the
2983 currently playing track without the now invalid future track
2984 playing */
2985 audio_start_playback(0, AUDIO_START_RESTART);
2986 break;
2988 default: /* Nothing else is a state */
2989 break;
2993 #ifdef AUDIO_HAVE_RECORDING
2994 /* Load the requested encoder type
2995 (Q_AUDIO_LOAD_ENCODER) */
2996 static void audio_on_load_encoder(int afmt)
2998 bool res = true;
3000 if (play_status != PLAY_STOPPED)
3001 audio_stop_playback(); /* Can't load both types at once */
3002 else
3003 codec_unload(); /* Encoder still loaded, stop and unload it */
3005 if (afmt != AFMT_UNKNOWN)
3007 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
3008 if (res)
3009 codec_go(); /* These are run immediately */
3012 queue_reply(&audio_queue, res);
3014 #endif /* AUDIO_HAVE_RECORDING */
3016 static void audio_thread(void)
3018 struct queue_event ev;
3020 pcm_postinit();
3022 while (1)
3024 switch (filling)
3026 /* Active states */
3027 case STATE_FULL:
3028 case STATE_END_OF_PLAYLIST:
3029 if (buf_get_watermark() == 0)
3031 /* End of buffering for now, let's calculate the watermark,
3032 register for a low buffer event and unboost */
3033 audio_update_filebuf_watermark(0);
3034 add_event(BUFFER_EVENT_BUFFER_LOW, true,
3035 buffer_event_buffer_low_callback);
3037 /* Fall-through */
3038 case STATE_FINISHED:
3039 /* All data was buffered */
3040 cancel_cpu_boost();
3041 /* Fall-through */
3042 case STATE_FILLING:
3043 case STATE_ENDING:
3044 if (audio_pcmbuf_track_change_scan())
3046 /* Transfer notification to audio queue event */
3047 ev.id = Q_AUDIO_TRACK_CHANGED;
3048 ev.data = 1;
3050 else
3052 /* If doing auto skip, poll pcmbuf track notifications a bit
3053 faster to promply detect the transition */
3054 queue_wait_w_tmo(&audio_queue, &ev,
3055 skip_pending == TRACK_SKIP_NONE ?
3056 HZ/2 : HZ/10);
3058 break;
3060 /* Idle states */
3061 default:
3062 queue_wait(&audio_queue, &ev);
3064 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3065 switch (ev.id)
3067 #ifdef AUDIO_HAVE_RECORDING
3068 /* Must monitor the encoder message for recording so it can remove
3069 it if we process the insertion before it does. It cannot simply
3070 be removed from under recording however. */
3071 case Q_AUDIO_LOAD_ENCODER:
3072 break;
3073 #endif
3074 case SYS_USB_DISCONNECTED:
3075 filling = STATE_IDLE;
3076 break;
3078 default:
3079 if (filling == STATE_USB)
3080 continue;
3082 #endif /* CONFIG_PLATFORM */
3085 switch (ev.id)
3087 /** Codec and track change messages **/
3088 case Q_AUDIO_CODEC_COMPLETE:
3089 /* Codec is done processing track and has gone idle */
3090 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data);
3091 audio_on_codec_complete(ev.data);
3092 break;
3094 case Q_AUDIO_CODEC_SEEK_COMPLETE:
3095 /* Codec is done seeking */
3096 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
3097 audio_on_codec_seek_complete();
3098 break;
3100 case Q_AUDIO_TRACK_CHANGED:
3101 /* PCM track change done */
3102 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
3103 audio_on_track_changed();
3104 break;
3106 /** Control messages **/
3107 case Q_AUDIO_PLAY:
3108 LOGFQUEUE("audio < Q_AUDIO_PLAY");
3109 audio_start_playback(ev.data, 0);
3110 break;
3112 case Q_AUDIO_STOP:
3113 LOGFQUEUE("audio < Q_AUDIO_STOP");
3114 audio_stop_playback();
3115 if (ev.data != 0)
3116 queue_clear(&audio_queue);
3117 break;
3119 case Q_AUDIO_PAUSE:
3120 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
3121 audio_on_pause(ev.data);
3122 break;
3124 case Q_AUDIO_SKIP:
3125 LOGFQUEUE("audio < Q_AUDIO_SKIP");
3126 audio_on_skip();
3127 break;
3129 case Q_AUDIO_DIR_SKIP:
3130 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
3131 audio_on_dir_skip(ev.data);
3132 break;
3134 case Q_AUDIO_PRE_FF_REWIND:
3135 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
3136 audio_on_pre_ff_rewind();
3137 break;
3139 case Q_AUDIO_FF_REWIND:
3140 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
3141 audio_on_ff_rewind(ev.data);
3142 break;
3144 case Q_AUDIO_FLUSH:
3145 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data);
3146 audio_on_audio_flush();
3147 break;
3149 /** Buffering messages **/
3150 case Q_AUDIO_BUFFERING:
3151 /* some buffering event */
3152 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data);
3153 audio_on_buffering(ev.data);
3154 break;
3156 case Q_AUDIO_FILL_BUFFER:
3157 /* continue buffering next track */
3158 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");
3159 audio_on_fill_buffer();
3160 break;
3162 case Q_AUDIO_FINISH_LOAD_TRACK:
3163 /* metadata is buffered */
3164 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK");
3165 audio_on_finish_load_track(ev.data);
3166 break;
3168 case Q_AUDIO_HANDLE_FINISHED:
3169 /* some other type is buffered */
3170 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED");
3171 audio_on_handle_finished(ev.data);
3172 break;
3174 /** Miscellaneous messages **/
3175 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3176 /* buffer needs to be reinitialized */
3177 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3178 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3179 break;
3181 #ifdef HAVE_DISK_STORAGE
3182 case Q_AUDIO_UPDATE_WATERMARK:
3183 /* buffering watermark needs updating */
3184 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data);
3185 audio_update_filebuf_watermark(ev.data);
3186 break;
3187 #endif /* HAVE_DISK_STORAGE */
3189 #ifdef AUDIO_HAVE_RECORDING
3190 case Q_AUDIO_LOAD_ENCODER:
3191 /* load an encoder for recording */
3192 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3193 audio_on_load_encoder(ev.data);
3194 break;
3195 #endif /* AUDIO_HAVE_RECORDING */
3197 case SYS_USB_CONNECTED:
3198 LOGFQUEUE("audio < SYS_USB_CONNECTED");
3199 audio_stop_playback();
3200 #ifdef PLAYBACK_VOICE
3201 voice_stop();
3202 #endif
3203 filling = STATE_USB;
3204 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3205 break;
3207 case SYS_TIMEOUT:
3208 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
3209 break;
3211 default:
3212 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
3213 break;
3214 } /* end switch */
3215 } /* end while */
3219 /* --- Buffering callbacks --- */
3221 /* Called when fullness is below the watermark level */
3222 static void buffer_event_buffer_low_callback(void *data)
3224 logf("low buffer callback");
3225 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: buffer low");
3226 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_BUFFER_LOW);
3227 (void)data;
3230 /* Called when handles must be discarded in order to buffer new data */
3231 static void buffer_event_rebuffer_callback(void *data)
3233 logf("rebuffer callback");
3234 LOGFQUEUE("buffering > audio Q_AUDIO_BUFFERING: rebuffer");
3235 audio_queue_post(Q_AUDIO_BUFFERING, BUFFER_EVENT_REBUFFER);
3236 (void)data;
3239 /* A handle has completed buffering and all required data is available */
3240 static void buffer_event_finished_callback(void *data)
3242 int hid = *(const int *)data;
3243 const enum data_type htype = buf_handle_data_type(hid);
3245 logf("handle %d finished buffering (type:%u)", hid, (unsigned)htype);
3247 /* Limit queue traffic */
3248 switch (htype)
3250 case TYPE_ID3:
3251 /* The metadata handle for the last loaded track has been buffered.
3252 We can ask the audio thread to load the rest of the track's data. */
3253 LOGFQUEUE("buffering > audio Q_AUDIO_FINISH_LOAD_TRACK: %d", hid);
3254 audio_queue_post(Q_AUDIO_FINISH_LOAD_TRACK, hid);
3255 break;
3257 case TYPE_PACKET_AUDIO:
3258 /* Strip any useless trailing tags that are left. */
3259 strip_tags(hid);
3260 /* Fall-through */
3261 case TYPE_ATOMIC_AUDIO:
3262 LOGFQUEUE("buffering > audio Q_AUDIO_HANDLE_FINISHED: %d", hid);
3263 audio_queue_post(Q_AUDIO_HANDLE_FINISHED, hid);
3264 break;
3266 default:
3267 /* Don't care to know about these */
3268 break;
3273 /** -- Codec callbacks -- **/
3275 /* Update elapsed time for next PCM insert */
3276 void audio_codec_update_elapsed(unsigned long elapsed)
3278 #ifdef AB_REPEAT_ENABLE
3279 ab_position_report(elapsed);
3280 #endif
3281 /* Save in codec's id3 where it is used at next pcm insert */
3282 id3_get(CODEC_ID3)->elapsed = elapsed;
3285 /* Update offset for next PCM insert */
3286 void audio_codec_update_offset(size_t offset)
3288 /* Save in codec's id3 where it is used at next pcm insert */
3289 id3_get(CODEC_ID3)->offset = offset;
3292 /* Codec has finished running */
3293 void audio_codec_complete(int status)
3295 #ifdef AB_REPEAT_ENABLE
3296 if (status >= CODEC_OK)
3298 /* Normal automatic skip */
3299 ab_end_of_track_report();
3301 #endif
3303 LOGFQUEUE("codec > audio Q_AUDIO_CODEC_COMPLETE: %d", status);
3304 audio_queue_post(Q_AUDIO_CODEC_COMPLETE, status);
3307 /* Codec has finished seeking */
3308 void audio_codec_seek_complete(void)
3310 LOGFQUEUE("codec > audio Q_AUDIO_CODEC_SEEK_COMPLETE");
3311 audio_queue_post(Q_AUDIO_CODEC_SEEK_COMPLETE, 0);
3315 /** --- Pcmbuf callbacks --- **/
3317 /* Update the elapsed and offset from the information cached during the
3318 PCM buffer insert */
3319 void audio_pcmbuf_position_callback(unsigned long elapsed, off_t offset,
3320 unsigned int key)
3322 if (key == position_key)
3324 struct mp3entry *id3 = id3_get(PLAYING_ID3);
3325 id3->elapsed = elapsed;
3326 id3->offset = offset;
3330 /* Synchronize position info to the codec's */
3331 void audio_pcmbuf_sync_position(void)
3333 audio_pcmbuf_position_callback(ci.id3->elapsed, ci.id3->offset,
3334 pcmbuf_get_position_key());
3337 /* Post message from pcmbuf that the end of the previous track has just
3338 * been played */
3339 void audio_pcmbuf_track_change(bool pcmbuf)
3341 if (pcmbuf)
3343 /* Notify of the change in special-purpose semaphore object */
3344 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
3345 audio_pcmbuf_track_change_post();
3347 else
3349 /* Safe to post directly to the queue */
3350 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
3351 audio_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
3355 /* May pcmbuf start PCM playback when the buffer is full enough? */
3356 bool audio_pcmbuf_may_play(void)
3358 return play_status == PLAY_PLAYING && !ff_rw_mode;
3362 /** -- External interfaces -- **/
3364 /* Return the playback and recording status */
3365 int audio_status(void)
3367 unsigned int ret = play_status;
3369 #ifdef AUDIO_HAVE_RECORDING
3370 /* Do this here for constitency with mpeg.c version */
3371 ret |= pcm_rec_status();
3372 #endif
3374 return (int)ret;
3377 /* Clear all accumulated audio errors for playback and recording */
3378 void audio_error_clear(void)
3380 #ifdef AUDIO_HAVE_RECORDING
3381 pcm_rec_error_clear();
3382 #endif
3385 /* Get a copy of the id3 data for the for current track + offset + skip delta */
3386 bool audio_peek_track(struct mp3entry *id3, int offset)
3388 bool retval = false;
3390 id3_mutex_lock();
3392 if (play_status != PLAY_STOPPED)
3394 id3->path[0] = '\0'; /* Null path means it should be filled now */
3395 retval = audio_get_track_metadata(offset + skip_offset, id3) &&
3396 id3->path[0] != '\0';
3399 id3_mutex_unlock();
3401 return retval;
3404 /* Return the mp3entry for the currently playing track */
3405 struct mp3entry * audio_current_track(void)
3407 struct mp3entry *id3;
3409 id3_mutex_lock();
3411 #ifdef AUDIO_FAST_SKIP_PREVIEW
3412 if (skip_offset != 0)
3414 /* This is a peekahead */
3415 id3 = id3_get(PLAYING_PEEK_ID3);
3416 audio_peek_track(id3, 0);
3418 else
3419 #endif
3421 /* Normal case */
3422 id3 = id3_get(PLAYING_ID3);
3423 audio_get_track_metadata(0, id3);
3426 id3_mutex_unlock();
3428 return id3;
3431 /* Obtains the mp3entry for the next track from the current */
3432 struct mp3entry * audio_next_track(void)
3434 struct mp3entry *id3 = id3_get(NEXTTRACK_ID3);
3436 id3_mutex_lock();
3438 #ifdef AUDIO_FAST_SKIP_PREVIEW
3439 if (skip_offset != 0)
3441 /* This is a peekahead */
3442 if (!audio_peek_track(id3, 1))
3443 id3 = NULL;
3445 else
3446 #endif
3448 /* Normal case */
3449 if (!audio_get_track_metadata(1, id3))
3450 id3 = NULL;
3453 id3_mutex_unlock();
3455 return id3;
3458 /* Start playback at the specified offset */
3459 void audio_play(long offset)
3461 logf("audio_play");
3463 #ifdef PLAYBACK_VOICE
3464 /* Truncate any existing voice output so we don't have spelling
3465 * etc. over the first part of the played track */
3466 talk_force_shutup();
3467 #endif
3469 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
3470 audio_queue_send(Q_AUDIO_PLAY, offset);
3473 /* Stop playback if playing */
3474 void audio_stop(void)
3476 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
3477 audio_queue_send(Q_AUDIO_STOP, 0);
3480 /* Pause playback if playing */
3481 void audio_pause(void)
3483 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
3484 audio_queue_send(Q_AUDIO_PAUSE, true);
3487 /* This sends a stop message and the audio thread will dump all its
3488 subsequent messages */
3489 void audio_hard_stop(void)
3491 /* Stop playback */
3492 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
3493 audio_queue_send(Q_AUDIO_STOP, 1);
3494 #ifdef PLAYBACK_VOICE
3495 voice_stop();
3496 #endif
3497 if (audiobuf_handle > 0)
3498 audiobuf_handle = core_free(audiobuf_handle);
3501 /* Resume playback if paused */
3502 void audio_resume(void)
3504 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
3505 audio_queue_send(Q_AUDIO_PAUSE, false);
3508 /* Skip the specified number of tracks forward or backward from the current */
3509 void audio_skip(int offset)
3511 id3_mutex_lock();
3513 /* If offset has to be backed-out to stay in range, no skip is done */
3514 int accum = skip_offset + offset;
3516 while (offset != 0 && !playlist_check(accum))
3518 offset += offset < 0 ? 1 : -1;
3519 accum = skip_offset + offset;
3522 if (offset != 0)
3524 /* Accumulate net manual skip count since the audio thread last
3525 processed one */
3526 skip_offset = accum;
3528 system_sound_play(SOUND_TRACK_SKIP);
3530 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", offset);
3532 #ifdef AUDIO_FAST_SKIP_PREVIEW
3533 /* Do this before posting so that the audio thread can correct us
3534 when things settle down - additionally, if audio gets a message
3535 and the delta is zero, the Q_AUDIO_SKIP handler (audio_on_skip)
3536 handler a skip event with the correct info but doesn't skip */
3537 send_event(PLAYBACK_EVENT_TRACK_SKIP, NULL);
3538 #endif /* AUDIO_FAST_SKIP_PREVIEW */
3540 /* Playback only needs the final state even if more than one is
3541 processed because it wasn't removed in time */
3542 queue_remove_from_head(&audio_queue, Q_AUDIO_SKIP);
3543 audio_queue_post(Q_AUDIO_SKIP, 0);
3545 else
3547 /* No more tracks */
3548 system_sound_play(SOUND_TRACK_NO_MORE);
3551 id3_mutex_unlock();
3554 /* Skip one track forward from the current */
3555 void audio_next(void)
3557 audio_skip(1);
3560 /* Skip one track backward from the current */
3561 void audio_prev(void)
3563 audio_skip(-1);
3566 /* Move one directory forward */
3567 void audio_next_dir(void)
3569 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
3570 audio_queue_post(Q_AUDIO_DIR_SKIP, 1);
3573 /* Move one directory backward */
3574 void audio_prev_dir(void)
3576 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
3577 audio_queue_post(Q_AUDIO_DIR_SKIP, -1);
3580 /* Pause playback in order to start a seek that flushes the old audio */
3581 void audio_pre_ff_rewind(void)
3583 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
3584 audio_queue_post(Q_AUDIO_PRE_FF_REWIND, 0);
3587 /* Seek to the new time in the current track */
3588 void audio_ff_rewind(long time)
3590 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
3591 audio_queue_post(Q_AUDIO_FF_REWIND, time);
3594 /* Clear all but the currently playing track then rebuffer */
3595 void audio_flush_and_reload_tracks(void)
3597 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
3598 audio_queue_post(Q_AUDIO_FLUSH, 0);
3601 /* Return the pointer to the main audio buffer, optionally preserving
3602 voicing */
3603 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3605 unsigned char *buf;
3607 if (audio_is_initialized)
3609 audio_hard_stop();
3611 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
3613 if (buffer_size == NULL)
3615 /* Special case for talk_init to use since it already knows it's
3616 trashed */
3617 buffer_state = AUDIOBUF_STATE_TRASHED;
3618 return NULL;
3621 /* make sure buffer is freed and re-allocated to simplify code below
3622 * (audio_hard_stop() likely has done that already) */
3623 if (audiobuf_handle > 0)
3624 audiobuf_handle = core_free(audiobuf_handle);
3626 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
3627 buf = core_get_data(audiobuf_handle);
3629 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
3630 || !talk_voice_required())
3632 logf("get buffer: talk, audio");
3633 /* Ok to use everything from audiobuf - voice is loaded,
3634 the talk buffer is not needed because voice isn't being used, or
3635 could be AUDIOBUF_STATE_TRASHED already. If state is
3636 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't
3637 written without the caller knowing what's going on. Changing certain
3638 settings may move it to a worse condition but the memory in use by
3639 something else will remain undisturbed.
3641 if (buffer_state != AUDIOBUF_STATE_TRASHED)
3643 talk_buffer_steal();
3644 buffer_state = AUDIOBUF_STATE_TRASHED;
3647 else
3649 logf("get buffer: audio");
3650 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
3651 still AUDIOBUF_STATE_INITIALIZED */
3652 /* Skip talk buffer and move pcm buffer to end to maximize available
3653 contiguous memory - no audio running means voice will not need the
3654 swap space */
3655 size_t talkbuf_size;
3656 buf += talkbuf_size = talkbuf_init(buf);
3657 filebuflen -= talkbuf_size;
3658 filebuflen -= voicebuf_init(buf + filebuflen);
3660 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
3663 *buffer_size = filebuflen;
3664 return buf;
3667 #ifdef HAVE_RECORDING
3668 /* Stop audio, voice and obtain all available buffer space */
3669 unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3671 audio_hard_stop();
3672 return audio_get_buffer(true, buffer_size);
3674 #endif /* HAVE_RECORDING */
3676 /* Restore audio buffer to a particular state (one more valid than the current
3677 state) */
3678 bool audio_restore_playback(int type)
3680 switch (type)
3682 case AUDIO_WANT_PLAYBACK:
3683 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
3684 audio_reset_buffer();
3685 return true;
3686 case AUDIO_WANT_VOICE:
3687 if (buffer_state == AUDIOBUF_STATE_TRASHED)
3688 audio_reset_buffer();
3689 return true;
3690 default:
3691 return false;
3696 /** --- Miscellaneous public interfaces --- **/
3698 #ifdef HAVE_ALBUMART
3699 /* Return which album art handle is current for the user in the given slot */
3700 int playback_current_aa_hid(int slot)
3702 if ((unsigned)slot < MAX_MULTIPLE_AA)
3704 struct track_info *info = track_list_user_current(skip_offset);
3706 if (!info && abs(skip_offset) <= 1)
3708 /* Give the actual position a go */
3709 info = track_list_user_current(0);
3712 if (info)
3713 return info->aa_hid[slot];
3716 return ERR_HANDLE_NOT_FOUND;
3719 /* Find an album art slot that doesn't match the dimensions of another that
3720 is already claimed - increment the use count if it is */
3721 int playback_claim_aa_slot(struct dim *dim)
3723 int i;
3725 /* First try to find a slot already having the size to reuse it since we
3726 don't want albumart of the same size buffered multiple times */
3727 FOREACH_ALBUMART(i)
3729 struct albumart_slot *slot = &albumart_slots[i];
3731 if (slot->dim.width == dim->width &&
3732 slot->dim.height == dim->height)
3734 slot->used++;
3735 return i;
3739 /* Size is new, find a free slot */
3740 FOREACH_ALBUMART(i)
3742 if (!albumart_slots[i].used)
3744 albumart_slots[i].used++;
3745 albumart_slots[i].dim = *dim;
3746 return i;
3750 /* Sorry, no free slot */
3751 return -1;
3754 /* Invalidate the albumart_slot - decrement the use count if > 0 */
3755 void playback_release_aa_slot(int slot)
3757 if ((unsigned)slot < MAX_MULTIPLE_AA)
3759 struct albumart_slot *aa_slot = &albumart_slots[slot];
3761 if (aa_slot->used > 0)
3762 aa_slot->used--;
3765 #endif /* HAVE_ALBUMART */
3768 #ifdef HAVE_RECORDING
3769 /* Load an encoder and run it */
3770 bool audio_load_encoder(int afmt)
3772 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3773 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3774 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3775 #else
3776 (void)afmt;
3777 return true;
3778 #endif
3781 /* Stop an encoder and unload it */
3782 void audio_remove_encoder(void)
3784 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3785 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3786 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3787 #endif
3789 #endif /* HAVE_RECORDING */
3791 /* Is an automatic skip in progress? If called outside transition callbacks,
3792 indicates the last skip type at the time it was processed and isn't very
3793 meaningful. */
3794 bool audio_automatic_skip(void)
3796 return automatic_skip;
3799 /* Would normally calculate byte offset from an elapsed time but is not
3800 used on SWCODEC */
3801 int audio_get_file_pos(void)
3803 return 0;
3806 /* Return the elapsed time of the track previous to the current */
3807 unsigned long audio_prev_elapsed(void)
3809 return prev_track_elapsed;
3812 /* Return total file buffer length after accounting for the talk buf */
3813 size_t audio_get_filebuflen(void)
3815 return buf_length();
3818 /* How many tracks exist on the buffer - full or partial */
3819 int audio_track_count(void)
3820 __attribute__((alias("track_list_count")));
3822 /* Return total ringbuffer space occupied - ridx to widx */
3823 long audio_filebufused(void)
3825 return buf_used();
3829 /** -- Settings -- **/
3831 /* Enable or disable cuesheet support and allocate/don't allocate the
3832 extra associated resources */
3833 void audio_set_cuesheet(int enable)
3835 if (play_status == PLAY_STOPPED || !enable != !get_current_cuesheet())
3837 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3838 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3842 #ifdef HAVE_DISK_STORAGE
3843 /* Set the audio antiskip buffer margin by index */
3844 void audio_set_buffer_margin(int setting)
3846 static const unsigned short lookup[] =
3847 { 5, 15, 30, 60, 120, 180, 300, 600 };
3849 if ((unsigned)setting >= ARRAYLEN(lookup))
3850 setting = 0;
3852 logf("buffer margin: %u", (unsigned)lookup[setting]);
3854 LOGFQUEUE("audio > audio Q_AUDIO_UPDATE_WATERMARK: %u",
3855 (unsigned)lookup[setting]);
3856 audio_queue_post(Q_AUDIO_UPDATE_WATERMARK, lookup[setting]);
3858 #endif /* HAVE_DISK_STORAGE */
3860 #ifdef HAVE_CROSSFADE
3861 /* Take necessary steps to enable or disable the crossfade setting */
3862 void audio_set_crossfade(int enable)
3864 /* Tell it the next setting to use */
3865 pcmbuf_request_crossfade_enable(enable);
3867 /* Return if size hasn't changed or this is too early to determine
3868 which in the second case there's no way we could be playing
3869 anything at all */
3870 if (!pcmbuf_is_same_size())
3872 LOGFQUEUE("audio >| audio Q_AUDIO_REMAKE_AUDIO_BUFFER");
3873 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
3876 #endif /* HAVE_CROSSFADE */
3879 /** -- Startup -- **/
3881 /* Initialize the audio system - called from init() in main.c */
3882 void audio_init(void)
3884 /* Can never do this twice */
3885 if (audio_is_initialized)
3887 logf("audio: already initialized");
3888 return;
3891 logf("audio: initializing");
3893 /* Initialize queues before giving control elsewhere in case it likes
3894 to send messages. Thread creation will be delayed however so nothing
3895 starts running until ready if something yields such as talk_init. */
3896 queue_init(&audio_queue, true);
3898 mutex_init(&id3_mutex);
3900 pcm_init();
3902 codec_thread_init();
3904 /* This thread does buffer, so match its priority */
3905 audio_thread_id = create_thread(audio_thread, audio_stack,
3906 sizeof(audio_stack), 0, audio_thread_name
3907 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3908 IF_COP(, CPU));
3910 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3911 audio_thread_id);
3913 #ifdef PLAYBACK_VOICE
3914 voice_thread_init();
3915 #endif
3917 /* audio_reset_buffer must know the size of voice buffer so init
3918 talk first */
3919 talk_init();
3921 #ifdef HAVE_CROSSFADE
3922 /* Set crossfade setting for next buffer init which should be about... */
3923 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3924 #endif
3926 /* Initialize the buffering system */
3927 track_list_init();
3928 buffering_init();
3929 /* ...now! Set up the buffers */
3930 audio_reset_buffer();
3932 /* Probably safe to say */
3933 audio_is_initialized = true;
3935 sound_settings_apply();
3936 #ifdef HAVE_DISK_STORAGE
3937 audio_set_buffer_margin(global_settings.buffer_margin);
3938 #endif