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:
Christian Soffke 2025-11-23 23:33:19 +01:00
parent 0551c4a780
commit 4095b13d52
4 changed files with 91 additions and 27 deletions

View file

@ -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)

View file

@ -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();