- decode audio data directly from http_task()
Signed-off-by: Karl Osterseher <karli_o@gmx.at>
This commit is contained in:
@@ -1484,7 +1484,7 @@ static void player_task(void *pvParameters) {
|
||||
|
||||
const int64_t shortOffset = SHORT_OFFSET; // µs, softsync
|
||||
const int64_t miniOffset = MINI_OFFSET; // µs, softsync
|
||||
const int64_t hardResyncThreshold = 1000; // µs, hard sync
|
||||
const int64_t hardResyncThreshold = 2000; // µs, hard sync
|
||||
|
||||
if (initialSync == 1) {
|
||||
avg = age;
|
||||
@@ -1569,6 +1569,25 @@ static void player_task(void *pvParameters) {
|
||||
usec = diff2Server - sec * 1000000;
|
||||
msec = usec / 1000;
|
||||
usec = usec % 1000;
|
||||
|
||||
ESP_LOGI(TAG, "%d, %lldus, q %d", dir, avg,
|
||||
uxQueueMessagesWaiting(pcmChkQHdl));
|
||||
|
||||
// ESP_LOGI (TAG, "%d, %lldus, %lldus %llds,
|
||||
//%lld.%lldms", dir, age, avg, sec, msec, usec);
|
||||
|
||||
// ESP_LOGI(TAG, "%d, %lldus, %lldus, %lldus, q:%d", dir, avg,
|
||||
// shortMedian, miniMedian,
|
||||
// uxQueueMessagesWaiting(pcmChkQHdl));
|
||||
|
||||
// ESP_LOGI( TAG, "8b f
|
||||
// %d b %d", heap_caps_get_free_size(MALLOC_CAP_8BIT |
|
||||
// MALLOC_CAP_INTERNAL),
|
||||
// heap_caps_get_largest_free_block(MALLOC_CAP_8BIT |
|
||||
// MALLOC_CAP_INTERNAL)); ESP_LOGI( TAG, "32b f %d b %d",
|
||||
// heap_caps_get_free_size(MALLOC_CAP_32BIT |
|
||||
// MALLOC_CAP_EXEC), heap_caps_get_largest_free_block
|
||||
// (MALLOC_CAP_32BIT | MALLOC_CAP_EXEC));
|
||||
}
|
||||
|
||||
dir = 0;
|
||||
|
||||
759
main/main.c
759
main/main.c
@@ -147,7 +147,7 @@ typedef struct decoderData_s {
|
||||
// or SNAPCAST_MESSAGE_WIRE_CHUNK
|
||||
uint8_t *inData;
|
||||
tv_t timestamp;
|
||||
pcm_chunk_message_t *outData;
|
||||
uint8_t *outData;
|
||||
uint32_t bytes;
|
||||
} decoderData_t;
|
||||
|
||||
@@ -167,6 +167,22 @@ static int id_counter = 0;
|
||||
|
||||
static OpusDecoder *opusDecoder = NULL;
|
||||
|
||||
static decoderData_t decoderChunk = {
|
||||
.type = SNAPCAST_MESSAGE_INVALID,
|
||||
.inData = NULL,
|
||||
.timestamp = {0, 0},
|
||||
.outData = NULL,
|
||||
.bytes = 0,
|
||||
};
|
||||
|
||||
static decoderData_t pcmChunk = {
|
||||
.type = SNAPCAST_MESSAGE_INVALID,
|
||||
.inData = NULL,
|
||||
.timestamp = {0, 0},
|
||||
.outData = NULL,
|
||||
.bytes = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -278,34 +294,48 @@ static FLAC__StreamDecoderReadStatus read_callback(
|
||||
|
||||
(void)scSet;
|
||||
|
||||
xQueueReceive(decoderReadQHdl, &flacData, portMAX_DELAY);
|
||||
// xQueueReceive(decoderReadQHdl, &flacData, portMAX_DELAY);
|
||||
// if (xQueueReceive(decoderReadQHdl, &flacData, pdMS_TO_TICKS(100)))
|
||||
if (decoderChunk.inData) {
|
||||
// ESP_LOGI(TAG, "in flac read cb %ld %p", flacData->bytes,
|
||||
// flacData->inData);
|
||||
|
||||
// ESP_LOGI(TAG, "in flac read cb %d %p", flacData->bytes, flacData->inData);
|
||||
|
||||
if (flacData->bytes <= 0) {
|
||||
free_flac_data(flacData);
|
||||
if (decoderChunk.bytes <= 0) {
|
||||
// free_flac_data(flacData);
|
||||
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
|
||||
if (flacData->inData == NULL) {
|
||||
free_flac_data(flacData);
|
||||
// if (flacData->inData == NULL) {
|
||||
// free_flac_data(flacData);
|
||||
//
|
||||
// return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
// }
|
||||
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
}
|
||||
if (decoderChunk.bytes <= *bytes) {
|
||||
memcpy(buffer, decoderChunk.inData, decoderChunk.bytes);
|
||||
*bytes = decoderChunk.bytes;
|
||||
|
||||
if (flacData->bytes <= *bytes) {
|
||||
memcpy(buffer, flacData->inData, flacData->bytes);
|
||||
*bytes = flacData->bytes;
|
||||
// ESP_LOGW(TAG, "read all flac inData %d", *bytes);
|
||||
|
||||
free(decoderChunk.inData);
|
||||
decoderChunk.inData = NULL;
|
||||
decoderChunk.bytes = 0;
|
||||
} else {
|
||||
memcpy(buffer, flacData->inData, *bytes);
|
||||
// ESP_LOGW(TAG, "dind't read all flac inData %d", *bytes);
|
||||
flacData->inData += *bytes;
|
||||
flacData->bytes -= *bytes;
|
||||
memcpy(buffer, decoderChunk.inData, *bytes);
|
||||
|
||||
memmove(decoderChunk.inData, decoderChunk.inData + *bytes,
|
||||
decoderChunk.bytes - *bytes);
|
||||
decoderChunk.bytes -= *bytes;
|
||||
decoderChunk.inData =
|
||||
(uint8_t *)realloc(decoderChunk.inData, decoderChunk.bytes);
|
||||
|
||||
ESP_LOGW(TAG, "dind't read all flac inData %d", *bytes);
|
||||
// flacData->inData += *bytes;
|
||||
// flacData->bytes -= *bytes;
|
||||
}
|
||||
|
||||
free_flac_data(flacData);
|
||||
// free_flac_data(flacData);
|
||||
|
||||
// xQueueSend (flacReadQHdl, &flacData, portMAX_DELAY);
|
||||
|
||||
@@ -314,6 +344,9 @@ static FLAC__StreamDecoderReadStatus read_callback(
|
||||
// ESP_LOGE(TAG, "%s: data processed", __func__);
|
||||
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
} else {
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,10 +356,12 @@ static FLAC__StreamDecoderWriteStatus write_callback(
|
||||
const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
|
||||
const FLAC__int32 *const buffer[], void *client_data) {
|
||||
size_t i;
|
||||
decoderData_t *flacData = NULL; // = &flacOutData;
|
||||
decoderData_t *flacData = NULL;
|
||||
snapcastSetting_t *scSet = (snapcastSetting_t *)client_data;
|
||||
int ret = 0;
|
||||
uint32_t fragmentCnt = 0;
|
||||
size_t bytes = frame->header.blocksize * frame->header.channels *
|
||||
frame->header.bits_per_sample / 8;
|
||||
|
||||
(void)decoder;
|
||||
|
||||
@@ -334,8 +369,8 @@ static FLAC__StreamDecoderWriteStatus write_callback(
|
||||
|
||||
// xQueueReceive (flacReadQHdl, &flacData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGI(TAG, "in flac write cb %d %p", frame->header.blocksize,
|
||||
// flacData);
|
||||
// ESP_LOGI(TAG, "in flac write cb %ld %d, pcmChunk.bytes %ld",
|
||||
// frame->header.blocksize, bytes, pcmChunk.bytes);
|
||||
|
||||
if (frame->header.channels != scSet->ch) {
|
||||
ESP_LOGE(TAG,
|
||||
@@ -352,70 +387,91 @@ static FLAC__StreamDecoderWriteStatus write_callback(
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
if (buffer[0] == NULL) {
|
||||
ESP_LOGE(TAG, "ERROR: buffer [0] is NULL\n");
|
||||
ESP_LOGE(TAG, "ERROR: buffer [0] is NULL");
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
if (buffer[1] == NULL) {
|
||||
ESP_LOGE(TAG, "ERROR: buffer [1] is NULL\n");
|
||||
ESP_LOGE(TAG, "ERROR: buffer [1] is NULL");
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
|
||||
flacData = (decoderData_t *)malloc(sizeof(decoderData_t));
|
||||
if (flacData == NULL) {
|
||||
pcmChunk.outData =
|
||||
(uint8_t *)realloc(pcmChunk.outData, pcmChunk.bytes + bytes);
|
||||
if (!pcmChunk.outData) {
|
||||
ESP_LOGE(TAG, "%s, failed to allocate PCM chunk payload", __func__);
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
|
||||
memset(flacData, 0, sizeof(decoderData_t));
|
||||
|
||||
flacData->bytes = frame->header.blocksize * frame->header.channels *
|
||||
(frame->header.bits_per_sample / 8);
|
||||
|
||||
ret = allocate_pcm_chunk_memory(&(flacData->outData), flacData->bytes);
|
||||
|
||||
// ESP_LOGI (TAG, "mem %p %p %d", flacData->outData,
|
||||
// flacData->outData->fragment->payload, flacData->bytes);
|
||||
|
||||
if (ret == 0) {
|
||||
pcm_chunk_fragment_t *fragment = flacData->outData->fragment;
|
||||
|
||||
if (fragment->payload != NULL) {
|
||||
fragmentCnt = 0;
|
||||
|
||||
for (i = 0; i < frame->header.blocksize; i++) {
|
||||
// write little endian
|
||||
// flacData->outData[4 * i] = (uint8_t)buffer[0][i];
|
||||
// flacData->outData[4 * i + 1] = (uint8_t) (buffer[0][i] >> 8);
|
||||
// flacData->outData[4 * i + 2] = (uint8_t)buffer[1][i];
|
||||
// flacData->outData[4 * i + 3] = (uint8_t)(buffer[1][i] >> 8);
|
||||
|
||||
// TODO: for now fragmented payload is not supported and the whole
|
||||
// chunk is expected to be in the first fragment
|
||||
uint32_t tmpData;
|
||||
tmpData = ((uint32_t)((buffer[0][i] >> 8) & 0xFF) << 24) |
|
||||
((uint32_t)((buffer[0][i] >> 0) & 0xFF) << 16) |
|
||||
((uint32_t)((buffer[1][i] >> 8) & 0xFF) << 8) |
|
||||
((uint32_t)((buffer[1][i] >> 0) & 0xFF) << 0);
|
||||
|
||||
if (fragment != NULL) {
|
||||
volatile uint32_t *test =
|
||||
(volatile uint32_t *)(&(fragment->payload[fragmentCnt]));
|
||||
*test = (volatile uint32_t)tmpData;
|
||||
pcmChunk.outData[pcmChunk.bytes + 4 * i] = (uint8_t)(buffer[0][i]);
|
||||
pcmChunk.outData[pcmChunk.bytes + 4 * i + 1] = (uint8_t)(buffer[0][i] >> 8);
|
||||
pcmChunk.outData[pcmChunk.bytes + 4 * i + 2] = (uint8_t)(buffer[1][i]);
|
||||
pcmChunk.outData[pcmChunk.bytes + 4 * i + 3] = (uint8_t)(buffer[1][i] >> 8);
|
||||
}
|
||||
|
||||
fragmentCnt += 4;
|
||||
if (fragmentCnt >= fragment->size) {
|
||||
fragmentCnt = 0;
|
||||
pcmChunk.bytes += bytes;
|
||||
|
||||
fragment = fragment->nextFragment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scSet->chkInFrames = frame->header.blocksize;
|
||||
|
||||
// flacData = (decoderData_t *)malloc(sizeof(decoderData_t));
|
||||
// if (flacData == NULL) {
|
||||
// return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
// }
|
||||
//
|
||||
// memset(flacData, 0, sizeof(decoderData_t));
|
||||
//
|
||||
// flacData->bytes = frame->header.blocksize * frame->header.channels *
|
||||
// (frame->header.bits_per_sample / 8);
|
||||
//
|
||||
// ret = allocate_pcm_chunk_memory(&(flacData->outData), flacData->bytes);
|
||||
//
|
||||
//// ESP_LOGW (TAG, "block size: %ld", frame->header.blocksize);
|
||||
//
|
||||
// // ESP_LOGI (TAG, "mem %p %p %d", flacData->outData,
|
||||
// // flacData->outData->fragment->payload, flacData->bytes);
|
||||
//
|
||||
// if (ret == 0) {
|
||||
// pcm_chunk_fragment_t *fragment = flacData->outData->fragment;
|
||||
//
|
||||
// if (fragment->payload != NULL) {
|
||||
// fragmentCnt = 0;
|
||||
//
|
||||
// for (i = 0; i < frame->header.blocksize; i++) {
|
||||
// // write little endian
|
||||
// // flacData->outData[4 * i] = (uint8_t)buffer[0][i];
|
||||
// // flacData->outData[4 * i + 1] = (uint8_t) (buffer[0][i] >> 8);
|
||||
// // flacData->outData[4 * i + 2] = (uint8_t)buffer[1][i];
|
||||
// // flacData->outData[4 * i + 3] = (uint8_t)(buffer[1][i] >> 8);
|
||||
//
|
||||
// // TODO: for now fragmented payload is not supported and the whole
|
||||
// // chunk is expected to be in the first fragment
|
||||
// uint32_t tmpData;
|
||||
// tmpData = ((uint32_t)((buffer[0][i] >> 8) & 0xFF) << 24) |
|
||||
// ((uint32_t)((buffer[0][i] >> 0) & 0xFF) << 16) |
|
||||
// ((uint32_t)((buffer[1][i] >> 8) & 0xFF) << 8) |
|
||||
// ((uint32_t)((buffer[1][i] >> 0) & 0xFF) << 0);
|
||||
//
|
||||
// if (fragment != NULL) {
|
||||
// volatile uint32_t *test =
|
||||
// (volatile uint32_t *)(&(fragment->payload[fragmentCnt]));
|
||||
// *test = (volatile uint32_t)tmpData;
|
||||
// }
|
||||
//
|
||||
// fragmentCnt += 4;
|
||||
// if (fragmentCnt >= fragment->size) {
|
||||
// fragmentCnt = 0;
|
||||
//
|
||||
// fragment = fragment->nextFragment;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// flacData->outData = NULL;
|
||||
// }
|
||||
|
||||
xQueueSend(decoderWriteQHdl, &flacData, portMAX_DELAY);
|
||||
// xQueueSend(decoderWriteQHdl, &flacData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGE(TAG, "%s: data processed", __func__);
|
||||
|
||||
@@ -440,14 +496,14 @@ void metadata_callback(const FLAC__StreamDecoder *decoder,
|
||||
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
|
||||
// ESP_LOGI(TAG, "in flac meta cb");
|
||||
|
||||
flacData = (decoderData_t *)malloc(sizeof(decoderData_t));
|
||||
if (flacData == NULL) {
|
||||
ESP_LOGE(TAG, "in flac meta cb, malloc failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
memset(flacData, 0, sizeof(decoderData_t));
|
||||
// flacData = (decoderData_t *)malloc(sizeof(decoderData_t));
|
||||
// if (flacData == NULL) {
|
||||
// ESP_LOGE(TAG, "in flac meta cb, malloc failed");
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// memset(flacData, 0, sizeof(decoderData_t));
|
||||
|
||||
// save for later
|
||||
scSet->sr = metadata->data.stream_info.sample_rate;
|
||||
@@ -457,7 +513,7 @@ void metadata_callback(const FLAC__StreamDecoder *decoder,
|
||||
ESP_LOGI(TAG, "fLaC sampleformat: %ld:%d:%d", scSet->sr, scSet->bits,
|
||||
scSet->ch);
|
||||
|
||||
xQueueSend(decoderWriteQHdl, &flacData, portMAX_DELAY);
|
||||
// xQueueSend(decoderWriteQHdl, &flacData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGE(TAG, "%s: data processed", __func__);
|
||||
}
|
||||
@@ -476,6 +532,9 @@ void error_callback(const FLAC__StreamDecoder *decoder,
|
||||
FLAC__StreamDecoderErrorStatusString[status]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void flac_decoder_task(void *pvParameters) {
|
||||
// FLAC__bool ok = true;
|
||||
FLAC__StreamDecoderInitStatus init_status;
|
||||
@@ -510,6 +569,22 @@ static void flac_decoder_task(void *pvParameters) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add one timeval to another.
|
||||
*/
|
||||
tv_t timeval_add(tv_t *a, tv_t *b) {
|
||||
tv_t result;
|
||||
|
||||
result.sec = a->sec + b->sec;
|
||||
result.usec = a->usec + b->usec;
|
||||
if (result.usec >= 1000000) {
|
||||
result.sec += 1;
|
||||
result.usec -= 1000000;
|
||||
}
|
||||
|
||||
return result;
|
||||
} // timeval_add
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -517,14 +592,42 @@ void flac_task(void *pvParameters) {
|
||||
tv_t currentTimestamp;
|
||||
decoderData_t *pFlacData = NULL;
|
||||
snapcastSetting_t *scSet = (snapcastSetting_t *)pvParameters;
|
||||
FLAC__StreamDecoderInitStatus init_status;
|
||||
|
||||
if (flacDecoder != NULL) {
|
||||
FLAC__stream_decoder_finish(flacDecoder);
|
||||
FLAC__stream_decoder_delete(flacDecoder);
|
||||
flacDecoder = NULL;
|
||||
}
|
||||
|
||||
flacDecoder = FLAC__stream_decoder_new();
|
||||
if (flacDecoder == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to init flac decoder");
|
||||
return;
|
||||
}
|
||||
|
||||
init_status = FLAC__stream_decoder_init_stream(
|
||||
flacDecoder, read_callback, NULL, NULL, NULL, NULL, write_callback,
|
||||
metadata_callback, error_callback, scSet);
|
||||
if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
|
||||
ESP_LOGE(TAG, "ERROR: initializing decoder: %s\n",
|
||||
FLAC__StreamDecoderInitStatusString[init_status]);
|
||||
|
||||
// ok = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
xQueueReceive(decoderTaskQHdl, &pFlacData,
|
||||
portMAX_DELAY); // get data from tcp task
|
||||
portMAX_DELAY); // get data from http task
|
||||
|
||||
if (pFlacData != NULL) {
|
||||
currentTimestamp = pFlacData->timestamp;
|
||||
|
||||
// ESP_LOGE(TAG, "Got data with length %ld", pFlacData->bytes);
|
||||
|
||||
// ESP_LOGE(TAG, "1");
|
||||
// ESP_LOGE(TAG, "Got timestamp %lld",
|
||||
// (uint64_t)currentTimestamp.sec * 1000000 +
|
||||
// (uint64_t)currentTimestamp.usec);
|
||||
@@ -535,6 +638,7 @@ void flac_task(void *pvParameters) {
|
||||
// ESP_LOGE(TAG, "%s: decoderReadQHdl start", __func__);
|
||||
|
||||
xQueueSend(decoderReadQHdl, &pFlacData, portMAX_DELAY);
|
||||
// ESP_LOGE(TAG, "2");
|
||||
|
||||
// ESP_LOGE(TAG, "%s: decoderReadQHdl done", __func__);
|
||||
// and wait until data was
|
||||
@@ -546,24 +650,50 @@ void flac_task(void *pvParameters) {
|
||||
|
||||
// free(pFlacData->inData);
|
||||
// free(pFlacData);
|
||||
} else {
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
uint64_t frameCounter = 0;
|
||||
|
||||
if (FLAC__stream_decoder_process_until_end_of_stream(flacDecoder) ==
|
||||
false) {
|
||||
// if (FLAC__stream_decoder_process_single(flacDecoder) == false) {
|
||||
ESP_LOGE(TAG, "%s: decoder error", __func__);
|
||||
}
|
||||
// else {
|
||||
// ESP_LOGW(TAG, "%s: decoder done", __func__);
|
||||
//}
|
||||
|
||||
while (xQueueReceive(decoderWriteQHdl, &pFlacData, pdMS_TO_TICKS(10))) {
|
||||
pcm_chunk_message_t *pcmData = NULL;
|
||||
|
||||
// xSemaphoreGive(decoderWriteSemaphore);
|
||||
// and wait until it is done
|
||||
// ESP_LOGE(TAG, "%s: decoderWriteQHdl start", __func__);
|
||||
|
||||
xQueueReceive(decoderWriteQHdl, &pFlacData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGE(TAG, "%s: decoderWriteQHdl done", __func__);
|
||||
// ESP_LOGE(TAG, "3");
|
||||
|
||||
if (pFlacData->outData != NULL) {
|
||||
pcmData = pFlacData->outData;
|
||||
pcmData->timestamp = currentTimestamp;
|
||||
|
||||
size_t decodedSize = pcmData->totalSize; // pFlacData->bytes;
|
||||
scSet->chkInFrames =
|
||||
decodedSize / ((size_t)scSet->ch * (size_t)(scSet->bits / 8));
|
||||
|
||||
tv_t chunkDuration = {
|
||||
.sec = 0,
|
||||
.usec =
|
||||
(frameCounter * 1000000ULL * (uint64_t)scSet->chkInFrames) /
|
||||
scSet->sr,
|
||||
};
|
||||
pcmData->timestamp = currentTimestamp =
|
||||
timeval_add(¤tTimestamp, &chunkDuration);
|
||||
|
||||
frameCounter++;
|
||||
|
||||
// ESP_LOGI(TAG, "%s: got one frame of size %ld, timestamp %ld.%ld",
|
||||
// __func__, scSet->chkInFrames, currentTimestamp.sec,
|
||||
// currentTimestamp.usec);
|
||||
|
||||
// ESP_LOGW(TAG, "got FLAC decoded chunk size: %ld frames",
|
||||
// scSet->chkInFrames);
|
||||
|
||||
if (player_send_snapcast_setting(scSet) != pdPASS) {
|
||||
ESP_LOGE(TAG,
|
||||
"Failed to "
|
||||
@@ -597,6 +727,61 @@ void flac_task(void *pvParameters) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// pcm_chunk_message_t *pcmData = NULL;
|
||||
//
|
||||
// // xSemaphoreGive(decoderWriteSemaphore);
|
||||
// // and wait until it is done
|
||||
// // ESP_LOGE(TAG, "%s: decoderWriteQHdl start", __func__);
|
||||
//
|
||||
// xQueueReceive(decoderWriteQHdl, &pFlacData, portMAX_DELAY);
|
||||
//
|
||||
// // ESP_LOGE(TAG, "%s: decoderWriteQHdl done", __func__);
|
||||
//
|
||||
// if (pFlacData->outData != NULL) {
|
||||
// pcmData = pFlacData->outData;
|
||||
// pcmData->timestamp = currentTimestamp;
|
||||
//
|
||||
// size_t decodedSize = pcmData->totalSize; // pFlacData->bytes;
|
||||
// scSet->chkInFrames =
|
||||
// decodedSize / ((size_t)scSet->ch * (size_t)(scSet->bits / 8));
|
||||
//
|
||||
// ESP_LOGW(TAG, "got FLAC decoded chunk size: %ld frames",
|
||||
// scSet->chkInFrames);
|
||||
//
|
||||
// if (player_send_snapcast_setting(scSet) != pdPASS) {
|
||||
// ESP_LOGE(TAG,
|
||||
// "Failed to "
|
||||
// "notify "
|
||||
// "sync task "
|
||||
// "about "
|
||||
// "codec. Did you "
|
||||
// "init player?");
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// #if CONFIG_USE_DSP_PROCESSOR
|
||||
// dsp_processor_worker(pcmData->fragment->payload,
|
||||
// pcmData->fragment->size, scSet->sr);
|
||||
// #endif
|
||||
//
|
||||
// insert_pcm_chunk(pcmData);
|
||||
//
|
||||
// if (pFlacData->inData) {
|
||||
// free(pFlacData->inData);
|
||||
// pFlacData->inData = NULL;
|
||||
// }
|
||||
//
|
||||
// if (pFlacData) {
|
||||
// free(pFlacData);
|
||||
// pFlacData = NULL;
|
||||
// }
|
||||
// } else {
|
||||
// free_flac_data(pFlacData);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -636,6 +821,9 @@ void opus_decoder_task(void *pvParameters) {
|
||||
|
||||
scSet->chkInFrames = samples_per_frame;
|
||||
|
||||
ESP_LOGW(TAG, "got OPUS decoded chunk size: %ld frames",
|
||||
scSet->chkInFrames);
|
||||
|
||||
size_t bytes = samples_per_frame * scSet->ch * scSet->bits / 8;
|
||||
|
||||
if (samples_per_frame > 480) {
|
||||
@@ -787,10 +975,10 @@ static void http_get_task(void *pvParameters) {
|
||||
opusDecoder = NULL;
|
||||
}
|
||||
|
||||
if (t_flac_decoder_task != NULL) {
|
||||
vTaskDelete(t_flac_decoder_task);
|
||||
t_flac_decoder_task = NULL;
|
||||
}
|
||||
// if (t_flac_decoder_task != NULL) {
|
||||
// vTaskDelete(t_flac_decoder_task);
|
||||
// t_flac_decoder_task = NULL;
|
||||
// }
|
||||
|
||||
if (dec_task_handle != NULL) {
|
||||
vTaskDelete(dec_task_handle);
|
||||
@@ -1001,15 +1189,6 @@ static void http_get_task(void *pvParameters) {
|
||||
|
||||
firstNetBuf = NULL;
|
||||
|
||||
#define TEST_DECODER_TASK 1
|
||||
|
||||
decoderWriteSemaphore = xSemaphoreCreateMutex();
|
||||
xSemaphoreTake(decoderWriteSemaphore, portMAX_DELAY);
|
||||
|
||||
decoderReadSemaphore = xSemaphoreCreateMutex();
|
||||
xSemaphoreGive(decoderReadSemaphore); // only decoder read callback/task
|
||||
// can give semaphore
|
||||
|
||||
while (1) {
|
||||
rc2 = netconn_recv(lwipNetconn, &firstNetBuf);
|
||||
if (rc2 != ERR_OK) {
|
||||
@@ -1374,9 +1553,19 @@ static void http_get_task(void *pvParameters) {
|
||||
|
||||
internalState++;
|
||||
|
||||
// ESP_LOGI(TAG,
|
||||
// "chunk with size: %d, at time"
|
||||
// " %d.%d", wire_chnk.size,
|
||||
decoderChunk.bytes = wire_chnk.size;
|
||||
while (!decoderChunk.inData) {
|
||||
decoderChunk.inData =
|
||||
(uint8_t *)malloc(decoderChunk.bytes);
|
||||
if (!decoderChunk.inData) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
}
|
||||
|
||||
payloadOffset = 0;
|
||||
|
||||
// ESP_LOGI(TAG, "chunk with size: %u, at time %ld.%ld",
|
||||
// wire_chnk.size,
|
||||
// wire_chnk.timestamp.sec,
|
||||
// wire_chnk.timestamp.usec);
|
||||
|
||||
@@ -1460,81 +1649,11 @@ static void http_get_task(void *pvParameters) {
|
||||
}
|
||||
|
||||
case FLAC: {
|
||||
#if TEST_DECODER_TASK
|
||||
pDecData = NULL;
|
||||
while (!pDecData) {
|
||||
pDecData = (decoderData_t *)malloc(
|
||||
sizeof(decoderData_t));
|
||||
if (!pDecData) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
}
|
||||
|
||||
pDecData->bytes = tmp_size;
|
||||
|
||||
// store timestamp for
|
||||
// later use
|
||||
pDecData->timestamp = wire_chnk.timestamp;
|
||||
pDecData->inData = NULL;
|
||||
|
||||
// while ((!pFlacData->inData) && (mallocCnt < 100))
|
||||
// {
|
||||
while (!pDecData->inData) {
|
||||
pDecData->inData =
|
||||
(uint8_t *)malloc(pDecData->bytes);
|
||||
if (!pDecData->inData) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (pDecData->inData) {
|
||||
memcpy(pDecData->inData, start, tmp_size);
|
||||
pDecData->outData = NULL;
|
||||
pDecData->type = SNAPCAST_MESSAGE_WIRE_CHUNK;
|
||||
|
||||
// send data to separate task which will handle
|
||||
// this
|
||||
xQueueSend(decoderTaskQHdl, &pDecData,
|
||||
portMAX_DELAY);
|
||||
}
|
||||
#else
|
||||
flacData.bytes = tmp_size;
|
||||
flacData.timestamp =
|
||||
wire_chnk.timestamp; // store timestamp for
|
||||
// later use
|
||||
flacData.inData = start;
|
||||
pDecData = &flacData;
|
||||
|
||||
startTime = esp_timer_get_time();
|
||||
|
||||
xSemaphoreTake(decoderReadSemaphore, portMAX_DELAY);
|
||||
|
||||
// send data to flac decoder
|
||||
xQueueSend(decoderReadQHdl, &pDecData,
|
||||
portMAX_DELAY);
|
||||
// and wait until data was
|
||||
// processed
|
||||
xSemaphoreTake(decoderReadSemaphore, portMAX_DELAY);
|
||||
// need to release mutex
|
||||
// afterwards for next round
|
||||
xSemaphoreGive(decoderReadSemaphore);
|
||||
|
||||
#if 0 // enable heap memory analyzing
|
||||
{
|
||||
static uint32_t cnt = 0;
|
||||
if (++cnt % 8 == 0) {
|
||||
ESP_LOGI(
|
||||
TAG, "8bit %d, block %d, 32 bit %d, block %d, waiting %d",
|
||||
heap_caps_get_free_size(MALLOC_CAP_8BIT),
|
||||
heap_caps_get_largest_free_block(MALLOC_CAP_8BIT),
|
||||
heap_caps_get_free_size(MALLOC_CAP_32BIT |
|
||||
MALLOC_CAP_EXEC),
|
||||
heap_caps_get_largest_free_block(MALLOC_CAP_32BIT
|
||||
| MALLOC_CAP_EXEC), pcm_chunk_queue_msg_waiting());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
memcpy(&decoderChunk.inData[payloadOffset], start,
|
||||
tmp_size);
|
||||
payloadOffset += tmp_size;
|
||||
decoderChunk.outData = NULL;
|
||||
decoderChunk.type = SNAPCAST_MESSAGE_WIRE_CHUNK;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1624,37 +1743,95 @@ static void http_get_task(void *pvParameters) {
|
||||
}
|
||||
|
||||
case FLAC: {
|
||||
#if TEST_DECODER_TASK
|
||||
pDecData = NULL; // send NULL so we know to wait
|
||||
// for decoded data in task
|
||||
while (decoderChunk.bytes > 0) {
|
||||
if (FLAC__stream_decoder_process_single(
|
||||
flacDecoder) == 0) {
|
||||
ESP_LOGE(
|
||||
TAG,
|
||||
"%s: FLAC__stream_decoder_process_single "
|
||||
"failed",
|
||||
__func__);
|
||||
|
||||
// ESP_LOGE(TAG, "%s: flacTaskQHdl start
|
||||
// wireChnk", __func__);
|
||||
xQueueSend(decoderTaskQHdl, &pDecData,
|
||||
portMAX_DELAY);
|
||||
// ESP_LOGE(TAG, "%s: flacTaskQHdl stop wireChnk",
|
||||
// __func__);
|
||||
#else
|
||||
xSemaphoreGive(decoderWriteSemaphore);
|
||||
// and wait until it is done
|
||||
xQueueReceive(decoderWriteQHdl, &pDecData,
|
||||
portMAX_DELAY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDecData->outData != NULL) {
|
||||
pcmData = pDecData->outData;
|
||||
pcmData->timestamp = wire_chnk.timestamp;
|
||||
pcm_chunk_message_t *new_pcmChunk;
|
||||
int32_t ret = allocate_pcm_chunk_memory(
|
||||
&new_pcmChunk, pcmChunk.bytes);
|
||||
|
||||
size_t decodedSize =
|
||||
pcmData->totalSize; // pFlacData->bytes;
|
||||
// ESP_LOGE
|
||||
//(TAG, "block size: %ld", pcmChunk.bytes /
|
||||
//(scSet.ch * (scSet.bits/8)));
|
||||
|
||||
// ESP_LOGE(TAG,
|
||||
// "decoded size:
|
||||
// %d",
|
||||
// decodedSize);
|
||||
// ESP_LOGI (TAG, "mem %p %p %d",
|
||||
// flacData->outData,
|
||||
// flacData->outData->fragment->payload,
|
||||
// flacData->bytes);
|
||||
|
||||
if (ret == 0) {
|
||||
pcm_chunk_fragment_t *fragment =
|
||||
new_pcmChunk->fragment;
|
||||
uint32_t fragmentCnt = 0;
|
||||
|
||||
if (fragment->payload != NULL) {
|
||||
for (int i = 0;
|
||||
i < pcmChunk.bytes /
|
||||
(scSet.ch * (scSet.bits / 8));
|
||||
i++) {
|
||||
// TODO: for now fragmented payload is not
|
||||
// supported and the whole chunk is expected
|
||||
// to be in the first fragment
|
||||
uint32_t tmpData;
|
||||
memcpy(&tmpData,
|
||||
&pcmChunk.outData[fragmentCnt],
|
||||
(scSet.ch * (scSet.bits / 8)));
|
||||
// tmpData
|
||||
//=
|
||||
//((uint32_t)((buffer[0][i] >> 8) & 0xFF) <<
|
||||
// 24) |
|
||||
// ((uint32_t)((buffer[0][i]
|
||||
//>> 0) & 0xFF) << 16) |
|
||||
// ((uint32_t)((buffer[1][i]
|
||||
//>> 8) & 0xFF) << 8) |
|
||||
// ((uint32_t)((buffer[1][i]
|
||||
//>> 0) & 0xFF) << 0);
|
||||
|
||||
if (fragment != NULL) {
|
||||
volatile uint32_t *test =
|
||||
(volatile uint32_t *)(&(
|
||||
fragment->payload[fragmentCnt]));
|
||||
*test = (volatile uint32_t)tmpData;
|
||||
}
|
||||
|
||||
fragmentCnt +=
|
||||
(scSet.ch * (scSet.bits / 8));
|
||||
if (fragmentCnt >= fragment->size) {
|
||||
fragmentCnt = 0;
|
||||
|
||||
fragment = fragment->nextFragment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_pcmChunk->timestamp = wire_chnk.timestamp;
|
||||
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
if (new_pcmChunk.fragment->payload) {
|
||||
dsp_processor_worker(
|
||||
new_pcmChunk.fragment->payload,
|
||||
new_pcmChunk.fragment->size, scSet.sr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
insert_pcm_chunk(new_pcmChunk);
|
||||
}
|
||||
|
||||
free(pcmChunk.outData);
|
||||
pcmChunk.outData = NULL;
|
||||
pcmChunk.bytes = 0;
|
||||
|
||||
scSet.chkInFrames =
|
||||
decodedSize / ((size_t)scSet.ch *
|
||||
(size_t)(scSet.bits / 8));
|
||||
if (player_send_snapcast_setting(&scSet) !=
|
||||
pdPASS) {
|
||||
ESP_LOGE(TAG,
|
||||
@@ -1668,36 +1845,14 @@ static void http_get_task(void *pvParameters) {
|
||||
return;
|
||||
}
|
||||
|
||||
endTime = esp_timer_get_time();
|
||||
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
if ((pcmData) && (pcmData->fragment->payload)) {
|
||||
dsp_processor_worker(
|
||||
pcmData->fragment->payload,
|
||||
pcmData->fragment->size, scSet.sr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
insert_pcm_chunk(pcmData);
|
||||
|
||||
// ESP_LOGE(TAG, "duration = %lld", endTime -
|
||||
// startTime);
|
||||
|
||||
pcmData = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCM: {
|
||||
size_t decodedSize = wire_chnk.size;
|
||||
|
||||
// ESP_LOGW(TAG, "got
|
||||
// PCM chunk,
|
||||
// typedMsgCurrentPos
|
||||
// %d",
|
||||
// ESP_LOGW(TAG, "got PCM chunk,"
|
||||
// "typedMsgCurrentPos %d",
|
||||
// typedMsgCurrentPos);
|
||||
|
||||
if (pcmData) {
|
||||
@@ -1708,6 +1863,10 @@ static void http_get_task(void *pvParameters) {
|
||||
decodedSize /
|
||||
((size_t)scSet.ch * (size_t)(scSet.bits / 8));
|
||||
|
||||
ESP_LOGW(TAG,
|
||||
"got PCM decoded chunk size: %ld frames",
|
||||
scSet.chkInFrames);
|
||||
|
||||
if (player_send_snapcast_setting(&scSet) !=
|
||||
pdPASS) {
|
||||
ESP_LOGE(TAG,
|
||||
@@ -1982,15 +2141,6 @@ static void http_get_task(void *pvParameters) {
|
||||
// first ensure everything is set up
|
||||
// correctly and resources are
|
||||
// available
|
||||
if (t_flac_decoder_task != NULL) {
|
||||
vTaskDelete(t_flac_decoder_task);
|
||||
t_flac_decoder_task = NULL;
|
||||
}
|
||||
|
||||
if (dec_task_handle != NULL) {
|
||||
vTaskDelete(dec_task_handle);
|
||||
dec_task_handle = NULL;
|
||||
}
|
||||
|
||||
if (flacDecoder != NULL) {
|
||||
FLAC__stream_decoder_finish(flacDecoder);
|
||||
@@ -1998,36 +2148,14 @@ static void http_get_task(void *pvParameters) {
|
||||
flacDecoder = NULL;
|
||||
}
|
||||
|
||||
if (decoderWriteQHdl != NULL) {
|
||||
vQueueDelete(decoderWriteQHdl);
|
||||
decoderWriteQHdl = NULL;
|
||||
}
|
||||
|
||||
if (decoderReadQHdl != NULL) {
|
||||
vQueueDelete(decoderReadQHdl);
|
||||
decoderReadQHdl = NULL;
|
||||
}
|
||||
|
||||
if (decoderTaskQHdl != NULL) {
|
||||
vQueueDelete(decoderTaskQHdl);
|
||||
decoderTaskQHdl = NULL;
|
||||
}
|
||||
|
||||
if (opusDecoder != NULL) {
|
||||
opus_decoder_destroy(opusDecoder);
|
||||
opusDecoder = NULL;
|
||||
}
|
||||
|
||||
if (codec == OPUS) {
|
||||
decoderTaskQHdl =
|
||||
xQueueCreate(8, sizeof(decoderData_t *));
|
||||
if (decoderTaskQHdl == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create decoderTaskQHdl");
|
||||
return;
|
||||
}
|
||||
|
||||
// ESP_LOGI(TAG, "OPUS not
|
||||
// implemented yet"); return;
|
||||
// mplemented yet"); return;
|
||||
uint16_t channels;
|
||||
uint32_t rate;
|
||||
uint16_t bits;
|
||||
@@ -2062,103 +2190,38 @@ static void http_get_task(void *pvParameters) {
|
||||
OPUS_TASK_CORE_ID);
|
||||
}
|
||||
} else if (codec == FLAC) {
|
||||
decoderTaskQHdl =
|
||||
xQueueCreate(8, sizeof(decoderData_t *));
|
||||
if (decoderTaskQHdl == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create decoderTaskQHdl");
|
||||
decoderChunk.bytes = typedMsgLen;
|
||||
decoderChunk.inData =
|
||||
(uint8_t *)malloc(decoderChunk.bytes);
|
||||
memcpy(decoderChunk.inData, p_tmp, typedMsgLen);
|
||||
decoderChunk.outData = NULL;
|
||||
decoderChunk.type = SNAPCAST_MESSAGE_CODEC_HEADER;
|
||||
|
||||
flacDecoder = FLAC__stream_decoder_new();
|
||||
if (flacDecoder == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to init flac decoder");
|
||||
return;
|
||||
}
|
||||
|
||||
decoderReadQHdl =
|
||||
xQueueCreate(1, sizeof(decoderData_t *));
|
||||
if (decoderReadQHdl == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create flac read queue");
|
||||
FLAC__StreamDecoderInitStatus init_status =
|
||||
FLAC__stream_decoder_init_stream(
|
||||
flacDecoder, read_callback, NULL, NULL, NULL,
|
||||
NULL, write_callback, metadata_callback,
|
||||
error_callback, &scSet);
|
||||
if (init_status !=
|
||||
FLAC__STREAM_DECODER_INIT_STATUS_OK) {
|
||||
ESP_LOGE(TAG, "ERROR: initializing decoder: %s\n",
|
||||
FLAC__StreamDecoderInitStatusString
|
||||
[init_status]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
decoderWriteQHdl =
|
||||
xQueueCreate(1, sizeof(decoderData_t *));
|
||||
if (decoderWriteQHdl == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create flac write queue");
|
||||
return;
|
||||
}
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(
|
||||
flacDecoder);
|
||||
|
||||
if (t_flac_decoder_task == NULL) {
|
||||
xTaskCreatePinnedToCore(
|
||||
&flac_decoder_task, "flac_decoder_task",
|
||||
9 * 256, &scSet, FLAC_DECODER_TASK_PRIORITY,
|
||||
&t_flac_decoder_task,
|
||||
FLAC_DECODER_TASK_CORE_ID);
|
||||
}
|
||||
|
||||
#if TEST_DECODER_TASK
|
||||
if (dec_task_handle == NULL) {
|
||||
xTaskCreatePinnedToCore(
|
||||
&flac_task, "flac_task", 9 * 256, &scSet,
|
||||
FLAC_TASK_PRIORITY, &dec_task_handle,
|
||||
FLAC_TASK_CORE_ID);
|
||||
}
|
||||
|
||||
pDecData =
|
||||
(decoderData_t *)malloc(sizeof(decoderData_t));
|
||||
memset(pDecData, 0, sizeof(decoderData_t));
|
||||
|
||||
pDecData->bytes = typedMsgLen;
|
||||
pDecData->inData = (uint8_t *)malloc(typedMsgLen);
|
||||
memcpy(pDecData->inData, p_tmp, typedMsgLen);
|
||||
pDecData->outData = NULL;
|
||||
pDecData->type = SNAPCAST_MESSAGE_CODEC_HEADER;
|
||||
|
||||
// ESP_LOGE(TAG, "%s: flacTaskQHdl start codec
|
||||
// header", __func__);
|
||||
|
||||
// send codec header to flac decoder
|
||||
xQueueSend(decoderTaskQHdl, &pDecData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGE(TAG, "sent codec header");
|
||||
|
||||
// send NULL so we know to wait
|
||||
// for decoded data in task
|
||||
pDecData = NULL;
|
||||
xQueueSend(decoderTaskQHdl, &pDecData, portMAX_DELAY);
|
||||
|
||||
// ESP_LOGE(TAG, "%s: flacTaskQHdl done codec header",
|
||||
// ESP_LOGI(TAG, "%s: processed codec header",
|
||||
// __func__);
|
||||
|
||||
#else
|
||||
|
||||
if (flacData.outData != NULL) {
|
||||
free(flacData.outData);
|
||||
flacData.outData = NULL;
|
||||
}
|
||||
|
||||
flacData.bytes = typedMsgLen;
|
||||
flacData.inData = p_tmp;
|
||||
pDecData = &flacData;
|
||||
|
||||
// TODO: find a smarter way for
|
||||
// this wait for task creation done
|
||||
while (decoderReadQHdl == NULL) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
xSemaphoreTake(decoderReadSemaphore, portMAX_DELAY);
|
||||
|
||||
// send data to flac decoder
|
||||
xQueueSend(decoderReadQHdl, &pDecData, portMAX_DELAY);
|
||||
// and wait until data was
|
||||
// processed
|
||||
xSemaphoreTake(decoderReadSemaphore, portMAX_DELAY);
|
||||
// need to release mutex afterwards
|
||||
// for next round
|
||||
xSemaphoreGive(decoderReadSemaphore);
|
||||
// wait until it is done
|
||||
xQueueReceive(decoderWriteQHdl, &pDecData,
|
||||
portMAX_DELAY);
|
||||
|
||||
ESP_LOGI(TAG, "fLaC sampleformat: %d:%d:%d", scSet.sr,
|
||||
scSet.bits, scSet.ch);
|
||||
#endif
|
||||
} else if (codec == PCM) {
|
||||
uint16_t channels;
|
||||
uint32_t rate;
|
||||
|
||||
@@ -358,18 +358,52 @@ CONFIG_USE_SAMPLE_INSERTION=y
|
||||
#
|
||||
# Audio HAL
|
||||
#
|
||||
# CONFIG_AUDIO_BOARD_CUSTOM is not set
|
||||
CONFIG_AUDIO_BOARD_CUSTOM=y
|
||||
# CONFIG_ESP_LYRAT_V4_3_BOARD is not set
|
||||
# CONFIG_ESP_LYRAT_V4_2_BOARD is not set
|
||||
# CONFIG_ESP_LYRATD_MSC_V2_1_BOARD is not set
|
||||
# CONFIG_ESP_LYRATD_MSC_V2_2_BOARD is not set
|
||||
# CONFIG_ESP_LYRAT_MINI_V1_1_BOARD is not set
|
||||
CONFIG_ESP32_KORVO_DU1906_BOARD=y
|
||||
CONFIG_ESP32_KORVO_DU1906_DAC_TAS5805M=y
|
||||
# CONFIG_ESP32_KORVO_DU1906_DAC_ES7148 is not set
|
||||
CONFIG_ESP32_KORVO_DU1906_ADC_ES7243=y
|
||||
# CONFIG_ESP32_KORVO_DU1906_BOARD is not set
|
||||
# end of Audio HAL
|
||||
|
||||
#
|
||||
# Custom Audio Board
|
||||
#
|
||||
# CONFIG_DAC_PCM51XX is not set
|
||||
# CONFIG_DAC_PCM5102A is not set
|
||||
# CONFIG_DAC_MA120 is not set
|
||||
# CONFIG_DAC_MA120X0 is not set
|
||||
CONFIG_DAC_ADAU1961=y
|
||||
# CONFIG_DAC_MAX98357 is not set
|
||||
|
||||
#
|
||||
# DAC I2C control interface
|
||||
#
|
||||
CONFIG_DAC_I2C_SDA=12
|
||||
CONFIG_DAC_I2C_SCL=14
|
||||
CONFIG_DAC_I2C_ADDR=0x70
|
||||
# end of DAC I2C control interface
|
||||
|
||||
#
|
||||
# I2S master interface
|
||||
#
|
||||
CONFIG_MASTER_I2S_MCLK_PIN=3
|
||||
CONFIG_MASTER_I2S_BCK_PIN=15
|
||||
CONFIG_MASTER_I2S_LRCK_PIN=13
|
||||
CONFIG_MASTER_I2S_DATAOUT_PIN=4
|
||||
# end of I2S master interface
|
||||
|
||||
#
|
||||
# I2S slave interface
|
||||
#
|
||||
CONFIG_SLAVE_I2S_MCLK_PIN=0
|
||||
CONFIG_SLAVE_I2S_BCK_PIN=26
|
||||
CONFIG_SLAVE_I2S_LRCK_PIN=12
|
||||
CONFIG_SLAVE_I2S_DATAOUT_PIN=5
|
||||
# end of I2S slave interface
|
||||
# end of Custom Audio Board
|
||||
|
||||
#
|
||||
# ESP32 DSP processor config
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user