summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c156
1 files changed, 117 insertions, 39 deletions
diff --git a/apps/playback.c b/apps/playback.c
index c69bf39abd..4a5ef5c450 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -64,7 +64,10 @@
64#include "icons.h" 64#include "icons.h"
65#include "peakmeter.h" 65#include "peakmeter.h"
66#include "action.h" 66#include "action.h"
67#ifdef HAVE_ALBUMART
67#include "albumart.h" 68#include "albumart.h"
69#include "bmp.h"
70#endif
68#endif 71#endif
69#include "lang.h" 72#include "lang.h"
70#include "misc.h" 73#include "misc.h"
@@ -158,6 +161,7 @@ enum filling_state {
158}; 161};
159 162
160#define MAX_TRACK 128 163#define MAX_TRACK 128
164#define MAX_MULTIPLE_AA 1
161 165
162#define MAX_TRACK_MASK (MAX_TRACK-1) 166#define MAX_TRACK_MASK (MAX_TRACK-1)
163 167
@@ -206,7 +210,7 @@ struct track_info {
206 int id3_hid; /* The ID for the track's metadata handle */ 210 int id3_hid; /* The ID for the track's metadata handle */
207 int codec_hid; /* The ID for the track's codec handle */ 211 int codec_hid; /* The ID for the track's codec handle */
208#ifdef HAVE_ALBUMART 212#ifdef HAVE_ALBUMART
209 int aa_hid; /* The ID for the track's album art handle */ 213 int aa_hid[MAX_MULTIPLE_AA];/* The ID for the track's album art handle */
210#endif 214#endif
211 int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */ 215 int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */
212 216
@@ -215,6 +219,16 @@ struct track_info {
215 bool taginfo_ready; /* Is metadata read */ 219 bool taginfo_ready; /* Is metadata read */
216}; 220};
217 221
222
223#ifdef HAVE_ALBUMART
224struct albumart_slot {
225 struct dim dim; /* holds width, height of the albumart */
226 int used; /* counter, increments if something uses it */
227} albumart_slots[MAX_MULTIPLE_AA];
228
229#define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++)
230#endif
231
218static struct track_info tracks[MAX_TRACK]; 232static struct track_info tracks[MAX_TRACK];
219static volatile int track_ridx = 0; /* Track being decoded (A/C-) */ 233static volatile int track_ridx = 0; /* Track being decoded (A/C-) */
220static int track_widx = 0; /* Track being buffered (A) */ 234static int track_widx = 0; /* Track being buffered (A) */
@@ -367,11 +381,17 @@ static bool clear_track_info(struct track_info *track)
367 } 381 }
368 382
369#ifdef HAVE_ALBUMART 383#ifdef HAVE_ALBUMART
370 if (track->aa_hid >= 0) { 384 {
371 if (bufclose(track->aa_hid)) 385 int i;
372 track->aa_hid = -1; 386 FOREACH_ALBUMART(i)
373 else 387 {
374 return false; 388 if (track->aa_hid[i] >= 0) {
389 if (bufclose(track->aa_hid[i]))
390 track->aa_hid[i] = -1;
391 else
392 return false;
393 }
394 }
375 } 395 }
376#endif 396#endif
377 397
@@ -538,18 +558,6 @@ void audio_remove_encoder(void)
538 558
539#endif /* HAVE_RECORDING */ 559#endif /* HAVE_RECORDING */
540 560
541#ifdef HAVE_ALBUMART
542int audio_current_aa_hid(void)
543{
544 int cur_idx;
545 int offset = ci.new_track + wps_offset;
546
547 cur_idx = track_ridx + offset;
548 cur_idx &= MAX_TRACK_MASK;
549
550 return tracks[cur_idx].aa_hid;
551}
552#endif
553 561
554struct mp3entry* audio_current_track(void) 562struct mp3entry* audio_current_track(void)
555{ 563{
@@ -673,6 +681,58 @@ struct mp3entry* audio_next_track(void)
673 return NULL; 681 return NULL;
674} 682}
675 683
684#ifdef HAVE_ALBUMART
685int playback_current_aa_hid(int slot)
686{
687 if (slot < 0)
688 return -1;
689 int cur_idx;
690 int offset = ci.new_track + wps_offset;
691
692 cur_idx = track_ridx + offset;
693 cur_idx &= MAX_TRACK_MASK;
694
695 return tracks[cur_idx].aa_hid[slot];
696}
697
698int playback_claim_aa_slot(struct dim *dim)
699{
700 int i;
701 /* first try to find a slot already having the size to reuse it
702 * since we don't want albumart of the same size buffered multiple times */
703 FOREACH_ALBUMART(i)
704 {
705 struct albumart_slot *slot = &albumart_slots[i];
706 if (slot->dim.width == dim->width
707 && slot->dim.height == dim->height)
708 {
709 slot->used++;
710 return i;
711 }
712 }
713 /* size is new, find a free slot */
714 FOREACH_ALBUMART(i)
715 {
716 if (!albumart_slots[i].used)
717 {
718 albumart_slots[i].used++;
719 albumart_slots[i].dim = *dim;
720 return i;
721 }
722 }
723 /* sorry, no free slot */
724 return -1;
725}
726
727void playback_release_aa_slot(int slot)
728{
729 /* invalidate the albumart_slot */
730 struct albumart_slot *aa_slot = &albumart_slots[slot];
731 if (aa_slot->used > 0)
732 aa_slot->used--;
733}
734
735#endif
676void audio_play(long offset) 736void audio_play(long offset)
677{ 737{
678 logf("audio_play"); 738 logf("audio_play");
@@ -1671,7 +1731,7 @@ static bool audio_loadcodec(bool start_play)
1671 1731
1672 codec_get_full_path(codec_path, codec_fn); 1732 codec_get_full_path(codec_path, codec_fn);
1673 1733
1674 tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC); 1734 tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL);
1675 if (tracks[track_widx].codec_hid < 0) 1735 if (tracks[track_widx].codec_hid < 0)
1676 return false; 1736 return false;
1677 1737
@@ -1757,7 +1817,7 @@ static bool audio_load_track(size_t offset, bool start_play)
1757 /* Get track metadata if we don't already have it. */ 1817 /* Get track metadata if we don't already have it. */
1758 if (tracks[track_widx].id3_hid < 0) 1818 if (tracks[track_widx].id3_hid < 0)
1759 { 1819 {
1760 tracks[track_widx].id3_hid = bufopen(trackname, 0, TYPE_ID3); 1820 tracks[track_widx].id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL);
1761 1821
1762 if (tracks[track_widx].id3_hid < 0) 1822 if (tracks[track_widx].id3_hid < 0)
1763 { 1823 {
@@ -1859,26 +1919,37 @@ static void audio_finish_load_track(void)
1859 } 1919 }
1860 } 1920 }
1861#ifdef HAVE_ALBUMART 1921#ifdef HAVE_ALBUMART
1862 if (tracks[track_widx].aa_hid < 0)
1863 { 1922 {
1923 int i;
1864 char aa_path[MAX_PATH]; 1924 char aa_path[MAX_PATH];
1865 /* find_albumart will error out if the wps doesn't have AA */ 1925 FOREACH_ALBUMART(i)
1866 if (find_albumart(track_id3, aa_path, sizeof(aa_path)))
1867 { 1926 {
1868 tracks[track_widx].aa_hid = bufopen(aa_path, 0, TYPE_BITMAP); 1927 /* albumart_slots may change during a yield of bufopen,
1869 1928 * but that's no problem */
1870 if(tracks[track_widx].aa_hid == ERR_BUFFER_FULL) 1929 if (tracks[track_widx].aa_hid[i] >= 0 || !albumart_slots[i].used)
1930 continue;
1931 /* find_albumart will error out if the wps doesn't have AA */
1932 if (find_albumart(track_id3, aa_path, sizeof(aa_path),
1933 &(albumart_slots[i].dim)))
1871 { 1934 {
1872 filling = STATE_FULL; 1935 int aa_hid = bufopen(aa_path, 0, TYPE_BITMAP,
1873 logf("buffer is full for now"); 1936 &(albumart_slots[i].dim));
1874 return; /* No space for track's album art, not an error */ 1937
1875 } 1938 if(aa_hid == ERR_BUFFER_FULL)
1876 else if (tracks[track_widx].aa_hid < 0) 1939 {
1877 { 1940 filling = STATE_FULL;
1878 /* another error, ignore AlbumArt */ 1941 logf("buffer is full for now");
1879 logf("Album art loading failed"); 1942 return; /* No space for track's album art, not an error */
1943 }
1944 else if (aa_hid < 0)
1945 {
1946 /* another error, ignore AlbumArt */
1947 logf("Album art loading failed");
1948 }
1949 tracks[track_widx].aa_hid[i] = aa_hid;
1880 } 1950 }
1881 } 1951 }
1952
1882 } 1953 }
1883#endif 1954#endif
1884 1955
@@ -1954,7 +2025,8 @@ static void audio_finish_load_track(void)
1954 else 2025 else
1955 file_offset = 0; 2026 file_offset = 0;
1956 2027
1957 tracks[track_widx].audio_hid = bufopen(track_id3->path, file_offset, type); 2028 tracks[track_widx].audio_hid = bufopen(track_id3->path, file_offset, type,
2029 NULL);
1958 2030
1959 /* No space left, not an error */ 2031 /* No space left, not an error */
1960 if (tracks[track_widx].audio_hid == ERR_BUFFER_FULL) 2032 if (tracks[track_widx].audio_hid == ERR_BUFFER_FULL)
@@ -2558,7 +2630,6 @@ static void audio_thread(void)
2558 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); 2630 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED");
2559 audio_finalise_track_change(); 2631 audio_finalise_track_change();
2560 break; 2632 break;
2561
2562#ifndef SIMULATOR 2633#ifndef SIMULATOR
2563 case SYS_USB_CONNECTED: 2634 case SYS_USB_CONNECTED:
2564 LOGFQUEUE("audio < SYS_USB_CONNECTED"); 2635 LOGFQUEUE("audio < SYS_USB_CONNECTED");
@@ -2681,11 +2752,18 @@ void audio_init(void)
2681 tracks[i].audio_hid = -1; 2752 tracks[i].audio_hid = -1;
2682 tracks[i].id3_hid = -1; 2753 tracks[i].id3_hid = -1;
2683 tracks[i].codec_hid = -1; 2754 tracks[i].codec_hid = -1;
2684#ifdef HAVE_ALBUMART
2685 tracks[i].aa_hid = -1;
2686#endif
2687 tracks[i].cuesheet_hid = -1; 2755 tracks[i].cuesheet_hid = -1;
2688 } 2756 }
2757#ifdef HAVE_ALBUMART
2758 FOREACH_ALBUMART(i)
2759 {
2760 int j;
2761 for (j = 0; j < MAX_TRACK; j++)
2762 {
2763 tracks[j].aa_hid[i] = -1;
2764 }
2765 }
2766#endif
2689 2767
2690 add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback); 2768 add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback);
2691 add_event(BUFFER_EVENT_FINISHED, false, buffering_handle_finished_callback); 2769 add_event(BUFFER_EVENT_FINISHED, false, buffering_handle_finished_callback);