From 7d5e0d73758cbe20596653d730a5c4ba60d7a3eb Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 16 May 2010 11:13:42 +0000 Subject: FS#11263 - Radio Art support! %C and %Cl tags work in the radio screen and Base Skin when the radio is running. put your station images in .rockbox/fmpresets/.bmp or .jpg. Must be in preset mode and the preset name must match the filename git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26078 a1c6a512-1295-4272-9138-f99709370657 --- apps/appevents.h | 8 +- apps/buffering.c | 1 - apps/gui/skin_engine/skin_display.c | 11 ++- apps/gui/skin_engine/skin_tokens.c | 14 +++- apps/playback.c | 1 + apps/recorder/pcm_record.c | 3 + apps/recorder/radio.c | 143 ++++++++++++++++++++++++++++++++++++ apps/recorder/radio.h | 4 + 8 files changed, 179 insertions(+), 6 deletions(-) (limited to 'apps') diff --git a/apps/appevents.h b/apps/appevents.h index 91c45c59b3..fd578b90a2 100644 --- a/apps/appevents.h +++ b/apps/appevents.h @@ -31,7 +31,8 @@ /** Playback events **/ enum { - PLAYBACK_EVENT_TRACK_BUFFER = (EVENT_CLASS_PLAYBACK|1), + PLAYBACK_EVENT_START_PLAYBACK = (EVENT_CLASS_PLAYBACK|1), + PLAYBACK_EVENT_TRACK_BUFFER, PLAYBACK_EVENT_TRACK_FINISH, PLAYBACK_EVENT_TRACK_CHANGE, PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, @@ -53,6 +54,11 @@ enum { GUI_EVENT_THEME_CHANGED, }; +/** Recording events **/ +enum { + RECORDING_EVENT_START = (EVENT_CLASS_RECORDING|1), + RECORDING_EVENT_STOP, +}; #endif diff --git a/apps/buffering.c b/apps/buffering.c index f194e2b82d..371cf22103 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -1007,7 +1007,6 @@ int bufopen(const char *file, size_t offset, enum data_type type, } /* Other cases: there is a little more work. */ - int fd = open(file, O_RDONLY); if (fd < 0) return ERR_FILE_ERROR; diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index f7bc14db20..5c2b11866a 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -443,8 +443,15 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) if (data->albumart && data->albumart->vp == vp && data->albumart->draw) { - draw_album_art(gwps, playback_current_aa_hid(data->playback_aa_slot), - false); + int handle = playback_current_aa_hid(data->playback_aa_slot); +#if CONFIG_TUNER + if (in_radio_screen()) + { + struct dim dim = {data->albumart->width, data->albumart->height}; + handle = radio_get_art_hid(&dim); + } +#endif + draw_album_art(gwps, handle, false); data->albumart->draw = false; } #endif diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 3d944a5315..538f385e44 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -577,8 +577,18 @@ const char *get_token_value(struct gui_wps *gwps, return buf; #ifdef HAVE_ALBUMART case WPS_TOKEN_ALBUMART_FOUND: - if (data->albumart) { - if (playback_current_aa_hid(data->playback_aa_slot) >= 0) + if (data->albumart) + { + int handle = -1; + handle = playback_current_aa_hid(data->playback_aa_slot); +#if CONFIG_TUNER + if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) + { + struct dim dim = {data->albumart->width, data->albumart->height}; + handle = radio_get_art_hid(&dim); + } +#endif + if (handle >= 0) return "C"; } return NULL; diff --git a/apps/playback.c b/apps/playback.c index 390dd19846..0be45b035a 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -1709,6 +1709,7 @@ static void audio_play_start(size_t offset) { int i; + send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL); #if INPUT_SRC_CAPS != 0 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); audio_set_output_source(AUDIO_SRC_PLAYBACK); diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index e5a5107603..2567b56ef3 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c @@ -31,6 +31,7 @@ #include "audio.h" #include "sound.h" #include "metadata.h" +#include "appevents.h" #ifdef HAVE_SPDIF_IN #include "spdif.h" #endif @@ -1127,6 +1128,7 @@ static void pcmrec_new_stream(const char *filename, /* next file name */ static void pcmrec_init(void) { unsigned char *buffer; + send_event(RECORDING_EVENT_START, NULL); /* warings and errors */ warnings = @@ -1183,6 +1185,7 @@ static void pcmrec_close(void) pcm_close_recording(); reset_hardware(); audio_remove_encoder(); + send_event(RECORDING_EVENT_STOP, NULL); } /* pcmrec_close */ /* PCMREC_OPTIONS */ diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 026579516b..5425e8a2ab 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -69,6 +69,7 @@ #include "viewport.h" #include "skin_engine/skin_engine.h" #include "statusbar-skinned.h" +#include "buffering.h" #if CONFIG_TUNER @@ -199,10 +200,18 @@ static bool yesno_pop(const char* text) return ret; } +#if defined(HAVE_RECORDING) && defined(HAVE_ALBUMART) +static void recording_started_handler(void *data); +static void recording_stopped_handler(void *data); +#endif void radio_init(void) { tuner_init(); radio_off(); +#if defined(HAVE_RECORDING) && defined(HAVE_ALBUMART) + add_event(RECORDING_EVENT_START, false, recording_started_handler); + add_event(RECORDING_EVENT_STOP, false, recording_stopped_handler); +#endif } int get_radio_status(void) @@ -504,6 +513,131 @@ static struct gui_wps fms_skin[NB_SCREENS] = {{ .data = NULL }}; static struct wps_data fms_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }}; static struct wps_sync_data fms_skin_sync_data = { .do_full_update = false }; +#ifdef HAVE_ALBUMART +#define MAX_RADIOART_IMAGES 10 +struct radioart { + int handle; + long last_tick; + struct dim dim; + char name[MAX_FMPRESET_LEN+1]; +}; + +static struct radioart radioart[MAX_RADIOART_IMAGES]; +#ifdef HAVE_RECORDING +static bool allow_buffer_access = true; /* If we are recording dont touch the buffers! */ +#endif +static int find_oldest_image(void) +{ + int i; + long oldest_tick = radioart[0].last_tick; + int oldest_idx = 0; + for(i=1;iname, preset_name, MAX_FMPRESET_LEN+1); + ra->dim.height = dim->height; + ra->dim.width = dim->width; + ra->last_tick = current_tick; + ra->handle = bufopen(path, 0, TYPE_BITMAP, &ra->dim); + if (ra->handle == ERR_BUFFER_FULL) + { + int i = find_oldest_image(); + bufclose(i); + ra->handle = bufopen(path, 0, TYPE_BITMAP, &ra->dim); + } +#ifndef HAVE_NOISY_IDLE_MODE + cpu_idle_mode(true); +#endif + return ra->handle; +} +int radio_get_art_hid(struct dim *requested_dim) +{ + int preset = radio_current_preset(); + int i, free_idx = -1; + if ((radio_mode != RADIO_PRESET_MODE) || preset < 0) + return -1; +#ifdef HAVE_RECORDING + if (!allow_buffer_access) + return -1; +#endif + for(i=0;iwidth && + radioart[i].dim.height == requested_dim->height) + { + radioart[i].last_tick = current_tick; + return radioart[i].handle; + } + } + if (free_idx >= 0) + { + return load_radioart_image(&radioart[free_idx], + presets[preset].name, requested_dim); + } + else + { + int i = find_oldest_image(); + bufclose(radioart[i].handle); + return load_radioart_image(&radioart[i], + presets[preset].name, requested_dim); + } + + return -1; +} +static void playback_restarting_handler(void *data) +{ + (void)data; + int i; + for(i=0;i= 0) + bufclose(radioart[i].handle); + radioart[i].handle = -1; + radioart[i].name[0] = '\0'; + } +} +#ifdef HAVE_RECORDING +static void recording_started_handler(void *data) +{ + (void)data; + allow_buffer_access = false; + playback_restarting_handler(NULL); +} +static void recording_stopped_handler(void *data) +{ + (void)data; + allow_buffer_access = true; +} +#endif +#endif void fms_data_load(enum screen_type screen, const char *buf, bool isfile) { @@ -613,9 +747,18 @@ int radio_screen(void) { radio_load_presets(global_settings.fmr_file); } +#ifdef HAVE_ALBUMART + for(i=0;i