mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 19:47:02 +03:00
working buttons (LMS only)
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@@ -28,75 +29,87 @@
|
|||||||
|
|
||||||
static const char * TAG = "audio_controls";
|
static const char * TAG = "audio_controls";
|
||||||
|
|
||||||
typedef struct {
|
static actrls_t default_controls, current_controls;
|
||||||
void (*volume_up)(void);
|
|
||||||
void (*volume_down)(void);
|
|
||||||
void (*play_toggle)(void);
|
|
||||||
void (*play)(void);
|
|
||||||
void (*pause)(void);
|
|
||||||
void (*stop)(void);
|
|
||||||
} audio_control_t;
|
|
||||||
|
|
||||||
static audio_control_t default_control, current_control;
|
static void control_handler(void *id, button_event_e event, button_press_e press, bool long_press) {
|
||||||
|
actrls_config_t *key = (actrls_config_t*) id;
|
||||||
|
actrls_action_e action;
|
||||||
|
|
||||||
/****************************************************************************************
|
ESP_LOGD(TAG, "control gpio:%u press:%u long:%u event:%u", key->gpio, press, long_press, event);
|
||||||
* DOWN button
|
|
||||||
*/
|
switch(press) {
|
||||||
static void down(button_event_e event, button_press_e press, bool long_press) {
|
case BUTTON_NORMAL:
|
||||||
if (press == BUTTON_NORMAL) {
|
if (long_press) action = key->longpress[event == BUTTON_PRESSED ? 0 : 1];
|
||||||
if (!long_press) ESP_LOGI(TAG, "volume DOWN %u", event);
|
else action = key->normal[event == BUTTON_PRESSED ? 0 : 1];
|
||||||
else ESP_LOGI(TAG, "volume DOWN long %u", event);
|
break;
|
||||||
} else {
|
case BUTTON_SHIFTED:
|
||||||
if (!long_press) ESP_LOGI(TAG, "volume DOWN shifted %u", event);
|
if (long_press) action = key->longshifted[event == BUTTON_PRESSED ? 0 : 1];
|
||||||
else ESP_LOGI(TAG, "volume DOWN long shifted %u", event);
|
else action = key->shifted[event == BUTTON_PRESSED ? 0 : 1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
action = ACTRLS_NONE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
//if (event == BUTTON_PRESSED) (*current_control.volume_down)();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************
|
if (action != ACTRLS_NONE) {
|
||||||
* UP button
|
ESP_LOGD(TAG, " calling action %u", action);
|
||||||
*/
|
if (current_controls[action]) (*current_controls[action])();
|
||||||
static void up(button_event_e event, button_press_e press, bool long_press) {
|
}
|
||||||
if (press == BUTTON_NORMAL) {
|
}
|
||||||
if (!long_press) ESP_LOGI(TAG, "volume UP %u", event);
|
|
||||||
else ESP_LOGI(TAG, "volume UP long %u", event);
|
/*
|
||||||
} else {
|
void up(void *id, button_event_e event, button_press_e press, bool longpress) {
|
||||||
if (!long_press) ESP_LOGI(TAG, "volume UP shifted %u", event);
|
if (press == BUTTON_NORMAL) {
|
||||||
else ESP_LOGI(TAG, "volume UP long shifted %u", event);
|
if (longpress) ESP_LOGI(TAG, "up long %u", event);
|
||||||
|
else ESP_LOGI(TAG, "up %u", event);
|
||||||
|
} else if (press == BUTTON_SHIFTED) {
|
||||||
|
if (longpress) ESP_LOGI(TAG, "up shifted long %u", event);
|
||||||
|
else ESP_LOGI(TAG, "up shifted %u", event);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "don't know what we are doing here %u", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void down(void *id, button_event_e event, button_press_e press, bool longpress) {
|
||||||
|
if (press == BUTTON_NORMAL) {
|
||||||
|
if (longpress) ESP_LOGI(TAG, "down long %u", event);
|
||||||
|
else ESP_LOGI(TAG, "down %u", event);
|
||||||
|
} else if (press == BUTTON_SHIFTED) {
|
||||||
|
if (longpress) ESP_LOGI(TAG, "down shifted long %u", event);
|
||||||
|
else ESP_LOGI(TAG, "down shifted %u", event);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "don't know what we are doing here %u", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void actrls_init(int n, actrls_config_t *config) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
button_create(config + i, config[i].gpio, config[i].type, config[i].pull, control_handler, config[i].long_press, config[i].shifter_gpio);
|
||||||
}
|
}
|
||||||
//if (event == BUTTON_PRESSED) (*current_control.volume_up)();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void audio_controls_init(void) {
|
void actrls_set_default(actrls_t controls) {
|
||||||
/*
|
memcpy(default_controls, controls, sizeof(actrls_t));
|
||||||
button_create(18, BUTTON_LOW, true, up, 0, -1);
|
memcpy(current_controls, default_controls, sizeof(actrls_t));
|
||||||
button_create(19, BUTTON_LOW, true, down, 0, -1);
|
|
||||||
button_create(21, BUTTON_LOW, true, play, 0, -1);
|
|
||||||
*/
|
|
||||||
button_create(4, BUTTON_LOW, true, up, 2000, -1);
|
|
||||||
button_create(5, BUTTON_LOW, true, down, 3000, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void default_audio_control(audio_control_t *control) {
|
void actrls_set(actrls_t controls) {
|
||||||
default_control = current_control = *control;
|
memcpy(current_controls, controls, sizeof(actrls_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void register_audio_control(audio_control_t *control) {
|
void actrls_unset(void) {
|
||||||
current_control = *control;
|
memcpy(current_controls, default_controls, sizeof(actrls_t));
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void deregister_audio_control(void) {
|
|
||||||
current_control = default_control;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void audio_controls_init(void);
|
#include "buttons.h"
|
||||||
|
|
||||||
|
// BEWARE: this is the index of the array of action below
|
||||||
|
typedef enum { ACTRLS_NONE = -1, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY,
|
||||||
|
ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT,
|
||||||
|
ACTRLS_MAX
|
||||||
|
} actrls_action_e;
|
||||||
|
typedef void (*actrls_handler)(void);
|
||||||
|
typedef actrls_handler actrls_t[ACTRLS_MAX - ACTRLS_NONE - 1];
|
||||||
|
typedef struct {
|
||||||
|
int gpio;
|
||||||
|
int type;
|
||||||
|
bool pull;
|
||||||
|
int long_press;
|
||||||
|
int shifter_gpio;
|
||||||
|
actrls_action_e normal[2], longpress[2], shifted[2], longshifted[2]; // [0] keypressed, [1] keyreleased
|
||||||
|
} actrls_config_t;
|
||||||
|
|
||||||
|
void actrls_init(int n, actrls_config_t *config);
|
||||||
|
void actrls_set_default(actrls_t controls);
|
||||||
|
void actrls_set(actrls_t controls);
|
||||||
|
void actrls_unset(void);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ static int n_buttons = 0;
|
|||||||
#define DEBOUNCE 50
|
#define DEBOUNCE 50
|
||||||
|
|
||||||
static struct button_s {
|
static struct button_s {
|
||||||
|
void *id;
|
||||||
int gpio, index;
|
int gpio, index;
|
||||||
button_handler handler;
|
button_handler handler;
|
||||||
struct button_s *shifter;
|
struct button_s *shifter;
|
||||||
@@ -73,6 +74,7 @@ static void buttons_timer( TimerHandle_t xTimer ) {
|
|||||||
struct button_s *button = (struct button_s*) pvTimerGetTimerID (xTimer);
|
struct button_s *button = (struct button_s*) pvTimerGetTimerID (xTimer);
|
||||||
|
|
||||||
button->level = gpio_get_level(button->gpio);
|
button->level = gpio_get_level(button->gpio);
|
||||||
|
if (button->shifter && button->shifter->type == button->shifter->level) button->shifter->shifting = true;
|
||||||
|
|
||||||
if (button->long_press && !button->long_timer && button->level == button->type) {
|
if (button->long_press && !button->long_timer && button->level == button->type) {
|
||||||
// detect a long press, so hold event generation
|
// detect a long press, so hold event generation
|
||||||
@@ -97,7 +99,7 @@ static void buttons_task(void* arg) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
struct button_s button;
|
struct button_s button;
|
||||||
button_event_e event;
|
button_event_e event;
|
||||||
button_press_e press = BUTTON_NORMAL;
|
button_press_e press;
|
||||||
|
|
||||||
if (!xQueueReceive(button_evt_queue, &button, portMAX_DELAY)) continue;
|
if (!xQueueReceive(button_evt_queue, &button, portMAX_DELAY)) continue;
|
||||||
|
|
||||||
@@ -106,10 +108,8 @@ static void buttons_task(void* arg) {
|
|||||||
ESP_LOGD(TAG, "received event:%u from gpio:%u level:%u (timer %u shifting %u)", event, button.gpio, button.level, button.long_timer, button.shifting);
|
ESP_LOGD(TAG, "received event:%u from gpio:%u level:%u (timer %u shifting %u)", event, button.gpio, button.level, button.long_timer, button.shifting);
|
||||||
|
|
||||||
// find if shifting is activated
|
// find if shifting is activated
|
||||||
if (button.shifter && button.shifter->type == button.shifter->level) {
|
if (button.shifter && button.shifter->type == button.shifter->level) press = BUTTON_SHIFTED;
|
||||||
button.shifter->shifting = true;
|
else press = BUTTON_NORMAL;
|
||||||
press = BUTTON_SHIFTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
long_timer will be set either because we truly have a long press
|
long_timer will be set either because we truly have a long press
|
||||||
@@ -120,18 +120,18 @@ static void buttons_task(void* arg) {
|
|||||||
if (event == BUTTON_RELEASED) {
|
if (event == BUTTON_RELEASED) {
|
||||||
// early release of a long-press button, send press/release
|
// early release of a long-press button, send press/release
|
||||||
if (!button.shifting) {
|
if (!button.shifting) {
|
||||||
(*button.handler)(BUTTON_PRESSED, press, false);
|
(*button.handler)(button.id, BUTTON_PRESSED, press, false);
|
||||||
(*button.handler)(BUTTON_RELEASED, press, false);
|
(*button.handler)(button.id, BUTTON_RELEASED, press, false);
|
||||||
}
|
}
|
||||||
// button is a copy, so need to go to real context
|
// button is a copy, so need to go to real context
|
||||||
buttons[button.index].shifting = false;
|
buttons[button.index].shifting = false;
|
||||||
} else if (!button.shifting) {
|
} else if (!button.shifting) {
|
||||||
// normal long press and not shifting so don't discard
|
// normal long press and not shifting so don't discard
|
||||||
(*button.handler)(BUTTON_PRESSED, press, true);
|
(*button.handler)(button.id, BUTTON_PRESSED, press, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// normal press/release of a button or release of a long-press button
|
// normal press/release of a button or release of a long-press button
|
||||||
if (!button.shifting) (*button.handler)(event, press, button.long_press);
|
if (!button.shifting) (*button.handler)(button.id, event, press, button.long_press);
|
||||||
// button is a copy, so need to go to real context
|
// button is a copy, so need to go to real context
|
||||||
buttons[button.index].shifting = false;
|
buttons[button.index].shifting = false;
|
||||||
}
|
}
|
||||||
@@ -141,14 +141,14 @@ static void buttons_task(void* arg) {
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* dummy button handler
|
* dummy button handler
|
||||||
*/
|
*/
|
||||||
void dummy_handler(button_event_e event, button_press_e press) {
|
void dummy_handler(void *id, button_event_e event, button_press_e press) {
|
||||||
ESP_LOGW(TAG, "should not be here");
|
ESP_LOGW(TAG, "should not be here");
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Create buttons
|
* Create buttons
|
||||||
*/
|
*/
|
||||||
void button_create(int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio) {
|
void button_create(void *id, int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio) {
|
||||||
|
|
||||||
if (n_buttons >= MAX_BUTTONS) return;
|
if (n_buttons >= MAX_BUTTONS) return;
|
||||||
|
|
||||||
@@ -157,13 +157,14 @@ void button_create(int gpio, int type, bool pull, button_handler handler, int lo
|
|||||||
if (!n_buttons) {
|
if (!n_buttons) {
|
||||||
button_evt_queue = xQueueCreate(10, sizeof(struct button_s));
|
button_evt_queue = xQueueCreate(10, sizeof(struct button_s));
|
||||||
gpio_install_isr_service(0);
|
gpio_install_isr_service(0);
|
||||||
xTaskCreate(buttons_task, "buttons_task", 2048, NULL, ESP_TASK_PRIO_MIN + 1, NULL);
|
xTaskCreate(buttons_task, "buttons_task", 8192, NULL, ESP_TASK_PRIO_MIN + 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// just in case this structure is allocated later
|
// just in case this structure is allocated in a future release
|
||||||
memset(buttons + n_buttons, 0, sizeof(struct button_s));
|
memset(buttons + n_buttons, 0, sizeof(struct button_s));
|
||||||
|
|
||||||
// set mandatory parameters
|
// set mandatory parameters
|
||||||
|
buttons[n_buttons].id = id;
|
||||||
buttons[n_buttons].gpio = gpio;
|
buttons[n_buttons].gpio = gpio;
|
||||||
buttons[n_buttons].handler = handler;
|
buttons[n_buttons].handler = handler;
|
||||||
buttons[n_buttons].long_press = long_press;
|
buttons[n_buttons].long_press = long_press;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
typedef enum { BUTTON_PRESSED, BUTTON_RELEASED } button_event_e;
|
typedef enum { BUTTON_PRESSED, BUTTON_RELEASED } button_event_e;
|
||||||
typedef enum { BUTTON_NORMAL, BUTTON_SHIFTED } button_press_e;
|
typedef enum { BUTTON_NORMAL, BUTTON_SHIFTED } button_press_e;
|
||||||
typedef void (*button_handler)(button_event_e event, button_press_e mode, bool long_press);
|
typedef void (*button_handler)(void *id, button_event_e event, button_press_e mode, bool long_press);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
set long_press to 0 for no long-press
|
set long_press to 0 for no long-press
|
||||||
@@ -32,4 +32,4 @@ set shifter_gpio to -1 for no shift
|
|||||||
NOTE: shifter buttons *must* be created before shiftee
|
NOTE: shifter buttons *must* be created before shiftee
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void button_create(int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio);
|
void button_create(void *id, int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio);
|
||||||
@@ -14,7 +14,8 @@ CFLAGS += -O3 -DLINKALL -DLOOPBACK -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ON
|
|||||||
-I$(COMPONENT_PATH)/../codecs/inc/opus \
|
-I$(COMPONENT_PATH)/../codecs/inc/opus \
|
||||||
-I$(COMPONENT_PATH)/../codecs/inc/opusfile \
|
-I$(COMPONENT_PATH)/../codecs/inc/opusfile \
|
||||||
-I$(COMPONENT_PATH)/../driver_bt \
|
-I$(COMPONENT_PATH)/../driver_bt \
|
||||||
-I$(COMPONENT_PATH)/../raop
|
-I$(COMPONENT_PATH)/../raop \
|
||||||
|
-I$(COMPONENT_PATH)/../audio_controls
|
||||||
|
|
||||||
# -I$(COMPONENT_PATH)/../codecs/inc/faad2
|
# -I$(COMPONENT_PATH)/../codecs/inc/faad2
|
||||||
|
|
||||||
|
|||||||
127
components/squeezelite/controls.c
Normal file
127
components/squeezelite/controls.c
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* (c) Philippe G. 2019, philippe_44@outlook.com
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "squeezelite.h"
|
||||||
|
#include "audio_controls.h"
|
||||||
|
|
||||||
|
static log_level loglevel = lINFO;
|
||||||
|
|
||||||
|
static in_addr_t server_ip;
|
||||||
|
static u16_t server_hport;
|
||||||
|
static u16_t server_cport;
|
||||||
|
static u8_t mac[6];
|
||||||
|
static void (*chained_notify)(in_addr_t, u16_t, u16_t);
|
||||||
|
|
||||||
|
static void cli_send_cmd(char *cmd);
|
||||||
|
|
||||||
|
static void lms_volume_up(void) {
|
||||||
|
cli_send_cmd("button volup");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_volume_down(void) {
|
||||||
|
cli_send_cmd("button voldown");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_toggle(void) {
|
||||||
|
cli_send_cmd("pause");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_pause(void) {
|
||||||
|
cli_send_cmd("pause 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_play(void) {
|
||||||
|
cli_send_cmd("pause 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_stop(void) {
|
||||||
|
cli_send_cmd("button stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_rew(void) {
|
||||||
|
cli_send_cmd("button rew.repeat");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_fwd(void) {
|
||||||
|
cli_send_cmd("button fwd.repeat");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_prev(void) {
|
||||||
|
cli_send_cmd("button rew");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_next(void) {
|
||||||
|
cli_send_cmd("button fwd");
|
||||||
|
}
|
||||||
|
|
||||||
|
static actrls_t controls = {
|
||||||
|
lms_volume_up, lms_volume_down, // volume up, volume down
|
||||||
|
lms_toggle, lms_play, // toggle, play
|
||||||
|
lms_pause, lms_stop, // pause, stop
|
||||||
|
lms_rew, lms_fwd, // rew, fwd
|
||||||
|
lms_prev, lms_next, // prev, next
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cli_send_cmd(char *cmd) {
|
||||||
|
char packet[64];
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
int len, sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = server_ip;
|
||||||
|
addr.sin_port = htons(server_cport);
|
||||||
|
|
||||||
|
if (connect(sock, (struct sockaddr *) &addr, addrlen) < 0) {
|
||||||
|
LOG_ERROR("unable to connect to server %s:%hu with cli", inet_ntoa(server_ip), server_cport);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sprintf(packet, "%02x:%02x:%02x:%02x:%02x:%02x %s\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], cmd);
|
||||||
|
LOG_DEBUG("sending command %s at %s:%hu", packet, inet_ntoa(server_ip), server_cport);
|
||||||
|
|
||||||
|
if (send(sock, packet, len, 0) < 0) {
|
||||||
|
LOG_WARN("cannot send CLI %s", packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* Notification when server changes
|
||||||
|
*/
|
||||||
|
static void notify(in_addr_t ip, u16_t hport, u16_t cport) {
|
||||||
|
server_ip = ip;
|
||||||
|
server_hport = hport;
|
||||||
|
server_cport = cport;
|
||||||
|
LOG_INFO("notified server %s hport %hu cport %hu", inet_ntoa(ip), hport, cport);
|
||||||
|
if (chained_notify) (*chained_notify)(ip, hport, cport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* Initialize controls - shall be called once from output_init_embedded
|
||||||
|
*/
|
||||||
|
void cli_controls_init(void) {
|
||||||
|
get_mac(mac);
|
||||||
|
actrls_set_default(controls);
|
||||||
|
chained_notify = server_notify;
|
||||||
|
server_notify = notify;
|
||||||
|
}
|
||||||
@@ -45,5 +45,6 @@ int pthread_create_name(pthread_t *thread, _CONST pthread_attr_t *attr,
|
|||||||
|
|
||||||
void register_external(void);
|
void register_external(void);
|
||||||
void deregister_external(void);
|
void deregister_external(void);
|
||||||
|
void (*server_notify)(in_addr_t ip, u16_t hport, u16_t cport);
|
||||||
|
|
||||||
#endif // EMBEDDED_H
|
#endif // EMBEDDED_H
|
||||||
|
|||||||
@@ -28,18 +28,19 @@ extern struct buffer *outputbuf;
|
|||||||
#define LOCK mutex_lock(outputbuf->mutex)
|
#define LOCK mutex_lock(outputbuf->mutex)
|
||||||
#define UNLOCK mutex_unlock(outputbuf->mutex)
|
#define UNLOCK mutex_unlock(outputbuf->mutex)
|
||||||
|
|
||||||
|
// output_bt.c
|
||||||
extern void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params,
|
extern void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params,
|
||||||
unsigned rates[], unsigned rate_delay, unsigned idle);
|
unsigned rates[], unsigned rate_delay, unsigned idle);
|
||||||
extern void output_close_bt(void);
|
extern void output_close_bt(void);
|
||||||
|
|
||||||
|
// output_i2s.c
|
||||||
extern void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params,
|
extern void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params,
|
||||||
unsigned rates[], unsigned rate_delay, unsigned idle);
|
unsigned rates[], unsigned rate_delay, unsigned idle);
|
||||||
extern bool output_volume_i2s(unsigned left, unsigned right);
|
extern bool output_volume_i2s(unsigned left, unsigned right);
|
||||||
extern void output_close_i2s(void);
|
extern void output_close_i2s(void);
|
||||||
|
|
||||||
#ifdef CONFIG_BT_SINK
|
// controls.c
|
||||||
extern void decode_bt_init(void);
|
extern void cli_controls_init(void);
|
||||||
#endif
|
|
||||||
|
|
||||||
static log_level loglevel;
|
static log_level loglevel;
|
||||||
|
|
||||||
@@ -56,6 +57,8 @@ void output_init_embedded(log_level level, char *device, unsigned output_buf_siz
|
|||||||
output.start_frames = FRAME_BLOCK;
|
output.start_frames = FRAME_BLOCK;
|
||||||
output.rate_delay = rate_delay;
|
output.rate_delay = rate_delay;
|
||||||
|
|
||||||
|
cli_controls_init();
|
||||||
|
|
||||||
if (strcasestr(device, "BT ")) {
|
if (strcasestr(device, "BT ")) {
|
||||||
LOG_INFO("init Bluetooth");
|
LOG_INFO("init Bluetooth");
|
||||||
close_cb = &output_close_bt;
|
close_cb = &output_close_bt;
|
||||||
|
|||||||
@@ -583,6 +583,7 @@ static void *output_thread_i2s() {
|
|||||||
* Stats output thread
|
* Stats output thread
|
||||||
*/
|
*/
|
||||||
static void *output_thread_i2s_stats() {
|
static void *output_thread_i2s_stats() {
|
||||||
|
int memory_count = 0;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
#ifdef TAS57xx
|
#ifdef TAS57xx
|
||||||
@@ -617,11 +618,14 @@ static void *output_thread_i2s_stats() {
|
|||||||
LOG_INFO(" ----------+----------+-----------+-----------+");
|
LOG_INFO(" ----------+----------+-----------+-----------+");
|
||||||
RESET_ALL_MIN_MAX;
|
RESET_ALL_MIN_MAX;
|
||||||
}
|
}
|
||||||
LOG_INFO("Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
if (loglevel == lDEBUG || !memory_count--) {
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
LOG_INFO("Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
||||||
|
memory_count = (60*1000) / STATS_PERIOD_MS;
|
||||||
|
}
|
||||||
usleep(STATS_PERIOD_MS *1000);
|
usleep(STATS_PERIOD_MS *1000);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ static log_level loglevel;
|
|||||||
|
|
||||||
static sockfd sock = -1;
|
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_cport = 9090;
|
||||||
|
|
||||||
extern struct buffer *streambuf;
|
extern struct buffer *streambuf;
|
||||||
extern struct buffer *outputbuf;
|
extern struct buffer *outputbuf;
|
||||||
@@ -768,16 +770,17 @@ void wake_controller(void) {
|
|||||||
in_addr_t discover_server(char *default_server) {
|
in_addr_t discover_server(char *default_server) {
|
||||||
struct sockaddr_in d;
|
struct sockaddr_in d;
|
||||||
struct sockaddr_in s;
|
struct sockaddr_in s;
|
||||||
char *buf;
|
char buf[32], port_d[] = "JSON", clip_d[] = "CLIP";
|
||||||
struct pollfd pollinfo;
|
struct pollfd pollinfo;
|
||||||
unsigned port;
|
unsigned port;
|
||||||
|
u8_t len;
|
||||||
|
|
||||||
int disc_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
int disc_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
socklen_t enable = 1;
|
socklen_t enable = 1;
|
||||||
setsockopt(disc_sock, SOL_SOCKET, SO_BROADCAST, (const void *)&enable, sizeof(enable));
|
setsockopt(disc_sock, SOL_SOCKET, SO_BROADCAST, (const void *)&enable, sizeof(enable));
|
||||||
|
|
||||||
buf = "e";
|
len = sprintf(buf,"e%s%c%s", port_d, '\0', clip_d) + 1;
|
||||||
|
|
||||||
memset(&d, 0, sizeof(d));
|
memset(&d, 0, sizeof(d));
|
||||||
d.sin_family = AF_INET;
|
d.sin_family = AF_INET;
|
||||||
@@ -792,15 +795,26 @@ in_addr_t discover_server(char *default_server) {
|
|||||||
LOG_INFO("sending discovery");
|
LOG_INFO("sending discovery");
|
||||||
memset(&s, 0, sizeof(s));
|
memset(&s, 0, sizeof(s));
|
||||||
|
|
||||||
if (sendto(disc_sock, buf, 1, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
|
if (sendto(disc_sock, buf, len, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
|
||||||
LOG_INFO("error sending disovery");
|
LOG_INFO("error sending disovery");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll(&pollinfo, 1, 5000) == 1) {
|
if (poll(&pollinfo, 1, 5000) == 1) {
|
||||||
char readbuf[10];
|
char readbuf[32], *p;
|
||||||
socklen_t slen = sizeof(s);
|
socklen_t slen = sizeof(s);
|
||||||
recvfrom(disc_sock, readbuf, 10, 0, (struct sockaddr *)&s, &slen);
|
memset(readbuf, 0, 32);
|
||||||
|
recvfrom(disc_sock, readbuf, 32 - 1, 0, (struct sockaddr *)&s, &slen);
|
||||||
LOG_INFO("got response from: %s:%d", inet_ntoa(s.sin_addr), ntohs(s.sin_port));
|
LOG_INFO("got response from: %s:%d", inet_ntoa(s.sin_addr), ntohs(s.sin_port));
|
||||||
|
|
||||||
|
if ((p = strstr(readbuf, port_d)) != NULL) {
|
||||||
|
p += strlen(port_d);
|
||||||
|
slimproto_hport = atoi(p + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p = strstr(readbuf, clip_d)) != NULL) {
|
||||||
|
p += strlen(clip_d);
|
||||||
|
slimproto_cport = atoi(p + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_server) {
|
if (default_server) {
|
||||||
@@ -951,6 +965,10 @@ void slimproto(log_level level, char *server, u8_t mac[6], const char *name, con
|
|||||||
|
|
||||||
sendHELO(reconnect, fixed_cap, var_cap, mac);
|
sendHELO(reconnect, fixed_cap, var_cap, mac);
|
||||||
|
|
||||||
|
#if EMBEDDED
|
||||||
|
if (server_notify) (*server_notify)(slimproto_ip, slimproto_hport, slimproto_cport);
|
||||||
|
#endif
|
||||||
|
|
||||||
slimproto_run();
|
slimproto_run();
|
||||||
|
|
||||||
if (!reconnect) {
|
if (!reconnect) {
|
||||||
|
|||||||
@@ -282,10 +282,6 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if EMBEDDED
|
|
||||||
#include "embedded.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX || OSX || FREEBSD || EMBEDDED
|
#if LINUX || OSX || FREEBSD || EMBEDDED
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -391,6 +387,10 @@ typedef BOOL bool;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if EMBEDDED
|
||||||
|
#include "embedded.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(MSG_NOSIGNAL)
|
#if !defined(MSG_NOSIGNAL)
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -76,8 +76,18 @@ static bool bWifiConnected=false;
|
|||||||
extern const uint8_t server_cert_pem_start[] asm("_binary_github_pem_start");
|
extern const uint8_t server_cert_pem_start[] asm("_binary_github_pem_start");
|
||||||
extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end");
|
extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end");
|
||||||
|
|
||||||
|
static const actrls_config_t board_1[] = {
|
||||||
|
// normal long shifted long shifted
|
||||||
|
{ 4, BUTTON_LOW, true, 1000, -1, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
|
||||||
|
{ 5, BUTTON_LOW, true, 1000, 4, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_TOGGLE, ACTRLS_NONE}, {ACTRLS_FWD, ACTRLS_PLAY} },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const actrls_config_t board_2[] = {
|
||||||
|
// normal long shifted long shifted
|
||||||
|
{ 21, BUTTON_LOW, true, 1000, -1, {ACTRLS_TOGGLE, ACTRLS_NONE}, {ACTRLS_STOP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
|
||||||
|
{ 18, BUTTON_LOW, true, 1000, 21, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_REW, ACTRLS_PLAY} },
|
||||||
|
{ 19, BUTTON_LOW, true, 1000, 21, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_FWD, ACTRLS_PLAY} },
|
||||||
|
};
|
||||||
|
|
||||||
/* brief this is an exemple of a callback that you can setup in your own app to get notified of wifi manager event */
|
/* brief this is an exemple of a callback that you can setup in your own app to get notified of wifi manager event */
|
||||||
void cb_connection_got_ip(void *pvParameter){
|
void cb_connection_got_ip(void *pvParameter){
|
||||||
@@ -381,7 +391,7 @@ void app_main()
|
|||||||
led_config(LED_RED, LED_RED_GPIO, 0);
|
led_config(LED_RED, LED_RED_GPIO, 0);
|
||||||
|
|
||||||
ESP_LOGD(TAG,"Initializing audio control buttons");
|
ESP_LOGD(TAG,"Initializing audio control buttons");
|
||||||
audio_controls_init();
|
actrls_init(sizeof(board_1) / sizeof(actrls_config_t), (actrls_config_t*) board_1);
|
||||||
|
|
||||||
/* start the wifi manager */
|
/* start the wifi manager */
|
||||||
ESP_LOGD(TAG,"Blinking led");
|
ESP_LOGD(TAG,"Blinking led");
|
||||||
|
|||||||
Reference in New Issue
Block a user