diff --git a/components/codecs/lib/libmad.a b/components/codecs/lib/libmad.a
index fdb17fae..fa9aced8 100644
Binary files a/components/codecs/lib/libmad.a and b/components/codecs/lib/libmad.a differ
diff --git a/components/display/ST77xx.c b/components/display/ST77xx.c
index 3deaee2a..78d59d87 100644
--- a/components/display/ST77xx.c
+++ b/components/display/ST77xx.c
@@ -90,7 +90,7 @@ static void Update16( struct GDS_Device* Device ) {
for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize);
optr += ChunkSize;
- if (optr - Private->iRAM < PAGE_BLOCK && i < LastRow) continue;
+ if (optr - Private->iRAM <= (PAGE_BLOCK - ChunkSize) && i < LastRow) continue;
Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM;
}
@@ -157,7 +157,7 @@ static void Update24( struct GDS_Device* Device ) {
for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 3, ChunkSize);
optr += ChunkSize;
- if (optr - Private->iRAM < PAGE_BLOCK && i < LastRow) continue;
+ if (optr - Private->iRAM <= (PAGE_BLOCK - ChunkSize) && i < LastRow) continue;
Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM;
}
diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c
index af263eab..20b8547d 100644
--- a/components/squeezelite/display.c
+++ b/components/squeezelite/display.c
@@ -628,8 +628,9 @@ static void grfe_handler( u8_t *data, int len) {
scroller.active = false;
- // visu has priority when full screen on small screens
- if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) {
+ // full screen artwork or for small screen, full screen visu has priority
+ if (((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) ||
+ (artwork.enable && artwork.x == 0 && artwork.y == 0)) {
xSemaphoreGive(displayer.mutex);
return;
}
@@ -751,8 +752,11 @@ static void grfg_handler(u8_t *data, int len) {
LOG_DEBUG("gfrg s:%hu w:%hu (len:%u)", htons(pkt->screen), htons(pkt->width), len);
- // on small screen, visu has priority when full screen
- if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) return;
+ // full screen artwork or for small screen, visu has priority when full screen
+ if (((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) ||
+ (artwork.enable && artwork.x == 0 && artwork.y == 0)) {
+ return;
+ }
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
@@ -795,7 +799,7 @@ static void grfa_handler(u8_t *data, int len) {
// when using full screen visualizer on small screen there is a brief overlay
artwork.enable = (length != 0);
-
+
// just a config or an actual artwork
if (length < 32) {
if (artwork.enable) {
@@ -840,8 +844,10 @@ static void grfa_handler(u8_t *data, int len) {
* Update visualization bars
*/
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;
+ // no update when artwork is full screen (but no need to protect against not owning the display as we are playing
+ if ((artwork.enable && artwork.x == 0 && artwork.y == 0) || pthread_mutex_trylock(&visu_export.mutex)) {
+ return;
+ }
int mode = visu.mode & ~VISU_ESP32;
diff --git a/components/squeezelite/mad.c b/components/squeezelite/mad.c
index a34b5e2b..ccc6d50b 100644
--- a/components/squeezelite/mad.c
+++ b/components/squeezelite/mad.c
@@ -243,8 +243,6 @@ static decode_state mad_decode(void) {
MAD(m, synth_frame, &m->synth, &m->frame);
if (decode.new_stream) {
- // seems that mad can use some help in term of sync detection
- if (m->stream.next_frame[0] != 0xff || (m->stream.next_frame[1] & 0xf0) != 0xf0) continue;
LOCK_O;
LOG_INFO("setting track_start");
output.next_sample_rate = decode_newstream(m->synth.pcm.samplerate, output.supported_rates);
diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c
index be32c635..f06d6e8f 100644
--- a/components/squeezelite/output_i2s.c
+++ b/components/squeezelite/output_i2s.c
@@ -234,6 +234,11 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
set_i2s_pin(spdif_config, &i2s_spdif_pin);
set_i2s_pin(dac_config, &i2s_dac_pin);
+ /* BEWARE: i2s. must be patched to set tx_msb_right/rx_msb_right to 1
+ * or SPDIF will not work. These settings are not accessible from
+ * userland and I don't know why
+ */
+
// common I2S initialization
i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX;
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
diff --git a/components/squeezelite/stream.c b/components/squeezelite/stream.c
index f9247e11..73d097ce 100644
--- a/components/squeezelite/stream.c
+++ b/components/squeezelite/stream.c
@@ -42,8 +42,30 @@ static log_level loglevel;
static struct buffer buf;
struct buffer *streambuf = &buf;
-#define LOCK mutex_lock(streambuf->mutex)
-#define UNLOCK mutex_unlock(streambuf->mutex)
+#define LOCK mutex_lock(streambuf->mutex)
+#define UNLOCK mutex_unlock(streambuf->mutex)
+
+/*
+After a lot of hesitation, I've added that "poll mutex" to prevent
+socket from being allocated while we are still in poll(). The issue
+happens is we have a close quickly followed by an open, we might still
+be in the poll() and simple OS fail as they re-allocate the same socket
+on which a thread is still waiting.
+Ideally, you want to set the lock in the disconnect() but that would mean
+very often we'd have to always wait for the end of the poll(), i.e. up to
+100ms for nothing most of the time where if it is in the open(), it is
+less elegant as closing a socket on which there is a poll() is not good
+but it's more efficient as it is very rare that you'd have an open() less
+then 100ms after a close()
+*/
+#if EMBEDDED
+static mutex_type poll_mutex;
+#define LOCK_L mutex_lock(poll_mutex)
+#define UNLOCK_L mutex_unlock(poll_mutex)
+#else
+#define LOCK_L
+#define UNLOCK_L
+#endif
static sockfd fd;
@@ -187,6 +209,7 @@ static void *stream_thread() {
} else {
+ LOCK_L;
pollinfo.fd = fd;
pollinfo.events = POLLIN;
if (stream.state == SEND_HEADERS) {
@@ -195,9 +218,10 @@ static void *stream_thread() {
}
UNLOCK;
-
+
if (_poll(ssl, &pollinfo, 100)) {
+ UNLOCK_L;
LOCK;
// check socket has not been closed while in poll
@@ -350,7 +374,7 @@ static void *stream_thread() {
UNLOCK;
} else {
-
+ UNLOCK_L;
LOG_SDEBUG("poll timeout");
}
}
@@ -403,6 +427,9 @@ void stream_init(log_level level, unsigned stream_buf_size) {
*stream.header = '\0';
fd = -1;
+#if EMBEDDED
+ mutex_create_p(poll_mutex);
+#endif
#if LINUX || FREEBSD
touch_memory(streambuf->buf, streambuf->size);
@@ -432,13 +459,16 @@ void stream_close(void) {
#endif
free(stream.header);
buf_destroy(streambuf);
+#if EMBEDDED
+ mutex_destroy(poll_mutex);
+#endif
}
void stream_file(const char *header, size_t header_len, unsigned threshold) {
buf_flush(streambuf);
LOCK;
-
+
stream.header_len = header_len;
memcpy(stream.header, header, header_len);
*(stream.header+header_len) = '\0';
@@ -473,7 +503,9 @@ void stream_file(const char *header, size_t header_len, unsigned threshold) {
void stream_sock(u32_t ip, u16_t port, const char *header, size_t header_len, unsigned threshold, bool cont_wait) {
struct sockaddr_in addr;
+ LOCK_L;
int sock = socket(AF_INET, SOCK_STREAM, 0);
+ UNLOCK_L;
if (sock < 0) {
LOG_ERROR("failed to create socket");
diff --git a/plugin/SqueezeESP32.zip b/plugin/SqueezeESP32.zip
index 41c94a05..8a052484 100644
Binary files a/plugin/SqueezeESP32.zip and b/plugin/SqueezeESP32.zip differ
diff --git a/plugin/SqueezeESP32/Graphics.pm b/plugin/SqueezeESP32/Graphics.pm
index b23cf95b..6f763be7 100644
--- a/plugin/SqueezeESP32/Graphics.pm
+++ b/plugin/SqueezeESP32/Graphics.pm
@@ -78,7 +78,7 @@ sub displayWidth {
if ($display->widthOverride) {
my $artwork = $prefs->client($client)->get('artwork');
if ($artwork->{'enable'} && $artwork->{'y'} < 32 && ($client->isPlaying || $client->isPaused)) {
- return $artwork->{x} + ($display->modes->[$mode || 0]{_width} || 0);
+ return ($artwork->{x} || $display->widthOverride) + ($display->modes->[$mode || 0]{_width} || 0);
} else {
return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0);
}
@@ -113,9 +113,9 @@ sub build_modes {
my $artwork = $cprefs->get('artwork');
my $disp_width = $cprefs->get('width') || 128;
- # if artwork is in main display, reduce width
- my $width = ($artwork->{'enable'} && $artwork->{'y'} < 32) ? $artwork->{'x'} : $disp_width;
- my $width_low = ($artwork->{'enable'} && ($artwork->{'y'} >= 32 || $disp_width - $artwork->{'x'} > 32)) ? $artwork->{'x'} : $disp_width;
+ # if artwork is in main display, reduce width but when artwork is (0,0) fake it
+ my $width = ($artwork->{'enable'} && $artwork->{'y'} < 32 && $artwork->{'x'}) ? $artwork->{'x'} : $disp_width;
+ 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');
diff --git a/plugin/SqueezeESP32/Player.pm b/plugin/SqueezeESP32/Player.pm
index 1e065155..78eba318 100644
--- a/plugin/SqueezeESP32/Player.pm
+++ b/plugin/SqueezeESP32/Player.pm
@@ -221,6 +221,11 @@ sub clear_artwork {
if ($artwork && $artwork->{'enable'}) {
main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . $request->getRequestString());
$client->pluginData('artwork_md5', '');
+ # refresh screen and disable artwork when artwork was full screen (hack)
+ if (!$artwork->{'x'} && !$artwork->{'y'}) {
+ $client->sendFrame(grfa => \("\x00"x4)) unless $artwork->{'x'} || $artwork->{'y'};
+ $client->display->update;
+ }
}
}
diff --git a/plugin/SqueezeESP32/PlayerSettings.pm b/plugin/SqueezeESP32/PlayerSettings.pm
index d4a4e2d6..cde4bb0c 100644
--- a/plugin/SqueezeESP32/PlayerSettings.pm
+++ b/plugin/SqueezeESP32/PlayerSettings.pm
@@ -31,7 +31,7 @@ sub page {
sub prefs {
my ($class, $client) = @_;
my @prefs;
- push @prefs, qw(width small_VU) if $client->displayWidth;
+ push @prefs, qw(width small_VU) if defined $client->displayWidth;
return ($prefs->client($client), @prefs);
}
@@ -41,7 +41,7 @@ sub handler {
my ($cprefs, @prefs) = $class->prefs($client);
if ($paramRef->{'saveSettings'}) {
- if ($client->displayWidth) {
+ if (defined $client->displayWidth) {
$cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15);
my $spectrum = {
scale => $paramRef->{'pref_spectrum_scale'} || 25,
@@ -76,7 +76,7 @@ sub handler {
$client->update_tones($equalizer);
}
- if ($client->displayWidth) {
+ if (defined $client->displayWidth) {
# the Settings super class can't handle anything but scalar values
# we need to populate the $paramRef for the other prefs manually
$paramRef->{'pref_spectrum'} = $cprefs->get('spectrum');
diff --git a/plugin/SqueezeESP32/install.xml b/plugin/SqueezeESP32/install.xml
index 6cc9ba28..ef8c3894 100644
--- a/plugin/SqueezeESP32/install.xml
+++ b/plugin/SqueezeESP32/install.xml
@@ -10,6 +10,6 @@
PLUGIN_SQUEEZEESP32PLUGIN_SQUEEZEESP32_DESCPlugins::SqueezeESP32::Plugin
- 0.103
+ 0.104Philippe
diff --git a/plugin/repo.xml b/plugin/repo.xml
index 572a6419..8a7a7cac 100644
--- a/plugin/repo.xml
+++ b/plugin/repo.xml
@@ -1,10 +1,10 @@
-
+
https://github.com/sle118/squeezelite-esp32
Philippe
- d07bb3b0a283fbde50e5533dca695a4505971f03
+ 79e505a30d7b6dbf43893acab176d57438e2a4a1philippe_44@outlook.comSqueezeESP32 additional player id (100)http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip