From 5e5dc9ba29106ab6769950b2b71c76237dbcf423 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Wed, 18 Mar 2020 23:42:44 -0700 Subject: [PATCH] 1st artwork version --- components/display/core/gds.c | 4 ++ components/display/core/gds_image.c | 4 +- components/display/core/gds_image.h | 5 +- components/squeezelite/display.c | 41 +++++++----- plugin/SqueezeESP32.zip | Bin 7561 -> 7772 bytes plugin/SqueezeESP32/Graphics.pm | 27 ++++++-- .../plugins/SqueezeESP32/settings/basic.html | 20 ------ plugin/SqueezeESP32/Player.pm | 15 ++++- plugin/SqueezeESP32/PlayerSettings.pm | 10 ++- plugin/SqueezeESP32/Plugin.pm | 59 ++++++++++++++++++ plugin/SqueezeESP32/Settings.pm | 30 --------- plugin/SqueezeESP32/SqueezeESP32.zip | Bin 0 -> 7772 bytes plugin/SqueezeESP32/install.xml | 2 +- plugin/SqueezeESP32/strings.txt | 16 +++++ plugin/repo.xml | 4 +- 15 files changed, 158 insertions(+), 79 deletions(-) delete mode 100644 plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html delete mode 100644 plugin/SqueezeESP32/Settings.pm create mode 100644 plugin/SqueezeESP32/SqueezeESP32.zip diff --git a/components/display/core/gds.c b/components/display/core/gds.c index d315b027..26242a60 100644 --- a/components/display/core/gds.c +++ b/components/display/core/gds.c @@ -60,6 +60,10 @@ void GDS_Clear( struct GDS_Device* Device, int Color ) { } void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color ) { + // -1 means up to width/height + if (x2 < 0) x2 = Device->Width - 1; + if (y2 < 0) y2 = Device->Height - 1; + // driver can provide own optimized clear window if (Device->ClearWindow) { Device->ClearWindow( Device, x1, y1, x2, y2, Color ); diff --git a/components/display/core/gds_image.c b/components/display/core/gds_image.c index a5919f74..ebd274e1 100644 --- a/components/display/core/gds_image.c +++ b/components/display/core/gds_image.c @@ -218,8 +218,10 @@ bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int // then place it if (Fit & GDS_IMAGE_CENTER_X) Context.XOfs = (Device->Width + x - Context.Width) / 2; + else if (Fit & GDS_IMAGE_RIGHT) Context.XOfs = Device->Width - Context.Width; if (Fit & GDS_IMAGE_CENTER_Y) Context.YOfs = (Device->Height + y - Context.Height) / 2; - + else if (Fit & GDS_IMAGE_BOTTOM) Context.YOfs = Device->Height - Context.Height; + Context.XMin = x - Context.XOfs; Context.YMin = y - Context.YOfs; diff --git a/components/display/core/gds_image.h b/components/display/core/gds_image.h index fa87001a..0becd94a 100644 --- a/components/display/core/gds_image.h +++ b/components/display/core/gds_image.h @@ -9,8 +9,11 @@ struct GDS_Device; enum { GDS_RGB565, GDS_RGB555, GDS_RGB444 }; -#define GDS_IMAGE_TOP 0x00 +#define GDS_IMAGE_LEFT 0x00 #define GDS_IMAGE_CENTER_X 0x01 +#define GDS_IMAGE_RIGHT 0x04 +#define GDS_IMAGE_TOP 0x00 +#define GDS_IMAGE_BOTTOM 0x08 #define GDS_IMAGE_CENTER_Y 0x02 #define GDS_IMAGE_CENTER (GDS_IMAGE_CENTER_X | GDS_IMAGE_CENTER_Y) #define GDS_IMAGE_FIT 0x10 diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index 555ee983..c85cf4a2 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -62,7 +62,9 @@ struct grfg_packet { struct grfa_packet { char opcode[4]; - u32_t length; + u32_t length; + u16_t x; + u16_t y; u32_t offset; }; @@ -140,6 +142,7 @@ static struct scroller_s { static struct { u8_t *data; u32_t size; + u16_t x, y; } artwork; #define MAX_BARS 32 @@ -313,7 +316,7 @@ static void send_server(void) { pkt_header.length = htonl(sizeof(pkt_header) - 8); pkt_header.mode = ANIC_resp; - send_packet((u8_t *)&pkt_header, sizeof(pkt_header)); + send_packet((uint8_t *) &pkt_header, sizeof(pkt_header)); ANIC_resp = ANIM_NONE; } @@ -321,18 +324,22 @@ static void send_server(void) { if (SETD_width) { struct SETD_header pkt_header; - LOG_INFO("sending width %u", SETD_width); - memset(&pkt_header, 0, sizeof(pkt_header)); memcpy(&pkt_header.opcode, "SETD", 4); pkt_header.id = 0xfe; // id 0xfe is width S:P:Squeezebox2 - pkt_header.length = htonl(sizeof(pkt_header) + 2 - 8); + pkt_header.length = htonl(sizeof(pkt_header) + 4 - 8); + + u16_t height = GDS_GetHeight(display); + LOG_INFO("sending dimension %ux%u", SETD_width, height); SETD_width = htons(SETD_width); - send_packet((u8_t *)&pkt_header, sizeof(pkt_header)); - send_packet((uint8_t*) &SETD_width, 2); - + height = htons(height); + + send_packet((uint8_t *) &pkt_header, sizeof(pkt_header)); + send_packet((uint8_t *) &SETD_width, 2); + send_packet((uint8_t *) &height, 2); + SETD_width = 0; } @@ -661,10 +668,10 @@ static void grfa_handler(u8_t *data, int len) { int offset = htonl(pkt->offset); int length = htonl(pkt->length); - LOG_INFO("gfra l:%u o:%u s:%u", length, offset, size); - // new grfa artwork, allocate memory if (!offset) { + artwork.x = htons(pkt->x); + artwork.y = htons(pkt->y); if (artwork.data) free(artwork.data); artwork.data = malloc(length); artwork.size = 0; @@ -674,8 +681,14 @@ static void grfa_handler(u8_t *data, int len) { memcpy(artwork.data + offset, data + sizeof(struct grfa_packet), size); artwork.size += size; if (artwork.size == length) { - GDS_DrawJPEG(display, artwork.data, 0, 32, GDS_IMAGE_CENTER); - } + 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); + free(artwork.data); + artwork.data = NULL; + artwork.size = 0; + } + + LOG_INFO("gfra l:%u x:%hu, y:%hu, o:%u s:%u", length, artwork.x, artwork.y, offset, size); } /**************************************************************************************** @@ -820,7 +833,7 @@ static void visu_handler( u8_t *data, int len) { visu.mode = pkt->which; // little trick to clean the taller screens when switching visu - 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.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) { @@ -878,7 +891,7 @@ static void visu_handler( u8_t *data, int len) { // reset bars maximum for (int i = visu.n; --i >= 0;) visu.bars[i].max = 0; - GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row - visu.height - 1); + GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1); LOG_INFO("Visualizer with %u bars of width %d:%d:%d:%d (%w:%u,h:%u,c:%u,r:%u,s:%.02f)", visu.n, visu.bar_border, visu.bar_width, visu.bar_gap, visu.border, visu.width, visu.height, visu.col, visu.row, visu.spectrum_scale); } else { diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip index 871345cc5d83a05d2509da56db6515bef41c97b9..2a3b0eebcdb365ef11b617d71d3ffef688565697 100644 GIT binary patch delta 6209 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 v_Yv;TubSVv6#Hk|JNOue^A=02AAgNrC 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 diff --git a/plugin/SqueezeESP32/Graphics.pm b/plugin/SqueezeESP32/Graphics.pm index 225c907b..a8dead59 100644 --- a/plugin/SqueezeESP32/Graphics.pm +++ b/plugin/SqueezeESP32/Graphics.pm @@ -71,7 +71,12 @@ sub displayWidth { } if ($display->widthOverride) { - return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0); + my $artwork = $prefs->client($client)->get('artwork'); + if ($artwork->{'enable'} && $artwork->{'y'} < 32) { + return $artwork->{x} + ($display->modes->[$mode || 0]{_width} || 0); + } else { + return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0); + } } else { return $display->modes->[$mode || 0]{width}; } @@ -101,9 +106,21 @@ sub build_modes { my $cprefs = $prefs->client($client); my $width = shift || $cprefs->get('width') || 128; + my $artwork = $cprefs->get('artwork'); + + # if artwork is in main display, reduce width + $width = $artwork->{'x'} - 1 if $artwork->{'enable'} && $artwork->{y} < 32; + my $small_VU = $cprefs->get('small_VU'); my $spectrum = $cprefs->get('spectrum'); + my $small_spectrum_pos = { x => $width - int ($spectrum->{small}->{size} * $width / 100), + width => int ($spectrum->{small}->{size} * $width / 100), + }; + my $small_VU_pos = { x => $width - int ($small_VU * $width / 100), + width => int ($small_VU * $width / 100), + }; + my @modes = ( # mode 0 { desc => ['BLANK'], @@ -135,14 +152,14 @@ sub build_modes { params => [$VISUALIZER_NONE] }, # mode 7 { desc => ['VISUALIZER_VUMETER_SMALL'], - bar => 0, secs => 0, width => $width, _width => int -($small_VU*$width/100), + 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, int ($small_VU*$width/100), 32, int -($small_VU*$width/100), 0, 2] }, + params => [$VISUALIZER_VUMETER, $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 => int -($spectrum->{small}->{size}*$width/100), + 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, int ($spectrum->{small}->{size}*$width/100), 32, int -($spectrum->{small}->{size}*$width/100), 0, 2, int ($spectrum->{small}->{size}/100*$width/$spectrum->{small}->{band}), $spectrum->{scale}] }, + params => [$VISUALIZER_SPECTRUM_ANALYZER, $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, diff --git a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html b/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html deleted file mode 100644 index fdf77916..00000000 --- a/plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/basic.html +++ /dev/null @@ -1,20 +0,0 @@ -[% PROCESS settings/header.html %] - - [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_BANNER" %] -
[% "PLUGIN_SQUEEZEESP32_BANNER_TEXT" | string %]
- [% END %] - -
- - [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_WIDTH" desc="PLUGIN_SQUEEZEESP32_WIDTH_DESC" %] - - [% END %] - - [% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE" desc="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE_DESC" %] - - [% END %] - - -
- -[% PROCESS settings/footer.html %] diff --git a/plugin/SqueezeESP32/Player.pm b/plugin/SqueezeESP32/Player.pm index 946eb303..d3692e2e 100644 --- a/plugin/SqueezeESP32/Player.pm +++ b/plugin/SqueezeESP32/Player.pm @@ -20,8 +20,8 @@ sub playerSettingsFrame { my $value; my $id = unpack('C', $$data_ref); - - # New SETD command 0xfe for display width + + # New SETD command 0xfe for display width & height if ($id == 0xfe) { $value = (unpack('Cn', $$data_ref))[1]; if ($value > 100 && $value < 400) { @@ -30,7 +30,9 @@ sub playerSettingsFrame { $client->display->widthOverride(1, $value); $client->update; } - $log->info("Setting player width $value for ", $client->name); + my $height = (unpack('Cnn', $$data_ref))[2]; + $prefs->client($client)->set('height', $height || 0); + $log->info("Setting player $value" . "x" . "$height for ", $client->name); } $client->SUPER::playerSettingsFrame($data_ref); @@ -40,4 +42,11 @@ sub hasScrolling { return 1; } + +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 4c88dcfd..1ff4f7b9 100644 --- a/plugin/SqueezeESP32/PlayerSettings.pm +++ b/plugin/SqueezeESP32/PlayerSettings.pm @@ -30,7 +30,7 @@ sub page { sub prefs { my ($class, $client) = @_; - my @prefs = qw(width small_VU spectrum); + my @prefs = qw(width small_VU spectrum artwork); return ($prefs->client($client), @prefs); } @@ -47,6 +47,11 @@ sub handler { full => { band => $paramRef->{'pref_spectrum_full_band'} }, }; $cprefs->set('spectrum', $spectrum); + my $artwork = { enable => $paramRef->{'pref_artwork_enable'}, + x => $paramRef->{'pref_artwork_x'}, + y => $paramRef->{'pref_artwork_y'}, + }; + $cprefs->set('artwork', $artwork); $client->display->modes($client->display->build_modes); $client->display->update; } @@ -56,9 +61,10 @@ sub handler { # here I don't know why you need to set again spectrum which is a reference # to a hash. Using $paramRef->{prefs} does not work either. It seems that - # soem are copies of value, some are references, can't figure out.This whole + # some are copies of value, some are references, can't figure out. This whole # logic of "Settings" is beyond me and I really hate it $paramRef->{'pref_spectrum'} = $cprefs->get('spectrum'); + $paramRef->{'pref_artwork'} = $cprefs->get('artwork'); return $class->SUPER::handler($client, $paramRef); } diff --git a/plugin/SqueezeESP32/Plugin.pm b/plugin/SqueezeESP32/Plugin.pm index 5078f66c..22a462d6 100644 --- a/plugin/SqueezeESP32/Plugin.pm +++ b/plugin/SqueezeESP32/Plugin.pm @@ -3,8 +3,12 @@ package Plugins::SqueezeESP32::Plugin; use strict; use base qw(Slim::Plugin::Base); + +use Digest::MD5 qw(md5); +use List::Util qw(min); use Slim::Utils::Prefs; use Slim::Utils::Log; +use Slim::Web::ImageProxy; my $prefs = preferences('plugin.squeezeesp32'); @@ -28,6 +32,61 @@ sub initPlugin { $class->SUPER::initPlugin(@_); Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' }); $log->info("Added class 100 for SqueezeESP32"); + + Slim::Control::Request::subscribe(\&update_artwork, [ ['newmetadata'] ] ); + Slim::Control::Request::subscribe(\&update_artwork, [ ['playlist'], ['open', 'newsong'] ]); } +sub update_artwork { + my $request = shift; + my $client = $request->client; + my $cprefs = $prefs->client($client); + my $artwork = $cprefs->get('artwork'); + + return unless $client->model eq 'squeezeesp32' && $artwork->{'enable'}; + + my $reqstr = $request->getRequestString(); + #my $path = $request->getParam('_path'); + + my $s = $artwork->{'y'} >= 32 ? $cprefs->get('height') - $artwork->{'y'} : 32; + $s = min($s, $cprefs->get('width') - $artwork->{'x'}); + + my $path = 'music/current/cover_' . $s . 'x' . $s . '_o.jpg'; + my $body = Slim::Web::Graphics::artworkRequest($client, $path, undef, \&send_artwork, undef, HTTP::Response->new); + + send_artwork($client, undef, \$body) if $body; + + $log->info("artwork update notification $reqstr with $path"); +} + +sub send_artwork { + my ($client, $params, $dataref) = @_; + + # I'm not sure why we are called so often, so only send when needed + my $md5 = md5($$dataref); + return if $client->pluginData('artwork_md5') eq $md5; + + $client->pluginData('artwork', $dataref); + $client->pluginData('artwork_md5', $md5); + + my $artwork = $prefs->client($client)->get('artwork'); + my $length = length $$dataref; + my $offset = 0; + + $log->info("got resized artwork (length: ", length $$dataref, ")"); + + my $header = pack('Nnn', $length, $artwork->{'x'}, $artwork->{'y'}); + + while ($length > 0) { + $length = 1280 if $length > 1280; + $log->info("sending grfa $length"); + + my $data = $header . pack('N', $offset) . substr( $$dataref, 0, $length, '' ); + + $client->sendFrame( grfa => \$data ); + $offset += $length; + $length = length $$dataref; + } +} + 1; diff --git a/plugin/SqueezeESP32/Settings.pm b/plugin/SqueezeESP32/Settings.pm deleted file mode 100644 index 1ef18504..00000000 --- a/plugin/SqueezeESP32/Settings.pm +++ /dev/null @@ -1,30 +0,0 @@ -package Plugins::SqueezeESP32::Settings; -use base qw(Slim::Web::Settings); - -use strict; - -use Slim::Utils::Prefs; -use Slim::Utils::Log; - -my $log = logger('plugin.squeezeesp32'); - -sub name { - return 'PLUGIN_SQUEEZEESP32'; -} - -sub page { - return 'plugins/SqueezeESP32/settings/basic.html'; -} - -sub prefs { - return (preferences('plugin.squeezeesp32'), qw(width spectrum_scale)); -} - -sub handler { - my ($class, $client, $params, $callback, @args) = @_; - - $callback->($client, $params, $class->SUPER::handler($client, $params), @args); -} - - -1; diff --git a/plugin/SqueezeESP32/SqueezeESP32.zip b/plugin/SqueezeESP32/SqueezeESP32.zip new file mode 100644 index 0000000000000000000000000000000000000000..2a3b0eebcdb365ef11b617d71d3ffef688565697 GIT binary patch literal 7772 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 PLUGIN_SQUEEZEESP32_DESC Plugins::SqueezeESP32::Plugin - 0.31 + 0.40 Philippe diff --git a/plugin/SqueezeESP32/strings.txt b/plugin/SqueezeESP32/strings.txt index 1dd9e492..d5ed82c2 100644 --- a/plugin/SqueezeESP32/strings.txt +++ b/plugin/SqueezeESP32/strings.txt @@ -53,3 +53,19 @@ PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND_DESC EN The number of bands is the width of the screen divided by this factor + +PLUGIN_SQUEEZEESP32_ARTWORK + EN Artwork + +PLUGIN_SQUEEZEESP32_ARTWORK_DESC + EN When Y position is less than 32, then artwork is display at the right of the main screen and x defines the starting position + EN Using artwork on less than 16-levels grayscale display if really poor quality + +PLUGIN_SQUEEZEESP32_ARTWORK_ENABLE + EN Enable + +PLUGIN_SQUEEZEESP32_ARTWORK_X + EN X + +PLUGIN_SQUEEZEESP32_ARTWORK_Y + EN Y diff --git a/plugin/repo.xml b/plugin/repo.xml index 45a2e536..e0c81729 100644 --- a/plugin/repo.xml +++ b/plugin/repo.xml @@ -1,10 +1,10 @@ - + https://github.com/sle118/squeezelite-esp32 Philippe - 6dc35a0f9f9b287d205f7532cbb642b08407a284 + aa122a85db949c903ffa978d3e3b4ee3205e4ec2 philippe_44@outlook.com SqueezeESP32 additional player id (100) http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip