mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-04 15:49:02 +03:00
Compare commits
13 Commits
Muse.16.15
...
Muse.16.15
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08c7ccdf28 | ||
|
|
0002256630 | ||
|
|
b3ee25e3be | ||
|
|
d53ae66547 | ||
|
|
26708ea51a | ||
|
|
9c711d73f5 | ||
|
|
d0ac871a3b | ||
|
|
38fee20680 | ||
|
|
12ae3d08b6 | ||
|
|
2931a5100e | ||
|
|
c148cd16ae | ||
|
|
38fb90d179 | ||
|
|
61ff6a8915 |
90
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
90
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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.
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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", ×tamp);
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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, ¤t.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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
BIN
components/wifi-manager/webapp/dist/index.html.gz
vendored
BIN
components/wifi-manager/webapp/dist/index.html.gz
vendored
Binary file not shown.
2
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js
vendored
Normal file
2
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js.gz
vendored
Normal file
BIN
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js.gz
vendored
Normal file
Binary file not shown.
1
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js.map
vendored
Normal file
1
components/wifi-manager/webapp/dist/js/index.35c7f4.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
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
Binary file not shown.
1
components/wifi-manager/webapp/dist/js/node_vendors.35c7f4.bundle.js.map
vendored
Normal file
1
components/wifi-manager/webapp/dist/js/node_vendors.35c7f4.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
BIN
server_certs/DigiCertGlobalRootCA.crt.50
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.50
Normal file
Binary file not shown.
BIN
server_certs/DigiCertGlobalRootCA.crt.51
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.51
Normal file
Binary file not shown.
BIN
server_certs/DigiCertGlobalRootCA.crt.52
Normal file
BIN
server_certs/DigiCertGlobalRootCA.crt.52
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.22
Normal file
BIN
server_certs/r2m01.cer.22
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.23
Normal file
BIN
server_certs/r2m01.cer.23
Normal file
Binary file not shown.
BIN
server_certs/r2m01.cer.24
Normal file
BIN
server_certs/r2m01.cer.24
Normal file
Binary file not shown.
Reference in New Issue
Block a user