mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-07 05:35:02 -05:00
plugins: Oscilloscope & VU Meter: Support USB audio
Also show current mixer frequency in title of VU meter, and adjust the menu title from "VU Meter Menu" to just "VU Meter" Change-Id: I5bf8f55a3c9874618cac939fe32a611ac96f52ff
This commit is contained in:
parent
0551c4a780
commit
4095b13d52
4 changed files with 91 additions and 27 deletions
|
|
@ -62,6 +62,10 @@
|
||||||
#include "usbstack/usb_hid.h"
|
#include "usbstack/usb_hid.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USB_ENABLE_AUDIO
|
||||||
|
#include "usbstack/usb_audio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define WRAPPER(_x_) _x_ ## _wrapper
|
#define WRAPPER(_x_) _x_ ## _wrapper
|
||||||
|
|
||||||
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
||||||
|
|
@ -845,6 +849,9 @@ static const struct plugin_api rockbox_api = {
|
||||||
add_playbacklog,
|
add_playbacklog,
|
||||||
&device_battery_tables,
|
&device_battery_tables,
|
||||||
yesno_pop_confirm,
|
yesno_pop_confirm,
|
||||||
|
#ifdef USB_ENABLE_AUDIO
|
||||||
|
usb_audio_get_playing,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int plugin_buffer_handle;
|
static int plugin_buffer_handle;
|
||||||
|
|
|
||||||
|
|
@ -994,6 +994,9 @@ struct plugin_api {
|
||||||
void (*add_playbacklog)(struct mp3entry *id3);
|
void (*add_playbacklog)(struct mp3entry *id3);
|
||||||
struct battery_tables_t *device_battery_tables;
|
struct battery_tables_t *device_battery_tables;
|
||||||
bool (*yesno_pop_confirm)(const char* text);
|
bool (*yesno_pop_confirm)(const char* text);
|
||||||
|
#ifdef USB_ENABLE_AUDIO
|
||||||
|
bool (*usb_audio_get_playing)(void);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* plugin header */
|
/* plugin header */
|
||||||
|
|
|
||||||
|
|
@ -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; /* delay in 100ths of a tick */
|
||||||
static long osc_delay_error; /* delay fraction error accumulator */
|
static long osc_delay_error; /* delay fraction error accumulator */
|
||||||
|
|
||||||
|
static enum pcm_mixer_channel channel;
|
||||||
|
|
||||||
/* implementation */
|
/* implementation */
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -938,7 +940,7 @@ static int last_right;
|
||||||
static void get_peaks(int *left, int *right)
|
static void get_peaks(int *left, int *right)
|
||||||
{
|
{
|
||||||
static struct pcm_peaks peaks;
|
static struct pcm_peaks peaks;
|
||||||
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
|
rb->mixer_channel_calculate_peaks(channel,
|
||||||
&peaks);
|
&peaks);
|
||||||
*left = peaks.left;
|
*left = peaks.left;
|
||||||
*right = peaks.right;
|
*right = peaks.right;
|
||||||
|
|
@ -1501,7 +1503,7 @@ static long anim_waveform_horizontal(void)
|
||||||
|
|
||||||
long cur_tick = *rb->current_tick;
|
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();
|
osd_lcd_update_prepare();
|
||||||
rb->lcd_hline(0, LCD_WIDTH-1, 1*LCD_HEIGHT/4);
|
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;
|
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();
|
osd_lcd_update_prepare();
|
||||||
rb->lcd_vline(1*LCD_WIDTH/4, 0, LCD_HEIGHT-1);
|
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)
|
static void anim_waveform_exit(void)
|
||||||
{
|
{
|
||||||
/* Remove any buffer hook */
|
/* 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
|
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||||
/* Remove our boost */
|
/* Remove our boost */
|
||||||
rb->cancel_cpu_boost();
|
rb->cancel_cpu_boost();
|
||||||
|
|
@ -1906,7 +1908,7 @@ static void graphmode_setup(void)
|
||||||
#ifdef OSCILLOSCOPE_GRAPHMODE
|
#ifdef OSCILLOSCOPE_GRAPHMODE
|
||||||
if (osc.graphmode == GRAPH_WAVEFORM)
|
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);
|
waveform_buffer_callback);
|
||||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||||
rb->trigger_cpu_boost(); /* Just looks better */
|
rb->trigger_cpu_boost(); /* Just looks better */
|
||||||
|
|
@ -1914,7 +1916,7 @@ static void graphmode_setup(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK,
|
rb->mixer_channel_set_buffer_hook(channel,
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||||
rb->cancel_cpu_boost();
|
rb->cancel_cpu_boost();
|
||||||
|
|
@ -2005,6 +2007,21 @@ static void osc_setup(void)
|
||||||
graphmode_setup();
|
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)
|
enum plugin_status plugin_start(const void* parameter)
|
||||||
{
|
{
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
|
|
@ -2012,10 +2029,25 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
int lastbutton = BUTTON_NONE;
|
int lastbutton = BUTTON_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
channel = PCM_MIXER_CHAN_PLAYBACK;
|
||||||
|
|
||||||
osc_setup();
|
osc_setup();
|
||||||
|
|
||||||
while (!exit)
|
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();
|
long delay = oscilloscope_draw();
|
||||||
|
|
||||||
if (delay <= 0)
|
if (delay <= 0)
|
||||||
|
|
|
||||||
|
|
@ -666,7 +666,7 @@ static bool vu_meter_menu(void)
|
||||||
bool menu_quit = false;
|
bool menu_quit = false;
|
||||||
bool exit = 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",
|
"Minimeters","Decay Speed","Playback Control",
|
||||||
"Quit");
|
"Quit");
|
||||||
|
|
||||||
|
|
@ -811,14 +811,8 @@ static void draw_digital_minimeters(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void analog_meter(void) {
|
static void draw_analog_meter(uint32_t left_peak, uint32_t right_peak)
|
||||||
|
{
|
||||||
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
|
|
||||||
|
|
||||||
if(vumeter_settings.analog_use_db_scale) {
|
if(vumeter_settings.analog_use_db_scale) {
|
||||||
left_needle_top_x = analog_db_scale[left_peak * half_width / MAX_PEAK];
|
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;
|
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 void draw_digital_meter(uint32_t left_peak, uint32_t right_peak)
|
||||||
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
|
|
||||||
|
|
||||||
if(vumeter_settings.digital_use_db_scale) {
|
if(vumeter_settings.digital_use_db_scale) {
|
||||||
num_left_leds = digital_db_scale[left_peak * 44 / MAX_PEAK];
|
num_left_leds = digital_db_scale[left_peak * 44 / MAX_PEAK];
|
||||||
num_right_leds = digital_db_scale[right_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);
|
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)
|
static void vu_meter_cleanup(void)
|
||||||
{
|
{
|
||||||
/* Turn on backlight timeout (revert to settings) */
|
/* Turn on backlight timeout (revert to settings) */
|
||||||
backlight_use_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;
|
int button;
|
||||||
#if defined(VUMETER_HELP_PRE) || defined(VUMETER_MENU_PRE)
|
#if defined(VUMETER_HELP_PRE) || defined(VUMETER_MENU_PRE)
|
||||||
int lastbutton = BUTTON_NONE;
|
int lastbutton = BUTTON_NONE;
|
||||||
|
|
@ -964,12 +977,21 @@ enum plugin_status plugin_start(const void* parameter) {
|
||||||
{
|
{
|
||||||
rb->lcd_clear_display();
|
rb->lcd_clear_display();
|
||||||
|
|
||||||
rb->lcd_putsxy(half_width-23, 0, "VU Meter");
|
draw_title();
|
||||||
|
|
||||||
|
#ifdef USB_ENABLE_AUDIO
|
||||||
|
if (rb->usb_audio_get_playing())
|
||||||
|
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_USBAUDIO,
|
||||||
|
&peaks);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
|
||||||
|
&peaks);
|
||||||
|
|
||||||
if(vumeter_settings.meter_type == ANALOG)
|
if(vumeter_settings.meter_type == ANALOG)
|
||||||
analog_meter();
|
draw_analog_meter(peaks.left, peaks.right);
|
||||||
else
|
else
|
||||||
digital_meter();
|
draw_digital_meter(peaks.left, peaks.right);
|
||||||
|
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue