Compare commits

...

13 Commits

Author SHA1 Message Date
philippe44
08c7ccdf28 put timestamp at end of ellipse 2023-09-12 18:37:27 -07:00
philippe44
0002256630 Fix AirPlay artwork disappearing 2023-09-12 18:16:38 -07:00
philippe44
b3ee25e3be add "power" gpio 2023-09-12 15:03:58 -07:00
philippe44
d53ae66547 Update README.md 2023-09-12 15:03:28 -07:00
Sébastien
26708ea51a Update bug_report.md 2023-09-12 12:43:12 -04:00
Sébastien
9c711d73f5 Update issue templates 2023-09-12 12:32:20 -04:00
github-actions
d0ac871a3b Update prebuilt objects [skip actions] 2023-09-12 01:39:04 +00:00
philippe44
38fee20680 better handling of AIrPlay network issues - release 2023-09-11 18:36:08 -07:00
philippe44
12ae3d08b6 Update README.md 2023-09-11 13:28:06 -07:00
github-actions
2931a5100e Update prebuilt objects [skip actions] 2023-09-11 05:32:43 +00:00
philippe44
c148cd16ae Merge branch 'master-v4.3' of https://github.com/sle118/squeezelite-esp32 into master-v4.3 2023-09-10 22:27:41 -07:00
philippe44
38fb90d179 pseudo-idle task requires more stack (cJSON) - release 2023-09-10 22:27:36 -07:00
github-actions
61ff6a8915 Update prebuilt objects [skip actions] 2023-09-10 05:15:25 +00:00
39 changed files with 268 additions and 70 deletions

90
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,90 @@
---
name: Bug report
about: How to Submit an Issue for the squeezelite-esp32 Project
title: ''
labels: ''
assignees: ''
---
To help us resolve your issue as quickly as possible, please follow these guidelines when submitting an issue. Providing all the necessary information will save both your time and ours.
### Describe the bug
A clear and concise description of what the bug is.
### Preliminary Information
1. **Firmware Version**: Specify the version of the firmware you are using.
2. **Plugin Version**: Mention the version of the plugin installed on your LMS (Logitech Media Server).
### Hardware Details
Please describe your hardware setup:
- **ESP32 Module**: For example, ESP32 WROVER, ESP32-S3, etc.
- **Board Type**: If applicable, e.g., ESP32 audio kit, etc.
- **DAC Chip**: Specify the DAC chip you are using.
- **Additional Hardware**: Include details about any other hardware like rotary controls, buttons, screens (SPI, I2C), Ethernet, IO expansion, etc.
### NVS Settings
Follow these steps to share your NVS settings:
1. Open the web UI of your device.
2. Click on the "Credit" tab.
3. Enable the "Show NVS Editor" checkbox. This allows you to view or change the NVS configuration even when not in recovery mode.
4. Navigate to the "NVS Editor" tab.
5. Scroll to the bottom and click "Download Config".
6. Share the downloaded content here.
<details>
<pre><code>
Your log content here
</code></pre>
</details>
### Logs
To share logs:
1. Connect your player to a computer using a USB cable. Use a built-in Serial-USB adapter if your player has one, or an external USB adapter otherwise.
2. Go to the [web installer](https://sle118.github.io/squeezelite-esp32-installer/).
3. Click "Connect to Device".
4. Select the appropriate serial port.
5. Click "Logs And Console".
6. Download the logs and share them here. Please remove any sensitive information like Wi-Fi passwords or MAC addresses.
- **If the problem occurs soon after booting**: Share the full log until the issue occurs.
- **If the problem occurs later during playback**: Trim the logs to include information just before and after the problem occurs.
#### Example Log
Here's an example log for reference. Make sure to obfuscate sensitive information like Wi-Fi passwords, MAC addresses, and change IP addresses to something more generic.
<details>
<pre><code>
=== START OF LOG ===
Example of log from the console
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
...
I (1041) cpu_start: Application information:
I (1044) cpu_start: Project name: Squeezelite-ESP32
I (1050) cpu_start: App version: I2S-4MFlash-1336
I (1055) cpu_start: Compile time: Aug 12 2023 01:20:18
I (1062) cpu_start: ELF file SHA256: 34241d6e99fd1d6b...
I (1068) cpu_start: ESP-IDF: v4.3.5-dirty
...
I (1133) heap_init: At 40094A8C len 0000B574 (45 KiB): IRAM
I (1139) spiram: Adding pool of 4066K of external SPI memory to heap allocator
=== END OF LOG ===
</code></pre>
</details>
### Issue Description
1. **Observed Behavior**: Describe what you think is wrong.
2. **Expected Behavior**: Describe what you expect should happen.
3. **Steps to Reproduce**: Provide a step-by-step guide on how to replicate the issue.

View File

@@ -272,6 +272,8 @@ GPIO can be set to GND provide or Vcc at boot. This is convenient to power devic
The `<amp>` parameter can use used to assign a GPIO that will be set to active level (default 1) when playback starts. It will be reset when squeezelite becomes idle. The idle timeout is set on the squeezelite command line through `-C <timeout>`
The `<power>` parameter can use used to assign a GPIO that will be set to active level (default 1) when player is powered on and reset when powered off
If you have an audio jack that supports insertion (use :0 or :1 to set the level when inserted), you can specify which GPIO it's connected to. Using the parameter jack_mutes_amp allows to mute the amp when headset (e.g.) is inserted.
You can set the Green and Red status led as well with their respective active state (:0 or :1) or specific the chipset if you use addressable RGB led.
@@ -281,7 +283,7 @@ The `<ir>` parameter set the GPIO associated to an IR receiver. No need to add p
Syntax is:
```
<gpio>=Vcc|GND|amp[:1|0]|ir[:nec|rc5]|jack[:0|1]|green[:0|1|ws2812]|red[:0|1|ws2812]|spkfault[:0|1][,<repeated sequence for next GPIO>]
<gpio>=Vcc|GND|amp[:1|0]|power[:1:0]|ir[:nec|rc5]|jack[:0|1]|green[:0|1|ws2812]|red[:0|1|ws2812]|spkfault[:0|1][,<repeated sequence for next GPIO>]
```
You can define the defaults for jack, spkfault leds at compile time but nvs parameter takes precedence except for named configurations ((SqueezeAMP, Muse ...) where these are forced at runtime.
**Note that gpio 36 and 39 are input only and cannot use interrupt. When set to jack or speaker fault, a 100ms polling checks their value but that's expensive**
@@ -498,7 +500,7 @@ model=dm9051|w5500,cs=<gpio>,speed=<clk_in_Hz>,intr=<gpio>[,rst=<gpio>]
### Battery / ADC
The NVS parameter "bat_config" sets the ADC1 channel used to measure battery/DC voltage. The "atten" value attenuates the input voltage to the ADC input (the read value maintains a 0-1V rage) where: 0=no attenuation(0..800mV), 1=2.5dB attenuation(0..1.1V), 2=6dB attenuation(0..1.35V), 3=11dB attenuation(0..2.6V). Scale is a float ratio applied to every sample of the 12 bits ADC. A measure is taken every 10s and an average is made every 5 minutes (not a sliding window). Syntax is
```
channel=0..7,scale=<scale>,cells=<2|3>[,atten=<0|1|2|3>]
channel=0..7,scale=<scale>,cells=<1..3>[,atten=<0|1|2|3>]
```
NB: Set parameter to empty to disable battery reading. For named configurations (SqueezeAMP, Muse ...), this is ignored (except for SqueezeAMP where number of cells is required)

View File

@@ -297,6 +297,12 @@ CONFIG_AUDIO_CONTROLS=""
CONFIG_AMP_GPIO=-1
# end of AMP configuration
#
# POWER configuration
#
CONFIG_POWER_GPIO=-1
# end of POWER configuration
#
# Audio JACK
#

View File

@@ -264,6 +264,12 @@ CONFIG_CSPOT_SINK=y
#
# end of Display Screen
#
# POWER configuration
#
CONFIG_POWER_GPIO=-1
# end of POWER configuration
#
# Various I/O
#

View File

@@ -288,6 +288,12 @@ CONFIG_AUDIO_CONTROLS=""
CONFIG_AMP_GPIO=-1
# end of AMP configuration
#
# POWER configuration
#
CONFIG_POWER_GPIO=-1
# end of POWER configuration
#
# Compiler options
#

View File

@@ -276,6 +276,7 @@ bool raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
free(ctx);
}
/*----------------------------------------------------------------------------*/
bool raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
struct sockaddr_in addr;
@@ -325,7 +326,7 @@ bool raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
break;
}
default:
break;
break;
}
// no command to send to remote or no remote found yet
@@ -348,16 +349,19 @@ bool raop_cmd(struct raop_ctx_s *ctx, raop_event_t event, void *param) {
asprintf(&method, "GET /ctrl-int/1/%s HTTP/1.0", command);
kd_add(headers, "Active-Remote", ctx->active_remote.id);
kd_add(headers, "Connection", "close");
kd_add(headers, "Connection", "close");
buf = http_send(sock, method, headers);
len = recv(sock, resp, 512, 0);
if (len > 0) resp[len-1] = '\0';
if (len > 0) resp[len-1] = '\0';
LOG_INFO("[%p]: sending airplay remote\n%s<== received ==>\n%s", ctx, buf, resp);
NFREE(method);
NFREE(buf);
kd_free(headers);
success = true;
} else {
kd_free(headers);
LOG_INFO("[%p]: can't connect to remote for %s", ctx, command);
}
free(command);
@@ -622,15 +626,19 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
struct metadata_s metadata;
dmap_settings settings = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
NULL
};
NULL
};
settings.ctx = &metadata;
memset(&metadata, 0, sizeof(struct metadata_s));
settings.ctx = &metadata;
if (!dmap_parse(&settings, body, len)) {
uint32_t timestamp = 0;
if ((p = kd_lookup(headers, "RTP-Info")) != NULL) sscanf(p, "%*[^=]=%d", &timestamp);
LOG_INFO("[%p]: received metadata (ts: %d)\n\tartist: %s\n\talbum: %s\n\ttitle: %s",
ctx, metadata.artist ? metadata.artist : "", metadata.album ? metadata.album : "",
metadata.title ? metadata.title : "");
ctx, timestamp, metadata.artist ? metadata.artist : "", metadata.album ? metadata.album : "",
metadata.title ? metadata.title : "");
success = ctx->cmd_cb(RAOP_METADATA, metadata.artist, metadata.album, metadata.title, timestamp);
free_metadata(&metadata);
}
} else if (body && ((p = kd_lookup(headers, "Content-Type")) != NULL) && strcasestr(p, "image/jpeg")) {
uint32_t timestamp = 0;

View File

@@ -113,13 +113,19 @@ static bool cmd_handler(raop_event_t event, ...) {
case RAOP_SETUP:
actrls_set(controls, false, NULL, actrls_ir_action);
displayer_control(DISPLAYER_ACTIVATE, "AIRPLAY", true);
displayer_artwork(NULL);
break;
case RAOP_PLAY:
displayer_control(DISPLAYER_TIMER_RUN);
break;
case RAOP_FLUSH:
displayer_control(DISPLAYER_TIMER_PAUSE);
break;
break;
case RAOP_STALLED:
raop_abort(raop);
actrls_unset();
displayer_control(DISPLAYER_SHUTDOWN);
break;
case RAOP_STOP:
actrls_unset();
displayer_control(DISPLAYER_SUSPEND);
@@ -127,7 +133,6 @@ static bool cmd_handler(raop_event_t event, ...) {
case RAOP_METADATA: {
char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*);
displayer_metadata(artist, album, title);
displayer_artwork(NULL);
break;
}
case RAOP_ARTWORK: {
@@ -191,8 +196,7 @@ void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) {
*/
void raop_disconnect(void) {
LOG_INFO("forced disconnection");
displayer_control(DISPLAYER_SHUTDOWN);
// in case we can't communicate with AirPlay controller, abort session
if (!raop_cmd(raop, RAOP_STOP, NULL)) raop_abort(raop);
actrls_unset();
if (!raop_cmd(raop, RAOP_STOP, NULL)) cmd_handler(RAOP_STALLED);
else displayer_control(DISPLAYER_SHUTDOWN);
}

View File

@@ -14,7 +14,7 @@
#define RAOP_SAMPLE_RATE 44100
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_ARTWORK, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP,
typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_ARTWORK, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP, RAOP_STALLED,
RAOP_VOLUME, RAOP_TIMING, RAOP_PREV, RAOP_NEXT, RAOP_REW, RAOP_FWD,
RAOP_VOLUME_UP, RAOP_VOLUME_DOWN, RAOP_RESUME, RAOP_TOGGLE } raop_event_t ;

View File

@@ -82,7 +82,7 @@ static log_level *loglevel = &raop_loglevel;
#define RTP_SYNC (0x01)
#define NTP_SYNC (0x02)
#define RESEND_TO 200
#define RESEND_TO 250
enum { DATA = 0, CONTROL, TIMING };
@@ -149,6 +149,7 @@ typedef struct rtp_s {
struct alac_codec_s *alac_codec;
int flush_seqno;
bool playing;
int stalled;
raop_data_cb_t data_cb;
raop_cmd_cb_t cmd_cb;
} rtp_t;
@@ -466,26 +467,27 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
abuf = ctx->audio_buffer + BUFIDX(seqno);
ctx->ab_write = seqno;
LOG_SDEBUG("packet expected seqno:%hu rtptime:%u (W:%hu R:%hu)", seqno, rtptime, ctx->ab_write, ctx->ab_read);
} else if (seq_order(ctx->ab_write, seqno)) {
seq_t i;
u32_t now;
// newer than expected
if (ctx->latency && seq_order(ctx->latency / ctx->frame_size, seqno - ctx->ab_write - 1)) {
// only get rtp latency-1 frames back (last one is seqno)
LOG_WARN("[%p] too many missing frames %hu seq: %hu, (W:%hu R:%hu)", ctx, seqno - ctx->ab_write - 1, seqno, ctx->ab_write, ctx->ab_read);
ctx->ab_write = seqno - ctx->latency / ctx->frame_size;
}
// this is a shitstorm, reset buffer
LOG_WARN("[%p] too many missing frames %hu seq: %hu, (W:%hu R:%hu)", ctx, seqno - ctx->ab_write - 1, seqno, ctx->ab_write, ctx->ab_read);
ctx->ab_read = seqno;
} else {
// request re-send missed frames and evaluate resent date as a whole *after*
rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1);
// resend date is after all requests have been sent
u32_t now = gettime_ms();
// set expected timing of missed frames for buffer_push_packet and set last_resend date
for (seq_t i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
ctx->audio_buffer[BUFIDX(i)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
ctx->audio_buffer[BUFIDX(i)].last_resend = now;
}
LOG_DEBUG("[%p]: packet newer seqno:%hu rtptime:%u (W:%hu R:%hu)", ctx, seqno, rtptime, ctx->ab_write, ctx->ab_read);
}
// need to request re-send and adjust timing of gaps
rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1);
for (now = gettime_ms(), i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
ctx->audio_buffer[BUFIDX(i)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
ctx->audio_buffer[BUFIDX(i)].last_resend = now;
}
LOG_DEBUG("[%p]: packet newer seqno:%hu rtptime:%u (W:%hu R:%hu)", ctx, seqno, rtptime, ctx->ab_write, ctx->ab_read);
abuf = ctx->audio_buffer + BUFIDX(seqno);
ctx->ab_write = seqno;
} else if (seq_order(ctx->ab_read, seqno + 1)) {
@@ -524,10 +526,9 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
static void buffer_push_packet(rtp_t *ctx) {
abuf_t *curframe = NULL;
u32_t now, playtime, hold = max((ctx->latency * 1000) / (8 * RAOP_SAMPLE_RATE), 100);
int i;
// not ready to play yet
if (!ctx->playing || ctx->synchro.status != (RTP_SYNC | NTP_SYNC)) return;
if (!ctx->playing || ctx->synchro.status != (RTP_SYNC | NTP_SYNC)) return;
// there is always at least one frame in the buffer
do {
@@ -573,10 +574,11 @@ static void buffer_push_packet(rtp_t *ctx) {
LOG_SDEBUG("playtime %u %d [W:%hu R:%hu] %d", playtime, playtime - now, ctx->ab_write, ctx->ab_read, curframe->ready);
// each missing packet will be requested up to (latency_frames / 16) times
for (i = 0; seq_order(ctx->ab_read + i, ctx->ab_write); i += 16) {
for (int i = 0; seq_order(ctx->ab_read + i, ctx->ab_write); i += 16) {
abuf_t *frame = ctx->audio_buffer + BUFIDX(ctx->ab_read + i);
if (!frame->ready && now - frame->last_resend > RESEND_TO) {
rtp_request_resend(ctx, ctx->ab_read + i, ctx->ab_read + i);
// stop if one fails
if (!rtp_request_resend(ctx, ctx->ab_read + i, ctx->ab_read + i)) break;
frame->last_resend = now;
}
}
@@ -613,7 +615,10 @@ static void rtp_thread_func(void *arg) {
FD_ZERO(&fds);
for (i = 0; i < 3; i++) { FD_SET(ctx->rtp_sockets[i].sock, &fds); }
if (select(sock + 1, &fds, NULL, NULL, &timeout) <= 0) {
if (ctx->stalled++ == 30*10) ctx->cmd_cb(RAOP_STALLED);
continue;
}
for (i = 0; i < 3; i++)
@@ -631,6 +636,7 @@ static void rtp_thread_func(void *arg) {
continue;
}
assert(plen <= MAX_PACKET);
ctx->stalled = 0;
type = packet[1] & ~0x80;
@@ -823,6 +829,7 @@ static bool rtp_request_resend(rtp_t *ctx, seq_t first, seq_t last) {
ctx->rtp_host.sin_port = htons(ctx->rtp_sockets[CONTROL].rport);
if (sizeof(req) != sendto(ctx->rtp_sockets[CONTROL].sock, req, sizeof(req), MSG_DONTWAIT, (struct sockaddr*) &ctx->rtp_host, sizeof(ctx->rtp_host))) {
LOG_WARN("[%p]: SENDTO failed (%s)", ctx, strerror(errno));
return false;
}

View File

@@ -26,7 +26,7 @@
#include "cJSON.h"
#include "tools.h"
#define PSEUDO_IDLE_STACK_SIZE (3*1024)
#define PSEUDO_IDLE_STACK_SIZE (6*1024)
#define MONITOR_TIMER (10*1000)
#define SCRATCH_SIZE 256
@@ -62,7 +62,7 @@ static void task_stats( cJSON* top ) {
current.n = uxTaskGetSystemState( current.tasks, current.n, &current.total );
cJSON_AddNumberToObject(top,"ntasks",current.n);
char scratch[SCRATCH_SIZE] = { 0 };
char scratch[SCRATCH_SIZE] = { };
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
#pragma message("Compiled with runtime stats")

View File

@@ -289,6 +289,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, va_list args)
raop_sync.enabled = !strcasestr(output.device, "BT");
output.next_sample_rate = output.current_sample_rate = RAOP_SAMPLE_RATE;
break;
case RAOP_STALLED:
case RAOP_STOP:
output.external = 0;
__attribute__ ((fallthrough));
@@ -492,7 +493,6 @@ void decode_restore(int external) {
#if CONFIG_AIRPLAY_SINK
case DECODE_RAOP:
raop_disconnect();
raop_state = RAOP_STOP;
break;
#endif
#if CONFIG_CSPOT_SINK

View File

@@ -15,13 +15,41 @@
#include "esp_system.h"
#include "esp_timer.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "monitor.h"
#include "platform_config.h"
#include "messaging.h"
#include "gpio_exp.h"
#include "accessors.h"
#ifndef CONFIG_POWER_GPIO_LEVEL
#define CONFIG_POWER_GPIO_LEVEL 1
#endif
static const char TAG[] = "embedded";
static struct {
int gpio, active;
} power_control = { CONFIG_POWER_GPIO, CONFIG_POWER_GPIO_LEVEL };
extern void sb_controls_init(void);
extern bool sb_displayer_init(void);
u8_t custom_player_id = 12;
mutex_type slimp_mutex;
static jmp_buf jumpbuf;
#ifndef POWER_LOCKED
static void set_power_gpio(int gpio, char *value) {
if (strcasestr(value, "power")) {
char *p = strchr(value, ':');
if (p) power_control.active = atoi(p + 1);
power_control.gpio = gpio;
}
}
#endif
void get_mac(u8_t mac[]) {
esp_read_mac(mac, ESP_MAC_WIFI_STA);
}
@@ -56,16 +84,22 @@ uint32_t _gettime_ms_(void) {
return (uint32_t) (esp_timer_get_time() / 1000);
}
extern void sb_controls_init(void);
extern bool sb_displayer_init(void);
u8_t custom_player_id = 12;
int embedded_init(void) {
mutex_create(slimp_mutex);
sb_controls_init();
custom_player_id = sb_displayer_init() ? 100 : 101;
#ifndef POWER_LOCKED
parse_set_GPIO(set_power_gpio);
#endif
if (power_control.gpio != -1) {
gpio_pad_select_gpio_x(power_control.gpio);
gpio_set_direction_x(power_control.gpio, GPIO_MODE_OUTPUT);
gpio_set_level_x(power_control.gpio, !power_control.active);
ESP_LOGI(TAG, "setting power GPIO %d (active:%d)", power_control.gpio, power_control.active);
}
return setjmp(jumpbuf);
}
@@ -73,6 +107,13 @@ void embedded_exit(int code) {
longjmp(jumpbuf, code + 1);
}
void powering(bool on) {
if (power_control.gpio != -1) {
ESP_LOGI(TAG, "powering player %s", on ? "ON" : "OFF");
gpio_set_level_x(power_control.gpio, on ? power_control.active : !power_control.active);
}
}
u16_t get_RSSI(void) {
wifi_ap_record_t wifidata;
esp_wifi_sta_get_ap_info(&wifidata);

View File

@@ -71,6 +71,7 @@ int embedded_init(void);
void register_external(void);
void deregister_external(void);
void decode_restore(int external);
void powering(bool on);
// used when other client wants to use slimproto socket to send messages
extern mutex_type slimp_mutex;
#define LOCK_P mutex_lock(slimp_mutex)

View File

@@ -441,6 +441,10 @@ static void process_aude(u8_t *pkt, int len) {
struct aude_packet *aude = (struct aude_packet *)pkt;
LOG_DEBUG("enable spdif: %d dac: %d", aude->enable_spdif, aude->enable_dac);
#if EMBEDDED
powering(aude->enable_spdif),
#endif
LOCK_O;
if (!aude->enable_spdif && output.state != OUTPUT_OFF) {

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -60,6 +60,9 @@ declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
@@ -122,6 +125,12 @@ declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;

View File

@@ -1,5 +1,5 @@
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.99c86edb045064f0ff9e.css.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.3bdc2f.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.3bdc2f.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.35c7f4.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.35c7f4.bundle.js.gz BINARY)

View File

@@ -6,29 +6,29 @@ extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_s
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
extern const uint8_t _index_3bdc2f_bundle_js_gz_start[] asm("_binary_index_3bdc2f_bundle_js_gz_start");
extern const uint8_t _index_3bdc2f_bundle_js_gz_end[] asm("_binary_index_3bdc2f_bundle_js_gz_end");
extern const uint8_t _node_vendors_3bdc2f_bundle_js_gz_start[] asm("_binary_node_vendors_3bdc2f_bundle_js_gz_start");
extern const uint8_t _node_vendors_3bdc2f_bundle_js_gz_end[] asm("_binary_node_vendors_3bdc2f_bundle_js_gz_end");
extern const uint8_t _index_35c7f4_bundle_js_gz_start[] asm("_binary_index_35c7f4_bundle_js_gz_start");
extern const uint8_t _index_35c7f4_bundle_js_gz_end[] asm("_binary_index_35c7f4_bundle_js_gz_end");
extern const uint8_t _node_vendors_35c7f4_bundle_js_gz_start[] asm("_binary_node_vendors_35c7f4_bundle_js_gz_start");
extern const uint8_t _node_vendors_35c7f4_bundle_js_gz_end[] asm("_binary_node_vendors_35c7f4_bundle_js_gz_end");
const char * resource_lookups[] = {
"/css/index.99c86edb045064f0ff9e.css.gz",
"/favicon-32x32.png",
"/index.html.gz",
"/js/index.3bdc2f.bundle.js.gz",
"/js/node_vendors.3bdc2f.bundle.js.gz",
"/js/index.35c7f4.bundle.js.gz",
"/js/node_vendors.35c7f4.bundle.js.gz",
""
};
const uint8_t * resource_map_start[] = {
_index_99c86edb045064f0ff9e_css_gz_start,
_favicon_32x32_png_start,
_index_html_gz_start,
_index_3bdc2f_bundle_js_gz_start,
_node_vendors_3bdc2f_bundle_js_gz_start
_index_35c7f4_bundle_js_gz_start,
_node_vendors_35c7f4_bundle_js_gz_start
};
const uint8_t * resource_map_end[] = {
_index_99c86edb045064f0ff9e_css_gz_end,
_favicon_32x32_png_end,
_index_html_gz_end,
_index_3bdc2f_bundle_js_gz_end,
_node_vendors_3bdc2f_bundle_js_gz_end
_index_35c7f4_bundle_js_gz_end,
_node_vendors_35c7f4_bundle_js_gz_end
};

View File

@@ -1,6 +1,6 @@
/***********************************
webpack_headers
dist/css/index.99c86edb045064f0ff9e.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.3bdc2f.bundle.js.gz,dist/js/node_vendors.3bdc2f.bundle.js.gz
dist/css/index.99c86edb045064f0ff9e.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.35c7f4.bundle.js.gz,dist/js/node_vendors.35c7f4.bundle.js.gz
***********************************/
#pragma once
#include <inttypes.h>

View File

@@ -148,6 +148,9 @@ menu "Squeezelite-ESP32"
int
default 21 if MUSE
default -1
config POWER_GPIO
int
default -1
config JACK_GPIO
int
default 34 if SQUEEZEAMP || MUSE
@@ -405,18 +408,29 @@ menu "Squeezelite-ESP32"
default 0
endmenu
menu "Amplifier"
visible if !TARGET_LOCKED
menu "External amplifier control"
visible if !AMP_LOCKED
config AMP_GPIO
int "Amplifier GPIO"
help
GPIO to switch on/off amplifier. Set to -1 for no amplifier.
GPIO to switch on/off external amplifier. Set to -1 for no amplifier.
config AMP_GPIO_LEVEL
depends on AMP_GPIO != -1
int "Active level(0/1)"
default 1
endmenu
menu "Power on/off status"
config POWER_GPIO
int "Power on/off GPIO"
help
GPIO that is switched when LMS turns player one. Set to -1 to disable
config POWER_GPIO_LEVEL
depends on POWER_GPIO != -1
int "Active level(0/1)"
default 1
endmenu
menu "Speaker Fault"
visible if !TARGET_LOCKED
config SPKFAULT_GPIO

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
server_certs/r2m01.cer.22 Normal file

Binary file not shown.

BIN
server_certs/r2m01.cer.23 Normal file

Binary file not shown.

BIN
server_certs/r2m01.cer.24 Normal file

Binary file not shown.