Pandora port: Exit rockbox by pressing the SELECT button
[maemo-rb.git] / apps / playback.c
blobdb07613bc87d735d03afdfa70aa0ce93a96259b0
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
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
23 /* TODO: Pause should be handled in here, rather than PCMBUF so that voice can
24 * play whilst audio is paused */
25 #include "config.h"
26 #include "system.h"
27 #include <string.h>
28 #include "playback.h"
29 #include "codec_thread.h"
30 #include "kernel.h"
31 #include "codecs.h"
32 #include "buffering.h"
33 #include "voice_thread.h"
34 #include "usb.h"
35 #include "ata.h"
36 #include "playlist.h"
37 #include "pcmbuf.h"
38 #include "buffer.h"
39 #include "cuesheet.h"
40 #ifdef HAVE_TAGCACHE
41 #include "tagcache.h"
42 #endif
43 #ifdef HAVE_LCD_BITMAP
44 #ifdef HAVE_ALBUMART
45 #include "albumart.h"
46 #endif
47 #endif
48 #include "sound.h"
49 #include "metadata.h"
50 #include "splash.h"
51 #include "talk.h"
52 #include "panic.h"
54 #ifdef HAVE_RECORDING
55 #include "pcm_record.h"
56 #endif
58 #define PLAYBACK_VOICE
60 /* amount of guess-space to allow for codecs that must hunt and peck
61 * for their correct seeek target, 32k seems a good size */
62 #define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
64 /* Define LOGF_ENABLE to enable logf output in this file */
65 /*#define LOGF_ENABLE*/
66 #include "logf.h"
68 /* macros to enable logf for queues
69 logging on SYS_TIMEOUT can be disabled */
70 #ifdef SIMULATOR
71 /* Define this for logf output of all queuing except SYS_TIMEOUT */
72 #define PLAYBACK_LOGQUEUES
73 /* Define this to logf SYS_TIMEOUT messages */
74 /*#define PLAYBACK_LOGQUEUES_SYS_TIMEOUT*/
75 #endif
77 #ifdef PLAYBACK_LOGQUEUES
78 #define LOGFQUEUE logf
79 #else
80 #define LOGFQUEUE(...)
81 #endif
83 #ifdef PLAYBACK_LOGQUEUES_SYS_TIMEOUT
84 #define LOGFQUEUE_SYS_TIMEOUT logf
85 #else
86 #define LOGFQUEUE_SYS_TIMEOUT(...)
87 #endif
90 static enum filling_state {
91 STATE_IDLE, /* audio is stopped: nothing to do */
92 STATE_FILLING, /* adding tracks to the buffer */
93 STATE_FULL, /* can't add any more tracks */
94 STATE_END_OF_PLAYLIST, /* all remaining tracks have been added */
95 STATE_FINISHED, /* all remaining tracks are fully buffered */
96 STATE_ENDING, /* audio playback is ending */
97 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
98 STATE_USB, /* USB mode, ignore most messages */
99 #endif
100 } filling;
102 /* As defined in plugins/lib/xxx2wav.h */
103 #define GUARD_BUFSIZE (32*1024)
105 bool audio_is_initialized = false;
106 static bool audio_thread_ready SHAREDBSS_ATTR = false;
108 /* Variables are commented with the threads that use them: *
109 * A=audio, C=codec, V=voice. A suffix of - indicates that *
110 * the variable is read but not updated on that thread. */
111 /* TBD: Split out "audio" and "playback" (ie. calling) threads */
113 /* Main state control */
114 static volatile bool playing SHAREDBSS_ATTR = false;/* Is audio playing? (A) */
115 static volatile bool paused SHAREDBSS_ATTR = false; /* Is audio paused? (A/C-) */
117 /* Ring buffer where compressed audio and codecs are loaded */
118 static unsigned char *filebuf = NULL; /* Start of buffer (A/C-) */
119 static unsigned char *malloc_buf = NULL; /* Start of malloc buffer (A/C-) */
120 static size_t filebuflen = 0; /* Size of buffer (A/C-) */
121 /* FIXME: make buf_ridx (C/A-) */
123 /* Possible arrangements of the buffer */
124 enum audio_buffer_state
126 AUDIOBUF_STATE_TRASHED = -1, /* trashed; must be reset */
127 AUDIOBUF_STATE_INITIALIZED = 0, /* voice+audio OR audio-only */
128 AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */
130 static int buffer_state = AUDIOBUF_STATE_TRASHED; /* Buffer state */
132 /* These are used to store the current and next (or prev if the current is the last)
133 * mp3entry's in a round-robin system. This guarentees that the pointer returned
134 * by audio_current/next_track will be valid for the full duration of the
135 * currently playing track */
136 static struct mp3entry mp3entry_buf[2];
137 struct mp3entry *thistrack_id3, /* the currently playing track */
138 *othertrack_id3; /* prev track during track-change-transition, or end of playlist,
139 * next track otherwise */
140 static struct mp3entry unbuffered_id3; /* the id3 for the first unbuffered track */
142 /* for cuesheet support */
143 static struct cuesheet *curr_cue = NULL;
146 #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT
148 #ifdef HAVE_ALBUMART
150 static struct albumart_slot {
151 struct dim dim; /* holds width, height of the albumart */
152 int used; /* counter, increments if something uses it */
153 } albumart_slots[MAX_MULTIPLE_AA];
155 #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
156 #endif
159 #define MAX_TRACK 128
160 #define MAX_TRACK_MASK (MAX_TRACK-1)
162 /* Track info structure about songs in the file buffer (A/C-) */
163 static struct track_info {
164 int audio_hid; /* The ID for the track's buffer handle */
165 int id3_hid; /* The ID for the track's metadata handle */
166 int codec_hid; /* The ID for the track's codec handle */
167 #ifdef HAVE_ALBUMART
168 int aa_hid[MAX_MULTIPLE_AA];/* The ID for the track's album art handle */
169 #endif
170 int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */
172 size_t filesize; /* File total length */
174 bool taginfo_ready; /* Is metadata read */
176 } tracks[MAX_TRACK];
178 static volatile int track_ridx = 0; /* Track being decoded (A/C-) */
179 static int track_widx = 0; /* Track being buffered (A) */
180 #define CUR_TI (&tracks[track_ridx]) /* Playing track info pointer (A/C-) */
182 static struct track_info *prev_ti = NULL; /* Pointer to the previously played
183 track */
185 /* Information used only for filling the buffer */
186 /* Playlist steps from playing track to next track to be buffered (A) */
187 static int last_peek_offset = 0;
189 /* Scrobbler support */
190 static unsigned long prev_track_elapsed = 0; /* Previous track elapsed time (C/A-)*/
192 /* Track change controls */
193 static bool automatic_skip = false; /* Who initiated in-progress skip? (A) */
194 extern bool track_transition; /* Are we in a track transition? */
195 static bool dir_skip = false; /* Is a directory skip pending? (A) */
196 static bool new_playlist = false; /* Are we starting a new playlist? (A) */
197 static int wps_offset = 0; /* Pending track change offset, to keep WPS responsive (A) */
198 static bool skipped_during_pause = false; /* Do we need to clear the PCM buffer when playback resumes (A) */
200 static bool start_play_g = false; /* Used by audio_load_track to notify
201 audio_finish_load_track about start_play */
203 /* True when a track load is in progress, i.e. audio_load_track() has returned
204 * but audio_finish_load_track() hasn't been called yet. Used to avoid allowing
205 * audio_load_track() to get called twice in a row, which would cause problems.
207 static bool track_load_started = false;
209 #ifdef HAVE_DISK_STORAGE
210 static size_t buffer_margin = 5; /* Buffer margin aka anti-skip buffer (A/C-) */
211 #endif
213 /* Event queues */
214 struct event_queue audio_queue SHAREDBSS_ATTR;
215 static struct event_queue pcmbuf_queue SHAREDBSS_ATTR;
217 extern struct codec_api ci;
218 extern unsigned int codec_thread_id;
220 /* Multiple threads */
221 /* Set the watermark to trigger buffer fill (A/C) */
222 static void set_filebuf_watermark(void);
224 /* Audio thread */
225 static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
226 static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
227 static const char audio_thread_name[] = "audio";
229 static void audio_thread(void);
230 static void audio_initiate_track_change(long direction);
231 static bool audio_have_tracks(void);
232 static void audio_reset_buffer(void);
233 static void audio_stop_playback(void);
235 /**************************************/
238 /** Pcmbuf callbacks */
240 /* Between the codec and PCM track change, we need to keep updating the
241 * "elapsed" value of the previous (to the codec, but current to the
242 * user/PCM/WPS) track, so that the progressbar reaches the end.
243 * During that transition, the WPS will display othertrack_id3. */
244 void audio_pcmbuf_position_callback(unsigned int time)
246 time += othertrack_id3->elapsed;
247 othertrack_id3->elapsed = (time >= othertrack_id3->length)
248 ? othertrack_id3->length : time;
251 /* Post message from pcmbuf that the end of the previous track
252 * has just been played. */
253 void audio_post_track_change(bool pcmbuf)
255 if (pcmbuf)
257 LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
258 queue_post(&pcmbuf_queue, Q_AUDIO_TRACK_CHANGED, 0);
260 else
262 LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
263 queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
267 /* Scan the pcmbuf queue and return true if a message pulled */
268 static bool pcmbuf_queue_scan(struct queue_event *ev)
270 if (!queue_empty(&pcmbuf_queue))
272 /* Transfer message to audio queue */
273 pcm_play_lock();
274 /* Pull message - never, ever any blocking call! */
275 queue_wait_w_tmo(&pcmbuf_queue, ev, 0);
276 pcm_play_unlock();
277 return true;
280 return false;
284 /** Helper functions */
286 static struct mp3entry *bufgetid3(int handle_id)
288 if (handle_id < 0)
289 return NULL;
291 struct mp3entry *id3;
292 ssize_t ret = bufgetdata(handle_id, 0, (void *)&id3);
294 if (ret != sizeof(struct mp3entry))
295 return NULL;
297 return id3;
300 static bool bufreadid3(int handle_id, struct mp3entry *id3out)
302 struct mp3entry *id3 = bufgetid3(handle_id);
304 if (id3)
306 copy_mp3entry(id3out, id3);
307 return true;
310 return false;
313 static bool clear_track_info(struct track_info *track)
315 /* bufclose returns true if the handle is not found, or if it is closed
316 * successfully, so these checks are safe on non-existant handles */
317 if (!track)
318 return false;
320 if (track->codec_hid >= 0) {
321 if (bufclose(track->codec_hid))
322 track->codec_hid = -1;
323 else
324 return false;
327 if (track->id3_hid >= 0) {
328 if (bufclose(track->id3_hid))
329 track->id3_hid = -1;
330 else
331 return false;
334 if (track->audio_hid >= 0) {
335 if (bufclose(track->audio_hid))
336 track->audio_hid = -1;
337 else
338 return false;
341 #ifdef HAVE_ALBUMART
343 int i;
344 FOREACH_ALBUMART(i)
346 if (track->aa_hid[i] >= 0) {
347 if (bufclose(track->aa_hid[i]))
348 track->aa_hid[i] = -1;
349 else
350 return false;
354 #endif
356 if (track->cuesheet_hid >= 0) {
357 if (bufclose(track->cuesheet_hid))
358 track->cuesheet_hid = -1;
359 else
360 return false;
363 track->filesize = 0;
364 track->taginfo_ready = false;
366 return true;
369 /* --- External interfaces --- */
371 /* This sends a stop message and the audio thread will dump all it's
372 subsequenct messages */
373 void audio_hard_stop(void)
375 /* Stop playback */
376 LOGFQUEUE("audio >| audio Q_AUDIO_STOP: 1");
377 queue_send(&audio_queue, Q_AUDIO_STOP, 1);
378 #ifdef PLAYBACK_VOICE
379 voice_stop();
380 #endif
383 bool audio_restore_playback(int type)
385 switch (type)
387 case AUDIO_WANT_PLAYBACK:
388 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
389 audio_reset_buffer();
390 return true;
391 case AUDIO_WANT_VOICE:
392 if (buffer_state == AUDIOBUF_STATE_TRASHED)
393 audio_reset_buffer();
394 return true;
395 default:
396 return false;
400 unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size)
402 unsigned char *buf, *end;
404 if (audio_is_initialized)
406 audio_hard_stop();
408 /* else buffer_state will be AUDIOBUF_STATE_TRASHED at this point */
410 /* Reset the buffering thread so that it doesn't try to use the data */
411 buffering_reset(filebuf, filebuflen);
413 if (buffer_size == NULL)
415 /* Special case for talk_init to use since it already knows it's
416 trashed */
417 buffer_state = AUDIOBUF_STATE_TRASHED;
418 return NULL;
421 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
422 || !talk_voice_required())
424 logf("get buffer: talk, audio");
425 /* Ok to use everything from audiobuf to audiobufend - voice is loaded,
426 the talk buffer is not needed because voice isn't being used, or
427 could be AUDIOBUF_STATE_TRASHED already. If state is
428 AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't written
429 without the caller knowing what's going on. Changing certain settings
430 may move it to a worse condition but the memory in use by something
431 else will remain undisturbed.
433 if (buffer_state != AUDIOBUF_STATE_TRASHED)
435 talk_buffer_steal();
436 buffer_state = AUDIOBUF_STATE_TRASHED;
439 buf = audiobuf;
440 end = audiobufend;
442 else
444 /* Safe to just return this if already AUDIOBUF_STATE_VOICED_ONLY or
445 still AUDIOBUF_STATE_INITIALIZED */
446 /* Skip talk buffer and move pcm buffer to end to maximize available
447 contiguous memory - no audio running means voice will not need the
448 swap space */
449 logf("get buffer: audio");
450 buf = audiobuf + talk_get_bufsize();
451 end = audiobufend - pcmbuf_init(audiobufend);
452 buffer_state = AUDIOBUF_STATE_VOICED_ONLY;
455 *buffer_size = end - buf;
457 return buf;
460 bool audio_buffer_state_trashed(void)
462 return buffer_state == AUDIOBUF_STATE_TRASHED;
465 #ifdef HAVE_RECORDING
466 unsigned char *audio_get_recording_buffer(size_t *buffer_size)
468 /* Stop audio, voice and obtain all available buffer space */
469 audio_hard_stop();
470 talk_buffer_steal();
472 unsigned char *end = audiobufend;
473 buffer_state = AUDIOBUF_STATE_TRASHED;
474 *buffer_size = end - audiobuf;
476 return (unsigned char *)audiobuf;
479 bool audio_load_encoder(int afmt)
481 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
482 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
483 return queue_send(&audio_queue, Q_AUDIO_LOAD_ENCODER, afmt) > 0;
484 #else
485 (void)afmt;
486 return true;
487 #endif
488 } /* audio_load_encoder */
490 void audio_remove_encoder(void)
492 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
493 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
494 queue_send(&audio_queue, Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
495 #endif
496 } /* audio_remove_encoder */
498 #endif /* HAVE_RECORDING */
501 struct mp3entry* audio_current_track(void)
503 const char *filename;
504 struct playlist_track_info trackinfo;
505 int cur_idx;
506 int offset = ci.new_track + wps_offset;
507 struct mp3entry *write_id3;
509 cur_idx = (track_ridx + offset) & MAX_TRACK_MASK;
511 if (cur_idx == track_ridx && *thistrack_id3->path)
513 /* The usual case */
514 if (tracks[cur_idx].cuesheet_hid >= 0 && !thistrack_id3->cuesheet)
516 bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
517 thistrack_id3->cuesheet = curr_cue;
519 return thistrack_id3;
521 else if (automatic_skip && offset == -1 && *othertrack_id3->path)
523 /* We're in a track transition. The codec has moved on to the next track,
524 but the audio being played is still the same (now previous) track.
525 othertrack_id3.elapsed is being updated in an ISR by
526 codec_pcmbuf_position_callback */
527 if (tracks[cur_idx].cuesheet_hid >= 0 && !thistrack_id3->cuesheet)
529 bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
530 othertrack_id3->cuesheet = curr_cue;
532 return othertrack_id3;
535 if (offset != 0)
537 /* Codec may be using thistrack_id3, so it must not be overwritten.
538 If this is a manual skip, othertrack_id3 will become
539 thistrack_id3 in audio_check_new_track().
540 FIXME: If this is an automatic skip, it probably means multiple
541 short tracks fit in the PCM buffer. Overwriting othertrack_id3
542 can lead to an incorrect value later.
543 Note that othertrack_id3 may also be used for next track.
545 write_id3 = othertrack_id3;
547 else
549 write_id3 = thistrack_id3;
552 if (tracks[cur_idx].id3_hid >= 0)
554 /* The current track's info has been buffered but not read yet, so get it */
555 if (bufreadid3(tracks[cur_idx].id3_hid, write_id3))
556 return write_id3;
559 /* We didn't find the ID3 metadata, so we fill temp_id3 with the little info
560 we have and return that. */
562 memset(write_id3, 0, sizeof(struct mp3entry));
564 playlist_get_track_info(NULL, playlist_next(0)+wps_offset, &trackinfo);
565 filename = trackinfo.filename;
566 if (!filename)
567 filename = "No file!";
569 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
570 if (tagcache_fill_tags(write_id3, filename))
571 return write_id3;
572 #endif
574 strlcpy(write_id3->path, filename, sizeof(write_id3->path));
575 write_id3->title = strrchr(write_id3->path, '/');
576 if (!write_id3->title)
577 write_id3->title = &write_id3->path[0];
578 else
579 write_id3->title++;
581 return write_id3;
584 struct mp3entry* audio_next_track(void)
586 int next_idx;
587 int offset = ci.new_track + wps_offset;
589 if (!audio_have_tracks())
590 return NULL;
592 if (wps_offset == -1 && *thistrack_id3->path)
594 /* We're in a track transition. The next track for the WPS is the one
595 currently being decoded. */
596 return thistrack_id3;
599 next_idx = (track_ridx + offset + 1) & MAX_TRACK_MASK;
601 if (tracks[next_idx].id3_hid >= 0)
603 if (bufreadid3(tracks[next_idx].id3_hid, othertrack_id3))
604 return othertrack_id3;
605 else
606 return NULL;
609 if (next_idx == track_widx)
611 /* The next track hasn't been buffered yet, so we return the static
612 version of its metadata. */
613 return &unbuffered_id3;
616 return NULL;
619 /* gets a copy of the id3 data */
620 bool audio_peek_track(struct mp3entry* id3, int offset)
622 int next_idx;
623 int new_offset = ci.new_track + wps_offset + offset;
625 if (!audio_have_tracks())
626 return false;
627 next_idx = (track_ridx + new_offset) & MAX_TRACK_MASK;
629 if (tracks[next_idx].id3_hid >= 0)
630 return bufreadid3(tracks[next_idx].id3_hid, id3);
632 return false;
635 #ifdef HAVE_ALBUMART
637 int playback_current_aa_hid(int slot)
639 if (slot < 0)
640 return -1;
641 int cur_idx;
642 int offset = ci.new_track + wps_offset;
644 cur_idx = track_ridx + offset;
645 cur_idx &= MAX_TRACK_MASK;
646 return tracks[cur_idx].aa_hid[slot];
649 int playback_claim_aa_slot(struct dim *dim)
651 int i;
653 /* first try to find a slot already having the size to reuse it
654 * since we don't want albumart of the same size buffered multiple times */
655 FOREACH_ALBUMART(i)
657 struct albumart_slot *slot = &albumart_slots[i];
658 if (slot->dim.width == dim->width
659 && slot->dim.height == dim->height)
661 slot->used++;
662 return i;
665 /* size is new, find a free slot */
666 FOREACH_ALBUMART(i)
668 if (!albumart_slots[i].used)
670 albumart_slots[i].used++;
671 albumart_slots[i].dim = *dim;
672 return i;
675 /* sorry, no free slot */
676 return -1;
679 void playback_release_aa_slot(int slot)
681 /* invalidate the albumart_slot */
682 struct albumart_slot *aa_slot = &albumart_slots[slot];
684 if (aa_slot->used > 0)
685 aa_slot->used--;
688 #endif
689 void audio_play(long offset)
691 logf("audio_play");
693 #ifdef PLAYBACK_VOICE
694 /* Truncate any existing voice output so we don't have spelling
695 * etc. over the first part of the played track */
696 talk_force_shutup();
697 #endif
699 /* Start playback */
700 LOGFQUEUE("audio >| audio Q_AUDIO_PLAY: %ld", offset);
701 /* Don't return until playback has actually started */
702 queue_send(&audio_queue, Q_AUDIO_PLAY, offset);
705 void audio_stop(void)
707 /* Stop playback */
708 LOGFQUEUE("audio >| audio Q_AUDIO_STOP");
709 /* Don't return until playback has actually stopped */
710 queue_send(&audio_queue, Q_AUDIO_STOP, 0);
713 void audio_pause(void)
715 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE");
716 /* Don't return until playback has actually paused */
717 queue_send(&audio_queue, Q_AUDIO_PAUSE, true);
720 void audio_resume(void)
722 LOGFQUEUE("audio >| audio Q_AUDIO_PAUSE resume");
723 /* Don't return until playback has actually resumed */
724 queue_send(&audio_queue, Q_AUDIO_PAUSE, false);
727 void audio_skip(int direction)
729 if (playlist_check(ci.new_track + wps_offset + direction))
731 if (global_settings.beep)
732 pcmbuf_beep(2000, 100, 2500*global_settings.beep);
734 LOGFQUEUE("audio > audio Q_AUDIO_SKIP %d", direction);
735 queue_post(&audio_queue, Q_AUDIO_SKIP, direction);
736 /* Update wps while our message travels inside deep playback queues. */
737 wps_offset += direction;
739 else
741 /* No more tracks. */
742 if (global_settings.beep)
743 pcmbuf_beep(1000, 100, 1500*global_settings.beep);
747 void audio_next(void)
749 audio_skip(1);
752 void audio_prev(void)
754 audio_skip(-1);
757 void audio_next_dir(void)
759 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP 1");
760 queue_post(&audio_queue, Q_AUDIO_DIR_SKIP, 1);
763 void audio_prev_dir(void)
765 LOGFQUEUE("audio > audio Q_AUDIO_DIR_SKIP -1");
766 queue_post(&audio_queue, Q_AUDIO_DIR_SKIP, -1);
769 void audio_pre_ff_rewind(void)
771 LOGFQUEUE("audio > audio Q_AUDIO_PRE_FF_REWIND");
772 queue_post(&audio_queue, Q_AUDIO_PRE_FF_REWIND, 0);
775 void audio_ff_rewind(long newpos)
777 LOGFQUEUE("audio > audio Q_AUDIO_FF_REWIND");
778 queue_post(&audio_queue, Q_AUDIO_FF_REWIND, newpos);
781 void audio_flush_and_reload_tracks(void)
783 LOGFQUEUE("audio > audio Q_AUDIO_FLUSH");
784 queue_post(&audio_queue, Q_AUDIO_FLUSH, 0);
787 void audio_error_clear(void)
789 #ifdef AUDIO_HAVE_RECORDING
790 pcm_rec_error_clear();
791 #endif
794 int audio_status(void)
796 int ret = 0;
798 if (playing)
799 ret |= AUDIO_STATUS_PLAY;
801 if (paused)
802 ret |= AUDIO_STATUS_PAUSE;
804 #ifdef HAVE_RECORDING
805 /* Do this here for constitency with mpeg.c version */
806 /* FIXME: pcm_rec_status() is deprecated */
807 ret |= pcm_rec_status();
808 #endif
810 return ret;
813 bool audio_automatic_skip(void)
815 return automatic_skip;
818 int audio_get_file_pos(void)
820 return 0;
823 #ifdef HAVE_DISK_STORAGE
824 void audio_set_buffer_margin(int setting)
826 static const unsigned short lookup[] = {5, 15, 30, 60, 120, 180, 300, 600};
827 buffer_margin = lookup[setting];
828 logf("buffer margin: %ld", (long)buffer_margin);
829 set_filebuf_watermark();
831 #endif
833 #ifdef HAVE_CROSSFADE
834 /* Take necessary steps to enable or disable the crossfade setting */
835 void audio_set_crossfade(int enable)
837 size_t offset;
838 bool was_playing;
839 size_t size;
841 /* Tell it the next setting to use */
842 pcmbuf_request_crossfade_enable(enable);
844 /* Return if size hasn't changed or this is too early to determine
845 which in the second case there's no way we could be playing
846 anything at all */
847 if (pcmbuf_is_same_size()) return;
849 offset = 0;
850 was_playing = playing;
852 /* Playback has to be stopped before changing the buffer size */
853 if (was_playing)
855 /* Store the track resume position */
856 offset = thistrack_id3->offset;
859 /* Blast it - audio buffer will have to be setup again next time
860 something plays */
861 audio_get_buffer(true, &size);
863 /* Restart playback if audio was running previously */
864 if (was_playing)
865 audio_play(offset);
867 #endif
869 /* --- Routines called from multiple threads --- */
871 static void set_filebuf_watermark(void)
873 if (!filebuf)
874 return; /* Audio buffers not yet set up */
876 #ifdef HAVE_DISK_STORAGE
877 int seconds;
878 int spinup = ata_spinup_time();
879 if (spinup)
880 seconds = (spinup / HZ) + 1;
881 else
882 seconds = 5;
884 seconds += buffer_margin;
885 #else
886 /* flash storage */
887 int seconds = 1;
888 #endif
890 /* bitrate of last track in buffer dictates watermark */
891 struct mp3entry* id3 = NULL;
892 if (tracks[track_widx].taginfo_ready)
893 id3 = bufgetid3(tracks[track_widx].id3_hid);
894 else
895 id3 = bufgetid3(tracks[track_widx-1].id3_hid);
896 if (!id3) {
897 logf("fwmark: No id3 for last track (r%d/w%d), aborting!", track_ridx, track_widx);
898 return;
900 size_t bytes = id3->bitrate * (1000/8) * seconds;
901 buf_set_watermark(bytes);
902 logf("fwmark: %d", bytes);
905 /* --- Buffering callbacks --- */
907 static void buffering_low_buffer_callback(void *data)
909 (void)data;
910 logf("low buffer callback");
912 if (filling == STATE_FULL || filling == STATE_END_OF_PLAYLIST) {
913 /* force a refill */
914 LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");
915 queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
919 static void buffering_handle_rebuffer_callback(void *data)
921 (void)data;
922 LOGFQUEUE("audio >| audio Q_AUDIO_FLUSH");
923 queue_post(&audio_queue, Q_AUDIO_FLUSH, 0);
926 static void buffering_handle_finished_callback(void *data)
928 logf("handle %d finished buffering", *(int*)data);
929 int hid = (*(int*)data);
931 if (hid == tracks[track_widx].id3_hid)
933 int offset = ci.new_track + wps_offset;
934 int next_idx = (track_ridx + offset + 1) & MAX_TRACK_MASK;
935 /* The metadata handle for the last loaded track has been buffered.
936 We can ask the audio thread to load the rest of the track's data. */
937 LOGFQUEUE("audio > audio Q_AUDIO_FINISH_LOAD");
938 queue_post(&audio_queue, Q_AUDIO_FINISH_LOAD, 0);
939 if (tracks[next_idx].id3_hid == hid)
940 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
942 else
944 /* This is most likely an audio handle, so we strip the useless
945 trailing tags that are left. */
946 strip_tags(hid);
948 if (hid == tracks[track_widx-1].audio_hid
949 && filling == STATE_END_OF_PLAYLIST)
951 /* This was the last track in the playlist.
952 We now have all the data we need. */
953 logf("last track finished buffering");
954 filling = STATE_FINISHED;
960 /* --- Audio thread --- */
962 static bool audio_have_tracks(void)
964 return (audio_track_count() != 0);
967 static int audio_free_track_count(void)
969 /* Used tracks + free tracks adds up to MAX_TRACK - 1 */
970 return MAX_TRACK - 1 - audio_track_count();
973 int audio_track_count(void)
975 /* Calculate difference from track_ridx to track_widx
976 * taking into account a possible wrap-around. */
977 return (MAX_TRACK + track_widx - track_ridx) & MAX_TRACK_MASK;
980 long audio_filebufused(void)
982 return (long) buf_used();
985 /* Update track info after successful a codec track change */
986 static void audio_update_trackinfo(void)
988 bool resume = false;
990 /* Load the curent track's metadata into curtrack_id3 */
991 if (CUR_TI->id3_hid >= 0)
992 bufreadid3(CUR_TI->id3_hid, thistrack_id3);
994 /* Reset current position */
995 thistrack_id3->elapsed = 0;
997 #ifdef HAVE_TAGCACHE
998 /* Ignoring resume position for automatic track change if so configured */
999 resume = global_settings.autoresume_enable &&
1000 (!automatic_skip /* Resume all manually selected tracks */
1001 || global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_ALWAYS
1002 || (global_settings.autoresume_automatic != AUTORESUME_NEXTTRACK_NEVER
1003 /* Not never resume? */
1004 && autoresumable(thistrack_id3))); /* Pass Resume filter? */
1005 #endif
1007 if (!resume)
1009 thistrack_id3->offset = 0;
1012 logf("audio_update_trackinfo: Set offset for %s to %lX\n",
1013 thistrack_id3->title, thistrack_id3->offset);
1015 /* Update the codec API */
1016 ci.filesize = CUR_TI->filesize;
1017 ci.id3 = thistrack_id3;
1018 ci.curpos = 0;
1019 ci.taginfo_ready = &CUR_TI->taginfo_ready;
1022 /* Clear tracks between write and read, non inclusive */
1023 static void audio_clear_track_entries(void)
1025 int cur_idx = track_widx;
1027 logf("Clearing tracks: r%d/w%d", track_ridx, track_widx);
1029 /* Loop over all tracks from write-to-read */
1030 while (1)
1032 cur_idx = (cur_idx + 1) & MAX_TRACK_MASK;
1034 if (cur_idx == track_ridx)
1035 break;
1037 clear_track_info(&tracks[cur_idx]);
1041 /* Clear all tracks */
1042 static bool audio_release_tracks(void)
1044 int i, cur_idx;
1046 logf("releasing all tracks");
1048 for(i = 0; i < MAX_TRACK; i++)
1050 cur_idx = (track_ridx + i) & MAX_TRACK_MASK;
1051 if (!clear_track_info(&tracks[cur_idx]))
1052 return false;
1055 return true;
1058 static bool audio_loadcodec(bool start_play)
1060 int prev_track, hid;
1061 char codec_path[MAX_PATH]; /* Full path to codec */
1062 const struct mp3entry *id3, *prev_id3;
1064 if (tracks[track_widx].id3_hid < 0) {
1065 return false;
1068 id3 = bufgetid3(tracks[track_widx].id3_hid);
1069 if (!id3)
1070 return false;
1072 const char *codec_fn = get_codec_filename(id3->codectype);
1073 if (codec_fn == NULL)
1074 return false;
1076 tracks[track_widx].codec_hid = -1;
1078 if (start_play)
1080 /* Load the codec directly from disk and save some memory. */
1081 track_ridx = track_widx;
1082 ci.filesize = CUR_TI->filesize;
1083 ci.id3 = thistrack_id3;
1084 ci.taginfo_ready = &CUR_TI->taginfo_ready;
1085 ci.curpos = 0;
1086 return codec_load(-1, id3->codectype);
1088 else
1090 /* If we already have another track than this one buffered */
1091 if (track_widx != track_ridx)
1093 prev_track = (track_widx - 1) & MAX_TRACK_MASK;
1095 id3 = bufgetid3(tracks[track_widx].id3_hid);
1096 prev_id3 = bufgetid3(tracks[prev_track].id3_hid);
1098 /* If the previous codec is the same as this one and the current
1099 * one is the correct one, there is no need to put another copy of
1100 * it on the file buffer */
1101 if (id3 && prev_id3)
1103 int codt = get_codec_base_type(id3->codectype);
1104 int prev_codt = get_codec_base_type(prev_id3->codectype);
1105 int cod_loaded = get_codec_base_type(codec_loaded());
1107 if (codt == prev_codt && codt == cod_loaded)
1109 logf("Reusing prev. codec");
1110 return true;
1116 codec_get_full_path(codec_path, codec_fn);
1118 hid = tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1120 /* not an error if codec load it supported, will load it from disk
1121 * application builds don't support it
1123 if (hid < 0 && hid != ERR_UNSUPPORTED_TYPE)
1124 return false;
1126 if (hid >= 0)
1127 logf("Loaded codec");
1128 else
1129 logf("Buffering codec unsupported, load later from disk");
1131 return true;
1134 /* Load metadata for the next track (with bufopen). The rest of the track
1135 loading will be handled by audio_finish_load_track once the metadata has been
1136 actually loaded by the buffering thread. */
1137 static bool audio_load_track(size_t offset, bool start_play)
1139 char name_buf[MAX_PATH + 1];
1140 const char *trackname;
1141 int fd = -1;
1143 if (track_load_started) {
1144 /* There is already a track load in progress, so track_widx hasn't been
1145 incremented yet. Loading another track would overwrite the one that
1146 hasn't finished loading. */
1147 logf("audio_load_track(): a track load is already in progress");
1148 return false;
1151 start_play_g = start_play; /* will be read by audio_finish_load_track */
1153 /* Stop buffer filling if there is no free track entries.
1154 Don't fill up the last track entry (we wan't to store next track
1155 metadata there). */
1156 if (!audio_free_track_count())
1158 logf("No free tracks");
1159 return false;
1162 last_peek_offset++;
1163 tracks[track_widx].taginfo_ready = false;
1165 logf("Buffering track: r%d/w%d", track_ridx, track_widx);
1166 /* Get track name from current playlist read position. */
1167 while ((trackname = playlist_peek(last_peek_offset, name_buf,
1168 sizeof(name_buf))) != NULL)
1170 /* Handle broken playlists. */
1171 fd = open(trackname, O_RDONLY);
1172 if (fd < 0)
1174 logf("Open failed");
1175 /* Skip invalid entry from playlist. */
1176 playlist_skip_entry(NULL, last_peek_offset);
1178 else
1179 break;
1182 if (!trackname)
1184 logf("End-of-playlist");
1185 memset(&unbuffered_id3, 0, sizeof(struct mp3entry));
1186 filling = STATE_END_OF_PLAYLIST;
1188 if (thistrack_id3->length == 0 && thistrack_id3->filesize == 0)
1190 /* Stop playback if no valid track was found. */
1191 audio_stop_playback();
1194 return false;
1197 tracks[track_widx].filesize = filesize(fd);
1199 if (offset > tracks[track_widx].filesize)
1200 offset = 0;
1202 /* Set default values */
1203 if (start_play)
1205 buf_set_watermark(filebuflen/2);
1206 dsp_configure(ci.dsp, DSP_RESET, 0);
1207 playlist_update_resume_info(audio_current_track());
1210 /* Get track metadata if we don't already have it. */
1211 if (tracks[track_widx].id3_hid < 0)
1213 tracks[track_widx].id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL);
1215 if (tracks[track_widx].id3_hid < 0)
1217 /* Buffer is full. */
1218 get_metadata(&unbuffered_id3, fd, trackname);
1219 last_peek_offset--;
1220 close(fd);
1221 logf("buffer is full for now (get metadata)");
1222 filling = STATE_FULL;
1223 return false;
1226 if (track_widx == track_ridx)
1228 /* TODO: Superfluos buffering call? */
1229 buf_request_buffer_handle(tracks[track_widx].id3_hid);
1230 if (bufreadid3(tracks[track_widx].id3_hid, thistrack_id3))
1232 thistrack_id3->offset = offset;
1233 logf("audio_load_track: set offset for %s to %lX\n",
1234 thistrack_id3->title,
1235 offset);
1237 else
1238 memset(thistrack_id3, 0, sizeof(struct mp3entry));
1241 if (start_play)
1243 playlist_update_resume_info(audio_current_track());
1247 close(fd);
1248 track_load_started = true; /* Remember that we've started loading a track */
1249 return true;
1252 #ifdef HAVE_ALBUMART
1253 /* Load any album art for the file */
1254 static void audio_load_albumart(struct mp3entry *track_id3)
1256 int i;
1258 FOREACH_ALBUMART(i)
1260 struct bufopen_bitmap_data user_data;
1261 int hid = ERR_HANDLE_NOT_FOUND;
1263 /* albumart_slots may change during a yield of bufopen,
1264 * but that's no problem */
1265 if (tracks[track_widx].aa_hid[i] >= 0 || !albumart_slots[i].used)
1266 continue;
1268 memset(&user_data, 0, sizeof(user_data));
1269 user_data.dim = &(albumart_slots[i].dim);
1271 /* we can only decode jpeg for embedded AA */
1272 if (track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG)
1274 user_data.embedded_albumart = &(track_id3->albumart);
1275 hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data);
1278 if (hid < 0 && hid != ERR_BUFFER_FULL)
1280 /* no embedded AA or it couldn't be loaded, try other sources */
1281 char path[MAX_PATH];
1283 if (find_albumart(track_id3, path, sizeof(path),
1284 &(albumart_slots[i].dim)))
1286 user_data.embedded_albumart = NULL;
1287 hid = bufopen(path, 0, TYPE_BITMAP, &user_data);
1291 if (hid == ERR_BUFFER_FULL)
1293 filling = STATE_FULL;
1294 logf("buffer is full for now (get album art)");
1296 else if (hid < 0)
1298 logf("Album art loading failed");
1301 tracks[track_widx].aa_hid[i] = hid;
1304 #endif
1306 /* Second part of the track loading: We now have the metadata available, so we
1307 can load the codec, the album art and finally the audio data.
1308 This is called on the audio thread after the buffering thread calls the
1309 buffering_handle_finished_callback callback. */
1310 static void audio_finish_load_track(void)
1312 size_t file_offset = 0;
1313 size_t offset = 0;
1314 bool start_play = start_play_g;
1316 track_load_started = false;
1318 if (tracks[track_widx].id3_hid < 0) {
1319 logf("No metadata");
1320 return;
1323 struct mp3entry *track_id3;
1325 if (track_widx == track_ridx)
1326 track_id3 = thistrack_id3;
1327 else
1328 track_id3 = bufgetid3(tracks[track_widx].id3_hid);
1330 if (track_id3->length == 0 && track_id3->filesize == 0)
1332 logf("audio_finish_load_track: invalid metadata");
1334 /* Invalid metadata */
1335 bufclose(tracks[track_widx].id3_hid);
1336 tracks[track_widx].id3_hid = -1;
1338 /* Skip invalid entry from playlist. */
1339 playlist_skip_entry(NULL, last_peek_offset--);
1341 /* load next track */
1342 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER %d", (int)start_play);
1343 queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, start_play);
1345 return;
1347 /* Try to load a cuesheet for the track */
1348 if (curr_cue)
1350 char cuepath[MAX_PATH];
1351 if (look_for_cuesheet_file(track_id3->path, cuepath))
1353 void *temp;
1354 tracks[track_widx].cuesheet_hid =
1355 bufalloc(NULL, sizeof(struct cuesheet), TYPE_CUESHEET);
1356 if (tracks[track_widx].cuesheet_hid >= 0)
1358 bufgetdata(tracks[track_widx].cuesheet_hid,
1359 sizeof(struct cuesheet), &temp);
1360 struct cuesheet *cuesheet = (struct cuesheet*)temp;
1361 if (!parse_cuesheet(cuepath, cuesheet))
1363 bufclose(tracks[track_widx].cuesheet_hid);
1364 track_id3->cuesheet = NULL;
1370 #ifdef HAVE_ALBUMART
1371 audio_load_albumart(track_id3);
1372 #endif
1374 /* Load the codec. */
1375 if (!audio_loadcodec(start_play))
1377 if (tracks[track_widx].codec_hid == ERR_BUFFER_FULL)
1379 /* No space for codec on buffer, not an error */
1380 filling = STATE_FULL;
1381 return;
1384 /* This is an error condition, either no codec was found, or reading
1385 * the codec file failed part way through, either way, skip the track */
1386 /* FIXME: We should not use splashf from audio thread! */
1387 splashf(HZ*2, "No codec for: %s", track_id3->path);
1388 /* Skip invalid entry from playlist. */
1389 playlist_skip_entry(NULL, last_peek_offset);
1390 return;
1393 track_id3->elapsed = 0;
1394 offset = track_id3->offset;
1395 size_t resume_rewind = (global_settings.resume_rewind *
1396 track_id3->bitrate * 1000) / 8;
1398 if (offset < resume_rewind)
1400 offset = 0;
1402 else
1404 offset -= resume_rewind;
1407 enum data_type type = TYPE_PACKET_AUDIO;
1409 switch (track_id3->codectype) {
1410 case AFMT_MPA_L1:
1411 case AFMT_MPA_L2:
1412 case AFMT_MPA_L3:
1413 if (offset > 0) {
1414 file_offset = offset;
1416 break;
1418 case AFMT_WAVPACK:
1419 if (offset > 0) {
1420 file_offset = offset;
1421 track_id3->elapsed = track_id3->length / 2;
1423 break;
1425 case AFMT_NSF:
1426 case AFMT_SPC:
1427 case AFMT_SID:
1428 logf("Loading atomic %d",track_id3->codectype);
1429 type = TYPE_ATOMIC_AUDIO;
1430 break;
1432 default:
1433 /* no special treatment needed */
1434 break;
1437 track_id3->offset = offset;
1439 logf("load track: %s", track_id3->path);
1441 if (file_offset > AUDIO_REBUFFER_GUESS_SIZE)
1442 file_offset -= AUDIO_REBUFFER_GUESS_SIZE;
1443 else if (track_id3->first_frame_offset)
1444 file_offset = track_id3->first_frame_offset;
1445 else
1446 file_offset = 0;
1448 tracks[track_widx].audio_hid = bufopen(track_id3->path, file_offset, type,
1449 NULL);
1451 /* No space left, not an error */
1452 if (tracks[track_widx].audio_hid == ERR_BUFFER_FULL)
1454 filling = STATE_FULL;
1455 logf("buffer is full for now (load audio)");
1456 return;
1458 else if (tracks[track_widx].audio_hid < 0)
1460 /* another error, do not continue either */
1461 logf("Could not add audio data handle");
1462 return;
1465 /* All required data is now available for the codec -- unless the
1466 autoresume feature is in effect. In the latter case, the codec
1467 must wait until after PLAYBACK_EVENT_TRACK_BUFFER, which may
1468 generate a resume position. */
1469 #ifdef HAVE_TAGCACHE
1470 if (! global_settings.autoresume_enable)
1471 #endif
1472 tracks[track_widx].taginfo_ready = true;
1474 if (start_play)
1476 ci.curpos=file_offset;
1477 buf_request_buffer_handle(tracks[track_widx].audio_hid);
1480 send_event(PLAYBACK_EVENT_TRACK_BUFFER, track_id3);
1482 #ifdef HAVE_TAGCACHE
1483 /* In case the autoresume feature has been enabled, finally all
1484 required data is available for the codec. */
1485 if (global_settings.autoresume_enable)
1486 tracks[track_widx].taginfo_ready = true;
1487 #endif
1489 track_widx = (track_widx + 1) & MAX_TRACK_MASK;
1491 /* load next track */
1492 LOGFQUEUE("audio > audio Q_AUDIO_FILL_BUFFER");
1493 queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
1495 return;
1498 static void audio_fill_file_buffer(bool start_play, size_t offset)
1500 trigger_cpu_boost();
1502 /* No need to rebuffer if there are track skips pending,
1503 * however don't cancel buffering on skipping while filling. */
1504 if (ci.new_track != 0 && filling != STATE_FILLING)
1505 return;
1506 filling = STATE_FILLING;
1508 /* Must reset the buffer before use if trashed or voice only - voice
1509 file size shouldn't have changed so we can go straight from
1510 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1511 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1512 audio_reset_buffer();
1514 logf("Starting buffer fill");
1516 if (!start_play)
1517 audio_clear_track_entries();
1519 /* Save the current resume position once. */
1520 playlist_update_resume_info(audio_current_track());
1522 audio_load_track(offset, start_play);
1525 static void audio_rebuffer(void)
1527 logf("Forcing rebuffer");
1529 clear_track_info(CUR_TI);
1531 /* Reset track pointers */
1532 track_widx = track_ridx;
1533 audio_clear_track_entries();
1535 /* Reset a possibly interrupted track load */
1536 track_load_started = false;
1538 /* Fill the buffer */
1539 last_peek_offset = -1;
1540 ci.curpos = 0;
1542 if (!CUR_TI->taginfo_ready)
1543 memset(thistrack_id3, 0, sizeof(struct mp3entry));
1545 audio_fill_file_buffer(false, 0);
1548 /* Called on request from the codec to get a new track. This is the codec part
1549 of the track transition. */
1550 static void audio_last_track(bool automatic)
1552 if (automatic)
1554 ci.new_track = 0;
1555 automatic_skip = false;
1557 if (filling != STATE_ENDING)
1559 /* Monitor remaining PCM before stopping */
1560 filling = STATE_ENDING;
1561 pcmbuf_monitor_track_change(true);
1564 codec_stop();
1566 else
1568 audio_stop_playback();
1572 static void audio_check_new_track(void)
1574 int track_count;
1575 int old_track_ridx;
1576 int i, idx;
1577 bool forward;
1578 struct mp3entry *temp;
1580 if (ci.new_track == 0)
1582 ci.new_track++;
1583 automatic_skip = true;
1586 track_count = audio_track_count();
1587 old_track_ridx = track_ridx;
1589 /* Now it's good time to send track finish events. */
1590 send_event(PLAYBACK_EVENT_TRACK_FINISH, thistrack_id3);
1591 /* swap the mp3entry pointers */
1592 temp = thistrack_id3;
1593 thistrack_id3 = othertrack_id3;
1594 othertrack_id3 = temp;
1595 ci.id3 = thistrack_id3;
1596 memset(thistrack_id3, 0, sizeof(struct mp3entry));
1598 if (dir_skip)
1600 dir_skip = false;
1601 /* regardless of the return value we need to rebuffer.
1602 if it fails the old playlist will resume, else the
1603 next dir will start playing */
1604 playlist_next_dir(ci.new_track);
1605 ci.new_track = 0;
1606 audio_rebuffer();
1607 goto skip_done;
1610 if (new_playlist)
1611 ci.new_track = 0;
1613 /* If the playlist isn't that big */
1614 if (automatic_skip)
1616 while (!playlist_check(ci.new_track))
1618 if (ci.new_track >= 0)
1620 audio_last_track(true);
1621 return;
1623 ci.new_track++;
1627 /* Update the playlist */
1628 last_peek_offset -= ci.new_track;
1630 if (playlist_next(ci.new_track) < 0)
1632 /* End of list */
1633 audio_last_track(automatic_skip);
1634 return;
1637 if (new_playlist)
1639 ci.new_track = 1;
1640 new_playlist = false;
1643 /* Save a pointer to the old track to allow later clearing */
1644 prev_ti = CUR_TI;
1646 for (i = 0; i < ci.new_track; i++)
1648 idx = (track_ridx + i) & MAX_TRACK_MASK;
1649 struct mp3entry *id3 = bufgetid3(tracks[idx].id3_hid);
1650 ssize_t offset = buf_handle_offset(tracks[idx].audio_hid);
1651 if (!id3 || offset < 0 || (unsigned)offset > id3->first_frame_offset)
1653 /* We don't have all the audio data for that track, so clear it,
1654 but keep the metadata. */
1655 if (tracks[idx].audio_hid >= 0 && bufclose(tracks[idx].audio_hid))
1657 tracks[idx].audio_hid = -1;
1658 tracks[idx].filesize = 0;
1663 /* Move to the new track */
1664 track_ridx = (track_ridx + ci.new_track) & MAX_TRACK_MASK;
1665 buf_set_base_handle(CUR_TI->audio_hid);
1667 if (automatic_skip)
1669 wps_offset = -ci.new_track;
1672 /* If it is not safe to even skip this many track entries */
1673 if (ci.new_track >= track_count || ci.new_track <= track_count - MAX_TRACK)
1675 ci.new_track = 0;
1676 audio_rebuffer();
1677 goto skip_done;
1680 forward = ci.new_track > 0;
1681 ci.new_track = 0;
1683 /* If the target track is clearly not in memory */
1684 if (CUR_TI->filesize == 0 || !CUR_TI->taginfo_ready)
1686 audio_rebuffer();
1687 goto skip_done;
1690 /* When skipping backwards, it is possible that we've found a track that's
1691 * buffered, but which is around the track-wrap and therefore not the track
1692 * we are looking for */
1693 if (!forward)
1695 int cur_idx = track_ridx;
1696 bool taginfo_ready = true;
1697 /* We've wrapped the buffer backwards if new > old */
1698 bool wrap = track_ridx > old_track_ridx;
1700 while (1)
1702 cur_idx = (cur_idx + 1) & MAX_TRACK_MASK;
1704 /* if we've advanced past the wrap when cur_idx is zeroed */
1705 if (!cur_idx)
1706 wrap = false;
1708 /* if we aren't still on the wrap and we've caught the old track */
1709 if (!(wrap || cur_idx < old_track_ridx))
1710 break;
1712 /* If we hit a track in between without valid tag info, bail */
1713 if (!tracks[cur_idx].taginfo_ready)
1715 taginfo_ready = false;
1716 break;
1719 if (!taginfo_ready)
1721 audio_rebuffer();
1725 skip_done:
1726 audio_update_trackinfo();
1727 pcmbuf_start_track_change(automatic_skip);
1729 if (get_codec_base_type(codec_loaded()) ==
1730 get_codec_base_type(thistrack_id3->codectype))
1732 /* codec is the same base type */
1733 logf("New track loaded");
1734 codec_ack_msg(Q_CODEC_REQUEST_COMPLETE, false);
1736 else
1738 /* a codec change is required */
1739 logf("New codec: %d/%d", thistrack_id3->codectype, codec_loaded());
1740 codec_ack_msg(Q_CODEC_REQUEST_COMPLETE, true);
1741 codec_load(tracks[track_ridx].codec_hid, thistrack_id3->codectype);
1742 tracks[track_ridx].codec_hid = -1; /* Codec thread will close it */
1746 unsigned long audio_prev_elapsed(void)
1748 return prev_track_elapsed;
1751 void audio_set_prev_elapsed(unsigned long setting)
1753 prev_track_elapsed = setting;
1756 /* Stop the codec and reset the PCM buffer */
1757 static void audio_stop_codec_flush(void)
1759 bool pcm_playing;
1761 pcmbuf_pause(true);
1763 codec_stop();
1765 pcm_play_lock();
1767 pcm_playing = pcm_is_playing();
1769 pcmbuf_play_stop();
1770 queue_clear(&pcmbuf_queue);
1772 if (pcm_playing)
1773 pcmbuf_pause(paused);
1775 pcm_play_unlock();
1778 static void audio_stop_playback(void)
1780 if (playing)
1782 /* If we were playing, save resume information */
1783 struct mp3entry *id3 = NULL;
1785 if (!ci.stop_codec)
1786 id3 = audio_current_track();
1788 /* Save the current playing spot, or NULL if the playlist has ended */
1789 playlist_update_resume_info(id3);
1791 /* Now it's good time to send track finish events. Do this
1792 only if this hasn't been done already as part of a track
1793 switch. */
1794 if (id3 == thistrack_id3)
1795 send_event(PLAYBACK_EVENT_TRACK_FINISH, thistrack_id3);
1797 /* TODO: Create auto bookmark too? */
1799 prev_track_elapsed = othertrack_id3->elapsed;
1801 remove_event(BUFFER_EVENT_BUFFER_LOW, buffering_low_buffer_callback);
1804 audio_stop_codec_flush();
1805 paused = false;
1806 playing = false;
1807 track_load_started = false;
1809 filling = STATE_IDLE;
1811 /* Mark all entries null. */
1812 audio_clear_track_entries();
1814 /* Close all tracks */
1815 audio_release_tracks();
1818 static void audio_play_start(size_t offset)
1820 int i;
1822 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
1823 #if INPUT_SRC_CAPS != 0
1824 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
1825 audio_set_output_source(AUDIO_SRC_PLAYBACK);
1826 #endif
1828 paused = false;
1829 audio_stop_codec_flush();
1831 playing = true;
1832 track_load_started = false;
1834 ci.new_track = 0;
1835 ci.seek_time = 0;
1836 wps_offset = 0;
1838 sound_set_volume(global_settings.volume);
1839 track_widx = track_ridx = 0;
1840 buf_set_base_handle(-1);
1842 /* Clear all track entries. */
1843 for (i = 0; i < MAX_TRACK; i++) {
1844 clear_track_info(&tracks[i]);
1847 last_peek_offset = -1;
1849 /* Officially playing */
1850 queue_reply(&audio_queue, 1);
1852 audio_fill_file_buffer(true, offset);
1854 add_event(BUFFER_EVENT_BUFFER_LOW, false, buffering_low_buffer_callback);
1856 LOGFQUEUE("audio > audio Q_AUDIO_TRACK_CHANGED");
1857 queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
1861 /* Invalidates all but currently playing track. */
1862 static void audio_invalidate_tracks(void)
1864 if (audio_have_tracks())
1866 last_peek_offset = 0;
1867 track_widx = track_ridx;
1869 /* Mark all other entries null (also buffered wrong metadata). */
1870 audio_clear_track_entries();
1872 track_widx = (track_widx + 1) & MAX_TRACK_MASK;
1874 audio_fill_file_buffer(false, 0);
1875 send_event(PLAYBACK_EVENT_TRACK_CHANGE, thistrack_id3);
1879 static void audio_new_playlist(void)
1881 /* Prepare to start a new fill from the beginning of the playlist */
1882 last_peek_offset = -1;
1884 /* Signal the codec to initiate a track change forward */
1885 new_playlist = true;
1886 ci.new_track = 1;
1888 if (audio_have_tracks())
1890 if (paused)
1891 skipped_during_pause = true;
1892 track_widx = track_ridx;
1893 audio_clear_track_entries();
1895 track_widx = (track_widx + 1) & MAX_TRACK_MASK;
1897 /* Mark the current track as invalid to prevent skipping back to it */
1898 CUR_TI->taginfo_ready = false;
1901 /* Officially playing */
1902 queue_reply(&audio_queue, 1);
1904 audio_fill_file_buffer(false, 0);
1907 /* Called on manual track skip */
1908 static void audio_initiate_track_change(long direction)
1910 logf("audio_initiate_track_change(%ld)", direction);
1912 ci.new_track += direction;
1913 wps_offset -= direction;
1914 if (paused)
1915 skipped_during_pause = true;
1918 /* Called on manual dir skip */
1919 static void audio_initiate_dir_change(long direction)
1921 dir_skip = true;
1922 ci.new_track = direction;
1923 if (paused)
1924 skipped_during_pause = true;
1927 /* Called when PCM track change is complete */
1928 static void audio_finalise_track_change(void)
1930 logf("audio_finalise_track_change");
1932 if (automatic_skip)
1934 wps_offset = 0;
1935 automatic_skip = false;
1937 /* Invalidate prevtrack_id3 */
1938 memset(othertrack_id3, 0, sizeof(struct mp3entry));
1940 if (prev_ti && prev_ti->audio_hid < 0)
1942 /* No audio left so we clear all the track info. */
1943 clear_track_info(prev_ti);
1946 send_event(PLAYBACK_EVENT_TRACK_CHANGE, thistrack_id3);
1947 playlist_update_resume_info(audio_current_track());
1950 static void audio_seek_complete(void)
1952 logf("audio_seek_complete");
1954 if (!playing)
1955 return;
1957 /* If seeking-while-playing, pcm_is_paused() is true.
1958 * If seeking-while-paused, audio_status PAUSE is true.
1959 * A seamless seek skips this section. */
1960 ci.seek_time = 0;
1962 pcm_play_lock();
1964 if (pcm_is_paused() || paused)
1966 /* Clear the buffer */
1967 pcmbuf_play_stop();
1969 /* If seeking-while-playing, resume PCM playback */
1970 if (!paused)
1971 pcmbuf_pause(false);
1974 pcm_play_unlock();
1977 static void audio_codec_status_message(long reason, int status)
1979 /* TODO: Push the errors up to the normal UI somewhere */
1980 switch (reason)
1982 case Q_CODEC_LOAD_DISK:
1983 case Q_CODEC_LOAD:
1984 if (!playing)
1985 return;
1987 if (status < 0)
1989 splash(HZ*2, "Codec failure");
1990 audio_check_new_track();
1992 break;
1994 #ifdef AUDIO_HAVE_RECORDING
1995 case Q_ENCODER_LOAD_DISK:
1996 if (status < 0)
1997 splash(HZ*2, "Encoder failure");
1998 break;
1999 #endif /* AUDIO_HAVE_RECORDING */
2004 * Layout audio buffer as follows - iram buffer depends on target:
2005 * [|SWAP:iram][|TALK]|FILE|GUARD|PCM|[SWAP:dram[|iram]|]
2007 static void audio_reset_buffer(void)
2009 /* see audio_get_recording_buffer if this is modified */
2010 logf("audio_reset_buffer");
2012 /* If the setup of anything allocated before the file buffer is
2013 changed, do check the adjustments after the buffer_alloc call
2014 as it will likely be affected and need sliding over */
2016 /* Initially set up file buffer as all space available */
2017 malloc_buf = audiobuf + talk_get_bufsize();
2019 /* Align the malloc buf to line size.
2020 * Especially important to cf targets that do line reads/writes.
2021 * Also for targets which need aligned DMA storage buffers */
2022 malloc_buf = (unsigned char *)(((uintptr_t)malloc_buf + (CACHEALIGN_SIZE - 1)) & ~(CACHEALIGN_SIZE - 1));
2023 filebuf = malloc_buf; /* filebuf line align implied */
2024 filebuflen = (audiobufend - filebuf) & ~(CACHEALIGN_SIZE - 1);
2026 /* Subtract whatever the pcm buffer says it used plus the guard buffer */
2027 const size_t pcmbuf_size = pcmbuf_init(filebuf + filebuflen) +GUARD_BUFSIZE;
2028 if(pcmbuf_size > filebuflen)
2029 panicf("%s(): EOM (%zu > %zu)", __func__, pcmbuf_size, filebuflen);
2031 filebuflen -= pcmbuf_size;
2033 /* Make sure filebuflen is a longword multiple after adjustment - filebuf
2034 will already be line aligned */
2035 filebuflen &= ~3;
2037 buffering_reset(filebuf, filebuflen);
2039 /* Clear any references to the file buffer */
2040 buffer_state = AUDIOBUF_STATE_INITIALIZED;
2042 #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
2043 /* Make sure everything adds up - yes, some info is a bit redundant but
2044 aids viewing and the sumation of certain variables should add up to
2045 the location of others. */
2047 size_t pcmbufsize;
2048 const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize);
2049 logf("mabuf: %08X", (unsigned)malloc_buf);
2050 logf("fbuf: %08X", (unsigned)filebuf);
2051 logf("fbufe: %08X", (unsigned)(filebuf + filebuflen));
2052 logf("gbuf: %08X", (unsigned)(filebuf + filebuflen));
2053 logf("gbufe: %08X", (unsigned)(filebuf + filebuflen + GUARD_BUFSIZE));
2054 logf("pcmb: %08X", (unsigned)pcmbuf);
2055 logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize));
2057 #endif
2060 static void audio_thread(void)
2062 struct queue_event ev;
2064 pcm_postinit();
2066 audio_thread_ready = true;
2068 while (1)
2070 switch (filling) {
2071 case STATE_IDLE:
2072 queue_wait(&audio_queue, &ev);
2073 break;
2075 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2076 case STATE_USB:
2077 queue_wait(&audio_queue, &ev);
2078 switch (ev.id) {
2079 #ifdef AUDIO_HAVE_RECORDING
2080 /* Must monitor the encoder message for recording so it can
2081 remove it if we process the insertion before it does. It
2082 cannot simply be removed from under recording however. */
2083 case Q_AUDIO_LOAD_ENCODER:
2084 break;
2085 #endif
2086 case SYS_USB_DISCONNECTED:
2087 filling = STATE_IDLE;
2088 default:
2089 continue;
2091 break;
2092 #endif /* CONFIG_PLATFORM */
2094 default:
2095 /* End of buffering, let's calculate the watermark and
2096 unboost */
2097 set_filebuf_watermark();
2098 cancel_cpu_boost();
2099 /* Fall-through */
2100 case STATE_FILLING:
2101 case STATE_ENDING:
2102 if (!pcmbuf_queue_scan(&ev))
2103 queue_wait_w_tmo(&audio_queue, &ev, HZ/2);
2104 break;
2107 switch (ev.id) {
2109 case Q_AUDIO_FILL_BUFFER:
2110 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER %d", (int)ev.data);
2111 audio_fill_file_buffer((bool)ev.data, 0);
2112 break;
2114 case Q_AUDIO_FINISH_LOAD:
2115 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD");
2116 audio_finish_load_track();
2117 buf_set_base_handle(CUR_TI->audio_hid);
2118 break;
2120 case Q_AUDIO_PLAY:
2121 LOGFQUEUE("audio < Q_AUDIO_PLAY");
2122 if (playing && ev.data <= 0)
2123 audio_new_playlist();
2124 else
2126 audio_stop_playback();
2127 audio_play_start((size_t)ev.data);
2129 break;
2131 case Q_AUDIO_STOP:
2132 LOGFQUEUE("audio < Q_AUDIO_STOP");
2133 if (playing)
2134 audio_stop_playback();
2135 if (ev.data != 0)
2136 queue_clear(&audio_queue);
2137 break;
2139 case Q_AUDIO_PAUSE:
2140 LOGFQUEUE("audio < Q_AUDIO_PAUSE");
2141 if (!(bool) ev.data && skipped_during_pause
2142 #ifdef HAVE_CROSSFADE
2143 && !pcmbuf_is_crossfade_active()
2144 #endif
2146 pcmbuf_play_stop(); /* Flush old track on resume after skip */
2147 skipped_during_pause = false;
2148 if (!playing)
2149 break;
2150 pcmbuf_pause((bool)ev.data);
2151 paused = (bool)ev.data;
2152 break;
2154 case Q_AUDIO_SKIP:
2155 LOGFQUEUE("audio < Q_AUDIO_SKIP");
2156 audio_initiate_track_change((long)ev.data);
2157 break;
2159 case Q_AUDIO_PRE_FF_REWIND:
2160 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND");
2161 if (!playing)
2162 break;
2163 pcmbuf_pause(true);
2164 break;
2166 case Q_AUDIO_FF_REWIND:
2167 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND");
2168 if (!playing)
2169 break;
2171 if (filling == STATE_ENDING)
2173 /* Temp workaround: There is no codec available */
2174 if (!paused)
2175 pcmbuf_pause(false);
2176 break;
2179 if ((long)ev.data == 0)
2181 /* About to restart the track - send track finish
2182 events if not already done. */
2183 if (thistrack_id3 == audio_current_track())
2184 send_event(PLAYBACK_EVENT_TRACK_FINISH, thistrack_id3);
2187 if (automatic_skip)
2189 /* An automatic track skip is in progress. Finalize it,
2190 then go back to the previous track */
2191 audio_finalise_track_change();
2192 ci.new_track = -1;
2194 ci.seek_time = (long)ev.data+1;
2195 break;
2197 case Q_AUDIO_CHECK_NEW_TRACK:
2198 LOGFQUEUE("audio < Q_AUDIO_CHECK_NEW_TRACK");
2199 audio_check_new_track();
2200 break;
2202 case Q_AUDIO_DIR_SKIP:
2203 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP");
2204 audio_initiate_dir_change(ev.data);
2205 break;
2207 case Q_AUDIO_FLUSH:
2208 LOGFQUEUE("audio < Q_AUDIO_FLUSH");
2209 audio_invalidate_tracks();
2210 break;
2212 case Q_AUDIO_TRACK_CHANGED:
2213 /* PCM track change done */
2214 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2215 if (filling != STATE_ENDING)
2216 audio_finalise_track_change();
2217 else if (playing)
2218 audio_stop_playback();
2219 break;
2221 case Q_AUDIO_SEEK_COMPLETE:
2222 /* Codec seek done */
2223 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE");
2224 audio_seek_complete();
2225 codec_ack_msg(Q_AUDIO_SEEK_COMPLETE, false);
2226 break;
2228 case Q_CODEC_LOAD:
2229 case Q_CODEC_LOAD_DISK:
2230 #ifdef AUDIO_HAVE_RECORDING
2231 case Q_ENCODER_LOAD_DISK:
2232 #endif
2233 /* These are received when a codec has finished normally or
2234 upon a codec error */
2235 audio_codec_status_message(ev.id, ev.data);
2236 break;
2238 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2239 case SYS_USB_CONNECTED:
2240 LOGFQUEUE("audio < SYS_USB_CONNECTED");
2241 if (playing)
2242 audio_stop_playback();
2243 #ifdef PLAYBACK_VOICE
2244 voice_stop();
2245 #endif
2246 filling = STATE_USB;
2247 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2248 break;
2249 #endif
2251 #ifdef AUDIO_HAVE_RECORDING
2252 case Q_AUDIO_LOAD_ENCODER:
2253 if (playing)
2254 audio_stop_playback();
2255 else
2256 codec_stop(); /* If encoder still loaded, stop it */
2258 if (ev.data == AFMT_UNKNOWN)
2259 break;
2261 queue_reply(&audio_queue,
2262 codec_load(-1, ev.data | CODEC_TYPE_ENCODER));
2263 break;
2264 #endif /* AUDIO_HAVE_RECORDING */
2266 case SYS_TIMEOUT:
2267 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");
2268 break;
2270 default:
2271 /* LOGFQUEUE("audio < default : %08lX", ev.id); */
2272 break;
2273 } /* end switch */
2274 } /* end while */
2277 /* Initialize the audio system - called from init() in main.c.
2278 * Last function because of all the references to internal symbols
2280 void audio_init(void)
2282 unsigned int audio_thread_id;
2284 /* Can never do this twice */
2285 if (audio_is_initialized)
2287 logf("audio: already initialized");
2288 return;
2291 logf("audio: initializing");
2293 /* Initialize queues before giving control elsewhere in case it likes
2294 to send messages. Thread creation will be delayed however so nothing
2295 starts running until ready if something yields such as talk_init. */
2296 queue_init(&audio_queue, true);
2297 queue_init(&pcmbuf_queue, false);
2299 pcm_init();
2301 codec_init_codec_api();
2303 thistrack_id3 = &mp3entry_buf[0];
2304 othertrack_id3 = &mp3entry_buf[1];
2306 /* cuesheet support */
2307 if (global_settings.cuesheet)
2308 curr_cue = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2310 /* initialize the buffer */
2311 filebuf = audiobuf;
2313 /* audio_reset_buffer must to know the size of voice buffer so init
2314 talk first */
2315 talk_init();
2317 make_codec_thread();
2319 audio_thread_id = create_thread(audio_thread, audio_stack,
2320 sizeof(audio_stack), CREATE_THREAD_FROZEN,
2321 audio_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
2322 IF_COP(, CPU));
2324 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
2325 audio_thread_id);
2327 #ifdef PLAYBACK_VOICE
2328 voice_thread_init();
2329 #endif
2331 #ifdef HAVE_CROSSFADE
2332 /* Set crossfade setting for next buffer init which should be about... */
2333 pcmbuf_request_crossfade_enable(global_settings.crossfade);
2334 #endif
2336 /* initialize the buffering system */
2338 buffering_init();
2339 /* ...now! Set up the buffers */
2340 audio_reset_buffer();
2342 int i;
2343 for(i = 0; i < MAX_TRACK; i++)
2345 tracks[i].audio_hid = -1;
2346 tracks[i].id3_hid = -1;
2347 tracks[i].codec_hid = -1;
2348 tracks[i].cuesheet_hid = -1;
2350 #ifdef HAVE_ALBUMART
2351 FOREACH_ALBUMART(i)
2353 int j;
2354 for (j = 0; j < MAX_TRACK; j++)
2356 tracks[j].aa_hid[i] = -1;
2359 #endif
2361 add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback);
2362 add_event(BUFFER_EVENT_FINISHED, false, buffering_handle_finished_callback);
2364 /* Probably safe to say */
2365 audio_is_initialized = true;
2367 sound_settings_apply();
2368 #ifdef HAVE_DISK_STORAGE
2369 audio_set_buffer_margin(global_settings.buffer_margin);
2370 #endif
2372 /* it's safe to let the threads run now */
2373 #ifdef PLAYBACK_VOICE
2374 voice_thread_resume();
2375 #endif
2376 codec_thread_resume();
2377 thread_thaw(audio_thread_id);
2379 } /* audio_init */
2381 bool audio_is_thread_ready(void)
2383 return audio_thread_ready;
2386 size_t audio_get_filebuflen(void)
2388 return filebuflen;
2391 int get_audio_hid()
2393 return CUR_TI->audio_hid;