mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 21:17:18 +03:00
add buttons/rotary/ir/BT sink in sleep + battery low-voltage
This commit is contained in:
@@ -9,12 +9,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "squeezelite.h"
|
||||
#include "equalizer.h"
|
||||
#include "perf_trace.h"
|
||||
#include "platform_config.h"
|
||||
#include <assert.h>
|
||||
#include "services.h"
|
||||
#include "led.h"
|
||||
|
||||
extern struct outputstate output;
|
||||
extern struct buffer *outputbuf;
|
||||
@@ -39,6 +41,7 @@ static bool running = false;
|
||||
static uint8_t *btout;
|
||||
static frames_t oframes;
|
||||
static bool stats;
|
||||
static uint32_t bt_idle_since;
|
||||
|
||||
static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags,
|
||||
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
|
||||
@@ -60,10 +63,28 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
|
||||
RESET_MIN_MAX_DURATION(lock_out_time)
|
||||
|
||||
DECLARE_ALL_MIN_MAX;
|
||||
|
||||
/****************************************************************************************
|
||||
* Get inactivity callback
|
||||
*/
|
||||
static uint32_t bt_idle_callback(void) {
|
||||
return output.state <= OUTPUT_STOPPED ? pdTICKS_TO_MS(xTaskGetTickCount()) - bt_idle_since : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Init BT sink
|
||||
*/
|
||||
void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
|
||||
loglevel = level;
|
||||
running = true;
|
||||
|
||||
// idle counter
|
||||
bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
services_sleep_setsleeper(bt_idle_callback);
|
||||
|
||||
// even BT has a right to use led :-)
|
||||
led_blink(LED_GREEN, 200, 1000);
|
||||
|
||||
running = true;
|
||||
output.write_cb = &_write_frames;
|
||||
hal_bluetooth_init(device);
|
||||
char *p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0);
|
||||
@@ -72,6 +93,9 @@ void output_init_bt(log_level level, char *device, unsigned output_buf_size, cha
|
||||
equalizer_set_samplerate(output.current_sample_rate);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Close BT sink
|
||||
*/
|
||||
void output_close_bt(void) {
|
||||
LOCK;
|
||||
running = false;
|
||||
@@ -80,6 +104,9 @@ void output_close_bt(void) {
|
||||
equalizer_close();
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Data framing callback
|
||||
*/
|
||||
static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags,
|
||||
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
|
||||
|
||||
@@ -120,6 +147,9 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
|
||||
return (int)out_frames;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Data callback for BT stack
|
||||
*/
|
||||
int32_t output_bt_data(uint8_t *data, int32_t len) {
|
||||
int32_t iframes = len / BYTES_PER_FRAME, start_timer = 0;
|
||||
|
||||
@@ -153,6 +183,9 @@ int32_t output_bt_data(uint8_t *data, int32_t len) {
|
||||
return oframes * BYTES_PER_FRAME;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Tick for BT
|
||||
*/
|
||||
void output_bt_tick(void) {
|
||||
static time_t lastTime=0;
|
||||
|
||||
@@ -186,3 +219,18 @@ void output_bt_tick(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* BT playback stop
|
||||
*/
|
||||
void output_bt_stop(void) {
|
||||
led_blink(LED_GREEN, 200, 1000);
|
||||
bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* BT playback start
|
||||
*/
|
||||
void output_bt_start(void) {
|
||||
led_on(LED_GREEN);
|
||||
bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
}
|
||||
|
||||
@@ -103,11 +103,11 @@ const struct adac_s *adac = &dac_external;
|
||||
|
||||
static log_level loglevel;
|
||||
|
||||
static uint32_t stopped_time;
|
||||
static uint32_t i2s_idle_since;
|
||||
static void (*pseudo_idle_chain)(uint32_t);
|
||||
static bool (*slimp_handler_chain)(u8_t *data, int len);
|
||||
static bool jack_mutes_amp;
|
||||
static bool running, isI2SStarted, ended, i2s_stats;
|
||||
static bool running, isI2SStarted, ended;
|
||||
static i2s_config_t i2s_config;
|
||||
static u8_t *obuf;
|
||||
static frames_t oframes;
|
||||
@@ -128,7 +128,7 @@ DECLARE_ALL_MIN_MAX;
|
||||
static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags,
|
||||
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
|
||||
static void output_thread_i2s(void *arg);
|
||||
static void i2s_idle(uint32_t now);
|
||||
static void i2s_stats(uint32_t now);
|
||||
|
||||
static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count);
|
||||
static void (*jack_handler_chain)(bool inserted);
|
||||
@@ -202,6 +202,13 @@ static void set_amp_gpio(int gpio, char *value) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************************
|
||||
* Get inactivity callback
|
||||
*/
|
||||
static uint32_t i2s_idle_callback(void) {
|
||||
return output.state <= OUTPUT_STOPPED ? pdTICKS_TO_MS(xTaskGetTickCount()) - i2s_idle_since : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* Set pin from config string
|
||||
*/
|
||||
@@ -418,11 +425,15 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
|
||||
|
||||
// do we want stats
|
||||
p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0);
|
||||
i2s_stats = p && (*p == '1' || *p == 'Y' || *p == 'y');
|
||||
if (p && (*p == '1' || *p == 'Y' || *p == 'y')) {
|
||||
pseudo_idle_chain = pseudo_idle_svc;
|
||||
pseudo_idle_svc = i2s_stats;
|
||||
}
|
||||
free(p);
|
||||
|
||||
pseudo_idle_chain = pseudo_idle_svc;
|
||||
pseudo_idle_svc = i2s_idle;
|
||||
|
||||
// register a callback for inactivity
|
||||
i2s_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
services_sleep_setsleeper(i2s_idle_callback);
|
||||
|
||||
// create task as a FreeRTOS task but uses stack in internal RAM
|
||||
{
|
||||
@@ -433,7 +444,6 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Terminate DAC output
|
||||
*/
|
||||
@@ -497,8 +507,7 @@ static void output_thread_i2s(void *arg) {
|
||||
uint32_t fullness = gettime_ms();
|
||||
bool synced;
|
||||
output_state state = OUTPUT_OFF - 1;
|
||||
stopped_time = pdMS_TO_TICKS(xTaskGetTickCount());
|
||||
|
||||
|
||||
while (running) {
|
||||
|
||||
TIME_MEASUREMENT_START(timer_start);
|
||||
@@ -513,7 +522,7 @@ static void output_thread_i2s(void *arg) {
|
||||
if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, !amp_control.active);
|
||||
LOG_INFO("switching off amp GPIO %d", amp_control.gpio);
|
||||
} else if (output.state == OUTPUT_STOPPED) {
|
||||
stopped_time = pdMS_TO_TICKS(xTaskGetTickCount());
|
||||
i2s_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
adac->speaker(false);
|
||||
led_blink(LED_GREEN, 200, 1000);
|
||||
} else if (output.state == OUTPUT_RUNNING) {
|
||||
@@ -640,17 +649,14 @@ static void output_thread_i2s(void *arg) {
|
||||
/****************************************************************************************
|
||||
* stats output callback
|
||||
*/
|
||||
static void i2s_idle(uint32_t now) {
|
||||
static void i2s_stats(uint32_t now) {
|
||||
static uint32_t last;
|
||||
|
||||
// first chain to next handler
|
||||
if (pseudo_idle_chain) pseudo_idle_chain(now);
|
||||
|
||||
// call the sleep mamanger
|
||||
if (output.state <= OUTPUT_STOPPED) services_sleep_callback(now - stopped_time);
|
||||
|
||||
// then see if we need to act
|
||||
if (!i2s_stats || output.state <= OUTPUT_STOPPED || now < last + STATS_PERIOD_MS) return;
|
||||
if (output.state <= OUTPUT_STOPPED || now < last + STATS_PERIOD_MS) return;
|
||||
last = now;
|
||||
|
||||
LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d", output.state, output.current_sample_rate, BYTES_PER_FRAME);
|
||||
|
||||
Reference in New Issue
Block a user