Merge branch 'fix_20ms_chunk_size_bug' into network_if_component
# Conflicts: # main/CMakeLists.txt
This commit is contained in:
@@ -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})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,25 @@ 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) {
|
||||
sr = 44100;
|
||||
}
|
||||
|
||||
// ensure save setting
|
||||
int bits = setting->bits;
|
||||
if (bits == 0) {
|
||||
bits = I2S_DATA_BIT_WIDTH_16BIT;
|
||||
}
|
||||
|
||||
// ensure save setting
|
||||
uint32_t chkInFrames = setting->chkInFrames;
|
||||
if (chkInFrames == 0) {
|
||||
chkInFrames = 1152;
|
||||
}
|
||||
|
||||
#if USE_SAMPLE_INSERTION
|
||||
i2sDmaBufCnt = 22;
|
||||
// OPUS has a minimum frame size of 120
|
||||
@@ -153,7 +172,7 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
|
||||
int __dmaBufLen;
|
||||
|
||||
__dmaBufCnt = 1;
|
||||
__dmaBufLen = setting->chkInFrames;
|
||||
__dmaBufLen = chkInFrames;
|
||||
while ((__dmaBufLen >= __dmaBufMaxLen) || (__dmaBufCnt <= 1)) {
|
||||
if ((__dmaBufLen % 2) == 0) {
|
||||
__dmaBufCnt *= 2;
|
||||
@@ -170,11 +189,11 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
|
||||
i2sDmaBufMaxLen = __dmaBufLen;
|
||||
|
||||
// check i2s_set_get_apll_freq() how it is done
|
||||
fi2s_clk = 2 * setting->sr *
|
||||
I2S_MCLK_MULTIPLE_256; // setting->ch * setting->bits * m_scale;
|
||||
fi2s_clk =
|
||||
2 * sr * I2S_MCLK_MULTIPLE_256; // setting->ch * setting->bits * m_scale;
|
||||
|
||||
apll_normal_predefine[0] = setting->bits;
|
||||
apll_normal_predefine[1] = setting->sr;
|
||||
apll_normal_predefine[0] = bits;
|
||||
apll_normal_predefine[1] = sr;
|
||||
if (rtc_clk_apll_coeff_calc(
|
||||
fi2s_clk, &apll_normal_predefine[5], &apll_normal_predefine[2],
|
||||
&apll_normal_predefine[3], &apll_normal_predefine[4]) == 0) {
|
||||
@@ -184,16 +203,16 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum,
|
||||
#define UPPER_SR_SCALER 1.0001
|
||||
#define LOWER_SR_SCALER 0.9999
|
||||
|
||||
apll_corr_predefine[0][0] = setting->bits;
|
||||
apll_corr_predefine[0][1] = setting->sr * UPPER_SR_SCALER;
|
||||
apll_corr_predefine[0][0] = bits;
|
||||
apll_corr_predefine[0][1] = sr * UPPER_SR_SCALER;
|
||||
if (rtc_clk_apll_coeff_calc(
|
||||
fi2s_clk * UPPER_SR_SCALER, &apll_corr_predefine[0][5],
|
||||
&apll_corr_predefine[0][2], &apll_corr_predefine[0][3],
|
||||
&apll_corr_predefine[0][4]) == 0) {
|
||||
ESP_LOGE(TAG, "ERROR, fi2s_clk * %f", UPPER_SR_SCALER);
|
||||
}
|
||||
apll_corr_predefine[1][0] = setting->bits;
|
||||
apll_corr_predefine[1][1] = setting->sr * LOWER_SR_SCALER;
|
||||
apll_corr_predefine[1][0] = bits;
|
||||
apll_corr_predefine[1][1] = sr * LOWER_SR_SCALER;
|
||||
if (rtc_clk_apll_coeff_calc(
|
||||
fi2s_clk * LOWER_SR_SCALER, &apll_corr_predefine[1][5],
|
||||
&apll_corr_predefine[1][2], &apll_corr_predefine[1][3],
|
||||
@@ -217,21 +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);
|
||||
|
||||
// ensure save setting
|
||||
int32_t sr = setting->sr;
|
||||
if (sr == 0) {
|
||||
sr = 44100;
|
||||
}
|
||||
|
||||
// ensure save setting
|
||||
int bits = setting->bits;
|
||||
if (bits == 0) {
|
||||
bits = I2S_DATA_BIT_WIDTH_16BIT;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG,
|
||||
"player_setup_i2s: dma_buf_len is %ld, dma_buf_count is %ld, sample "
|
||||
"rate: %ld, bits: %d",
|
||||
@@ -260,35 +264,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));
|
||||
@@ -367,11 +343,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;
|
||||
@@ -386,7 +365,7 @@ int init_player(void) {
|
||||
xSemaphoreGive(snapcastSettingsMux);
|
||||
}
|
||||
|
||||
ret = player_setup_i2s(I2S_NUM_0, ¤tSnapcastSetting);
|
||||
ret = player_setup_i2s(¤tSnapcastSetting);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "player_setup_i2s failed: %d", ret);
|
||||
|
||||
@@ -1224,7 +1203,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);
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES esp_timer esp_wifi nvs_flash audio_board audio_hal audio_sal net_functions opus flac ota_server
|
||||
ui_http_server network_interface
|
||||
|
||||
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 network_interface custom_board
|
||||
)
|
||||
|
||||
set_source_files_properties(main.c PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)
|
||||
|
||||
113
main/main.c
113
main/main.c
@@ -100,7 +100,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
|
||||
@@ -134,6 +133,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
|
||||
@@ -404,14 +412,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");
|
||||
void init_snapcast(QueueHandle_t audioQHdl) {
|
||||
audioDACQHdl = audioQHdl;
|
||||
audioDACSemaphore = xSemaphoreCreateMutex();
|
||||
audioDAC_data.mute = true;
|
||||
audioDAC_data.volume = 100;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
} else {
|
||||
return audio_hal_set_mute(board_handle->audio_hal, mute);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
#define INTERFACE_ETH 0
|
||||
@@ -2259,8 +2288,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) {
|
||||
@@ -2270,9 +2298,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
|
||||
}
|
||||
|
||||
@@ -2675,6 +2701,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
|
||||
|
||||
@@ -2689,9 +2718,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,
|
||||
@@ -2723,7 +2749,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 {
|
||||
@@ -2748,13 +2774,42 @@ 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) |
|
||||
@@ -2822,4 +2877,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user