mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 19:47:02 +03:00
handle case w/o display - release
This commit is contained in:
@@ -175,7 +175,7 @@ static bool cmd_handler(bt_sink_cmd_t cmd, ...) {
|
|||||||
displayer_control(DISPLAYER_TIMER_RUN);
|
displayer_control(DISPLAYER_TIMER_RUN);
|
||||||
break;
|
break;
|
||||||
case BT_SINK_STOP:
|
case BT_SINK_STOP:
|
||||||
// not sure of difference between pause and stop for displayer
|
// not sure of difference between pause and stop for displayer
|
||||||
case BT_SINK_PAUSE:
|
case BT_SINK_PAUSE:
|
||||||
displayer_control(DISPLAYER_TIMER_PAUSE);
|
displayer_control(DISPLAYER_TIMER_PAUSE);
|
||||||
break;
|
break;
|
||||||
@@ -397,7 +397,7 @@ void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_param
|
|||||||
bt_av_playback_changed();
|
bt_av_playback_changed();
|
||||||
break;
|
break;
|
||||||
case ESP_AVRC_RN_PLAY_POS_CHANGED:
|
case ESP_AVRC_RN_PLAY_POS_CHANGED:
|
||||||
ESP_LOGI(BT_AV_TAG, "Play position changed: %d-ms", event_parameter->play_pos);
|
ESP_LOGD(BT_AV_TAG, "Play position changed: %d (ms)", event_parameter->play_pos);
|
||||||
(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, event_parameter->play_pos, -1);
|
(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, event_parameter->play_pos, -1);
|
||||||
bt_av_play_pos_changed();
|
bt_av_play_pos_changed();
|
||||||
break;
|
break;
|
||||||
@@ -440,7 +440,7 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: {
|
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: {
|
||||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id);
|
ESP_LOGD(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id);
|
||||||
bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter);
|
bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
// here we should include all possible drivers
|
// here we should include all possible drivers
|
||||||
extern struct display_s SSD1306_display;
|
extern struct display_s SSD1306_display;
|
||||||
|
|
||||||
struct display_s *display;
|
struct display_s *display = NULL;
|
||||||
|
|
||||||
static const char *TAG = "display";
|
static const char *TAG = "display";
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ void display_init(char *welcome) {
|
|||||||
init = true;
|
init = true;
|
||||||
ESP_LOGI(TAG, "Display initialization successful");
|
ESP_LOGI(TAG, "Display initialization successful");
|
||||||
} else {
|
} else {
|
||||||
|
display = NULL;
|
||||||
ESP_LOGE(TAG, "Display initialization failed");
|
ESP_LOGE(TAG, "Display initialization failed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -103,7 +104,7 @@ void display_init(char *welcome) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* This is not really thread-safe as displayer_task might be in the middle of line drawing
|
* This is not thread-safe as displayer_task might be in the middle of line drawing
|
||||||
* but it won't crash (I think) and making it thread-safe would be complicated for a
|
* but it won't crash (I think) and making it thread-safe would be complicated for a
|
||||||
* feature which is secondary (the LMS version of scrolling is thread-safe)
|
* feature which is secondary (the LMS version of scrolling is thread-safe)
|
||||||
*/
|
*/
|
||||||
@@ -128,11 +129,19 @@ static void displayer_task(void *args) {
|
|||||||
if (scroll_sleep <= 10) {
|
if (scroll_sleep <= 10) {
|
||||||
// something to scroll (or we'll wake-up every pause ms ... no big deal)
|
// something to scroll (or we'll wake-up every pause ms ... no big deal)
|
||||||
if (*displayer.string && displayer.state == DISPLAYER_ACTIVE) {
|
if (*displayer.string && displayer.state == DISPLAYER_ACTIVE) {
|
||||||
display->line(2, -displayer.offset, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.string);
|
|
||||||
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
// need to work with local copies as we don't want to suspend caller
|
||||||
|
int offset = -displayer.offset;
|
||||||
|
char *string = strdup(displayer.string);
|
||||||
scroll_sleep = displayer.offset ? displayer.speed : displayer.pause;
|
scroll_sleep = displayer.offset ? displayer.speed : displayer.pause;
|
||||||
displayer.offset = displayer.offset >= displayer.boundary ? 0 : (displayer.offset + min(displayer.by, displayer.boundary - displayer.offset));
|
displayer.offset = displayer.offset >= displayer.boundary ? 0 : (displayer.offset + min(displayer.by, displayer.boundary - displayer.offset));
|
||||||
|
|
||||||
xSemaphoreGive(displayer.mutex);
|
xSemaphoreGive(displayer.mutex);
|
||||||
|
|
||||||
|
// now display using safe copies, can be lengthy
|
||||||
|
display->line(2, offset, DISPLAY_CLEAR | DISPLAY_UPDATE, string);
|
||||||
|
free(string);
|
||||||
} else {
|
} else {
|
||||||
scroll_sleep = DEFAULT_SLEEP;
|
scroll_sleep = DEFAULT_SLEEP;
|
||||||
}
|
}
|
||||||
@@ -149,8 +158,8 @@ static void displayer_task(void *args) {
|
|||||||
displayer.tick = tick;
|
displayer.tick = tick;
|
||||||
displayer.elapsed += elapsed / 1000;
|
displayer.elapsed += elapsed / 1000;
|
||||||
xSemaphoreGive(displayer.mutex);
|
xSemaphoreGive(displayer.mutex);
|
||||||
if (displayer.elapsed < 3600) sprintf(counter, "%2u:%02u", displayer.elapsed / 60, displayer.elapsed % 60);
|
if (displayer.elapsed < 3600) sprintf(counter, "%5u:%02u", displayer.elapsed / 60, displayer.elapsed % 60);
|
||||||
else sprintf(counter, "%2u:%2u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60);
|
else sprintf(counter, "%2u:%02u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60);
|
||||||
display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter);
|
display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter);
|
||||||
timer_sleep = 1000;
|
timer_sleep = 1000;
|
||||||
} else timer_sleep = max(1000 - elapsed, 0);
|
} else timer_sleep = max(1000 - elapsed, 0);
|
||||||
@@ -171,6 +180,10 @@ void displayer_metadata(char *artist, char *album, char *title) {
|
|||||||
char *string = displayer.string, *p;
|
char *string = displayer.string, *p;
|
||||||
int len = SCROLLABLE_SIZE;
|
int len = SCROLLABLE_SIZE;
|
||||||
|
|
||||||
|
// need a display!
|
||||||
|
if (!display) return;
|
||||||
|
|
||||||
|
// just do title if there is no config set
|
||||||
if (!displayer.metadata_config) {
|
if (!displayer.metadata_config) {
|
||||||
strncpy(displayer.string, title ? title : "", SCROLLABLE_SIZE);
|
strncpy(displayer.string, title ? title : "", SCROLLABLE_SIZE);
|
||||||
return;
|
return;
|
||||||
@@ -218,7 +231,7 @@ void displayer_metadata(char *artist, char *album, char *title) {
|
|||||||
p = strchr(q + 1, '%');
|
p = strchr(q + 1, '%');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
string = strdup(title ? title : "");
|
strncpy(string, title ? title : "", SCROLLABLE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get optional scroll speed
|
// get optional scroll speed
|
||||||
@@ -232,11 +245,13 @@ void displayer_metadata(char *artist, char *album, char *title) {
|
|||||||
xSemaphoreGive(displayer.mutex);
|
xSemaphoreGive(displayer.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void displayer_scroll(char *string, int speed) {
|
void displayer_scroll(char *string, int speed) {
|
||||||
|
// need a display!
|
||||||
|
if (!display) return;
|
||||||
|
|
||||||
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
if (speed) displayer.speed = speed;
|
if (speed) displayer.speed = speed;
|
||||||
@@ -252,10 +267,13 @@ void displayer_scroll(char *string, int speed) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) {
|
void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) {
|
||||||
|
// need a display!
|
||||||
|
if (!display) return;
|
||||||
|
|
||||||
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
if (elapsed >= 0) displayer.elapsed = elapsed;
|
if (elapsed >= 0) displayer.elapsed = elapsed / 1000;
|
||||||
if (duration >= 0) displayer.duration = duration;
|
if (duration >= 0) displayer.duration = duration / 1000;
|
||||||
if (displayer.timer) displayer.tick = xTaskGetTickCount();
|
if (displayer.timer) displayer.tick = xTaskGetTickCount();
|
||||||
|
|
||||||
xSemaphoreGive(displayer.mutex);
|
xSemaphoreGive(displayer.mutex);
|
||||||
@@ -267,6 +285,8 @@ void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) {
|
|||||||
void displayer_control(enum displayer_cmd_e cmd, ...) {
|
void displayer_control(enum displayer_cmd_e cmd, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
if (!display) return;
|
||||||
|
|
||||||
va_start(args, cmd);
|
va_start(args, cmd);
|
||||||
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
xSemaphoreTake(displayer.mutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ static bool set_font(int num, enum display_font_e font, int space) {
|
|||||||
lines[0].y = lines[0].space;
|
lines[0].y = lines[0].space;
|
||||||
for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space;
|
for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "adding line %u at %u (height:%u)", num + 1, lines[num].y, lines[num].font->Height);
|
ESP_LOGI(TAG, "adding line %u at %d (height:%u)", num + 1, lines[num].y, lines[num].font->Height);
|
||||||
|
|
||||||
if (lines[num].y + lines[num].font->Height > Display.Height) {
|
if (lines[num].y + lines[num].font->Height > Display.Height) {
|
||||||
ESP_LOGW(TAG, "line does not fit display");
|
ESP_LOGW(TAG, "line does not fit display");
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character,
|
|||||||
|
|
||||||
NullCheck( ( GlyphData = GetCharPtr( DisplayHandle->Font, Character ) ), return );
|
NullCheck( ( GlyphData = GetCharPtr( DisplayHandle->Font, Character ) ), return );
|
||||||
|
|
||||||
if ( Character >= DisplayHandle->Font->StartChar || Character <= DisplayHandle->Font->EndChar ) {
|
if ( Character >= DisplayHandle->Font->StartChar && Character <= DisplayHandle->Font->EndChar ) {
|
||||||
/* The first byte in the glyph data is the width of the character in pixels, skip over */
|
/* The first byte in the glyph data is the width of the character in pixels, skip over */
|
||||||
GlyphData++;
|
GlyphData++;
|
||||||
GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8;
|
GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8;
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, va_list args)
|
|||||||
ms = ((u64_t) ((_buf_used(outputbuf) - raop_sync.len) / BYTES_PER_FRAME + output.device_frames + output.frames_in_process) * 1000) / RAOP_SAMPLE_RATE - (now - output.updated);
|
ms = ((u64_t) ((_buf_used(outputbuf) - raop_sync.len) / BYTES_PER_FRAME + output.device_frames + output.frames_in_process) * 1000) / RAOP_SAMPLE_RATE - (now - output.updated);
|
||||||
raop_sync.error[raop_sync.idx] = (raop_sync.playtime - now) - ms;
|
raop_sync.error[raop_sync.idx] = (raop_sync.playtime - now) - ms;
|
||||||
sync_nb = SYNC_NB;
|
sync_nb = SYNC_NB;
|
||||||
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, raop_sync.error[raop_sync.idx]);
|
LOG_DEBUG("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, raop_sync.error[raop_sync.idx]);
|
||||||
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -137,10 +137,16 @@ static void scroll_task(void* arg);
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void sb_display_init(void) {
|
bool sb_display_init(void) {
|
||||||
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
|
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
|
||||||
static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
|
static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
|
||||||
|
|
||||||
|
// no display, just make sure we won't have requests
|
||||||
|
if (!display || display->height == 0 || display->width == 0) {
|
||||||
|
LOG_INFO("no display for LMS");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// need to force height to 32 maximum
|
// need to force height to 32 maximum
|
||||||
display_width = display->width;
|
display_width = display->width;
|
||||||
display_height = min(display->height, 32);
|
display_height = min(display->height, 32);
|
||||||
@@ -163,6 +169,8 @@ void sb_display_init(void) {
|
|||||||
|
|
||||||
notify_chain = server_notify;
|
notify_chain = server_notify;
|
||||||
server_notify = server;
|
server_notify = server;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
|
|||||||
@@ -50,9 +50,11 @@ uint32_t _gettime_ms_(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern void sb_controls_init(void);
|
extern void sb_controls_init(void);
|
||||||
extern void sb_display_init(void);
|
extern bool sb_display_init(void);
|
||||||
|
|
||||||
|
u8_t custom_player_id = 12;
|
||||||
|
|
||||||
void embedded_init(void) {
|
void embedded_init(void) {
|
||||||
sb_controls_init();
|
sb_controls_init();
|
||||||
sb_display_init();
|
if (sb_display_init()) custom_player_id = 100;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,10 @@
|
|||||||
#define OUTPUT_THREAD_STACK_SIZE 6 * 1024
|
#define OUTPUT_THREAD_STACK_SIZE 6 * 1024
|
||||||
#define IR_THREAD_STACK_SIZE 6 * 1024
|
#define IR_THREAD_STACK_SIZE 6 * 1024
|
||||||
|
|
||||||
#define PLAYER_ID 100
|
// or can be as simple as #define PLAYER_ID 100
|
||||||
|
#define PLAYER_ID custom_player_id;
|
||||||
|
extern u8_t custom_player_id;
|
||||||
|
|
||||||
#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION
|
#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION
|
||||||
#define EXT_BSS __attribute__((section(".ext_ram.bss")))
|
#define EXT_BSS __attribute__((section(".ext_ram.bss")))
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static sockfd sock = -1;
|
|||||||
static in_addr_t slimproto_ip = 0;
|
static in_addr_t slimproto_ip = 0;
|
||||||
static u16_t slimproto_hport = 9000;
|
static u16_t slimproto_hport = 9000;
|
||||||
static u16_t slimproto_cport = 9090;
|
static u16_t slimproto_cport = 9090;
|
||||||
static u8_t player_id = PLAYER_ID;
|
static u8_t player_id;
|
||||||
|
|
||||||
extern struct buffer *streambuf;
|
extern struct buffer *streambuf;
|
||||||
extern struct buffer *outputbuf;
|
extern struct buffer *outputbuf;
|
||||||
|
|||||||
Reference in New Issue
Block a user