mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-10 13:37:03 +03:00
Merge branch 'master' of https://github.com/sle118/squeezelite-esp32.git
This commit is contained in:
@@ -25,7 +25,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "ctype.h"
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "esp_vfs_dev.h"
|
#include "esp_vfs_dev.h"
|
||||||
@@ -90,10 +89,10 @@ static void * free_fn(void * ptr){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void init_cJSON(){
|
void init_cJSON(){
|
||||||
|
static cJSON_Hooks hooks;
|
||||||
// initialize cJSON hooks it uses SPIRAM memory
|
// initialize cJSON hooks it uses SPIRAM memory
|
||||||
// as opposed to IRAM
|
// as opposed to IRAM
|
||||||
#if RECOVERY_APPLICATION==0
|
#if RECOVERY_APPLICATION==0
|
||||||
static cJSON_Hooks hooks;
|
|
||||||
// In squeezelite mode, allocate memory from PSRAM. Otherwise allocate from internal RAM
|
// In squeezelite mode, allocate memory from PSRAM. Otherwise allocate from internal RAM
|
||||||
// as recovery will lock flash access when erasing FLASH or writing to OTA partition.
|
// as recovery will lock flash access when erasing FLASH or writing to OTA partition.
|
||||||
hooks.malloc_fn=&malloc_fn;
|
hooks.malloc_fn=&malloc_fn;
|
||||||
@@ -705,39 +704,6 @@ esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_ALPHA(c) isalpha((int)c)
|
|
||||||
#define TO_UPPER(c) toupper((int)c)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char * strstri (const char * str1, const char * str2){
|
|
||||||
char *cp = (char *) str1;
|
|
||||||
char *s1, *s2;
|
|
||||||
|
|
||||||
if ( *str2=='\0' )
|
|
||||||
return((char *)str1);
|
|
||||||
|
|
||||||
while (*cp){
|
|
||||||
s1 = cp;
|
|
||||||
s2 = (char *) str2;
|
|
||||||
while ( *s1!='\0' && *s2!='\0' && (IS_ALPHA(*s1) && IS_ALPHA(*s2))?!(TO_UPPER(*s1) - TO_UPPER(*s2)):!(*s1-*s2)){
|
|
||||||
ESP_LOGW(TAG,"Matched [%c] = [%c] ", IS_ALPHA(*s1)?TO_UPPER(*s1):*s1,IS_ALPHA(*s2)?TO_UPPER(*s2):*s2);
|
|
||||||
++s1, ++s2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (*s2=='\0'){
|
|
||||||
ESP_LOGW(TAG,"String %s found!", str2);
|
|
||||||
return(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
++cp;
|
|
||||||
ESP_LOGW(TAG,"%s not found. s2 is [%c]. Moving forward to %s", str2, *s2, cp);
|
|
||||||
}
|
|
||||||
ESP_LOGW(TAG,"String %s not found", str2);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
IMPLEMENT_SET_DEFAULT(uint8_t,NVS_TYPE_U8);
|
IMPLEMENT_SET_DEFAULT(uint8_t,NVS_TYPE_U8);
|
||||||
IMPLEMENT_SET_DEFAULT(int8_t,NVS_TYPE_I8);
|
IMPLEMENT_SET_DEFAULT(int8_t,NVS_TYPE_I8);
|
||||||
IMPLEMENT_SET_DEFAULT(uint16_t,NVS_TYPE_U16);
|
IMPLEMENT_SET_DEFAULT(uint16_t,NVS_TYPE_U16);
|
||||||
@@ -751,4 +717,3 @@ IMPLEMENT_GET_NUM(uint16_t,NVS_TYPE_U16);
|
|||||||
IMPLEMENT_GET_NUM(int16_t,NVS_TYPE_I16);
|
IMPLEMENT_GET_NUM(int16_t,NVS_TYPE_I16);
|
||||||
IMPLEMENT_GET_NUM(uint32_t,NVS_TYPE_U32);
|
IMPLEMENT_GET_NUM(uint32_t,NVS_TYPE_U32);
|
||||||
IMPLEMENT_GET_NUM(int32_t,NVS_TYPE_I32);
|
IMPLEMENT_GET_NUM(int32_t,NVS_TYPE_I32);
|
||||||
|
|
||||||
|
|||||||
@@ -37,4 +37,4 @@ void * config_alloc_get(nvs_type_t nvs_type, const char *key) ;
|
|||||||
bool wait_for_commit();
|
bool wait_for_commit();
|
||||||
char * config_alloc_get_json(bool bFormatted);
|
char * config_alloc_get_json(bool bFormatted);
|
||||||
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value);
|
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value);
|
||||||
char * strstri (const char * str1, const char * str2);
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ void display_init(char *welcome) {
|
|||||||
|
|
||||||
if (item && *item) {
|
if (item && *item) {
|
||||||
char * drivername=strstr(item,"driver");
|
char * drivername=strstr(item,"driver");
|
||||||
if( !drivername || (drivername && (strstr(drivername,"SSD1306") || strstr(drivername,"ssd1306")))){
|
if (!drivername || (drivername && strcasestr(drivername,"SSD1306"))) {
|
||||||
handle = &SSD1306_handle;
|
handle = &SSD1306_handle;
|
||||||
if (handle->init(item, welcome)) {
|
if (handle->init(item, welcome)) {
|
||||||
slimp_handler_chain = slimp_handler;
|
slimp_handler_chain = slimp_handler;
|
||||||
@@ -73,7 +73,7 @@ void display_init(char *welcome) {
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Display initialization failed");
|
ESP_LOGE(TAG, "Display initialization failed");
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
ESP_LOGE(TAG,"Unknown display driver name in display config: %s",item);
|
ESP_LOGE(TAG,"Unknown display driver name in display config: %s",item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static void vfdc_handler( u8_t *_data, int bytes_read) {
|
|||||||
void grfe_handler( u8_t *data, int len) {
|
void grfe_handler( u8_t *data, int len) {
|
||||||
data += 8;
|
data += 8;
|
||||||
len -= 8;
|
len -= 8;
|
||||||
|
|
||||||
#ifndef FULL_REFRESH
|
#ifndef FULL_REFRESH
|
||||||
// force addressing mode by lines
|
// force addressing mode by lines
|
||||||
if (AddressMode != AddressMode_Horizontal) {
|
if (AddressMode != AddressMode_Horizontal) {
|
||||||
@@ -255,7 +255,7 @@ void grfe_handler( u8_t *data, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to minmize I2C traffic which is very slow
|
// try to minmize I2C traffic which is very slow
|
||||||
int rows = Display.Height / 8;
|
int rows = (Display.Height > 32) ? 4 : Display.Height / 8;
|
||||||
for (int r = 0; r < rows; r++) {
|
for (int r = 0; r < rows; r++) {
|
||||||
uint8_t first = 0, last;
|
uint8_t first = 0, last;
|
||||||
uint8_t *optr = Display.Framebuffer + r*Display.Width, *iptr = data + r;
|
uint8_t *optr = Display.Framebuffer + r*Display.Width, *iptr = data + r;
|
||||||
@@ -281,12 +281,15 @@ void grfe_handler( u8_t *data, int len) {
|
|||||||
// to be verified, but this is as fast as using a pointer on data
|
// to be verified, but this is as fast as using a pointer on data
|
||||||
for (int i = len - 1; i >= 0; i--) data[i] = BitReverseTable256[data[i]];
|
for (int i = len - 1; i >= 0; i--) data[i] = BitReverseTable256[data[i]];
|
||||||
|
|
||||||
|
if (Display.Height > 32) SSD1306_SetPageAddress( &Display, 0, 32/8-1);
|
||||||
|
|
||||||
// force addressing mode by columns
|
// force addressing mode by columns
|
||||||
if (AddressMode != AddressMode_Vertical) {
|
if (AddressMode != AddressMode_Vertical) {
|
||||||
AddressMode = AddressMode_Vertical;
|
AddressMode = AddressMode_Vertical;
|
||||||
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
|
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
|
||||||
}
|
}
|
||||||
SSD1306_WriteRawData( &Display, data, len);
|
|
||||||
|
SSD1306_WriteRawData(&Display, data, len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ static bool SSD1306_Init( struct SSD1306_Device* DeviceHandle, int Width, int He
|
|||||||
SSD1306_HWReset( DeviceHandle );
|
SSD1306_HWReset( DeviceHandle );
|
||||||
|
|
||||||
/* Init sequence according to SSD1306.pdf */
|
/* Init sequence according to SSD1306.pdf */
|
||||||
SSD1306_SetMuxRatio( DeviceHandle, 0x3F );
|
SSD1306_SetMuxRatio( DeviceHandle, Height - 1 );
|
||||||
SSD1306_SetDisplayOffset( DeviceHandle, 0x00 );
|
SSD1306_SetDisplayOffset( DeviceHandle, 0x00 );
|
||||||
SSD1306_SetDisplayStartLine( DeviceHandle, 0 );
|
SSD1306_SetDisplayStartLine( DeviceHandle, 0 );
|
||||||
SSD1306_SetHFlip( DeviceHandle, false );
|
SSD1306_SetHFlip( DeviceHandle, false );
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ static void control_handler(void *client, button_event_e event, button_press_e p
|
|||||||
ESP_LOGD(TAG, "control gpio:%u press:%u long:%u event:%u action:%u", key->gpio, press, long_press, event, action);
|
ESP_LOGD(TAG, "control gpio:%u press:%u long:%u event:%u action:%u", key->gpio, press, long_press, event, action);
|
||||||
|
|
||||||
if (action > ACTRLS_MAX) {
|
if (action > ACTRLS_MAX) {
|
||||||
// need to do the remap here
|
// need to do the remap here using button_remap
|
||||||
ESP_LOGD(TAG, "remapping buttons");
|
ESP_LOGD(TAG, "remapping buttons");
|
||||||
} else if (action != ACTRLS_NONE) {
|
} else if (action != ACTRLS_NONE) {
|
||||||
ESP_LOGD(TAG, "calling action %u", action);
|
ESP_LOGD(TAG, "calling action %u", action);
|
||||||
@@ -304,8 +304,6 @@ esp_err_t actrls_init_json(const char *config) {
|
|||||||
esp_err_t loc_err = actrls_process_button(button, cur_config);
|
esp_err_t loc_err = actrls_process_button(button, cur_config);
|
||||||
err = (err == ESP_OK) ? loc_err : err;
|
err = (err == ESP_OK) ? loc_err : err;
|
||||||
if (loc_err == ESP_OK) {
|
if (loc_err == ESP_OK) {
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Calling button_create");
|
|
||||||
button_create((void*) cur_config, cur_config->gpio,cur_config->type, cur_config->pull,cur_config->debounce,
|
button_create((void*) cur_config, cur_config->gpio,cur_config->type, cur_config->pull,cur_config->debounce,
|
||||||
control_handler, cur_config->long_press, cur_config->shifter_gpio);
|
control_handler, cur_config->long_press, cur_config->shifter_gpio);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -4,36 +4,42 @@ use strict;
|
|||||||
|
|
||||||
use base qw(Slim::Display::Squeezebox2);
|
use base qw(Slim::Display::Squeezebox2);
|
||||||
|
|
||||||
|
use Slim::Utils::Prefs;
|
||||||
|
use Slim::Utils::Log;
|
||||||
|
|
||||||
|
my $prefs = preferences('plugin.squeezeesp32');
|
||||||
|
|
||||||
my $VISUALIZER_NONE = 0;
|
my $VISUALIZER_NONE = 0;
|
||||||
|
my $width = $prefs->get('width') || 128;
|
||||||
|
|
||||||
my @modes = (
|
my @modes = (
|
||||||
# mode 0
|
# mode 0
|
||||||
{ desc => ['BLANK'],
|
{ desc => ['BLANK'],
|
||||||
bar => 0, secs => 0, width => 128,
|
bar => 0, secs => 0, width => $width,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 1
|
# mode 1
|
||||||
{ desc => ['PROGRESS_BAR'],
|
{ desc => ['PROGRESS_BAR'],
|
||||||
bar => 1, secs => 0, width => 128,
|
bar => 1, secs => 0, width => $width,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 2
|
# mode 2
|
||||||
{ desc => ['ELAPSED'],
|
{ desc => ['ELAPSED'],
|
||||||
bar => 0, secs => 1, width => 128,
|
bar => 0, secs => 1, width => $width,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 3
|
# mode 3
|
||||||
{ desc => ['ELAPSED', 'AND', 'PROGRESS_BAR'],
|
{ desc => ['ELAPSED', 'AND', 'PROGRESS_BAR'],
|
||||||
bar => 1, secs => 1, width => 128,
|
bar => 1, secs => 1, width => $width,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 4
|
# mode 4
|
||||||
{ desc => ['REMAINING'],
|
{ desc => ['REMAINING'],
|
||||||
bar => 0, secs => -1, width => 128,
|
bar => 0, secs => -1, width => $width,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 5
|
# mode 5
|
||||||
{ desc => ['CLOCK'],
|
{ desc => ['CLOCK'],
|
||||||
bar => 0, secs => 0, width => 128, clock => 1,
|
bar => 0, secs => 0, width => $width, clock => 1,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
# mode 6
|
# mode 6
|
||||||
{ desc => ['SETUP_SHOWBUFFERFULLNESS'],
|
{ desc => ['SETUP_SHOWBUFFERFULLNESS'],
|
||||||
bar => 0, secs => 0, width => 128, fullness => 1,
|
bar => 0, secs => 0, width => $width, fullness => 1,
|
||||||
params => [$VISUALIZER_NONE] },
|
params => [$VISUALIZER_NONE] },
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -45,6 +51,12 @@ sub nmodes {
|
|||||||
return $#modes;
|
return $#modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# I don't think LMS renderer handles properly screens other than 32 pixels. It
|
||||||
|
# seems that all we get is a 32 pixel-tall data with anything else padded to 0
|
||||||
|
# i.e. if we try 64 pixels height, bytes 0..3 and 4..7 will contains the same
|
||||||
|
# pattern than the 32 pixels version, where one would have expected bytes 4..7
|
||||||
|
# to be empty
|
||||||
|
|
||||||
=comment
|
=comment
|
||||||
sub bytesPerColumn {
|
sub bytesPerColumn {
|
||||||
return 4;
|
return 4;
|
||||||
@@ -56,11 +68,11 @@ sub displayHeight {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub displayWidth {
|
sub displayWidth {
|
||||||
return shift->widthOverride(@_) || 128;
|
return shift->widthOverride(@_) || $width;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub vfdmodel {
|
sub vfdmodel {
|
||||||
return 'graphic-128x32';
|
return 'graphic-'.$width.'x32';
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[% PROCESS settings/header.html %]
|
||||||
|
|
||||||
|
<div class="prefDesc">
|
||||||
|
|
||||||
|
[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_WIDTH" desc="PLUGIN_SQUEEZEESP32_WIDTH_DESC" %]
|
||||||
|
<input type="text" class="stdedit" name="pref_width" id="pref_width" value="[% prefs.pref_width %]" size="3">
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
[% PROCESS settings/footer.html %]
|
||||||
@@ -8,7 +8,9 @@ use Slim::Utils::Log;
|
|||||||
|
|
||||||
my $prefs = preferences('plugin.squeezeesp32');
|
my $prefs = preferences('plugin.squeezeesp32');
|
||||||
|
|
||||||
$prefs->init();
|
$prefs->init({
|
||||||
|
width => 128,
|
||||||
|
});
|
||||||
|
|
||||||
my $log = Slim::Utils::Log->addLogCategory({
|
my $log = Slim::Utils::Log->addLogCategory({
|
||||||
'category' => 'plugin.squeezeesp32',
|
'category' => 'plugin.squeezeesp32',
|
||||||
@@ -18,6 +20,11 @@ my $log = Slim::Utils::Log->addLogCategory({
|
|||||||
|
|
||||||
sub initPlugin {
|
sub initPlugin {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
|
|
||||||
|
if ( main::WEBUI ) {
|
||||||
|
require Plugins::SqueezeESP32::Settings;
|
||||||
|
Plugins::SqueezeESP32::Settings->new;
|
||||||
|
}
|
||||||
|
|
||||||
$class->SUPER::initPlugin(@_);
|
$class->SUPER::initPlugin(@_);
|
||||||
Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
|
Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
|
||||||
|
|||||||
30
plugin/SqueezeESP32/Settings.pm
Normal file
30
plugin/SqueezeESP32/Settings.pm
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub handler {
|
||||||
|
my ($class, $client, $params, $callback, @args) = @_;
|
||||||
|
|
||||||
|
$callback->($client, $params, $class->SUPER::handler($client, $params), @args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -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.3</version>
|
<version>0.4</version>
|
||||||
<creator>Philippe</creator>
|
<creator>Philippe</creator>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ WELCOME_TO_SQUEEZEESP32
|
|||||||
EN Welcome to SqueezeESP32
|
EN Welcome to SqueezeESP32
|
||||||
|
|
||||||
PLUGIN_SQUEEZEESP32
|
PLUGIN_SQUEEZEESP32
|
||||||
SqueezeESP32
|
EN SqueezeESP32
|
||||||
|
|
||||||
PLUGIN_SQUEEZEESP32_DESC
|
PLUGIN_SQUEEZEESP32_DESC
|
||||||
Adds a new player id (100) to enable display with SqueezeESP32
|
EN Adds a new player id (100) to enable display with SqueezeESP32
|
||||||
|
|
||||||
|
PLUGIN_SQUEEZEESP32_WIDTH
|
||||||
|
EN Screen width
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version='1.0' standalone='yes'?>
|
<?xml version='1.0' standalone='yes'?>
|
||||||
<extensions>
|
<extensions>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin version="0.3" name="SqueezeESP32" minTarget="7.9" maxTarget="7.*">
|
<plugin version="0.4" name="SqueezeESP32" minTarget="7.9" maxTarget="7.*">
|
||||||
<link>https://github.com/sle118/squeezelite-esp32</link>
|
<link>https://github.com/sle118/squeezelite-esp32</link>
|
||||||
<creator>Philippe</creator>
|
<creator>Philippe</creator>
|
||||||
<sha>799ae4860f9c009ac25c2ec35eb4070c5f474659</sha>
|
<sha>cec20d0489ed120d56ea2de836c616c7d970c0d5</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>
|
||||||
|
|||||||
Reference in New Issue
Block a user