setting client latency from Android app works now, reduce latency buffer size, only start flac decoder if necessary

This commit is contained in:
Carlos
2021-09-09 21:50:45 +02:00
Unverified
parent 14b3b41c1d
commit b65b4c24c7
5 changed files with 106 additions and 36 deletions

View File

@@ -181,4 +181,4 @@ Then on every `git commit`, a few sanity/formatting checks will be performed.
- [ok] Startup: do not start parsing on samples to codec before sample ring buffer hits requested buffer size.
- [ok] Start from empty buffer
- [ ] fill in missing component descriptions in Readme.md
- [ ] DAC latency setting from android app
- [ok] DAC latency setting from android app

View File

@@ -9,7 +9,7 @@
#define I2S_PORT I2S_NUM_0
#define LATENCY_MEDIAN_FILTER_LEN 99
#define LATENCY_MEDIAN_FILTER_LEN 49 // 99
#define SHORT_BUFFER_LEN 29

View File

@@ -395,7 +395,8 @@ player_send_snapcast_setting (snapcastSetting_t *setting)
if ((curSet.bits != setting->bits) || (curSet.buf_ms != setting->buf_ms)
|| (curSet.ch != setting->ch) || (curSet.chkDur_ms != setting->chkDur_ms)
|| (curSet.codec != setting->codec) || (curSet.muted != setting->muted)
|| (curSet.sr != setting->sr) || (curSet.volume != setting->volume))
|| (curSet.sr != setting->sr) || (curSet.volume != setting->volume)
|| (curSet.cDacLat_ms != setting->cDacLat_ms))
{
// check if it is only volume / mute related setting, which is handled by
// http_get_task()
@@ -405,8 +406,8 @@ player_send_snapcast_setting (snapcastSetting_t *setting)
&& (curSet.buf_ms == setting->buf_ms)
&& (curSet.ch == setting->ch)
&& (curSet.chkDur_ms == setting->chkDur_ms)
&& (curSet.codec == setting->codec)
&& (curSet.sr == setting->sr)))
&& (curSet.codec == setting->codec) && (curSet.sr == setting->sr)
&& (curSet.cDacLat_ms == setting->cDacLat_ms)))
{
// no notify needed, only set changed parameters
ret = player_set_snapcast_settings (setting);
@@ -1238,9 +1239,9 @@ player_task (void *pvParameters)
ESP_LOGI (TAG,
"snapserver config changed, buffer %dms, chunk %dms, "
"sample rate %d, ch %d, bits %d mute %d",
"sample rate %d, ch %d, bits %d mute %d latency %d",
scSet.buf_ms, scSet.chkDur_ms, scSet.sr, scSet.ch,
scSet.bits, scSet.muted);
scSet.bits, scSet.muted, scSet.cDacLat_ms);
gotSnapserverConfig = true;
}

View File

@@ -65,6 +65,7 @@ static void error_callback (const FLAC__StreamDecoder *decoder,
//#include "ma120.h"
static FLAC__StreamDecoder *flacDecoder = NULL;
static QueueHandle_t flacReadQHdl = NULL;
static QueueHandle_t flacWriteQHdl = NULL;
@@ -76,9 +77,12 @@ const char *VERSION_STRING = "0.0.2";
#define OTA_TASK_PRIORITY 6
#define OTA_TASK_CORE_ID tskNO_AFFINITY
xTaskHandle t_ota_task;
xTaskHandle t_http_get_task;
xTaskHandle t_flac_decoder_task;
#define FLAC_TASK_PRIORITY HTTP_TASK_PRIORITY + 1
#define FLAC_TASK_CORE_ID 1 // tskNO_AFFINITY
xTaskHandle t_ota_task = NULL;
xTaskHandle t_http_get_task = NULL;
xTaskHandle t_flac_decoder_task = NULL;
struct timeval tdif, tavg;
audio_board_handle_t board_handle = NULL;
@@ -271,7 +275,6 @@ static void
flac_decoder_task (void *pvParameters)
{
FLAC__bool ok = true;
FLAC__StreamDecoder *flacDecoder = NULL;
FLAC__StreamDecoderInitStatus init_status;
snapcastSetting_t *scSet = (snapcastSetting_t *)pvParameters;
@@ -381,11 +384,6 @@ http_get_task (void *pvParameters)
mdns_init ();
#endif
// TODO: only create this task, if we need flac
// also add an ogg variant
xTaskCreatePinnedToCore (&flac_decoder_task, "flac_decoder_task", 4 * 4096,
&scSet, 6, &t_flac_decoder_task, 1);
while (1)
{
if (reset_latency_buffer () < 0)
@@ -406,6 +404,31 @@ http_get_task (void *pvParameters)
opusDecoder = NULL;
}
if (t_flac_decoder_task != NULL)
{
vTaskDelete (t_flac_decoder_task);
t_flac_decoder_task = NULL;
}
if (flacDecoder != NULL)
{
FLAC__stream_decoder_finish (flacDecoder);
FLAC__stream_decoder_delete (flacDecoder);
flacDecoder = NULL;
}
if (flacWriteQHdl != NULL)
{
vQueueDelete (flacWriteQHdl);
flacWriteQHdl = NULL;
}
if (flacReadQHdl != NULL)
{
vQueueDelete (flacReadQHdl);
flacReadQHdl = NULL;
}
#if SNAPCAST_SERVER_USE_MDNS
// Find snapcast server
// Connect to first snapcast server found
@@ -675,6 +698,37 @@ http_get_task (void *pvParameters)
size = codec_header_message.size;
start = codec_header_message.payload;
if (opusDecoder != NULL)
{
opus_decoder_destroy (opusDecoder);
opusDecoder = NULL;
}
if (t_flac_decoder_task != NULL)
{
vTaskDelete (t_flac_decoder_task);
t_flac_decoder_task = NULL;
}
if (flacDecoder != NULL)
{
FLAC__stream_decoder_finish (flacDecoder);
FLAC__stream_decoder_delete (flacDecoder);
flacDecoder = NULL;
}
if (flacWriteQHdl != NULL)
{
vQueueDelete (flacWriteQHdl);
flacWriteQHdl = NULL;
}
if (flacReadQHdl != NULL)
{
vQueueDelete (flacReadQHdl);
flacReadQHdl = NULL;
}
// ESP_LOGI(TAG, "Received codec header message with size
// %d", codec_header_message.size);
@@ -702,11 +756,6 @@ http_get_task (void *pvParameters)
}
int error = 0;
if (opusDecoder != NULL)
{
opus_decoder_destroy (opusDecoder);
opusDecoder = NULL;
}
opusDecoder
= opus_decoder_create (rate, channels, &error);
if (error != 0)
@@ -732,6 +781,14 @@ http_get_task (void *pvParameters)
{
codec = FLAC;
if (t_flac_decoder_task == NULL)
{
xTaskCreatePinnedToCore (
&flac_decoder_task, "flac_decoder_task",
4 * 4096, &scSet, FLAC_TASK_PRIORITY,
&t_flac_decoder_task, FLAC_TASK_CORE_ID);
}
// check if audio buffer was previously allocated by some
// other codec this would happen if codec is changed
// while client was running
@@ -751,6 +808,12 @@ http_get_task (void *pvParameters)
flacData.inData = codec_header_message.payload;
pFlacData = &flacData;
// wait for task creation done
while (flacReadQHdl == NULL)
{
vTaskDelay (10);
}
// send data to flac decoder
xQueueSend (flacReadQHdl, &pFlacData, portMAX_DELAY);
// and wait until it is done
@@ -908,7 +971,7 @@ http_get_task (void *pvParameters)
audio = (int16_t *)realloc (
audio,
pcm_size * scSet.ch * (scSet.bits / 8));
// audio = (int16_t
// audio = (int16_t,
// *)heap_caps_realloc(
// (int32_t
// *)audio, frameSize *
@@ -982,11 +1045,17 @@ http_get_task (void *pvParameters)
flacData.inData = wire_chunk_message.payload;
pFlacData = &flacData;
// startTime =
// esp_timer_get_time ();
// send data to flac decoder
xQueueSend (flacReadQHdl, &pFlacData, portMAX_DELAY);
// and wait until it is done
xQueueReceive (flacWriteQHdl, &pFlacData,
portMAX_DELAY);
// endTime =
// esp_timer_get_time ();
// ESP_LOGW(TAG,
//"%lld", endTime - startTime);
wire_chunk_message_t pcm_chunk_message;
@@ -1267,7 +1336,7 @@ http_get_task (void *pvParameters)
// Do a initial time sync with the server at boot
// we need to fill diffBuff fast so we get a good
// estimate of latency
timeout = 50000;
timeout = 100000;
}
esp_timer_start_once (timeSyncMessageTimer, timeout);

View File

@@ -546,7 +546,7 @@ CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y
# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set
# end of Wi-Fi
#