Compare commits

..

11 Commits

13 changed files with 95 additions and 68 deletions

View File

@@ -35,7 +35,7 @@ static bool I2CDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data,
bool GDS_I2CInit( int PortNumber, int SDA, int SCL, int Speed ) { bool GDS_I2CInit( int PortNumber, int SDA, int SCL, int Speed ) {
I2CPortNumber = PortNumber; I2CPortNumber = PortNumber;
I2CWait = pdMS_TO_TICKS( Speed ? Speed / 4000 : 100 ); I2CWait = pdMS_TO_TICKS( Speed ? (250 * 250000) / Speed : 250 );
if (SDA != -1 && SCL != -1) { if (SDA != -1 && SCL != -1) {
i2c_config_t Config = { 0 }; i2c_config_t Config = { 0 };

View File

@@ -85,7 +85,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 %d on:%d off:%d, pushed:%u", idx, ontime, offtime, pushed);
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) {
@@ -231,8 +231,7 @@ 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);
@@ -242,4 +241,6 @@ void led_svc_init(void) {
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);
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 );
} }

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

@@ -46,27 +46,17 @@ struct buffer *streambuf = &buf;
#define UNLOCK mutex_unlock(streambuf->mutex) #define UNLOCK mutex_unlock(streambuf->mutex)
/* /*
After a lot of hesitation, I've added that "poll mutex" to prevent When LMS sends a close/open sequence very quickly, the stream thread might
socket from being allocated while we are still in poll(). The issue still be waiting in the poll() on the closed socket. It is never recommended
happens is we have a close quickly followed by an open, we might still to have a thread closing a socket used by another thread but it works, as
be in the poll() and simple OS fail as they re-allocate the same socket opposed to an infinite select().
on which a thread is still waiting. In stream_sock() a new socket is created and full OS will allocate a different
Ideally, you want to set the lock in the disconnect() but that would mean one but on RTOS and simple IP stack, the same might be re-used and that causes
very often we'd have to always wait for the end of the poll(), i.e. up to an exception as a thread is already waiting on a newly allocated socket
100ms for nothing most of the time where if it is in the open(), it is A simple variable that forces stream_sock() to wait until we are out of poll()
less elegant as closing a socket on which there is a poll() is not good is enough and much faster than a mutex
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 bool polling;
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; static sockfd fd;
struct streamstate stream; struct streamstate stream;
@@ -209,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) {
@@ -218,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
@@ -374,7 +365,7 @@ static void *stream_thread() {
UNLOCK; UNLOCK;
} else { } else {
UNLOCK_L; polling = false;
LOG_SDEBUG("poll timeout"); LOG_SDEBUG("poll timeout");
} }
} }
@@ -427,9 +418,6 @@ void stream_init(log_level level, unsigned stream_buf_size) {
*stream.header = '\0'; *stream.header = '\0';
fd = -1; fd = -1;
#if EMBEDDED
mutex_create_p(poll_mutex);
#endif
#if LINUX || FREEBSD #if LINUX || FREEBSD
touch_memory(streambuf->buf, streambuf->size); touch_memory(streambuf->buf, streambuf->size);
@@ -459,9 +447,6 @@ void stream_close(void) {
#endif #endif
free(stream.header); free(stream.header);
buf_destroy(streambuf); buf_destroy(streambuf);
#if EMBEDDED
mutex_destroy(poll_mutex);
#endif
} }
void stream_file(const char *header, size_t header_len, unsigned threshold) { void stream_file(const char *header, size_t header_len, unsigned threshold) {
@@ -503,9 +488,12 @@ 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;
LOCK_L; #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);
UNLOCK_L;
if (sock < 0) { if (sock < 0) {
LOG_ERROR("failed to create socket"); LOG_ERROR("failed to create socket");

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;
} }

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

@@ -447,7 +447,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,"*******************************************************************************************");

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 }
@@ -54,7 +66,7 @@ sub init {
my $client = shift; my $client = shift;
if (!$handlersAdded) { if (!$handlersAdded) {
# Add a handler for line-in/out status changes # Add a handler for line-in/out status changes
Slim::Networking::Slimproto::addHandler( LIOS => \&lineInOutStatus ); Slim::Networking::Slimproto::addHandler( LIOS => \&lineInOutStatus );
@@ -117,25 +129,41 @@ sub playerSettingsFrame {
} }
sub bass { sub bass {
return tone(2, @_); my ($client, $new) = @_;
} my $value = $client->SUPER::bass($new);
sub treble { $client->update_equalizer($value, [2, 1, 3]) if defined $new;
return tone(8, @_);
return $value;
} }
sub tone { sub treble {
my ($center, $client, $value) = @_; my ($client, $new) = @_;
my $equalizer = $prefs->client($client)->get('equalizer'); my $value = $client->SUPER::treble($new);
if (defined($value)) { $client->update_equalizer($value, [8, 9, 7]) if defined $new;
$equalizer->[$center-1] = int($value * 0.2 + 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);
}
return int($equalizer->[$center-1] * 0.2 + $equalizer->[$center] * 0.7 + $equalizer->[$center+1] * 0.1); return $value;
}
sub update_equalizer {
my ($client, $value, $index) = @_;
return if $client->tone_update;
my $equalizer = $prefs->client($client)->get('equalizer');
$equalizer->[$index->[0]] = $value;
$equalizer->[$index->[1]] = int($value / 2 + 0.5);
$equalizer->[$index->[2]] = int($value / 4 + 0.5);
$prefs->client($client)->set('equalizer', $equalizer);
}
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>