Separate components better and remove audio_board dependencies (#110)

* Remove audio board dependency from lightsnapcast.

* Move dac settings (i2c communication) to main task. Remove audio_board dependency from http_get_task

* Remove unneeded dependencies from dsp_processor component.
This commit is contained in:
luar123
2025-02-16 20:25:46 +01:00
committed by GitHub
Unverified
parent fafbb26a95
commit 38d749e6cc
8 changed files with 111 additions and 98 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@ libopus
managed_components
sdkconfig
sdkconfig.old
dependencies.lock
# Created by https://www.toptal.com/developers/gitignore/api/c,c++,eclipse
# Edit at https://www.toptal.com/developers/gitignore?templates=c,c++,eclipse

View File

@@ -1,10 +1,6 @@
set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES audio_board audio_sal audio_hal esp-dsp)
set(COMPONENT_PRIV_REQUIRES esp-dsp)
list(APPEND COMPONENT_ADD_INCLUDEDIRS ./include)
set(COMPONENT_SRCS ./dsp_processor.c)
register_component()
# IDF >=4
idf_component_get_property(audio_board_lib audio_board COMPONENT_LIB)
set_property(TARGET ${audio_board_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${COMPONENT_LIB})

View File

@@ -1,3 +1,3 @@
idf_component_register(SRCS "snapcast.c" "player.c"
INCLUDE_DIRS "include"
REQUIRES custom_board libbuffer json libmedian audio_board esp_wifi driver esp_timer)
REQUIRES libbuffer json libmedian esp_wifi driver esp_timer)

View File

@@ -63,7 +63,7 @@ typedef struct snapcastSetting_s {
uint32_t pcmBufSize;
} snapcastSetting_t;
int init_player(void);
int init_player(i2s_std_gpio_config_t pin_config0_, i2s_port_t i2sNum_);
int deinit_player(void);
int32_t allocate_pcm_chunk_memory(pcm_chunk_message_t **pcmChunk, size_t bytes);

View File

@@ -24,7 +24,6 @@
#include <math.h>
#include "MedianFilter.h"
#include "board_pins_config.h"
#include "driver/gptimer.h"
#include "driver/i2s_std.h"
#include "player.h"
@@ -99,11 +98,14 @@ static bool gpTimerRunning = false;
static void player_task(void *pvParameters);
extern esp_err_t audio_set_mute(bool mute);
extern void audio_set_mute(bool mute);
static i2s_chan_handle_t tx_chan = NULL; // I2S tx channel handler
static bool i2sEnabled = false;
i2s_std_gpio_config_t pin_config0;
i2s_port_t i2sNum;
/**
*
*/
@@ -137,8 +139,7 @@ esp_err_t my_i2s_channel_enable(i2s_chan_handle_t handle) {
/**
*
*/
static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
snapcastSetting_t *setting) {
static esp_err_t player_setup_i2s(snapcastSetting_t *setting) {
// ensure save setting
int32_t sr = setting->sr;
if (sr == 0) {
@@ -235,8 +236,6 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
};
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
board_i2s_pin_t pin_config0;
get_i2s_pins(i2sNum, &pin_config0);
ESP_LOGI(TAG,
"player_setup_i2s: dma_buf_len is %ld, dma_buf_count is %ld, sample "
@@ -261,35 +260,7 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
.slot_cfg =
I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits, I2S_SLOT_MODE_STEREO),
#endif
.gpio_cfg =
{
.mclk = pin_config0.mck_io_num,
.bclk = pin_config0.bck_io_num,
.ws = pin_config0.ws_io_num,
.dout = pin_config0.data_out_num,
.din = pin_config0.data_in_num,
.invert_flags =
{
#if CONFIG_INVERT_MCLK_LEVEL
.mclk_inv = true,
#else
.mclk_inv = false,
#endif
#if CONFIG_INVERT_BCLK_LEVEL
.bclk_inv = true,
#else
.bclk_inv = false,
#endif
#if CONFIG_INVERT_WORD_SELECT_LEVEL
.ws_inv = true,
#else
.ws_inv = false,
#endif
},
},
.gpio_cfg = pin_config0,
};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
@@ -368,11 +339,14 @@ int deinit_player(void) {
/**
* call before http task creation!
*/
int init_player(void) {
int init_player(i2s_std_gpio_config_t pin_config0_, i2s_port_t i2sNum_) {
int ret = 0;
deinit_player();
pin_config0 = pin_config0_;
i2sNum = i2sNum_;
currentSnapcastSetting.buf_ms = 0;
currentSnapcastSetting.chkInFrames = 0;
currentSnapcastSetting.codec = NONE;
@@ -387,7 +361,7 @@ int init_player(void) {
xSemaphoreGive(snapcastSettingsMux);
}
ret = player_setup_i2s(I2S_NUM_0, &currentSnapcastSetting);
ret = player_setup_i2s(&currentSnapcastSetting);
if (ret < 0) {
ESP_LOGE(TAG, "player_setup_i2s failed: %d", ret);
@@ -1225,7 +1199,7 @@ static void player_task(void *pvParameters) {
audio_set_mute(true);
my_i2s_channel_disable(tx_chan);
ret = player_setup_i2s(I2S_NUM_0, &__scSet);
ret = player_setup_i2s(&__scSet);
if (ret < 0) {
ESP_LOGE(TAG, "player_setup_i2s failed: %d", ret);

View File

@@ -1,32 +0,0 @@
dependencies:
espressif/esp-dsp:
component_hash: fa7fe74305df6da25867437ebcd4213e047cbfc0556cf92067ab657fce537c6e
dependencies:
- name: idf
require: private
version: '>=4.2'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.5.2
espressif/mdns:
component_hash: d36b265164be5139f92de993f08f5ecaa0de0c0acbf84deee1f10bb5902d04ff
dependencies:
- name: idf
require: private
version: '>=5.0'
source:
registry_url: https://components.espressif.com/
type: service
version: 1.4.3
idf:
source:
type: idf
version: 5.1.5
direct_dependencies:
- espressif/esp-dsp
- espressif/mdns
- idf
manifest_hash: 01df6f188570b9e5362f7a00a294b1d3403de1f5ce8cbd848004d3bc88aa09a8
target: esp32
version: 2.0.0

View File

@@ -1,7 +1,7 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES esp_timer esp_wifi nvs_flash wifi_interface audio_board audio_hal audio_sal net_functions opus flac ota_server
ui_http_server improv_wifi eth_interface
ui_http_server improv_wifi eth_interface custom_board
)
set_source_files_properties(main.c PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)

View File

@@ -96,7 +96,6 @@ TaskHandle_t t_http_get_task = NULL;
#define NORMAL_SYNC_LATENCY_BUF 1000000 // in µs
struct timeval tdif, tavg;
static audio_board_handle_t board_handle = NULL;
/* snapast parameters; configurable in menuconfig */
#define SNAPCAST_SERVER_USE_MDNS CONFIG_SNAPSERVER_USE_MDNS
@@ -128,6 +127,15 @@ dspFlows_t dspFlow = dspfEQBassTreble;
#endif
#endif
typedef struct audioDACdata_s {
bool mute;
int volume;
} audioDACdata_t;
audioDACdata_t audioDAC_data;
static QueueHandle_t audioDACQHdl = NULL;
SemaphoreHandle_t audioDACSemaphore = NULL;
typedef struct decoderData_s {
uint32_t type; // should be SNAPCAST_MESSAGE_CODEC_HEADER
// or SNAPCAST_MESSAGE_WIRE_CHUNK
@@ -422,14 +430,35 @@ void error_callback(const FLAC__StreamDecoder *decoder,
/**
*
*/
esp_err_t audio_set_mute(bool mute) {
if (!board_handle) {
ESP_LOGW(TAG, "audio board not initialized yet");
return ESP_OK;
} else {
return audio_hal_set_mute(board_handle->audio_hal, mute);
void init_snapcast(QueueHandle_t audioQHdl) {
audioDACQHdl = audioQHdl;
audioDACSemaphore = xSemaphoreCreateMutex();
audioDAC_data.mute = true;
audioDAC_data.volume = 100;
}
/**
*
*/
void audio_set_mute(bool mute) {
xSemaphoreTake(audioDACSemaphore, portMAX_DELAY);
if (mute != audioDAC_data.mute) {
audioDAC_data.mute = mute;
xQueueOverwrite(audioDACQHdl, &audioDAC_data);
}
xSemaphoreGive(audioDACSemaphore);
}
/**
*
*/
void audio_set_volume(int volume) {
xSemaphoreTake(audioDACSemaphore, portMAX_DELAY);
if (volume != audioDAC_data.volume) {
audioDAC_data.volume = volume;
xQueueOverwrite(audioDACQHdl, &audioDAC_data);
}
xSemaphoreGive(audioDACSemaphore);
}
/**
@@ -2056,8 +2085,7 @@ static void http_get_task(void *pvParameters) {
(double)server_settings_message.volume / 100);
}
#endif
audio_hal_set_mute(board_handle->audio_hal,
server_settings_message.muted);
audio_set_mute(server_settings_message.muted);
}
if (scSet.volume != server_settings_message.volume) {
@@ -2067,9 +2095,7 @@ static void http_get_task(void *pvParameters) {
(double)server_settings_message.volume / 100);
}
#else
audio_hal_set_volume(
board_handle->audio_hal,
server_settings_message.volume);
audio_set_volume(server_settings_message.volume);
#endif
}
@@ -2469,6 +2495,9 @@ void app_main(void) {
gpio_config(&cfg);
#endif
board_i2s_pin_t pin_config0;
get_i2s_pins(I2S_NUM_0, &pin_config0);
#if CONFIG_AUDIO_BOARD_CUSTOM && CONFIG_DAC_ADAU1961
// some codecs need i2s mclk for initialization
@@ -2483,9 +2512,6 @@ void app_main(void) {
};
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
board_i2s_pin_t pin_config0;
get_i2s_pins(I2S_NUM_0, &pin_config0);
i2s_std_clk_config_t i2s_clkcfg = {
.sample_rate_hz = 44100,
.clk_src = I2S_CLK_SRC_APLL,
@@ -2517,7 +2543,7 @@ void app_main(void) {
#endif
ESP_LOGI(TAG, "Start codec chip");
board_handle = audio_board_init();
audio_board_handle_t board_handle = audio_board_init();
if (board_handle) {
ESP_LOGI(TAG, "Audio board_init done");
} else {
@@ -2542,13 +2568,43 @@ void app_main(void) {
#endif
// ESP_LOGI(TAG, "init player");
init_player();
i2s_std_gpio_config_t i2s_pin_config0 =
{
.mclk = pin_config0.mck_io_num,
.bclk = pin_config0.bck_io_num,
.ws = pin_config0.ws_io_num,
.dout = pin_config0.data_out_num,
.din = pin_config0.data_in_num,
.invert_flags =
{
#if CONFIG_INVERT_MCLK_LEVEL
.mclk_inv = true,
#else
.mclk_inv = false,
#endif
#if CONFIG_INVERT_BCLK_LEVEL
.bclk_inv = true,
#else
.bclk_inv = false,
#endif
#if CONFIG_INVERT_WORD_SELECT_LEVEL
.ws_inv = true,
#else
.ws_inv = false,
#endif
},
};
QueueHandle_t audioQHdl = xQueueCreate(1, sizeof(audioDACdata_t));
init_snapcast(audioQHdl);
init_player(i2s_pin_config0, I2S_NUM_0);
// ensure there is no noise from DAC
{
board_i2s_pin_t pin_config0;
get_i2s_pins(I2S_NUM_0, &pin_config0);
gpio_config_t gpioCfg = {
.pin_bit_mask =
BIT64(pin_config0.mck_io_num) | BIT64(pin_config0.data_out_num) |
@@ -2612,4 +2668,22 @@ void app_main(void) {
// continue;
// }
// }
audioDACdata_t dac_data;
audioDACdata_t dac_data_old = {
.mute = true,
.volume = 100,
};
while(1) {
if (xQueueReceive(audioQHdl, &dac_data, portMAX_DELAY) == pdTRUE) {
if (dac_data.mute != dac_data_old.mute){
audio_hal_set_mute(board_handle->audio_hal, dac_data.mute);
}
if (dac_data.volume != dac_data_old.volume){
audio_hal_set_volume(board_handle->audio_hal, dac_data.volume);
}
dac_data_old = dac_data;
}
}
}