diff --git a/Dockerfile b/Dockerfile
index 9918175d..ae8eda76 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,8 +18,6 @@ RUN wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a
RUN tar -xzf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
RUN rm xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
-# Patch I2S in esp-idf
-RUN cp /workspace/squeezelite-esp32/idf-patch/i2s.c /workspace/esp-idf/components/driver/i2s.c
RUN rm -r /workspace/squeezelite-esp32
RUN mkdir /workspace/squeezelite-esp32
diff --git a/build-scripts/I2S-4MFlash-sdkconfig.defaults b/build-scripts/I2S-4MFlash-sdkconfig.defaults
index 6452dd4a..e4358543 100644
--- a/build-scripts/I2S-4MFlash-sdkconfig.defaults
+++ b/build-scripts/I2S-4MFlash-sdkconfig.defaults
@@ -457,9 +457,9 @@ CONFIG_LWIP_SO_REUSE=y
CONFIG_LWIP_SO_REUSE_RXTOALL=y
# CONFIG_LWIP_SO_RCVBUF is not set
# CONFIG_LWIP_IP_FRAG is not set
-#CONFIG_LWIP_IP_REASSEMBLY is not set
# CONFIG_LWIP_STATS is not set
# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
+CONFIG_LWIP_IP_REASSEMBLY=y
CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
CONFIG_LWIP_GARP_TMR_INTERVAL=60
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
diff --git a/build-scripts/SqueezeAmp-sdkconfig.defaults b/build-scripts/SqueezeAmp-sdkconfig.defaults
index 6592908e..a43c90c7 100644
--- a/build-scripts/SqueezeAmp-sdkconfig.defaults
+++ b/build-scripts/SqueezeAmp-sdkconfig.defaults
@@ -457,7 +457,7 @@ CONFIG_LWIP_MAX_SOCKETS=16
# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
CONFIG_LWIP_SO_REUSE=y
CONFIG_LWIP_SO_REUSE_RXTOALL=y
-#CONFIG_LWIP_IP_REASSEMBLY is not set
+CONFIG_LWIP_IP_REASSEMBLY=y
CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
CONFIG_LWIP_GARP_TMR_INTERVAL=60
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
diff --git a/components/squeezelite/controls.c b/components/squeezelite/controls.c
index 508e549d..0860c57e 100644
--- a/components/squeezelite/controls.c
+++ b/components/squeezelite/controls.c
@@ -279,6 +279,7 @@ static void notify(in_addr_t ip, u16_t hport, u16_t cport) {
if (connect(cli_sock, (struct sockaddr *) &addr, addrlen) < 0) {
LOG_ERROR("unable to connect to server %s:%hu with cli", inet_ntoa(server_ip), server_cport);
+ closesocket(cli_sock);
cli_sock = -1;
}
diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c
index 20b8547d..8a2dae8a 100644
--- a/components/squeezelite/display.c
+++ b/components/squeezelite/display.c
@@ -808,6 +808,8 @@ static void grfa_handler(u8_t *data, int len) {
artwork.y = htons(pkt->y);
} else if (artwork.size) GDS_ClearWindow(display, artwork.x, artwork.y, -1, -1, GDS_COLOR_BLACK);
+ LOG_INFO("gfra en:%u x:%hu, y:%hu", artwork.enable, artwork.x, artwork.y);
+
// done in any case
return;
}
@@ -875,7 +877,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 = visu.max * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> (visu_export.gain == FIXED_ONE ? 7 : 1))) - 0.2543f);
+ visu.bars[i].current = visu.max * (0.01667f*10*log10f(0.0000001f + (visu.bars[i].current >> (visu_export.gain == FIXED_ONE ? 8 : 1))) - 0.2543f);
if (visu.bars[i].current > visu.max) visu.bars[i].current = visu.max;
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
}
@@ -917,7 +919,7 @@ static void visu_update(void) {
}
// convert to dB and bars, same back-off
- if (power) visu.bars[i].current = visu.max * (0.01667f*10*(log10f(power) - log10f(FFT_LEN/(visu_export.gain == FIXED_ONE ? 128 : 2)*2)) - 0.2543f);
+ if (power) visu.bars[i].current = visu.max * (0.01667f*10*(log10f(power) - log10f(FFT_LEN*(visu_export.gain == FIXED_ONE ? 256 : 2))) - 0.2543f);
if (visu.bars[i].current > visu.max) visu.bars[i].current = visu.max;
else if (visu.bars[i].current < 0) visu.bars[i].current = 0;
}
@@ -1042,7 +1044,7 @@ static void visu_handler( u8_t *data, int len) {
// little trick to clean the taller screens when switching visu
if (visu.row >= displayer.height) GDS_ClearExt(display, false, true, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
-
+
if (visu.mode) {
// these will be overidden if necessary
visu.col = visu.border = 0;
@@ -1065,13 +1067,27 @@ static void visu_handler( u8_t *data, int len) {
bars = htonl(pkt->bars);
visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.;
} else {
- // full screen visu, try to use bottom screen if available
+ // full screen visu, try to optimize orientation/shape
visu.width = htonl(pkt->full.width);
- visu.height = GDS_GetHeight(display) > displayer.height ? GDS_GetHeight(display) - displayer.height : GDS_GetHeight(display);
- visu.row = GDS_GetHeight(display) - visu.height;
+ visu.height = GDS_GetHeight(display);
- // try to estimate if we should rotate visu
- if (visu.height > displayer.height && visu.height > 2*visu.width) visu.rotate = true;
+ // do we have enough height to play with layout
+ if (GDS_GetHeight(display) > displayer.height) {
+ // by default, use up to the bottom of the display
+ visu.height -= displayer.height;
+ visu.row = displayer.height;
+
+ if (artwork.enable && artwork.y) {
+ // server sets width to artwork X offset to tell us to rotate
+ if (visu.width != artwork.x) {
+ visu.height = artwork.y - displayer.height;
+ if (visu.height <= 0) {
+ visu.height = displayer.height;
+ LOG_WARN("No room left for visualizer, disable it or increase artwork offset %d", artwork.y);
+ }
+ } else visu.rotate = true;
+ }
+ } else visu.row = 0;
// is this spectrum or analogue/digital
if ((visu.mode & ~VISU_ESP32) == VISU_SPECTRUM) {
@@ -1094,9 +1110,10 @@ static void visu_handler( u8_t *data, int len) {
visu.style = htonl(pkt->classical_vu.style);
if (visu.style) visu.row = visu.height - VU_HEIGHT;
}
- if (bars > MAX_BARS) bars = MAX_BARS;
}
+ if (bars > MAX_BARS) bars = MAX_BARS;
+
// for rotate, swap width & height
if (visu.rotate) visu_fit(bars, visu.height, visu.width);
else visu_fit(bars, visu.width, visu.height);
diff --git a/components/squeezelite/output_bt.c b/components/squeezelite/output_bt.c
index 3f294c3a..af629a4f 100644
--- a/components/squeezelite/output_bt.c
+++ b/components/squeezelite/output_bt.c
@@ -124,7 +124,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
int32_t output_bt_data(uint8_t *data, int32_t len) {
int32_t iframes = len / BYTES_PER_FRAME, start_timer = 0;
- if (len < 0 || data == NULL || !running) {
+ if (iframes <= 0 || data == NULL || !running) {
return 0;
}
@@ -135,9 +135,9 @@ int32_t output_bt_data(uint8_t *data, int32_t len) {
// for us to send. (BTC_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16) - availPcmBytes
SET_MIN_MAX(len,req);
TIME_MEASUREMENT_START(start_timer);
- SET_MIN_MAX_SIZED(_buf_used(outputbuf),bt,outputbuf->size);
LOCK;
+ SET_MIN_MAX_SIZED(_buf_used(outputbuf),bt,outputbuf->size);
output.device_frames = 0;
output.updated = gettime_ms();
output.frames_played_dmp = output.frames_played;
diff --git a/components/squeezelite/slimproto.c b/components/squeezelite/slimproto.c
index 8dd05b54..59f79d53 100644
--- a/components/squeezelite/slimproto.c
+++ b/components/squeezelite/slimproto.c
@@ -822,14 +822,14 @@ in_addr_t discover_server(char *default_server, int max) {
memset(&s, 0, sizeof(s));
if (sendto(disc_sock, buf, len, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
- LOG_INFO("error sending disovery");
+ LOG_INFO("error sending discovery");
}
if (poll(&pollinfo, 1, 5000) == 1) {
- char readbuf[32], *p;
+ char readbuf[64], *p;
socklen_t slen = sizeof(s);
- memset(readbuf, 0, 32);
- recvfrom(disc_sock, readbuf, 32 - 1, 0, (struct sockaddr *)&s, &slen);
+ memset(readbuf, 0, sizeof(readbuf));
+ recvfrom(disc_sock, readbuf, sizeof(readbuf) - 1, 0, (struct sockaddr *)&s, &slen);
LOG_INFO("got response from: %s:%d", inet_ntoa(s.sin_addr), ntohs(s.sin_port));
if ((p = strstr(readbuf, port_d)) != NULL) {
diff --git a/components/wifi-manager/CMakeLists.txt b/components/wifi-manager/CMakeLists.txt
index a6782082..8ce2910e 100644
--- a/components/wifi-manager/CMakeLists.txt
+++ b/components/wifi-manager/CMakeLists.txt
@@ -3,7 +3,7 @@ set( WEBPACK_DIR webapp/webpack/dist )
idf_component_register( SRC_DIRS . webapp
INCLUDE_DIRS . webapp ${IDF_PATH}/components/esp_http_server/src ${IDF_PATH}/components/esp_http_server/src/port/esp32 ${IDF_PATH}/components/esp_http_server/src/util ${IDF_PATH}/components/esp_http_server/src/
REQUIRES squeezelite-ota json mdns
- PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console driver_bt
+ PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console driver_bt
)
diff --git a/plugin/SqueezeESP32/Graphics.pm b/plugin/SqueezeESP32/Graphics.pm
index 6f763be7..ce82b9fe 100644
--- a/plugin/SqueezeESP32/Graphics.pm
+++ b/plugin/SqueezeESP32/Graphics.pm
@@ -17,6 +17,17 @@ my $VISUALIZER_WAVEFORM = 3;
my $VISUALIZER_VUMETER_ESP32 = 0x11;
my $VISUALIZER_SPECTRUM_ANALYZER_ESP32 = 0x12;
+my %SPECTRUM_DEFAULTS = (
+ scale => 25,
+ small => {
+ size => 25,
+ band => 5.33
+ },
+ full => {
+ band => 8
+ },
+);
+
{
#__PACKAGE__->mk_accessor('array', 'modes');
__PACKAGE__->mk_accessor('rw', 'modes');
@@ -33,14 +44,16 @@ sub new {
$cprefs->init( {
width => 128,
small_VU => 15,
- spectrum => { scale => 25,
- small => { size => 25, band => 5.33 },
- full => { band => 8 },
- },
- }
- );
-
- $display->init_accessor(
+ spectrum => \%SPECTRUM_DEFAULTS,
+ } );
+
+ $prefs->migrateClient(2, sub {
+ my ($cprefs, $client) = @_;
+ sanitizeSpectrum($cprefs->get('spectrum'));
+ 1;
+ });
+
+ $display->init_accessor(
modes => $display->build_modes,
# Only seems to matter for screensaver and update to decide font. Not
# any value is acceptable, so use Boom value which seems to be best
@@ -106,6 +119,16 @@ sub displayHeight {
return 32;
}
+sub sanitizeSpectrum {
+ my ($spectrum) = shift;
+
+ $spectrum->{small}->{size} ||= $SPECTRUM_DEFAULTS{small}->{size};
+ $spectrum->{small}->{band} ||= $SPECTRUM_DEFAULTS{small}->{band};
+ $spectrum->{full}->{band} ||= $SPECTRUM_DEFAULTS{full}->{band};
+
+ return $spectrum;
+}
+
sub build_modes {
my $client = shift->client;
my $cprefs = $prefs->client($client);
@@ -118,9 +141,9 @@ sub build_modes {
my $width_low = ($artwork->{'enable'} && $artwork->{'x'} && ($artwork->{'y'} >= 32 || $disp_width - $artwork->{'x'} > 32)) ? $artwork->{'x'} : $disp_width;
my $small_VU = $cprefs->get('small_VU');
- my $spectrum = $cprefs->get('spectrum');
-
- my $small_spectrum_pos = { x => $width - int ($spectrum->{small}->{size} * $width / 100),
+ my $spectrum = sanitizeSpectrum($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),
@@ -224,7 +247,7 @@ my @extra = (
);
@modes = (@modes, @extra) if $cprefs->get('height') > 32;
-
+
return \@modes;
}
diff --git a/plugin/SqueezeESP32/Player.pm b/plugin/SqueezeESP32/Player.pm
index 5dddc64a..2f97ba6f 100644
--- a/plugin/SqueezeESP32/Player.pm
+++ b/plugin/SqueezeESP32/Player.pm
@@ -91,16 +91,19 @@ sub init {
}
$client->SUPER::init(@_);
- $client->config_artwork;
- $client->send_equalizer;
-
main::INFOLOG && $log->is_info && $log->info("SqueezeESP player connected: " . $client->id);
}
sub initPrefs {
my $client = shift;
+
$sprefs->client($client)->init($defaultPrefs);
- $prefs->client($client)->init( { equalizer => [(0) x 10] } );
+
+ $prefs->client($client)->init( {
+ equalizer => [(0) x 10],
+ artwork => undef,
+ } );
+
$client->SUPER::initPrefs;
}
@@ -184,11 +187,13 @@ sub update_artwork {
my $cprefs = $prefs->client($client);
my $artwork = $cprefs->get('artwork') || return;
-
return unless $artwork->{'enable'};
+
+ my $header = pack('Nnn', $artwork->{'enable'}, $artwork->{'x'}, $artwork->{'y'});
+ $client->sendFrame( grfa => \$header );
+ $client->display->update;
my $s = min($cprefs->get('height') - $artwork->{'y'}, $cprefs->get('width') - $artwork->{'x'});
-
my $params = { force => shift || 0 };
my $path = 'music/current/cover_' . $s . 'x' . $s . '_o.jpg';
my $body = Slim::Web::Graphics::artworkRequest($client, $path, $params, \&send_artwork, undef, HTTP::Response->new);
@@ -248,13 +253,17 @@ sub config_artwork {
if ( my $artwork = $prefs->client($client)->get('artwork') ) {
my $header = pack('Nnn', $artwork->{'enable'}, $artwork->{'x'}, $artwork->{'y'});
$client->sendFrame( grfa => \$header );
+ $client->display->update;
}
}
sub reconnect {
my $client = shift;
- $client->pluginData('artwork_md5', '');
$client->SUPER::reconnect(@_);
+
+ $client->pluginData('artwork_md5', '');
+ $client->config_artwork;
+ $client->send_equalizer;
}
# Change the analog output mode between headphone and sub-woofer
diff --git a/plugin/SqueezeESP32/PlayerSettings.pm b/plugin/SqueezeESP32/PlayerSettings.pm
index d4a4e2d6..b2bbf166 100644
--- a/plugin/SqueezeESP32/PlayerSettings.pm
+++ b/plugin/SqueezeESP32/PlayerSettings.pm
@@ -43,22 +43,29 @@ sub handler {
if ($paramRef->{'saveSettings'}) {
if ($client->displayWidth) {
$cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15);
- my $spectrum = {
- scale => $paramRef->{'pref_spectrum_scale'} || 25,
- small => { size => $paramRef->{'pref_spectrum_small_size'} || 25,
- band => $paramRef->{'pref_spectrum_small_band'} || 5.33 },
- full => { band => $paramRef->{'pref_spectrum_full_band'} } || 8,
- };
+
+ require Plugins::SqueezeESP32::Graphics;
+ my $spectrum = Plugins::SqueezeESP32::Graphics::sanitizeSpectrum({
+ scale => $paramRef->{'pref_spectrum_scale'},
+ small => {
+ size => $paramRef->{'pref_spectrum_small_size'},
+ band => $paramRef->{'pref_spectrum_small_band'}
+ },
+ full => {
+ band => $paramRef->{'pref_spectrum_full_band'}
+ },
+ });
$cprefs->set('spectrum', $spectrum);
my $artwork = {
- enable => $paramRef->{'pref_artwork_enable'},
+ enable => $paramRef->{'pref_artwork_enable'} eq 'on',
x => $paramRef->{'pref_artwork_x'} || 0,
y => $paramRef->{'pref_artwork_y'} || 0,
};
+
$cprefs->set('artwork', $artwork);
$client->display->modes($client->display->build_modes);
- $client->display->update;
+ # the display update will be done below, after all is completed
# force update or disable artwork
if ($artwork->{'enable'}) {
@@ -66,6 +73,7 @@ sub handler {
} else {
$client->config_artwork();
}
+
}
my $equalizer = $cprefs->get('equalizer');
diff --git a/plugin/SqueezeESP32/Plugin.pm b/plugin/SqueezeESP32/Plugin.pm
index 007f65f4..d5a0158b 100644
--- a/plugin/SqueezeESP32/Plugin.pm
+++ b/plugin/SqueezeESP32/Plugin.pm
@@ -24,6 +24,12 @@ $prefs->migrateClient(1, sub {
1;
});
+$prefs->migrateClient(2, sub {
+ my ($cprefs, $client) = @_;
+ $cprefs->set('artwork', undef) if $cprefs->get('artwork') && ref $cprefs->get('artwork') ne 'HASH';
+ 1;
+});
+
$prefs->setChange(sub {
$_[2]->send_equalizer;
}, 'equalizer');
@@ -67,8 +73,9 @@ sub onNotification {
my $request = shift;
my $client = $request->client || return;
- if ($client->isa('Plugins::SqueezeESP32::Player')) {
- $client->update_artwork();
+ foreach my $player ($client->syncGroupActiveMembers) {
+ next unless $player->isa('Plugins::SqueezeESP32::Player');
+ $player->update_artwork;
}
}
diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml
index e241642f..200de627 100644
--- a/plugin/SqueezeESP32/install.xml
+++ b/plugin/SqueezeESP32/install.xml
@@ -10,6 +10,6 @@
PLUGIN_SQUEEZEESP32
PLUGIN_SQUEEZEESP32_DESC
Plugins::SqueezeESP32::Plugin
- 0.200
+ 0.211
Philippe
diff --git a/plugin/SqueezeESP32/strings.txt b/plugin/SqueezeESP32/strings.txt
index 0ab48a8c..965e67de 100644
--- a/plugin/SqueezeESP32/strings.txt
+++ b/plugin/SqueezeESP32/strings.txt
@@ -80,8 +80,10 @@ PLUGIN_SQUEEZEESP32_ARTWORK
PLUGIN_SQUEEZEESP32_ARTWORK_DESC
DE Wenn die Y Position kleiner als 32 ist, dann werden Plattenhüllen auf der rechten Seite angezeigt, und x definiert die Startposition.
DE Plattenhüllen werden auf Displays mit weniger als 16 Graustufen in sehr geringer Qualität angezeigt.
- EN When Y position is less than 32, then artwork is displayed 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
+ EN When Y position is less than 32, then artwork is displayed at the right of the main screen and X defines the starting position
+ EN
On large screen, it's possible to rotate the VU/Spectrum by setting a small X offset (typically 32). That will push the
+ EN artwork to the right and make space for a vertical VU to its left.
+ EN
Note that using artwork on less than 16-levels grayscale display if really poor quality
PLUGIN_SQUEEZEESP32_ARTWORK_ENABLE
DE Aktivieren