From ff40290610320486e583f3dfb2afd0031e23d828 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 20 Mar 2020 23:55:26 -0700 Subject: [PATCH] handle "generic" visualizer - release --- components/squeezelite/display.c | 153 +++++++++++++++++++++----- plugin/SqueezeESP32.zip | Bin 7987 -> 7995 bytes plugin/SqueezeESP32/Graphics.pm | 24 ++-- plugin/SqueezeESP32/Player.pm | 10 +- plugin/SqueezeESP32/PlayerSettings.pm | 8 +- plugin/SqueezeESP32/Plugin.pm | 6 + plugin/SqueezeESP32/install.xml | 2 +- plugin/repo.xml | 4 +- 8 files changed, 154 insertions(+), 53 deletions(-) diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index cace344e..b20f1be5 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -86,6 +86,29 @@ struct visu_packet { u32_t bars; u32_t spectrum_scale; }; + struct { + u32_t mono; + u32_t bandwidth; + u32_t preemph; + struct { + u32_t pos; + u32_t width; + u32_t orient; + u32_t bar_width; + u32_t bar_space; + u32_t clipping; + u32_t bar_intens; + u32_t bar_cap_intens; + } channels[2]; + }; + struct { + u32_t mono; + u32_t style; + struct { + u32_t pos; + u32_t width; + } channels[2]; + } classical_vu; }; }; @@ -143,9 +166,11 @@ static struct { u8_t *data; u32_t size; u16_t x, y; + bool enable; } artwork; #define MAX_BARS 32 +#define VISU_ESP32 0x10 static EXT_RAM_ATTR struct { int bar_gap, bar_width, bar_border; struct { @@ -157,6 +182,11 @@ static EXT_RAM_ATTR struct { enum { VISU_BLANK, VISU_VUMETER, VISU_SPECTRUM, VISU_WAVEFORM } mode; int speed, wake; float fft[FFT_LEN*2], samples[FFT_LEN*2], hanning[FFT_LEN]; + struct { + u8_t *frame; + int width; + bool active; + } back; } visu; #define ANIM_NONE 0x00 @@ -221,6 +251,33 @@ static void displayer_task(void* arg); ANIM_SCREEN_2 0x08 # For scrollonce only, screen 2 was scrolling */ +/* classical visu not our specific version) + Parameters for the spectrum analyzer: + 0 - Channels: stereo == 0, mono == 1 + 1 - Bandwidth: 0..22050Hz == 0, 0..11025Hz == 1 + 2 - Preemphasis in dB per KHz + Left channel parameters: + 3 - Position in pixels + 4 - Width in pixels + 5 - orientation: left to right == 0, right to left == 1 + 6 - Bar width in pixels + 7 - Bar spacing in pixels + 8 - Clipping: show all subbands == 0, clip higher subbands == 1 + 9 - Bar intensity (greyscale): 1-3 + 10 - Bar cap intensity (greyscale): 1-3 + Right channel parameters (not required for mono): + 11-18 - same as left channel parameters + + Parameters for the vumeter: + 0 - Channels: stereo == 0, mono == 1 + 1 - Style: digital == 0, analog == 1 + Left channel parameters: + 2 - Position in pixels + 3 - Width in pixels + Right channel parameters (not required for mono): + 4-5 - same as left channel parameters +*/ + /**************************************************************************************** * */ @@ -242,6 +299,7 @@ bool sb_display_init(void) { // create visu configuration visu.bar_gap = 1; visu.speed = 100; + visu.back.frame = calloc(1, (displayer.width * displayer.height) / 8); dsps_fft2r_init_fc32(visu.fft, FFT_LEN); dsps_wind_hann_f32(visu.hanning, FFT_LEN); @@ -517,7 +575,7 @@ static void grfe_handler( u8_t *data, int len) { scroller.active = false; // we are not in control or we are displaying visu on a small screen, do not do screen update - if (visu.mode && !visu.col && visu.row < SB_HEIGHT) { + if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < SB_HEIGHT) { xSemaphoreGive(displayer.mutex); return; } @@ -531,6 +589,16 @@ static void grfe_handler( u8_t *data, int len) { // draw new frame, it might be less than full screen (small visu) int width = ((len - sizeof(struct grfe_packet)) * 8) / displayer.height; + + // when doing screensaver, that frame becomes a visu background + if (!(visu.mode & VISU_ESP32)) { + visu.back.width = width; + memset(visu.back.frame, 0, (displayer.width * displayer.height) / 8); + memcpy(visu.back.frame, data + sizeof(struct grfe_packet), (width * displayer.height) / 8); + // this is a bit tricky but basically that checks if frame if full of 0 + visu.back.active = *visu.back.frame || memcmp(visu.back.frame, visu.back.frame + 1, width - 1); + } + GDS_DrawBitmapCBR(display, data + sizeof(struct grfe_packet), width, displayer.height, GDS_COLOR_WHITE); GDS_Update(display); } @@ -570,7 +638,7 @@ static void grfs_handler(u8_t *data, int len) { int size = len - sizeof(struct grfs_packet); int offset = htons(pkt->offset); - LOG_DEBUG("gfrs s:%u d:%u p:%u sp:%u by:%hu m:%hu w:%hu o:%hu", + LOG_DEBUG("grfs s:%u d:%u p:%u sp:%u by:%hu m:%hu w:%hu o:%hu", (int) pkt->screen, (int) pkt->direction, // 1=left, 2=right htonl(pkt->pause), // in ms @@ -666,6 +734,14 @@ static void grfa_handler(u8_t *data, int len) { int offset = htonl(pkt->offset); int length = htonl(pkt->length); + artwork.enable = (length != 0); + + // clean up if we are disabling previously enabled artwork + if (!artwork.enable) { + if (artwork.size) GDS_ClearWindow(display, artwork.x, artwork.y, -1, -1, GDS_COLOR_BLACK); + return; + } + // new grfa artwork, allocate memory if (!offset) { // same trick to clean current/previous window @@ -679,7 +755,6 @@ static void grfa_handler(u8_t *data, int len) { artwork.y = htons(pkt->y); if (artwork.data) free(artwork.data); artwork.data = malloc(length); - artwork.size = 0; } // copy artwork data @@ -687,7 +762,7 @@ static void grfa_handler(u8_t *data, int len) { artwork.size += size; if (artwork.size == length) { GDS_ClearWindow(display, artwork.x, artwork.y, -1, -1, GDS_COLOR_BLACK); - GDS_DrawJPEG(display, artwork.data, artwork.x, artwork.y, artwork.y < 32 ? (GDS_IMAGE_RIGHT | GDS_IMAGE_TOP) : GDS_IMAGE_CENTER); + GDS_DrawJPEG(display, artwork.data, artwork.x, artwork.y, artwork.y < SB_HEIGHT ? (GDS_IMAGE_RIGHT | GDS_IMAGE_TOP) : GDS_IMAGE_CENTER); free(artwork.data); artwork.data = NULL; } @@ -701,9 +776,11 @@ static void grfa_handler(u8_t *data, int len) { static void visu_update(void) { // no need to protect against no woning the display as we are playing if (pthread_mutex_trylock(&visu_export.mutex)) return; + + int mode = visu.mode & ~VISU_ESP32; // not enough samples - if (visu_export.level < (visu.mode == VISU_VUMETER ? RMS_LEN : FFT_LEN) * 2 && visu_export.running) { + if (visu_export.level < (mode == VISU_VUMETER ? RMS_LEN : FFT_LEN) * 2 && visu_export.running) { pthread_mutex_unlock(&visu_export.mutex); return; } @@ -713,7 +790,7 @@ static void visu_update(void) { if (visu_export.running) { - if (visu.mode == VISU_VUMETER) { + if (mode == VISU_VUMETER) { s16_t *iptr = visu_export.buffer; // calculate sum(L²+R²), try to not overflow at the expense of some precision @@ -726,7 +803,7 @@ static void visu_update(void) { // convert to dB (1 bit remaining for getting X²/N, 60dB dynamic starting from 0dBFS = 3 bits back-off) for (int i = visu.n; --i >= 0;) { - visu.bars[i].current = 32 * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> 1)) - 0.2543f); + visu.bars[i].current = SB_HEIGHT * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> 1)) - 0.2543f); if (visu.bars[i].current > 31) visu.bars[i].current = 31; else if (visu.bars[i].current < 0) visu.bars[i].current = 0; } @@ -768,7 +845,7 @@ static void visu_update(void) { } // convert to dB and bars, same back-off - if (power) visu.bars[i].current = 32 * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f); + if (power) visu.bars[i].current = SB_HEIGHT * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/2*2)) - 0.2543f); if (visu.bars[i].current > 31) visu.bars[i].current = 31; else if (visu.bars[i].current < 0) visu.bars[i].current = 0; } @@ -783,6 +860,11 @@ static void visu_update(void) { int clear = 0; for (int i = visu.n; --i >= 0;) clear = max(clear, visu.bars[i].max); if (clear) GDS_ClearExt(display, false, false, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1); + + // draw background if we are in screensaver mode + if (!(visu.mode & VISU_ESP32) && visu.back.active) { + GDS_DrawBitmapCBR(display, visu.back.frame, visu.back.width, displayer.height, GDS_COLOR_WHITE); + } // there is much more optimization to be done here, like not redrawing bars unless needed for (int i = visu.n; --i >= 0;) { @@ -840,31 +922,44 @@ static void visu_handler( u8_t *data, int len) { if (visu.row >= SB_HEIGHT) GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1); if (visu.mode) { - if (pkt->count >= 4) { - // small visu, then go were we are told to - pkt->height = htonl(pkt->height); - pkt->row = htonl(pkt->row); - pkt->col = htonl(pkt->col); + // these will be overidden if necessary + visu.col = visu.border = 0; + visu.width = displayer.width; + + // what type of visu + if (visu.mode & VISU_ESP32) { + if (pkt->count >= 4) { + // more than 4 parameters, this is small visu, then go were we are told to + pkt->height = htonl(pkt->height); + pkt->row = htonl(pkt->row); + pkt->col = htonl(pkt->col); - visu.width = htonl(pkt->width); - visu.height = pkt->height ? pkt->height : SB_HEIGHT; - visu.col = pkt->col < 0 ? displayer.width + pkt->col : pkt->col; - visu.row = pkt->row < 0 ? GDS_GetHeight(display) + pkt->row : pkt->row; - visu.border = htonl(pkt->border); - bars = htonl(pkt->bars); - visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.; + visu.width = htonl(pkt->width); + visu.height = pkt->height ? pkt->height : SB_HEIGHT; + visu.col = pkt->col < 0 ? displayer.width + pkt->col : pkt->col; + visu.row = pkt->row < 0 ? GDS_GetHeight(display) + pkt->row : pkt->row; + visu.border = htonl(pkt->border); + bars = htonl(pkt->bars); + visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.; + } else { + // full screen visu, try to use bottom screen if available + visu.height = GDS_GetHeight(display) > SB_HEIGHT ? GDS_GetHeight(display) - SB_HEIGHT : GDS_GetHeight(display); + bars = htonl(pkt->full.bars); + visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.; + visu.row = GDS_GetHeight(display) - visu.height; + } } else { - // full screen visu, try to use bottom screen if available - visu.width = displayer.width; - visu.height = GDS_GetHeight(display) > SB_HEIGHT ? GDS_GetHeight(display) - SB_HEIGHT : GDS_GetHeight(display); - visu.col = visu.border = 0; - visu.row = GDS_GetHeight(display) - visu.height; - bars = htonl(pkt->full.bars); - visu.spectrum_scale = htonl(pkt->full.spectrum_scale) / 100.; - } + // classical (screensaver) mode, don't try to optimize screen usage & force some params + visu.row = 0; + visu.height = SB_HEIGHT; + visu.spectrum_scale = 0.25; + if (artwork.enable && artwork.y < SB_HEIGHT) visu.width = artwork.x - 1; + if (visu.mode == VISU_SPECTRUM) bars = visu.width / (htonl(pkt->channels[0].bar_width) + htonl(pkt->channels[0].bar_space)); + if (bars > MAX_BARS) bars = MAX_BARS; + } // try to adapt to what we have - if (visu.mode == VISU_SPECTRUM) { + if ((visu.mode & ~VISU_ESP32) == VISU_SPECTRUM) { visu.n = bars ? bars : MAX_BARS; if (visu.spectrum_scale <= 0 || visu.spectrum_scale > 0.5) visu.spectrum_scale = 0.5; spectrum_limits(0, visu.n, 0); diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip index 1f183d0fdba213b88a47c237d37269544a109314..239a3142e3eebd58fd808a9ea9bf0e730d8fba4f 100644 GIT binary patch delta 4976 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 O9x=!O8EOB%;(q~!2RvZ_ delta 5016 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 XCmk_accessor('array', 'modes'); @@ -72,7 +74,7 @@ sub displayWidth { if ($display->widthOverride) { my $artwork = $prefs->client($client)->get('artwork'); - if ($artwork->{'enable'} && $artwork->{'y'} < 32) { + if ($artwork->{'enable'} && $artwork->{'y'} < 32 && $client->isPlaying) { return $artwork->{x} + ($display->modes->[$mode || 0]{_width} || 0); } else { return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0); @@ -105,7 +107,7 @@ sub build_modes { my $client = shift->client; my $cprefs = $prefs->client($client); - my $width = shift || $cprefs->get('width') || 128; + my $width = $cprefs->get('width') || 128; my $artwork = $cprefs->get('artwork'); # if artwork is in main display, reduce width @@ -154,39 +156,39 @@ sub build_modes { { desc => ['VISUALIZER_VUMETER_SMALL'], bar => 0, secs => 0, width => $width, _width => -$small_VU_pos->{'width'}, # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space) - params => [$VISUALIZER_VUMETER, $small_VU_pos->{'width'}, 32, $small_VU_pos->{'x'}, 0, 2] }, + params => [$VISUALIZER_VUMETER_ESP32, $small_VU_pos->{'width'}, 32, $small_VU_pos->{'x'}, 0, 2] }, # mode 8 { desc => ['VISUALIZER_SPECTRUM_ANALYZER_SMALL'], bar => 0, secs => 0, width => $width, _width => -$small_spectrum_pos->{'width'}, - # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space, bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, $small_spectrum_pos->{width}, 32, $small_spectrum_pos->{'x'}, 0, 2, $small_spectrum_pos->{'width'} / $spectrum->{small}->{band}, $spectrum->{scale}] }, + # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space, #bars, scale) + params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $small_spectrum_pos->{width}, 32, $small_spectrum_pos->{'x'}, 0, 2, $small_spectrum_pos->{'width'} / $spectrum->{small}->{band}, $spectrum->{scale}] }, # mode 9 { desc => ['VISUALIZER_VUMETER'], bar => 0, secs => 0, width => $width, - params => [$VISUALIZER_VUMETER] }, + params => [$VISUALIZER_VUMETER_ESP32] }, # mode 10 { desc => ['VISUALIZER_SPECTRUM_ANALYZER'], bar => 0, secs => 0, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, # mode 11 { desc => ['VISUALIZER_VUMETER', 'AND', 'ELAPSED'], bar => 0, secs => 1, width => $width, - params => [$VISUALIZER_VUMETER] }, + params => [$VISUALIZER_VUMETER_ESP32] }, # mode 12 { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'ELAPSED'], bar => 0, secs => 1, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, # mode 13 { desc => ['VISUALIZER_VUMETER', 'AND', 'REMAINING'], bar => 0, secs => -1, width => $width, - params => [$VISUALIZER_VUMETER] }, + params => [$VISUALIZER_VUMETER_ESP32] }, # mode 14 { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'REMAINING'], bar => 0, secs => -1, width => $width, # extra parameters (bars) - params => [$VISUALIZER_SPECTRUM_ANALYZER, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] }, ); return \@modes; diff --git a/plugin/SqueezeESP32/Player.pm b/plugin/SqueezeESP32/Player.pm index e0e6a3b7..3ae11b17 100644 --- a/plugin/SqueezeESP32/Player.pm +++ b/plugin/SqueezeESP32/Player.pm @@ -26,7 +26,7 @@ sub playerSettingsFrame { $value = (unpack('Cn', $$data_ref))[1]; if ($value > 100 && $value < 400) { $prefs->client($client)->set('width', $value); - $client->display->modes($client->display->build_modes($value)); + $client->display->modes($client->display->build_modes); $client->display->widthOverride(1, $value); $client->update; } @@ -38,7 +38,7 @@ sub playerSettingsFrame { $client->SUPER::playerSettingsFrame($data_ref); } -sub hasScrolling { +sub hasScrolling { return 1; } @@ -48,10 +48,4 @@ sub reconnect { $client->SUPER::reconnect(@_); } -sub directMetadata { - my $client = shift; - $client->SUPER::directMetadata(@_); - Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] ); -} - 1; diff --git a/plugin/SqueezeESP32/PlayerSettings.pm b/plugin/SqueezeESP32/PlayerSettings.pm index 4fd57722..eb95f098 100644 --- a/plugin/SqueezeESP32/PlayerSettings.pm +++ b/plugin/SqueezeESP32/PlayerSettings.pm @@ -55,8 +55,12 @@ sub handler { $client->display->modes($client->display->build_modes); $client->display->update; - # force update - Plugins::SqueezeESP32::Plugin::update_artwork($client, 1) if $artwork->{'enable'}; + # force update or disable artwork + if ($artwork->{'enable'}) { + Plugins::SqueezeESP32::Plugin::update_artwork($client, 1); + } else { + Plugins::SqueezeESP32::Plugin::disable_artwork($client); + } } # as there is nothing captured, we need to re-set these variables diff --git a/plugin/SqueezeESP32/Plugin.pm b/plugin/SqueezeESP32/Plugin.pm index 8d070910..3e845542 100644 --- a/plugin/SqueezeESP32/Plugin.pm +++ b/plugin/SqueezeESP32/Plugin.pm @@ -95,4 +95,10 @@ sub send_artwork { } } +sub disable_artwork { + my ($client) = @_; + my $header = pack('N', 0); + $client->sendFrame( grfa => \$header ); +} + 1; diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml index dbf8d9d4..d28e7f08 100644 --- a/plugin/SqueezeESP32/install.xml +++ b/plugin/SqueezeESP32/install.xml @@ -10,6 +10,6 @@ PLUGIN_SQUEEZEESP32 PLUGIN_SQUEEZEESP32_DESC Plugins::SqueezeESP32::Plugin - 0.43 + 0.50 Philippe diff --git a/plugin/repo.xml b/plugin/repo.xml index de7f3051..b0266385 100644 --- a/plugin/repo.xml +++ b/plugin/repo.xml @@ -1,10 +1,10 @@ - + https://github.com/sle118/squeezelite-esp32 Philippe - 3460f07b43dcdb2cbdf4d10e6536da7abd87b3a1 + 47feaf69a40ad4f87c58b34212d71e60dca99d3e philippe_44@outlook.com SqueezeESP32 additional player id (100) http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip