mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-29 05:40:50 +03:00
initial refactoring
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# for the forgetful, REQUIRES cannot use CONFIG_XXX due to parsing order
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
set(target_requires "driver_bt")
|
||||
set(target_requires "driver_bt" "platform_config")
|
||||
endif()
|
||||
|
||||
idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <driver/i2s.h>
|
||||
#include "adac.h"
|
||||
#include "ac101.h"
|
||||
|
||||
#include "Configurator.h"
|
||||
static const char TAG[] = "AC101";
|
||||
|
||||
#define SPKOUT_EN ((1 << 9) | (1 << 11) | (1 << 7) | (1 << 5))
|
||||
@@ -54,7 +54,7 @@ static void headset(bool active);
|
||||
static bool volume(unsigned left, unsigned right);
|
||||
static void power(adac_power_e mode);
|
||||
|
||||
const struct adac_s dac_ac101 = { "AC101", init, adac_deinit, power, speaker, headset, volume };
|
||||
const struct adac_s dac_ac101 = { sys_DACModelEnum_AC101, init, adac_deinit, power, speaker, headset, volume };
|
||||
|
||||
static void ac101_start(ac_module_t mode);
|
||||
static void ac101_stop(void);
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/i2s.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#include "Configurator.h"
|
||||
typedef enum { ADAC_ON = 0, ADAC_STANDBY, ADAC_OFF } adac_power_e;
|
||||
|
||||
struct adac_s {
|
||||
char *model;
|
||||
sys_DACModelEnum model;
|
||||
bool (*init)(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
|
||||
void (*deinit)(void);
|
||||
void (*power)(adac_power_e mode);
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
*/
|
||||
|
||||
#include "squeezelite.h"
|
||||
#include "platform_config.h"
|
||||
// #include "Configurator.h"
|
||||
#pragma message("fixme: look for TODO below")
|
||||
#include "audio_controls.h"
|
||||
|
||||
static log_level loglevel = lINFO;
|
||||
@@ -242,15 +243,16 @@ static bool ir_handler(u16_t addr, u16_t cmd) {
|
||||
* Initialize controls - shall be called once from output_init_embedded
|
||||
*/
|
||||
void sb_controls_init(void) {
|
||||
char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0);
|
||||
raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y');
|
||||
free(p);
|
||||
// TODO: Add support for the commented code
|
||||
// char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0);
|
||||
// raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y');
|
||||
// free(p);
|
||||
|
||||
LOG_INFO("initializing audio (buttons/rotary/ir) controls (raw:%u)", raw_mode);
|
||||
// LOG_INFO("initializing audio (buttons/rotary/ir) controls (raw:%u)", raw_mode);
|
||||
|
||||
get_mac(mac);
|
||||
actrls_set_default(LMS_controls, raw_mode, NULL, ir_handler);
|
||||
// get_mac(mac);
|
||||
// actrls_set_default(LMS_controls, raw_mode, NULL, ir_handler);
|
||||
|
||||
chained_notify = server_notify;
|
||||
server_notify = notify;
|
||||
// chained_notify = server_notify;
|
||||
// server_notify = notify;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "adac.h"
|
||||
#include "stdio.h"
|
||||
#include "math.h"
|
||||
#include "Configurator.h"
|
||||
#define CS4265_PULL_UP (0x4F )
|
||||
#define CS4265_PULL_DOWN (0x4E )
|
||||
|
||||
@@ -36,7 +37,7 @@ static bool volume(unsigned left, unsigned right);
|
||||
static void power(adac_power_e mode);
|
||||
static esp_err_t cs4265_update_bit(uint8_t reg_no,uint8_t mask,uint8_t val );
|
||||
static esp_err_t set_clock();
|
||||
const struct adac_s dac_cs4265 = { "CS4265", init, adac_deinit, power, speaker, headset, volume };
|
||||
const struct adac_s dac_cs4265 = { sys_DACModelEnum_CS4265, init, adac_deinit, power, speaker, headset, volume };
|
||||
|
||||
struct cs4265_cmd_s {
|
||||
uint8_t reg;
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/timers.h"
|
||||
#endif
|
||||
#include "platform_config.h"
|
||||
#include "Configurator.h"
|
||||
#include "accessors.h"
|
||||
#include "squeezelite.h"
|
||||
|
||||
|
||||
@@ -38,6 +39,7 @@ static bool enable_airplay;
|
||||
#define SYNC_WIN_FAST 2
|
||||
|
||||
static raop_event_t raop_state;
|
||||
static sys_Squeezelite * squeezelite;
|
||||
|
||||
static EXT_RAM_ATTR struct {
|
||||
bool enabled;
|
||||
@@ -446,44 +448,45 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args)
|
||||
* We provide the generic codec register option
|
||||
*/
|
||||
void register_external(void) {
|
||||
char *p;
|
||||
|
||||
sys_BluetoothSink * bt_sink;
|
||||
sys_AirPlay * airplay;
|
||||
sys_Spotify * spotify;
|
||||
#if CONFIG_BT_SINK
|
||||
if ((p = config_alloc_get(NVS_TYPE_STR, "enable_bt_sink")) != NULL) {
|
||||
enable_bt_sink = !strcmp(p,"1") || !strcasecmp(p,"y");
|
||||
free(p);
|
||||
if (!strcasestr(output.device, "BT") && enable_bt_sink) {
|
||||
enable_bt_sink= (SYS_SERVICES_BTSINK(bt_sink) && bt_sink->enabled);
|
||||
if ( enable_bt_sink) {
|
||||
#pragma message ("Is the BT sink logic correct?")
|
||||
if(SYS_SERVICES_SQUEEZELITE(squeezelite) && squeezelite->output_type == sys_OutputTypeEnum_OUTPUT_Bluetooth ){
|
||||
LOG_ERROR("BT Sink cannot be enabled with Bluetooth output");
|
||||
}
|
||||
else {
|
||||
bt_sink_init(bt_sink_cmd_handler, bt_sink_data_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_AIRPLAY_SINK
|
||||
if ((p = config_alloc_get(NVS_TYPE_STR, "enable_airplay")) != NULL) {
|
||||
enable_airplay = !strcmp(p,"1") || !strcasecmp(p,"y");
|
||||
free(p);
|
||||
if (enable_airplay){
|
||||
raop_sink_init(raop_sink_cmd_handler, raop_sink_data_handler);
|
||||
LOG_INFO("Initializing AirPlay sink");
|
||||
}
|
||||
enable_airplay = SYS_SERVICES_AIRPLAY(airplay) && airplay->enabled;
|
||||
if (enable_airplay){
|
||||
raop_sink_init(raop_sink_cmd_handler, raop_sink_data_handler);
|
||||
LOG_INFO("Initializing AirPlay sink");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_CSPOT_SINK
|
||||
if ((p = config_alloc_get(NVS_TYPE_STR, "enable_cspot")) != NULL) {
|
||||
enable_cspot = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0;
|
||||
free(p);
|
||||
if (enable_cspot){
|
||||
cspot_sink_init(cspot_cmd_handler, cspot_sink_data_handler);
|
||||
LOG_INFO("Initializing CSpot sink");
|
||||
}
|
||||
enable_cspot = SYS_SERVICES_SPOTIFY(spotify) && spotify->enabled;
|
||||
if (enable_cspot){
|
||||
cspot_sink_init(cspot_cmd_handler, cspot_sink_data_handler);
|
||||
LOG_INFO("Initializing CSpot sink");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void deregister_external(void) {
|
||||
#if CONFIG_BT_SINK
|
||||
if (!strcasestr(output.device, "BT") && enable_bt_sink) {
|
||||
sys_Squeezelite * squeezelite;
|
||||
if(SYS_SERVICES_SQUEEZELITE(squeezelite) && squeezelite->output_type != sys_OutputTypeEnum_OUTPUT_Bluetooth && enable_bt_sink ){
|
||||
bt_sink_deinit();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,20 +17,13 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "monitor.h"
|
||||
#include "platform_config.h"
|
||||
#include "Configurator.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 };
|
||||
static sys_GPIO * power=NULL;
|
||||
|
||||
extern void sb_controls_init(void);
|
||||
extern bool sb_displayer_init(void);
|
||||
@@ -40,16 +33,6 @@ 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);
|
||||
}
|
||||
@@ -88,16 +71,13 @@ 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);
|
||||
|
||||
if(SYS_GPIOS_NAME(power,power) && power->pin >= 0){
|
||||
gpio_pad_select_gpio_x(power->pin);
|
||||
gpio_set_direction_x(power->pin, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level_x(power->pin, !power->level);
|
||||
ESP_LOGI(TAG, "setting power GPIO %d (active:%d)", power->pin, power->level);
|
||||
}
|
||||
|
||||
return setjmp(jumpbuf);
|
||||
@@ -108,9 +88,9 @@ void embedded_exit(int code) {
|
||||
}
|
||||
|
||||
void powering(bool on) {
|
||||
if (power_control.gpio != -1) {
|
||||
if (power->pin != -1) {
|
||||
ESP_LOGI(TAG, "powering player %s", on ? "ON" : "OFF");
|
||||
gpio_set_level_x(power_control.gpio, on ? power_control.active : !power_control.active);
|
||||
gpio_set_level_x(power->pin, on ? power->level : !power->level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,25 +111,5 @@ u16_t get_battery(void) {
|
||||
}
|
||||
|
||||
void set_name(char *name) {
|
||||
char *cmd = config_alloc_get(NVS_TYPE_STR, "autoexec1");
|
||||
char *p, *q;
|
||||
|
||||
if (!cmd) return;
|
||||
|
||||
if ((p = strstr(cmd, " -n")) != NULL) {
|
||||
q = p + 3;
|
||||
// in case some smart dude has a " -" in player's name
|
||||
while ((q = strstr(q, " -")) != NULL) {
|
||||
if (!strchr(q, '"') || !strchr(q+1, '"')) break;
|
||||
q++;
|
||||
}
|
||||
if (q) memmove(p, q, strlen(q) + 1);
|
||||
else *p = '\0';
|
||||
}
|
||||
|
||||
asprintf(&q, "%s -n \"%s\"", cmd, name);
|
||||
config_set_value(NVS_TYPE_STR, "autoexec1", q);
|
||||
|
||||
free(q);
|
||||
free(cmd);
|
||||
strncpy(platform->names.squeezelite,name,sizeof(platform->names.squeezelite));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "math.h"
|
||||
#include "platform_config.h"
|
||||
#include "Configurator.h"
|
||||
#include "squeezelite.h"
|
||||
#include "equalizer.h"
|
||||
#include "esp_equalizer.h"
|
||||
@@ -20,12 +20,14 @@ static log_level loglevel = lINFO;
|
||||
|
||||
static EXT_RAM_ATTR struct {
|
||||
void *handle;
|
||||
float loudness, volume;
|
||||
uint32_t samplerate;
|
||||
float gain[EQ_BANDS], loudness_gain[EQ_BANDS];
|
||||
float volume;
|
||||
float loudness_gain[EQ_BANDS];
|
||||
bool update;
|
||||
sys_Equalizer *state;
|
||||
} equalizer;
|
||||
|
||||
|
||||
#define POLYNOME_COUNT 6
|
||||
|
||||
static const float loudness_envelope_coefficients[EQ_BANDS][POLYNOME_COUNT] = {
|
||||
@@ -67,11 +69,11 @@ static void calculate_loudness(void) {
|
||||
char trace[EQ_BANDS * 5 + 1];
|
||||
size_t n = 0;
|
||||
for (int i = 0; i < EQ_BANDS; i++) {
|
||||
for (int j = 0; j < POLYNOME_COUNT && equalizer.loudness != 0; j++) {
|
||||
for (int j = 0; j < POLYNOME_COUNT && equalizer.state->loudness != 0; j++) {
|
||||
equalizer.loudness_gain[i] +=
|
||||
loudness_envelope_coefficients[i][j] * pow(equalizer.volume, j);
|
||||
}
|
||||
equalizer.loudness_gain[i] *= equalizer.loudness / 2;
|
||||
equalizer.loudness_gain[i] *= equalizer.state->loudness / 2;
|
||||
n += sprintf(trace + n, "%.2g%c", equalizer.loudness_gain[i], i < EQ_BANDS ? ',' : '\0');
|
||||
}
|
||||
LOG_INFO("loudness %s", trace);
|
||||
@@ -81,22 +83,20 @@ static void calculate_loudness(void) {
|
||||
* initialize equalizer
|
||||
*/
|
||||
void equalizer_init(void) {
|
||||
// handle equalizer
|
||||
char *config = config_alloc_get(NVS_TYPE_STR, "equalizer");
|
||||
char *p = strtok(config, ", !");
|
||||
sys_Services * services;
|
||||
sys_Equalizer blank_eq = sys_Equalizer_init_default;
|
||||
|
||||
for (int i = 0; p && i < EQ_BANDS; i++) {
|
||||
equalizer.gain[i] = atoi(p);
|
||||
p = strtok(NULL, ", :");
|
||||
}
|
||||
|
||||
free(config);
|
||||
|
||||
// handle loudness
|
||||
config = config_alloc_get(NVS_TYPE_STR, "loudness");
|
||||
equalizer.loudness = atof(config) / 10.0;
|
||||
|
||||
free(config);
|
||||
equalizer.state = &sys_state->equalizer;
|
||||
if(!sys_state->has_equalizer ){
|
||||
sys_state->has_equalizer = true;
|
||||
if(SYS_SERVICES(services) && services->has_equalizer){
|
||||
memcpy(equalizer.state,&services->equalizer,sizeof(sys_Equalizer));
|
||||
}
|
||||
else {
|
||||
memcpy(equalizer.state,&blank_eq,sizeof(sys_Equalizer));
|
||||
}
|
||||
configurator_raise_state_changed();
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
@@ -135,7 +135,7 @@ void equalizer_set_volume(unsigned left, unsigned right) {
|
||||
volume = volume / 16.0 * 100.0;
|
||||
|
||||
// LMS has the bad habit to send multiple volume commands
|
||||
if (volume != equalizer.volume && equalizer.loudness) {
|
||||
if (volume != equalizer.volume && equalizer.state->loudness) {
|
||||
equalizer.volume = volume;
|
||||
calculate_loudness();
|
||||
equalizer.update = true;
|
||||
@@ -152,15 +152,16 @@ void equalizer_set_gain(int8_t *gain) {
|
||||
int n = 0;
|
||||
|
||||
for (int i = 0; i < EQ_BANDS; i++) {
|
||||
equalizer.gain[i] = gain[i];
|
||||
equalizer.state->gains[i] = gain[i];
|
||||
n += sprintf(config + n, "%d,", gain[i]);
|
||||
}
|
||||
|
||||
config[n-1] = '\0';
|
||||
config_set_value(NVS_TYPE_STR, "equalizer", config);
|
||||
|
||||
// update only if something changed
|
||||
if (!memcmp(equalizer.gain, gain, EQ_BANDS)) equalizer.update = true;
|
||||
if (!memcmp(&equalizer.state->gains, gain, EQ_BANDS)) {
|
||||
equalizer.update = true;
|
||||
configurator_raise_state_changed();
|
||||
}
|
||||
|
||||
LOG_INFO("equalizer gain %s", config);
|
||||
#else
|
||||
@@ -173,13 +174,11 @@ void equalizer_set_gain(int8_t *gain) {
|
||||
*/
|
||||
void equalizer_set_loudness(uint8_t loudness) {
|
||||
#if BYTES_PER_FRAME == 4
|
||||
char p[4];
|
||||
itoa(loudness, p, 10);
|
||||
config_set_value(NVS_TYPE_STR, "loudness", p);
|
||||
|
||||
// update loudness gains as a factor of loudness and volume
|
||||
if (equalizer.loudness != loudness / 10.0) {
|
||||
equalizer.loudness = loudness / 10.0;
|
||||
// update loudness gains as a factor of loudness and volume
|
||||
if (equalizer.state->loudness != loudness / 10.0) {
|
||||
equalizer.state->loudness = loudness / 10.0;
|
||||
configurator_raise_state_changed();
|
||||
calculate_loudness();
|
||||
equalizer.update = true;
|
||||
}
|
||||
@@ -188,6 +187,7 @@ void equalizer_set_loudness(uint8_t loudness) {
|
||||
#else
|
||||
LOG_INFO("no equalizer with 32 bits samples");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
@@ -211,7 +211,7 @@ void equalizer_process(uint8_t *buf, uint32_t bytes) {
|
||||
|
||||
bool active = false;
|
||||
for (int i = 0; i < EQ_BANDS; i++) {
|
||||
float gain = equalizer.gain[i] + equalizer.loudness_gain[i];
|
||||
float gain = equalizer.state->gains[i] + equalizer.loudness_gain[i];
|
||||
esp_equalizer_set_band_value(equalizer.handle, gain, i, 0);
|
||||
esp_equalizer_set_band_value(equalizer.handle, gain, i, 1);
|
||||
active |= gain != 0;
|
||||
|
||||
185
components/squeezelite/esp32_main.c
Normal file
185
components/squeezelite/esp32_main.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Squeezelite - lightweight headless squeezebox emulator
|
||||
*
|
||||
* (c) Adrian Smith 2012-2015, triode1@btinternet.com
|
||||
* Ralph Irving 2015-2017, ralph_irving@hotmail.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/>.
|
||||
*
|
||||
* Additions (c) Paul Hermann, 2015-2017 under the same license terms
|
||||
* -Control of Raspberry pi GPIO for amplifier power
|
||||
* -Launch script on power status change from LMS
|
||||
*/
|
||||
|
||||
#include "squeezelite.h"
|
||||
#include <signal.h>
|
||||
#include "Configurator.h"
|
||||
|
||||
extern bool user_rates;
|
||||
static unsigned int rates[MAX_SUPPORTED_SAMPLERATES] = {0};
|
||||
sys_Squeezelite* config;
|
||||
log_level loglevel = lDEBUG;
|
||||
static void sighandler(int signum) {
|
||||
slimproto_stop();
|
||||
|
||||
// remove ourselves in case above does not work, second SIGINT will cause non gracefull shutdown
|
||||
signal(signum, SIG_DFL);
|
||||
}
|
||||
|
||||
unsigned int* get_rates() {
|
||||
unsigned int ref[] TEST_RATES;
|
||||
sys_RatesOption* ratescfg = &config->rates;
|
||||
if (!config->has_rates || ((ratescfg->list_count == 0 || ratescfg->list[0] == 0) &&
|
||||
ratescfg->min == 0 && ratescfg->max == 0)) {
|
||||
user_rates = false;
|
||||
return rates;
|
||||
}
|
||||
|
||||
if (ratescfg->list_count > 0 && ratescfg->list[0] != 0) {
|
||||
// Sort the rates from the list
|
||||
for (int i = 0; i < ratescfg->list_count && i < MAX_SUPPORTED_SAMPLERATES; ++i) {
|
||||
rates[i] = ratescfg->list[i];
|
||||
}
|
||||
// Sort logic here if needed
|
||||
} else {
|
||||
// Use min and max to determine rates
|
||||
unsigned int min = ratescfg->min;
|
||||
unsigned int max = ratescfg->max;
|
||||
if (max < min) {
|
||||
unsigned int tmp = max;
|
||||
max = min;
|
||||
min = tmp;
|
||||
}
|
||||
for (int i = 0, j = 0; i < MAX_SUPPORTED_SAMPLERATES; ++i) {
|
||||
if (ref[i] <= max && ref[i] >= min) {
|
||||
rates[j++] = ref[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user_rates = true;
|
||||
return rates;
|
||||
}
|
||||
log_level log_level_from_sys_level(sys_DebugLevelEnum level) {
|
||||
switch (level) {
|
||||
case sys_DebugLevelEnum_DEFAULT:
|
||||
return lWARN;
|
||||
break;
|
||||
case sys_DebugLevelEnum_INFO:
|
||||
return lINFO;
|
||||
break;
|
||||
case sys_DebugLevelEnum_ERROR:
|
||||
return lERROR;
|
||||
break;
|
||||
case sys_DebugLevelEnum_WARN:
|
||||
return lWARN;
|
||||
break;
|
||||
case sys_DebugLevelEnum_DEBUG:
|
||||
return lDEBUG;
|
||||
break;
|
||||
case sys_DebugLevelEnum_SDEBUG:
|
||||
return lSDEBUG;
|
||||
break;
|
||||
default:
|
||||
return lWARN;
|
||||
}
|
||||
}
|
||||
void build_codec_string(sys_CodexEnum* list, size_t count, char* buffer, size_t buf_size) {
|
||||
const char* prefix = STR(sys_CodexEnum) "_c_";
|
||||
const char* name = NULL;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i > 0) {
|
||||
strncat(buffer, ", ", buf_size);
|
||||
}
|
||||
name = sys_CodexEnum_name(list[i]) + strlen(prefix);
|
||||
LOG_INFO("Found codec: %s ", name);
|
||||
strncat(buffer, name, buf_size);
|
||||
}
|
||||
LOG_INFO("Codec list: %s ", buffer);
|
||||
}
|
||||
int squeezelite_main_start() {
|
||||
u8_t mac[6];
|
||||
unsigned output_buf_size = 0;
|
||||
char include_codecs[101] = {0};
|
||||
char exclude_codecs[101] = {0};
|
||||
config = platform->has_services && platform->services.has_squeezelite
|
||||
? &platform->services.squeezelite
|
||||
: NULL;
|
||||
if (!config) {
|
||||
LOG_ERROR("Squeezelite not configured");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int err = embedded_init();
|
||||
if (err) return err;
|
||||
get_mac(mac);
|
||||
unsigned int * rates = get_rates();
|
||||
|
||||
signal(SIGINT, sighandler);
|
||||
signal(SIGTERM, sighandler);
|
||||
#if defined(SIGQUIT)
|
||||
signal(SIGQUIT, sighandler);
|
||||
#endif
|
||||
#if defined(SIGHUP)
|
||||
signal(SIGHUP, sighandler);
|
||||
#endif
|
||||
output_buf_size = config->buffers.output;
|
||||
|
||||
// set the output buffer size if not specified on the command line, take account of resampling
|
||||
if (!output_buf_size) {
|
||||
output_buf_size = OUTPUTBUF_SIZE;
|
||||
if (strlen(config->resample) > 0) {
|
||||
unsigned scale = 8;
|
||||
if (rates[0]) {
|
||||
scale = rates[0] / 44100;
|
||||
if (scale > 8) scale = 8;
|
||||
if (scale < 1) scale = 1;
|
||||
}
|
||||
output_buf_size *= scale;
|
||||
}
|
||||
}
|
||||
build_codec_string(config->excluded_codex, config->excluded_codex_count, exclude_codecs,
|
||||
sizeof(exclude_codecs));
|
||||
build_codec_string(
|
||||
config->included_codex, config->included_codex, include_codecs, sizeof(include_codecs));
|
||||
|
||||
unsigned int stream_buf_size =
|
||||
config->buffers.stream > 0 ? config->buffers.stream : STREAMBUF_SIZE;
|
||||
stream_init(
|
||||
log_level_from_sys_level(platform->services.squeezelite.log.stream), stream_buf_size);
|
||||
output_init_embedded();
|
||||
decode_init(log_level_from_sys_level(platform->services.squeezelite.log.decode), include_codecs,
|
||||
exclude_codecs);
|
||||
|
||||
#if RESAMPLE || RESAMPLE16
|
||||
if (strlen(config->resample) > 0) {
|
||||
process_init(config->resample);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!config->enabled) {
|
||||
LOG_ERROR("LMS is disabled");
|
||||
while (1)
|
||||
sleep(3600);
|
||||
}
|
||||
char* name = strlen(platform->names.squeezelite) > 0 ? platform->names.squeezelite
|
||||
: platform->names.device;
|
||||
slimproto(log_level_from_sys_level(platform->services.squeezelite.log.slimproto),
|
||||
config->server_name_ip, mac, name, NULL, NULL, config->max_rate);
|
||||
|
||||
decode_close();
|
||||
stream_close();
|
||||
output_close_embedded();
|
||||
return (0);
|
||||
}
|
||||
51
components/squeezelite/external/dac_external.c
vendored
51
components/squeezelite/external/dac_external.c
vendored
@@ -16,7 +16,9 @@
|
||||
#include "esp_log.h"
|
||||
#include "gpio_exp.h"
|
||||
#include "cJSON.h"
|
||||
#include "platform_config.h"
|
||||
#include "string.h"
|
||||
// #include "Configurator.h"
|
||||
#pragma message("fixme: look for TODO below")
|
||||
#include "adac.h"
|
||||
|
||||
static const char TAG[] = "DAC external";
|
||||
@@ -29,7 +31,7 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool
|
||||
|
||||
static bool i2c_json_execute(char *set);
|
||||
|
||||
const struct adac_s dac_external = { "i2s", init, adac_deinit, power, speaker, headset, volume };
|
||||
const struct adac_s dac_external = { sys_DACModelEnum_I2S, init, adac_deinit, power, speaker, headset, volume };
|
||||
static cJSON *i2c_json;
|
||||
static int i2c_addr;
|
||||
|
||||
@@ -58,34 +60,35 @@ static const struct {
|
||||
* init
|
||||
*/
|
||||
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck) {
|
||||
char *p;
|
||||
char *p=NULL;
|
||||
void * dummy = &codecs;
|
||||
// i2c_addr = adac_init(config, i2c_port_num);
|
||||
// if (!i2c_addr) return true;
|
||||
|
||||
i2c_addr = adac_init(config, i2c_port_num);
|
||||
if (!i2c_addr) return true;
|
||||
// ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr);
|
||||
|
||||
ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr);
|
||||
|
||||
p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL);
|
||||
// p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL);
|
||||
|
||||
if ((!p || !*p) && (p = strcasestr(config, "model")) != NULL) {
|
||||
char model[32] = "";
|
||||
int i;
|
||||
sscanf(p, "%*[^=]=%31[^,]", model);
|
||||
for (i = 0; *model && ((p = codecs[i].controlset) != NULL) && strcasecmp(codecs[i].model, model); i++);
|
||||
if (p) *mck = codecs[i].mclk;
|
||||
}
|
||||
// if ((!p || !*p) && (p = strcasestr(config, "model")) != NULL) {
|
||||
// char model[32] = "";
|
||||
// int i;
|
||||
// sscanf(p, "%*[^=]=%31[^,]", model);
|
||||
// for (i = 0; *model && ((p = codecs[i].controlset) != NULL) && strcasecmp(codecs[i].model, model); i++);
|
||||
// if (p) *mck = codecs[i].mclk;
|
||||
// }
|
||||
|
||||
i2c_json = cJSON_Parse(p);
|
||||
// i2c_json = cJSON_Parse(p);
|
||||
|
||||
if (!i2c_json) {
|
||||
ESP_LOGW(TAG, "no i2c controlset found");
|
||||
return true;
|
||||
}
|
||||
// if (!i2c_json) {
|
||||
// ESP_LOGW(TAG, "no i2c controlset found");
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (!i2c_json_execute("init")) {
|
||||
ESP_LOGE(TAG, "could not intialize DAC");
|
||||
return false;
|
||||
}
|
||||
// if (!i2c_json_execute("init")) {
|
||||
// ESP_LOGE(TAG, "could not intialize DAC");
|
||||
// return false;
|
||||
// }
|
||||
// TODO: Add support for the commented code
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ int squeezelite_main(int argc, char **argv) {
|
||||
stream_init(log_stream, stream_buf_size);
|
||||
|
||||
#if EMBEDDED
|
||||
output_init_embedded(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
|
||||
output_init_embedded();
|
||||
#else
|
||||
if (!strcmp(output_device, "-")) {
|
||||
output_init_stdout(log_output, output_buf_size, output_params, rates, rate_delay);
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
#include "squeezelite.h"
|
||||
#include "equalizer.h"
|
||||
#include "perf_trace.h"
|
||||
#include "platform_config.h"
|
||||
#include "services.h"
|
||||
#include "led.h"
|
||||
|
||||
#include "Configurator.h"
|
||||
extern log_level log_level_from_sys_level(sys_DebugLevelEnum level);
|
||||
static sys_Squeezelite * config = NULL;
|
||||
extern struct outputstate output;
|
||||
extern struct buffer *outputbuf;
|
||||
extern struct buffer *streambuf;
|
||||
@@ -32,7 +33,7 @@ extern u8_t *silencebuf;
|
||||
|
||||
#define STATS_REPORT_DELAY_MS 15000
|
||||
|
||||
extern void hal_bluetooth_init(const char * options);
|
||||
extern void hal_bluetooth_init();
|
||||
extern void hal_bluetooth_stop(void);
|
||||
extern u8_t config_spdif_gpio;
|
||||
|
||||
@@ -74,11 +75,10 @@ static uint32_t bt_idle_callback(void) {
|
||||
/****************************************************************************************
|
||||
* 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;
|
||||
|
||||
// idle counter
|
||||
bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
void output_init_bt() {
|
||||
config = &platform->services.squeezelite;
|
||||
loglevel = log_level_from_sys_level(config->log.output);
|
||||
bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount());
|
||||
services_sleep_setsleeper(bt_idle_callback);
|
||||
|
||||
// even BT has a right to use led :-)
|
||||
@@ -86,11 +86,11 @@ void output_init_bt(log_level level, char *device, unsigned output_buf_size, cha
|
||||
|
||||
running = true;
|
||||
output.write_cb = &_write_frames;
|
||||
hal_bluetooth_init(device);
|
||||
char *p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0);
|
||||
stats = p && (*p == '1' || *p == 'Y' || *p == 'y');
|
||||
free(p);
|
||||
hal_bluetooth_init();
|
||||
stats = platform->services.statistics;
|
||||
|
||||
equalizer_set_samplerate(output.current_sample_rate);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Squeezelite for esp32
|
||||
*
|
||||
* (c) Sebastien 2019
|
||||
@@ -10,27 +10,30 @@
|
||||
*/
|
||||
#include "squeezelite.h"
|
||||
#include "equalizer.h"
|
||||
#include "Configurator.h"
|
||||
extern log_level log_level_from_sys_level(sys_DebugLevelEnum level);
|
||||
static sys_Squeezelite* config = NULL;
|
||||
|
||||
|
||||
extern unsigned int* get_rates() ;
|
||||
extern struct outputstate output;
|
||||
extern struct buffer *outputbuf;
|
||||
extern struct buffer* outputbuf;
|
||||
|
||||
static bool (*slimp_handler_chain)(u8_t *data, int len);
|
||||
static bool (*slimp_handler_chain)(u8_t* data, int len);
|
||||
|
||||
#define FRAME_BLOCK MAX_SILENCE_FRAMES
|
||||
|
||||
#define LOCK mutex_lock(outputbuf->mutex)
|
||||
#define LOCK mutex_lock(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,
|
||||
unsigned rates[], unsigned rate_delay, unsigned idle);
|
||||
extern void output_close_bt(void);
|
||||
extern void output_init_bt(unsigned rates[]);
|
||||
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,
|
||||
unsigned rates[], unsigned rate_delay, unsigned idle);
|
||||
extern bool output_volume_i2s(unsigned left, unsigned right);
|
||||
extern void output_close_i2s(void);
|
||||
extern void output_init_i2s(unsigned rates[]);
|
||||
extern bool output_volume_i2s(unsigned left, unsigned right);
|
||||
extern void output_close_i2s(void);
|
||||
|
||||
// controls.c
|
||||
extern void cli_controls_init(void);
|
||||
@@ -42,137 +45,152 @@ static void (*close_cb)(void);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct eqlz_packet {
|
||||
char opcode[4];
|
||||
char opcode[4];
|
||||
};
|
||||
|
||||
struct loud_packet {
|
||||
char opcode[4];
|
||||
u8_t loudness;
|
||||
char opcode[4];
|
||||
u8_t loudness;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static bool handler(u8_t *data, int len){
|
||||
bool res = true;
|
||||
|
||||
if (!strncmp((char*) data, "eqlz", 4)) {
|
||||
s8_t *gain = (s8_t*) (data + sizeof(struct eqlz_packet));
|
||||
// update will be done at next opportunity
|
||||
equalizer_set_gain(gain);
|
||||
} else if (!strncmp((char*) data, "loud", 4)) {
|
||||
struct loud_packet *packet = (struct loud_packet*) data;
|
||||
// update will be done at next opportunity
|
||||
equalizer_set_loudness(packet->loudness);
|
||||
} else {
|
||||
res = false;
|
||||
}
|
||||
|
||||
// chain protocol handlers (bitwise or is fine)
|
||||
if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len);
|
||||
|
||||
return res;
|
||||
static bool handler(u8_t* data, int len) {
|
||||
bool res = true;
|
||||
|
||||
if (!strncmp((char*)data, "eqlz", 4)) {
|
||||
s8_t* gain = (s8_t*)(data + sizeof(struct eqlz_packet));
|
||||
// update will be done at next opportunity
|
||||
equalizer_set_gain(gain);
|
||||
} else if (!strncmp((char*)data, "loud", 4)) {
|
||||
struct loud_packet* packet = (struct loud_packet*)data;
|
||||
// update will be done at next opportunity
|
||||
equalizer_set_loudness(packet->loudness);
|
||||
} else {
|
||||
res = false;
|
||||
}
|
||||
|
||||
// chain protocol handlers (bitwise or is fine)
|
||||
if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void output_init_embedded(log_level level, char *device, unsigned output_buf_size, char *params,
|
||||
unsigned rates[], unsigned rate_delay, unsigned idle) {
|
||||
loglevel = level;
|
||||
LOG_INFO("init device: %s", device);
|
||||
|
||||
// chain handlers
|
||||
slimp_handler_chain = slimp_handler;
|
||||
slimp_handler = handler;
|
||||
|
||||
// init equalizer before backends
|
||||
equalizer_init();
|
||||
|
||||
memset(&output, 0, sizeof(output));
|
||||
output_init_common(level, device, output_buf_size, rates, idle);
|
||||
output.start_frames = FRAME_BLOCK;
|
||||
output.rate_delay = rate_delay;
|
||||
|
||||
#if CONFIG_BT_SINK
|
||||
if (strcasestr(device, "BT")) {
|
||||
LOG_INFO("init Bluetooth");
|
||||
close_cb = &output_close_bt;
|
||||
output_init_bt(level, device, output_buf_size, params, rates, rate_delay, idle);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
LOG_INFO("init I2S/SPDIF");
|
||||
close_cb = &output_close_i2s;
|
||||
volume_cb = &output_volume_i2s;
|
||||
output_init_i2s(level, device, output_buf_size, params, rates, rate_delay, idle);
|
||||
}
|
||||
|
||||
output_visu_init(level);
|
||||
|
||||
LOG_INFO("init completed.");
|
||||
}
|
||||
void output_init_embedded() {
|
||||
config = &platform->services.squeezelite;
|
||||
loglevel = log_level_from_sys_level(config->log.output);
|
||||
LOG_INFO("init device: %s", sys_OutputTypeEnum_name(config->output_type));
|
||||
|
||||
// chain handlers
|
||||
slimp_handler_chain = slimp_handler;
|
||||
slimp_handler = handler;
|
||||
|
||||
// init equalizer before backends
|
||||
equalizer_init();
|
||||
memset(&output, 0, sizeof(output));
|
||||
|
||||
output_init_common(loglevel, sys_OutputTypeEnum_name(config->output_type),
|
||||
config->buffers.output, get_rates(), config->amp_gpio_timeout);
|
||||
output.start_frames = FRAME_BLOCK;
|
||||
#pragma message("Rate delay logic incomplete")
|
||||
output.rate_delay = 0;
|
||||
|
||||
#if CONFIG_BT_SINK
|
||||
if (config->output_type == sys_OutputTypeEnum_OUTPUT_Bluetooth) {
|
||||
LOG_INFO("init Bluetooth");
|
||||
close_cb = &output_close_bt;
|
||||
output_init_bt(get_rates());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
close_cb = &output_close_i2s;
|
||||
volume_cb = &output_volume_i2s;
|
||||
output_init_i2s(get_rates());
|
||||
}
|
||||
|
||||
output_visu_init(loglevel);
|
||||
|
||||
LOG_INFO("init completed.");
|
||||
}
|
||||
|
||||
void output_close_embedded(void) {
|
||||
LOG_INFO("close output");
|
||||
if (close_cb) (*close_cb)();
|
||||
output_close_common();
|
||||
output_visu_close();
|
||||
LOG_INFO("close output");
|
||||
if (close_cb) (*close_cb)();
|
||||
output_close_common();
|
||||
output_visu_close();
|
||||
}
|
||||
|
||||
void set_volume(unsigned left, unsigned right) {
|
||||
LOG_DEBUG("setting internal gain left: %u right: %u", left, right);
|
||||
if (!volume_cb || !(*volume_cb)(left, right)) {
|
||||
LOCK;
|
||||
output.gainL = left;
|
||||
output.gainR = right;
|
||||
UNLOCK;
|
||||
}
|
||||
void set_volume(unsigned left, unsigned right) {
|
||||
LOG_DEBUG("setting internal gain left: %u right: %u", left, right);
|
||||
if (!volume_cb || !(*volume_cb)(left, right)) {
|
||||
LOCK;
|
||||
output.gainL = left;
|
||||
output.gainR = right;
|
||||
UNLOCK;
|
||||
}
|
||||
equalizer_set_volume(left, right);
|
||||
}
|
||||
|
||||
bool test_open(const char *device, unsigned rates[], bool userdef_rates) {
|
||||
memset(rates, 0, MAX_SUPPORTED_SAMPLERATES * sizeof(unsigned));
|
||||
if (!strcasecmp(device, "I2S")) {
|
||||
unsigned _rates[] = {
|
||||
#if BYTES_PER_FRAME == 4
|
||||
192000, 176400,
|
||||
#endif
|
||||
96000, 88200, 48000,
|
||||
44100, 32000, 24000, 22050, 16000,
|
||||
12000, 11025, 8000, 0 };
|
||||
memcpy(rates, _rates, sizeof(_rates));
|
||||
} else if (!strcasecmp(device, "SPDIF")) {
|
||||
unsigned _rates[] = { 96000, 88200, 48000,
|
||||
44100, 32000, 24000, 22050, 16000,
|
||||
12000, 11025, 8000, 0 };
|
||||
memcpy(rates, _rates, sizeof(_rates));
|
||||
} else {
|
||||
rates[0] = 44100;
|
||||
}
|
||||
return true;
|
||||
bool test_open(const char* device, unsigned rates[], bool userdef_rates) {
|
||||
memset(rates, 0, MAX_SUPPORTED_SAMPLERATES * sizeof(unsigned));
|
||||
if (config->output_type == sys_OutputTypeEnum_OUTPUT_I2S) {
|
||||
unsigned _rates[] = {
|
||||
#if BYTES_PER_FRAME == 4
|
||||
192000,
|
||||
176400,
|
||||
#endif
|
||||
96000,
|
||||
88200,
|
||||
48000,
|
||||
44100,
|
||||
32000,
|
||||
24000,
|
||||
22050,
|
||||
16000,
|
||||
12000,
|
||||
11025,
|
||||
8000,
|
||||
0
|
||||
};
|
||||
memcpy(rates, _rates, sizeof(_rates));
|
||||
} else if (config->output_type == sys_OutputTypeEnum_OUTPUT_SPDIF) {
|
||||
unsigned _rates[] = {
|
||||
96000, 88200, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0};
|
||||
memcpy(rates, _rates, sizeof(_rates));
|
||||
} else {
|
||||
rates[0] = 44100;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char* output_state_str(void){
|
||||
output_state state;
|
||||
LOCK;
|
||||
state = output.state;
|
||||
UNLOCK;
|
||||
switch (state) {
|
||||
case OUTPUT_OFF: return STR(OUTPUT_OFF);
|
||||
case OUTPUT_STOPPED: return STR(OUTPUT_STOPPED);
|
||||
case OUTPUT_BUFFER: return STR(OUTPUT_BUFFER);
|
||||
case OUTPUT_RUNNING: return STR(OUTPUT_RUNNING);
|
||||
case OUTPUT_PAUSE_FRAMES: return STR(OUTPUT_PAUSE_FRAMES);
|
||||
case OUTPUT_SKIP_FRAMES: return STR(OUTPUT_SKIP_FRAMES);
|
||||
case OUTPUT_START_AT: return STR(OUTPUT_START_AT);
|
||||
default: return "OUTPUT_UNKNOWN_STATE";
|
||||
}
|
||||
char* output_state_str(void) {
|
||||
output_state state;
|
||||
LOCK;
|
||||
state = output.state;
|
||||
UNLOCK;
|
||||
switch (state) {
|
||||
case OUTPUT_OFF:
|
||||
return STR(OUTPUT_OFF);
|
||||
case OUTPUT_STOPPED:
|
||||
return STR(OUTPUT_STOPPED);
|
||||
case OUTPUT_BUFFER:
|
||||
return STR(OUTPUT_BUFFER);
|
||||
case OUTPUT_RUNNING:
|
||||
return STR(OUTPUT_RUNNING);
|
||||
case OUTPUT_PAUSE_FRAMES:
|
||||
return STR(OUTPUT_PAUSE_FRAMES);
|
||||
case OUTPUT_SKIP_FRAMES:
|
||||
return STR(OUTPUT_SKIP_FRAMES);
|
||||
case OUTPUT_START_AT:
|
||||
return STR(OUTPUT_START_AT);
|
||||
default:
|
||||
return "OUTPUT_UNKNOWN_STATE";
|
||||
}
|
||||
}
|
||||
|
||||
bool output_stopped(void) {
|
||||
output_state state;
|
||||
LOCK;
|
||||
state = output.state;
|
||||
UNLOCK;
|
||||
return state <= OUTPUT_STOPPED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
output_state state;
|
||||
LOCK;
|
||||
state = output.state;
|
||||
UNLOCK;
|
||||
return state <= OUTPUT_STOPPED;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -755,7 +755,7 @@ void _pa_open(void);
|
||||
#if EMBEDDED
|
||||
void set_volume(unsigned left, unsigned right);
|
||||
bool test_open(const char *device, unsigned rates[], bool userdef_rates);
|
||||
void output_init_embedded(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle);
|
||||
void output_init_embedded();
|
||||
void output_close_embedded(void);
|
||||
#else
|
||||
// output_stdout.c
|
||||
|
||||
@@ -45,7 +45,7 @@ static void headset(bool active) { } ;
|
||||
static bool volume(unsigned left, unsigned right);
|
||||
static void power(adac_power_e mode) { };
|
||||
|
||||
const struct adac_s dac_tas5713 = {"TAS5713", init, adac_deinit, power, speaker, headset, volume};
|
||||
const struct adac_s dac_tas5713 = {sys_DACModelEnum_TAS5713, init, adac_deinit, power, speaker, headset, volume};
|
||||
|
||||
struct tas5713_cmd_s {
|
||||
uint8_t reg;
|
||||
|
||||
@@ -29,7 +29,7 @@ static void headset(bool active);
|
||||
static bool volume(unsigned left, unsigned right);
|
||||
static void power(adac_power_e mode);
|
||||
|
||||
const struct adac_s dac_tas57xx = { "TAS57xx", init, adac_deinit, power, speaker, headset, volume };
|
||||
const struct adac_s dac_tas57xx = { sys_DACModelEnum_TAS57xx, init, adac_deinit, power, speaker, headset, volume };
|
||||
|
||||
struct tas57xx_cmd_s {
|
||||
uint8_t reg;
|
||||
|
||||
@@ -30,7 +30,7 @@ static uint16_t i2c_read_shadow(uint8_t reg);
|
||||
|
||||
static int WM8978;
|
||||
|
||||
const struct adac_s dac_wm8978 = { "WM8978", init, adac_deinit, power, speaker, headset, volume };
|
||||
const struct adac_s dac_wm8978 = { sys_DACModelEnum_WM8978, init, adac_deinit, power, speaker, headset, volume };
|
||||
|
||||
// initiation table for non-readbale 9-bit i2c registers
|
||||
static uint16_t WM8978_REGVAL_TBL[58] = {
|
||||
|
||||
Reference in New Issue
Block a user