Compare commits

...

9 Commits

17 changed files with 129 additions and 64 deletions

Binary file not shown.

View File

@@ -90,7 +90,7 @@ static void Update16( struct GDS_Device* Device ) {
for (int i = FirstRow; i <= LastRow; i++) { for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize); memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize);
optr += 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); Device->WriteData(Device, Private->iRAM, optr - 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++) { for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 3, ChunkSize); memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 3, ChunkSize);
optr += 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); Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM; optr = Private->iRAM;
} }

View File

@@ -5,7 +5,6 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@@ -85,7 +84,7 @@ static void vCallbackFunction( TimerHandle_t xTimer ) {
bool led_blink_core(int idx, int ontime, int offtime, bool pushed) { bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
if (!leds[idx].gpio || leds[idx].gpio < 0 ) return false; if (!leds[idx].gpio || leds[idx].gpio < 0 ) return false;
ESP_LOGD(TAG,"led_blink_core"); ESP_LOGD(TAG,"led_blink_core led idx %d, ontime %d, offtime %d, pushing %s. Led state: pushedon %d, pushedoff %d, timer %s, pushed %s", idx,ontime,offtime,pushed?"TRUE":"FALSE", leds[idx].pushedon,leds[idx].pushedoff,leds[idx].timer?"TRUE":"FALSE", leds[idx].pushed?"TRUE":"FALSE");
if (leds[idx].timer) { if (leds[idx].timer) {
// normal requests waits if a pop is pending // normal requests waits if a pop is pending
if (!pushed && leds[idx].pushed) { if (!pushed && leds[idx].pushed) {
@@ -98,15 +97,18 @@ bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
// save current state if not already pushed // save current state if not already pushed
if (!leds[idx].pushed) { if (!leds[idx].pushed) {
ESP_LOGD(TAG,"Pushing state. Ontime %d->%d. Offtime %d->%d",leds[idx].pushedon,leds[idx].ontime, leds[idx].pushedoff,leds[idx].offtime);
leds[idx].pushedon = leds[idx].ontime; leds[idx].pushedon = leds[idx].ontime;
leds[idx].pushedoff = leds[idx].offtime; leds[idx].pushedoff = leds[idx].offtime;
leds[idx].pushed = pushed; leds[idx].pushed = pushed;
} }
// then set new one // then set new one
leds[idx].ontime = ontime; leds[idx].ontime = ontime;
leds[idx].offtime = offtime; leds[idx].offtime = offtime;
if (ontime == 0) { if (ontime == 0) {
ESP_LOGD(TAG,"led %d, setting reverse level", idx); ESP_LOGD(TAG,"led %d, setting reverse level", idx);
set_level(leds + idx, false); set_level(leds + idx, false);
@@ -124,6 +126,7 @@ bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
ESP_LOGD(TAG,"led %d, Setting gpio %d and starting timer", idx, leds[idx].gpio); ESP_LOGD(TAG,"led %d, Setting gpio %d and starting timer", idx, leds[idx].gpio);
if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false; if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false;
} }
ESP_LOGD(TAG,"led_blink_core END led idx %d, ontime %d, offtime %d, pushing %s. Led state: pushedon %d, pushedoff %d, timer %s, pushed %s", idx,ontime,offtime,pushed?"TRUE":"FALSE", leds[idx].pushedon,leds[idx].pushedoff,leds[idx].timer?"TRUE":"FALSE", leds[idx].pushed?"TRUE":"FALSE");
return true; return true;
@@ -231,15 +234,13 @@ void led_svc_init(void) {
#ifndef CONFIG_LED_LOCKED #ifndef CONFIG_LED_LOCKED
parse_set_GPIO(set_led_gpio); parse_set_GPIO(set_led_gpio);
#endif #endif
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d %d%%), red:%d (active:%d %d%%)", green.gpio, green.active, green.pwm, green.gpio, green.active, green.pwm );
char *nvs_item = config_alloc_get(NVS_TYPE_STR, "led_brightness"), *p; char *nvs_item = config_alloc_get(NVS_TYPE_STR, "led_brightness"), *p;
if (nvs_item) { if (nvs_item) {
if ((p = strcasestr(nvs_item, "green")) != NULL) green.pwm = atoi(strchr(p, '=') + 1); if ((p = strcasestr(nvs_item, "green")) != NULL) green.pwm = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "red")) != NULL) red.pwm = atoi(strchr(p, '=') + 1); if ((p = strcasestr(nvs_item, "red")) != NULL) red.pwm = atoi(strchr(p, '=') + 1);
free(nvs_item); free(nvs_item);
} }
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d %d%%), red:%d (active:%d %d%%)", green.gpio, green.active, green.pwm, red.gpio, red.active, red.pwm );
led_config(LED_GREEN, green.gpio, green.active, green.pwm); led_config(LED_GREEN, green.gpio, green.active, green.pwm);
led_config(LED_RED, red.gpio, red.active, red.pwm); led_config(LED_RED, red.gpio, red.active, red.pwm);
} }

View File

@@ -628,8 +628,9 @@ static void grfe_handler( u8_t *data, int len) {
scroller.active = false; scroller.active = false;
// visu has priority when full screen on small screens // full screen artwork or for small screen, full screen visu has priority
if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) { if (((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) ||
(artwork.enable && artwork.x == 0 && artwork.y == 0)) {
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
return; 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); 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 // full screen artwork or for small screen, visu has priority when full screen
if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) return; 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); xSemaphoreTake(displayer.mutex, portMAX_DELAY);
@@ -840,8 +844,10 @@ static void grfa_handler(u8_t *data, int len) {
* Update visualization bars * Update visualization bars
*/ */
static void visu_update(void) { static void visu_update(void) {
// no need to protect against no woning the display as we are playing // no update when artwork is full screen (but no need to protect against not owning the display as we are playing
if (pthread_mutex_trylock(&visu_export.mutex)) return; if ((artwork.enable && artwork.x == 0 && artwork.y == 0) || pthread_mutex_trylock(&visu_export.mutex)) {
return;
}
int mode = visu.mode & ~VISU_ESP32; int mode = visu.mode & ~VISU_ESP32;

View File

@@ -128,7 +128,7 @@ static esp_err_t i2c_write_reg(uint8_t reg, uint8_t val) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK); i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK); i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, val, I2C_MASTER_NACK); i2c_master_write_byte(cmd, val, I2C_MASTER_NACK);
@@ -153,11 +153,11 @@ static uint8_t i2c_read_reg(uint8_t reg) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK); i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK); i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_READ, I2C_MASTER_NACK); i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_READ, I2C_MASTER_NACK);
i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK); i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK);
i2c_master_stop(cmd); i2c_master_stop(cmd);

View File

@@ -243,8 +243,6 @@ static decode_state mad_decode(void) {
MAD(m, synth_frame, &m->synth, &m->frame); MAD(m, synth_frame, &m->synth, &m->frame);
if (decode.new_stream) { 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; LOCK_O;
LOG_INFO("setting track_start"); LOG_INFO("setting track_start");
output.next_sample_rate = decode_newstream(m->synth.pcm.samplerate, output.supported_rates); output.next_sample_rate = decode_newstream(m->synth.pcm.samplerate, output.supported_rates);

View File

@@ -40,14 +40,23 @@
static log_level loglevel; static log_level loglevel;
static struct buffer buf; static struct buffer buf;
static mutex_type poll_mutex;
struct buffer *streambuf = &buf; struct buffer *streambuf = &buf;
#define LOCK mutex_lock(streambuf->mutex) #define LOCK mutex_lock(streambuf->mutex)
#define UNLOCK mutex_unlock(streambuf->mutex) #define UNLOCK mutex_unlock(streambuf->mutex)
#define LOCK_L mutex_lock(poll_mutex)
#define UNLOCK_L mutex_unlock(poll_mutex)
/*
When LMS sends a close/open sequence very quickly, the stream thread might
still be waiting in the poll() on the closed socket. It is never recommended
to have a thread closing a socket used by another thread but it works, as
opposed to an infinite select().
In stream_sock() a new socket is created and full OS will allocate a different
one but on RTOS and simple IP stack, the same might be re-used and that causes
an exception as a thread is already waiting on a newly allocated socket
A simple variable that forces stream_sock() to wait until we are out of poll()
is enough and much faster than a mutex
*/
static bool polling;
static sockfd fd; static sockfd fd;
struct streamstate stream; struct streamstate stream;
@@ -190,7 +199,6 @@ static void *stream_thread() {
} else { } else {
LOCK_L;
pollinfo.fd = fd; pollinfo.fd = fd;
pollinfo.events = POLLIN; pollinfo.events = POLLIN;
if (stream.state == SEND_HEADERS) { if (stream.state == SEND_HEADERS) {
@@ -199,10 +207,12 @@ static void *stream_thread() {
} }
UNLOCK; UNLOCK;
// no mutex needed - we just want to know if we are inside poll()
polling = true;
if (_poll(ssl, &pollinfo, 100)) { if (_poll(ssl, &pollinfo, 100)) {
UNLOCK_L; polling = false;
LOCK; LOCK;
// check socket has not been closed while in poll // check socket has not been closed while in poll
@@ -355,7 +365,7 @@ static void *stream_thread() {
UNLOCK; UNLOCK;
} else { } else {
UNLOCK_L; polling = false;
LOG_SDEBUG("poll timeout"); LOG_SDEBUG("poll timeout");
} }
} }
@@ -408,7 +418,6 @@ void stream_init(log_level level, unsigned stream_buf_size) {
*stream.header = '\0'; *stream.header = '\0';
fd = -1; fd = -1;
mutex_create_p(poll_mutex);
#if LINUX || FREEBSD #if LINUX || FREEBSD
touch_memory(streambuf->buf, streambuf->size); touch_memory(streambuf->buf, streambuf->size);
@@ -438,7 +447,6 @@ void stream_close(void) {
#endif #endif
free(stream.header); free(stream.header);
buf_destroy(streambuf); buf_destroy(streambuf);
mutex_destroy(poll_mutex);
} }
void stream_file(const char *header, size_t header_len, unsigned threshold) { void stream_file(const char *header, size_t header_len, unsigned threshold) {
@@ -480,6 +488,11 @@ 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) { 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; struct sockaddr_in addr;
#if EMBEDDED
// wait till we are not polling anymore
while (polling && running) { usleep(10000); }
#endif
int sock = socket(AF_INET, SOCK_STREAM, 0); int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
@@ -588,13 +601,11 @@ bool stream_disconnect(void) {
ssl = NULL; ssl = NULL;
} }
#endif #endif
LOCK_L;
if (fd != -1) { if (fd != -1) {
closesocket(fd); closesocket(fd);
fd = -1; fd = -1;
disc = true; disc = true;
} }
UNLOCK_L,
stream.state = STOPPED; stream.state = STOPPED;
UNLOCK; UNLOCK;
return disc; return disc;

View File

@@ -462,7 +462,11 @@ cJSON * wifi_manager_get_basic_info(cJSON **old){
cJSON_AddNumberToObject(root,"Voltage", battery_value_svc()); cJSON_AddNumberToObject(root,"Voltage", battery_value_svc());
cJSON_AddNumberToObject(root,"disconnect_count", num_disconnect ); cJSON_AddNumberToObject(root,"disconnect_count", num_disconnect );
cJSON_AddNumberToObject(root,"avg_conn_time", num_disconnect>0?(total_connected_time/num_disconnect):0 ); cJSON_AddNumberToObject(root,"avg_conn_time", num_disconnect>0?(total_connected_time/num_disconnect):0 );
#if CONFIG_I2C_LOCKED
cJSON_AddTrueToObject(root, "is_i2c_locked");
#else
cJSON_AddFalseToObject(root, "is_i2c_locked");
#endif
ESP_LOGV(TAG, "wifi_manager_get_basic_info done"); ESP_LOGV(TAG, "wifi_manager_get_basic_info done");
return root; return root;
} }
@@ -689,6 +693,8 @@ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_
ESP_LOGD(TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s",stac->aid,STR_OR_BLANK(mac)); ESP_LOGD(TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s",stac->aid,STR_OR_BLANK(mac));
FREE_AND_NULL(mac); FREE_AND_NULL(mac);
xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_AP_STA_CONNECTED_BIT); xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_AP_STA_CONNECTED_BIT);
wifi_manager_send_message(EVENT_STA_CONNECTED, NULL);
} }
break; break;
case WIFI_EVENT_AP_STADISCONNECTED: case WIFI_EVENT_AP_STADISCONNECTED:
@@ -1476,6 +1482,9 @@ void wifi_manager( void * pvParameters ){
/* callback */ /* callback */
if(cb_ptr_arr[msg.code]) (*cb_ptr_arr[msg.code])(NULL); if(cb_ptr_arr[msg.code]) (*cb_ptr_arr[msg.code])(NULL);
break; break;
case EVENT_STA_CONNECTED:
if(cb_ptr_arr[msg.code]) (*cb_ptr_arr[msg.code])(NULL);
break;
case UPDATE_CONNECTION_OK: case UPDATE_CONNECTION_OK:
/* refresh JSON */ /* refresh JSON */
if(wifi_manager_lock_json_buffer( portMAX_DELAY )){ if(wifi_manager_lock_json_buffer( portMAX_DELAY )){

View File

@@ -191,7 +191,8 @@ typedef enum message_code_t {
ORDER_RESTART_RECOVERY = 16, ORDER_RESTART_RECOVERY = 16,
ORDER_RESTART_OTA_URL = 17, ORDER_RESTART_OTA_URL = 17,
ORDER_RESTART = 18, ORDER_RESTART = 18,
MESSAGE_CODE_COUNT = 19 /* important for the callback array */ EVENT_STA_CONNECTED = 19,
MESSAGE_CODE_COUNT = 20 /* important for the callback array */
}message_code_t; }message_code_t;

View File

@@ -44,7 +44,7 @@ menu "Squeezelite-ESP32"
string string
default "model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14:0" if SQUEEZEAMP default "model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14:0" if SQUEEZEAMP
default "model=AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32" if A1S default "model=AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32" if A1S
default "model=I2S,bck=26,ws=25,do=33,i2c=106,sda=21,scl=22" if TWATCH2020 default "model=I2S,bck=26,ws=25,do=33,i2c=53,sda=21,scl=22" if TWATCH2020
default "" default ""
config SPDIF_CONFIG config SPDIF_CONFIG
string string

View File

@@ -95,6 +95,10 @@ void cb_connection_sta_disconnected(void *pvParameter){
bWifiConnected=false; bWifiConnected=false;
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
} }
void cb_connection_sta_connected(void *pvParameter){
}
bool wait_for_wifi(){ bool wait_for_wifi(){
bool connected=(xEventGroupGetBits(wifi_event_group) & CONNECTED_BIT)!=0; bool connected=(xEventGroupGetBits(wifi_event_group) & CONNECTED_BIT)!=0;
if(!connected){ if(!connected){
@@ -447,7 +451,7 @@ void app_main()
/* start the wifi manager */ /* start the wifi manager */
ESP_LOGD(TAG,"Blinking led"); ESP_LOGD(TAG,"Blinking led");
led_blink(LED_GREEN, 250, 250); led_blink_pushed(LED_GREEN, 250, 250);
if(bypass_wifi_manager){ if(bypass_wifi_manager){
ESP_LOGW(TAG,"*******************************************************************************************"); ESP_LOGW(TAG,"*******************************************************************************************");
@@ -463,6 +467,7 @@ void app_main()
* This can be either after we're started the AP mode, or after we've started the STA mode */ * This can be either after we're started the AP mode, or after we've started the STA mode */
wifi_manager_set_callback(ORDER_START_AP, &start_telnet); wifi_manager_set_callback(ORDER_START_AP, &start_telnet);
wifi_manager_set_callback(ORDER_CONNECT_STA, &start_telnet); wifi_manager_set_callback(ORDER_CONNECT_STA, &start_telnet);
wifi_manager_set_callback(EVENT_STA_CONNECTED, &cb_connection_sta_connected);
} }
console_start(); console_start();

Binary file not shown.

View File

@@ -78,7 +78,7 @@ sub displayWidth {
if ($display->widthOverride) { if ($display->widthOverride) {
my $artwork = $prefs->client($client)->get('artwork'); my $artwork = $prefs->client($client)->get('artwork');
if ($artwork->{'enable'} && $artwork->{'y'} < 32 && ($client->isPlaying || $client->isPaused)) { 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 { } else {
return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0); return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0);
} }
@@ -113,9 +113,9 @@ sub build_modes {
my $artwork = $cprefs->get('artwork'); my $artwork = $cprefs->get('artwork');
my $disp_width = $cprefs->get('width') || 128; my $disp_width = $cprefs->get('width') || 128;
# if artwork is in main display, reduce 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'} : $disp_width; my $width = ($artwork->{'enable'} && $artwork->{'y'} < 32 && $artwork->{'x'}) ? $artwork->{'x'} : $disp_width;
my $width_low = ($artwork->{'enable'} && ($artwork->{'y'} >= 32 || $disp_width - $artwork->{'x'} > 32)) ? $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 $small_VU = $cprefs->get('small_VU');
my $spectrum = $cprefs->get('spectrum'); my $spectrum = $cprefs->get('spectrum');

View File

@@ -13,6 +13,19 @@ my $sprefs = preferences('server');
my $prefs = preferences('plugin.squeezeesp32'); my $prefs = preferences('plugin.squeezeesp32');
my $log = logger('plugin.squeezeesp32'); my $log = logger('plugin.squeezeesp32');
{
__PACKAGE__->mk_accessor('rw', 'tone_update');
}
sub new {
my $class = shift;
my $client = $class->SUPER::new(@_);
$client->init_accessor(
tone_update => 0,
);
return $client;
}
our $defaultPrefs = { our $defaultPrefs = {
'analogOutMode' => 0, 'analogOutMode' => 0,
'bass' => 0, 'bass' => 0,
@@ -44,7 +57,6 @@ sub hasIR { 1 }
# TODO: add in settings when ready # TODO: add in settings when ready
sub hasLineIn { 0 } sub hasLineIn { 0 }
sub hasHeadSubOut { 1 } sub hasHeadSubOut { 1 }
# TODO: LMS sliders are hard-coded in html file from -23 to +23
sub maxTreble { 20 } sub maxTreble { 20 }
sub minTreble { -13 } sub minTreble { -13 }
sub maxBass { 20 } sub maxBass { 20 }
@@ -117,25 +129,41 @@ sub playerSettingsFrame {
} }
sub bass { sub bass {
return tone(2, @_); my ($client, $new) = @_;
my $value = $client->SUPER::bass($new);
$client->update_equalizer($value, [2, 1, 3]) if defined $new;
return $value;
} }
sub treble { sub treble {
return tone(8, @_); my ($client, $new) = @_;
my $value = $client->SUPER::treble($new);
$client->update_equalizer($value, [8, 9, 7]) if defined $new;
return $value;
} }
sub tone { sub update_equalizer {
my ($center, $client, $value) = @_; my ($client, $value, $index) = @_;
return if $client->tone_update;
my $equalizer = $prefs->client($client)->get('equalizer'); my $equalizer = $prefs->client($client)->get('equalizer');
$equalizer->[$index->[0]] = $value;
if (defined($value)) { $equalizer->[$index->[1]] = int($value / 2 + 0.5);
$equalizer->[$center-1] = int($value * 0.2 + 0.5); $equalizer->[$index->[2]] = int($value / 4 + 0.5);
$equalizer->[$center] = int($value * 0.7 + 0.5);
$equalizer->[$center+1] = int($value * 0.1 + 0.5);
$prefs->client($client)->set('equalizer', $equalizer); $prefs->client($client)->set('equalizer', $equalizer);
} }
return int($equalizer->[$center-1] * 0.2 + $equalizer->[$center] * 0.7 + $equalizer->[$center+1] * 0.1); sub update_tones {
my ($client, $equalizer) = @_;
$client->tone_update(1);
$sprefs->client($client)->set('bass', int(($equalizer->[1] * 2 + $equalizer->[2] + $equalizer->[3] * 4) / 7 + 0.5));
$sprefs->client($client)->set('treble', int(($equalizer->[7] * 4 + $equalizer->[8] + $equalizer->[9] * 2) / 7 + 0.5));
$client->tone_update(0);
} }
sub update_artwork { sub update_artwork {
@@ -193,6 +221,11 @@ sub clear_artwork {
if ($artwork && $artwork->{'enable'}) { if ($artwork && $artwork->{'enable'}) {
main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . $request->getRequestString()); main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . $request->getRequestString());
$client->pluginData('artwork_md5', ''); $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;
}
} }
} }

View File

@@ -31,7 +31,7 @@ sub page {
sub prefs { sub prefs {
my ($class, $client) = @_; my ($class, $client) = @_;
my @prefs; 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); return ($prefs->client($client), @prefs);
} }
@@ -41,7 +41,7 @@ sub handler {
my ($cprefs, @prefs) = $class->prefs($client); my ($cprefs, @prefs) = $class->prefs($client);
if ($paramRef->{'saveSettings'}) { if ($paramRef->{'saveSettings'}) {
if ($client->displayWidth) { if (defined $client->displayWidth) {
$cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15); $cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15);
my $spectrum = { my $spectrum = {
scale => $paramRef->{'pref_spectrum_scale'} || 25, scale => $paramRef->{'pref_spectrum_scale'} || 25,
@@ -73,9 +73,10 @@ sub handler {
$equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0; $equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0;
} }
$cprefs->set('equalizer', $equalizer); $cprefs->set('equalizer', $equalizer);
$client->update_tones($equalizer);
} }
if ($client->displayWidth) { if (defined $client->displayWidth) {
# the Settings super class can't handle anything but scalar values # the Settings super class can't handle anything but scalar values
# we need to populate the $paramRef for the other prefs manually # we need to populate the $paramRef for the other prefs manually
$paramRef->{'pref_spectrum'} = $cprefs->get('spectrum'); $paramRef->{'pref_spectrum'} = $cprefs->get('spectrum');

View File

@@ -10,6 +10,6 @@
<name>PLUGIN_SQUEEZEESP32</name> <name>PLUGIN_SQUEEZEESP32</name>
<description>PLUGIN_SQUEEZEESP32_DESC</description> <description>PLUGIN_SQUEEZEESP32_DESC</description>
<module>Plugins::SqueezeESP32::Plugin</module> <module>Plugins::SqueezeESP32::Plugin</module>
<version>0.100</version> <version>0.104</version>
<creator>Philippe</creator> <creator>Philippe</creator>
</extensions> </extensions>

View File

@@ -1,10 +1,10 @@
<?xml version='1.0' standalone='yes'?> <?xml version='1.0' standalone='yes'?>
<extensions> <extensions>
<plugins> <plugins>
<plugin version="0.100" name="SqueezeESP32" minTarget="7.9" maxTarget="*"> <plugin version="0.104" name="SqueezeESP32" minTarget="7.9" maxTarget="*">
<link>https://github.com/sle118/squeezelite-esp32</link> <link>https://github.com/sle118/squeezelite-esp32</link>
<creator>Philippe</creator> <creator>Philippe</creator>
<sha>572fa8afeaa3bc3cfb245b8d42ba05739aec584b</sha> <sha>79e505a30d7b6dbf43893acab176d57438e2a4a1</sha>
<email>philippe_44@outlook.com</email> <email>philippe_44@outlook.com</email>
<desc lang="EN">SqueezeESP32 additional player id (100)</desc> <desc lang="EN">SqueezeESP32 additional player id (100)</desc>
<url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url> <url>http://github.com/sle118/squeezelite-esp32/raw/master/plugin/SqueezeESP32.zip</url>