diff --git a/apps/plugin.c b/apps/plugin.c index e7a533ac62..519fcd53bd 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -62,6 +62,10 @@ #include "usbstack/usb_hid.h" #endif +#ifdef USB_ENABLE_AUDIO +#include "usbstack/usb_audio.h" +#endif + #define WRAPPER(_x_) _x_ ## _wrapper #if (CONFIG_PLATFORM & PLATFORM_HOSTED) @@ -845,6 +849,9 @@ static const struct plugin_api rockbox_api = { add_playbacklog, &device_battery_tables, yesno_pop_confirm, +#ifdef USB_ENABLE_AUDIO + usb_audio_get_playing, +#endif }; static int plugin_buffer_handle; diff --git a/apps/plugin.h b/apps/plugin.h index 0e56257b2c..fcf7bf58ea 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -994,6 +994,9 @@ struct plugin_api { void (*add_playbacklog)(struct mp3entry *id3); struct battery_tables_t *device_battery_tables; bool (*yesno_pop_confirm)(const char* text); +#ifdef USB_ENABLE_AUDIO + bool (*usb_audio_get_playing)(void); +#endif }; /* plugin header */ diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c index 670b34be0c..63e855cceb 100644 --- a/apps/plugins/oscilloscope.c +++ b/apps/plugins/oscilloscope.c @@ -763,6 +763,8 @@ static bool one_frame_paused = false; /* Allow one frame to be drawn when paused static long osc_delay; /* delay in 100ths of a tick */ static long osc_delay_error; /* delay fraction error accumulator */ +static enum pcm_mixer_channel channel; + /* implementation */ @@ -938,7 +940,7 @@ static int last_right; static void get_peaks(int *left, int *right) { static struct pcm_peaks peaks; - rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK, + rb->mixer_channel_calculate_peaks(channel, &peaks); *left = peaks.left; *right = peaks.right; @@ -1501,7 +1503,7 @@ static long anim_waveform_horizontal(void) long cur_tick = *rb->current_tick; - if (rb->mixer_channel_status(PCM_MIXER_CHAN_PLAYBACK) != CHANNEL_PLAYING) + if (rb->mixer_channel_status(channel) != CHANNEL_PLAYING) { osd_lcd_update_prepare(); rb->lcd_hline(0, LCD_WIDTH-1, 1*LCD_HEIGHT/4); @@ -1695,7 +1697,7 @@ static long anim_waveform_vertical(void) long cur_tick = *rb->current_tick; - if (rb->mixer_channel_status(PCM_MIXER_CHAN_PLAYBACK) != CHANNEL_PLAYING) + if (rb->mixer_channel_status(channel) != CHANNEL_PLAYING) { osd_lcd_update_prepare(); rb->lcd_vline(1*LCD_WIDTH/4, 0, LCD_HEIGHT-1); @@ -1838,7 +1840,7 @@ static long anim_waveform_vertical(void) static void anim_waveform_exit(void) { /* Remove any buffer hook */ - rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK, NULL); + rb->mixer_channel_set_buffer_hook(channel, NULL); #ifdef HAVE_SCHEDULER_BOOSTCTRL /* Remove our boost */ rb->cancel_cpu_boost(); @@ -1906,7 +1908,7 @@ static void graphmode_setup(void) #ifdef OSCILLOSCOPE_GRAPHMODE if (osc.graphmode == GRAPH_WAVEFORM) { - rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK, + rb->mixer_channel_set_buffer_hook(channel, waveform_buffer_callback); #ifdef HAVE_SCHEDULER_BOOSTCTRL rb->trigger_cpu_boost(); /* Just looks better */ @@ -1914,7 +1916,7 @@ static void graphmode_setup(void) } else { - rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK, + rb->mixer_channel_set_buffer_hook(channel, NULL); #ifdef HAVE_SCHEDULER_BOOSTCTRL rb->cancel_cpu_boost(); @@ -2005,6 +2007,21 @@ static void osc_setup(void) graphmode_setup(); } +#ifdef USB_ENABLE_AUDIO +void switch_channel(enum pcm_mixer_channel new_channel) +{ + /* Remove any buffer hook */ + rb->mixer_channel_set_buffer_hook(channel, NULL); + + channel = new_channel; + +#ifdef OSCILLOSCOPE_GRAPHMODE + if (osc.graphmode == GRAPH_WAVEFORM) + rb->mixer_channel_set_buffer_hook(channel, waveform_buffer_callback); +#endif +} +#endif /* USB_ENABLE_AUDIO */ + enum plugin_status plugin_start(const void* parameter) { bool exit = false; @@ -2012,10 +2029,25 @@ enum plugin_status plugin_start(const void* parameter) int lastbutton = BUTTON_NONE; #endif + channel = PCM_MIXER_CHAN_PLAYBACK; + osc_setup(); while (!exit) { +#ifdef USB_ENABLE_AUDIO + if (rb->usb_audio_get_playing()) + { + if (channel != PCM_MIXER_CHAN_USBAUDIO) + switch_channel(PCM_MIXER_CHAN_USBAUDIO); + } + else + { + if (channel != PCM_MIXER_CHAN_PLAYBACK) + switch_channel(PCM_MIXER_CHAN_PLAYBACK); + } +#endif /* USB_ENABLE_AUDIO */ + long delay = oscilloscope_draw(); if (delay <= 0) diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c index cd9f50a2c6..7dd0bd786d 100644 --- a/apps/plugins/vu_meter.c +++ b/apps/plugins/vu_meter.c @@ -666,7 +666,7 @@ static bool vu_meter_menu(void) bool menu_quit = false; bool exit = false; - MENUITEM_STRINGLIST(menu,"VU Meter Menu",NULL,"Meter Type","Scale", + MENUITEM_STRINGLIST(menu,"VU Meter",NULL,"Meter Type","Scale", "Minimeters","Decay Speed","Playback Control", "Quit"); @@ -811,14 +811,8 @@ static void draw_digital_minimeters(void) { #endif } -static void analog_meter(void) { - - static struct pcm_peaks peaks; - rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK, - &peaks); - #define left_peak peaks.left - #define right_peak peaks.right - +static void draw_analog_meter(uint32_t left_peak, uint32_t right_peak) +{ if(vumeter_settings.analog_use_db_scale) { left_needle_top_x = analog_db_scale[left_peak * half_width / MAX_PEAK]; right_needle_top_x = analog_db_scale[right_peak * half_width / MAX_PEAK] + half_width; @@ -867,13 +861,8 @@ static void analog_meter(void) { } } -static void digital_meter(void) { - static struct pcm_peaks peaks; - rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK, - &peaks); - #define left_peak peaks.left - #define right_peak peaks.right - +static void draw_digital_meter(uint32_t left_peak, uint32_t right_peak) +{ if(vumeter_settings.digital_use_db_scale) { num_left_leds = digital_db_scale[left_peak * 44 / MAX_PEAK]; num_right_leds = digital_db_scale[right_peak * 44 / MAX_PEAK]; @@ -933,13 +922,37 @@ static void digital_meter(void) { rb->lcd_hline(0,LCD_WIDTH-1,half_height+3); } +static void draw_title(void) +{ + static unsigned int sampr; + static int x; + static char title[16]; + + if (sampr != rb->mixer_get_frequency()) + { + sampr = rb->mixer_get_frequency(); + if ((sampr % 1000) < 100) + rb->snprintf(title, sizeof title, "VU %d kHz", + sampr / 1000); + else + rb->snprintf(title, sizeof title, "VU %d.%u kHz", + sampr / 1000, (sampr % 1000) / 100); + + rb->font_getstringsize(title, &x, NULL, FONT_SYSFIXED); + x = half_width - (x/2); /* centered */ + } + rb->lcd_putsxy(x, 0, title); +} + static void vu_meter_cleanup(void) { /* Turn on backlight timeout (revert to settings) */ backlight_use_settings(); } -enum plugin_status plugin_start(const void* parameter) { +enum plugin_status plugin_start(const void* parameter) +{ + static struct pcm_peaks peaks; int button; #if defined(VUMETER_HELP_PRE) || defined(VUMETER_MENU_PRE) int lastbutton = BUTTON_NONE; @@ -964,12 +977,21 @@ enum plugin_status plugin_start(const void* parameter) { { rb->lcd_clear_display(); - rb->lcd_putsxy(half_width-23, 0, "VU Meter"); + draw_title(); - if(vumeter_settings.meter_type==ANALOG) - analog_meter(); +#ifdef USB_ENABLE_AUDIO + if (rb->usb_audio_get_playing()) + rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_USBAUDIO, + &peaks); else - digital_meter(); +#endif + rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK, + &peaks); + + if(vumeter_settings.meter_type == ANALOG) + draw_analog_meter(peaks.left, peaks.right); + else + draw_digital_meter(peaks.left, peaks.right); rb->lcd_update();