| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- #include <netinet/in.h>
- #include <stdlib.h>
- #include <string.h>
- #include "audio_decoder.h"
- #include "esp_log.h"
- #include "alac_magic_cookie.h"
- #include "decoder/impl/esp_aac_dec.h"
- #include "decoder/impl/esp_alac_dec.h"
- #include "esp_audio_dec.h"
- #define ADTS_HEADER_LEN 7
- #define MAX_FALLBACK_CHANNELS 2
- typedef enum {
- AUDIO_DECODER_NONE = 0,
- AUDIO_DECODER_PCM,
- AUDIO_DECODER_ALAC,
- AUDIO_DECODER_AAC
- } audio_decoder_kind_t;
- struct audio_decoder {
- audio_decoder_kind_t kind;
- audio_format_t format;
- void *alac_decoder;
- void *aac_decoder;
- uint8_t alac_magic_cookie[ALAC_MAGIC_COOKIE_SIZE];
- uint8_t *aac_frame_buffer;
- size_t aac_frame_buffer_size;
- };
- static const char *TAG = "audio_dec";
- // Reopen the AAC decoder to reset its internal state after a corrupt frame.
- // The codec's state machine can get stuck after certain errors (e.g. error 20)
- // and will continue failing every subsequent frame until it is recreated.
- static void aac_decoder_reset(audio_decoder_t *decoder) {
- if (decoder->aac_decoder) {
- esp_aac_dec_close(decoder->aac_decoder);
- decoder->aac_decoder = NULL;
- }
- esp_aac_dec_cfg_t aac_cfg = ESP_AAC_DEC_CONFIG_DEFAULT();
- aac_cfg.sample_rate = decoder->format.sample_rate;
- aac_cfg.channel = decoder->format.channels;
- aac_cfg.bits_per_sample =
- decoder->format.bits_per_sample ? decoder->format.bits_per_sample : 16;
- aac_cfg.no_adts_header = false;
- aac_cfg.aac_plus_enable = false;
- esp_audio_err_t err =
- esp_aac_dec_open(&aac_cfg, sizeof(aac_cfg), &decoder->aac_decoder);
- if (err != ESP_AUDIO_ERR_OK) {
- ESP_LOGE(TAG, "AAC decoder reset failed: %d", err);
- decoder->aac_decoder = NULL;
- } else {
- ESP_LOGW(TAG, "AAC decoder reset OK");
- }
- }
- static bool codec_is_alac(const char *codec) {
- if (!codec) {
- return false;
- }
- return strcmp(codec, "AppleLossless") == 0 || strcmp(codec, "ALAC") == 0;
- }
- static bool codec_is_aac(const char *codec) {
- if (!codec) {
- return false;
- }
- return strstr(codec, "AAC") != NULL || strstr(codec, "aac") != NULL ||
- strstr(codec, "mpeg4-generic") != NULL;
- }
- static bool aac_has_adts_header(const uint8_t *data, size_t len) {
- return len >= 2 && data[0] == 0xFF && (data[1] & 0xF0) == 0xF0;
- }
- static void build_adts_header(uint8_t *header, size_t frame_len,
- int sample_rate, int channels) {
- (void)sample_rate;
- (void)channels;
- int profile = 2;
- int freq_idx = 4;
- int chan_cfg = 2;
- int packet_len = (int)(frame_len + ADTS_HEADER_LEN);
- header[0] = 0xFF;
- header[1] = 0xF1;
- header[2] = ((profile - 1) << 6) + (freq_idx << 2) + (chan_cfg >> 2);
- header[3] = ((chan_cfg & 3) << 6) + (packet_len >> 11);
- header[4] = (packet_len & 0x7FF) >> 3;
- header[5] = ((packet_len & 7) << 5) + 0x1F;
- header[6] = 0xFC;
- }
- audio_decoder_t *audio_decoder_create(const audio_decoder_config_t *config) {
- if (!config) {
- return NULL;
- }
- audio_decoder_t *decoder = calloc(1, sizeof(*decoder));
- if (!decoder) {
- return NULL;
- }
- decoder->format = config->format;
- if (codec_is_alac(config->format.codec)) {
- decoder->kind = AUDIO_DECODER_ALAC;
- build_alac_magic_cookie(decoder->alac_magic_cookie, &config->format);
- esp_alac_dec_cfg_t alac_cfg = {.codec_spec_info =
- decoder->alac_magic_cookie,
- .spec_info_len = ALAC_MAGIC_COOKIE_SIZE};
- esp_audio_err_t err =
- esp_alac_dec_open(&alac_cfg, sizeof(alac_cfg), &decoder->alac_decoder);
- if (err != ESP_AUDIO_ERR_OK) {
- ESP_LOGE(TAG, "Failed to open ALAC decoder: %d", err);
- decoder->alac_decoder = NULL;
- decoder->kind = AUDIO_DECODER_NONE;
- }
- } else if (codec_is_aac(config->format.codec)) {
- decoder->kind = AUDIO_DECODER_AAC;
- esp_aac_dec_cfg_t aac_cfg = ESP_AAC_DEC_CONFIG_DEFAULT();
- aac_cfg.sample_rate = config->format.sample_rate;
- aac_cfg.channel = config->format.channels;
- aac_cfg.bits_per_sample =
- config->format.bits_per_sample ? config->format.bits_per_sample : 16;
- aac_cfg.no_adts_header = false;
- aac_cfg.aac_plus_enable = false;
- esp_audio_err_t err =
- esp_aac_dec_open(&aac_cfg, sizeof(aac_cfg), &decoder->aac_decoder);
- if (err != ESP_AUDIO_ERR_OK) {
- ESP_LOGE(TAG, "Failed to open AAC decoder: %d", err);
- decoder->aac_decoder = NULL;
- decoder->kind = AUDIO_DECODER_NONE;
- }
- } else if (strcmp(config->format.codec, "L16") == 0 ||
- strcmp(config->format.codec, "PCM") == 0) {
- decoder->kind = AUDIO_DECODER_PCM;
- } else {
- decoder->kind = AUDIO_DECODER_NONE;
- }
- return decoder;
- }
- void audio_decoder_destroy(audio_decoder_t *decoder) {
- if (!decoder) {
- return;
- }
- if (decoder->alac_decoder) {
- esp_alac_dec_close(decoder->alac_decoder);
- decoder->alac_decoder = NULL;
- }
- if (decoder->aac_decoder) {
- esp_aac_dec_close(decoder->aac_decoder);
- decoder->aac_decoder = NULL;
- }
- if (decoder->aac_frame_buffer) {
- free(decoder->aac_frame_buffer);
- decoder->aac_frame_buffer = NULL;
- decoder->aac_frame_buffer_size = 0;
- }
- free(decoder);
- }
- int audio_decoder_decode(audio_decoder_t *decoder, const uint8_t *input,
- size_t input_len, int16_t *output,
- size_t output_capacity_samples,
- audio_decode_info_t *info) {
- if (!decoder || !input || !output || output_capacity_samples == 0) {
- return -1;
- }
- int channels = decoder->format.channels;
- if (channels <= 0) {
- channels = MAX_FALLBACK_CHANNELS;
- }
- if (decoder->kind == AUDIO_DECODER_PCM) {
- size_t decoded_samples = input_len / (channels * sizeof(int16_t));
- if (decoded_samples > output_capacity_samples) {
- decoded_samples = output_capacity_samples;
- }
- const int16_t *src = (const int16_t *)input;
- for (size_t i = 0; i < decoded_samples * channels; i++) {
- output[i] = ntohs(src[i]);
- }
- if (info) {
- info->channels = channels;
- }
- return (int)decoded_samples;
- }
- if (decoder->kind == AUDIO_DECODER_ALAC) {
- if (!decoder->alac_decoder) {
- return -1;
- }
- esp_audio_dec_in_raw_t raw = {.buffer = (uint8_t *)input,
- .len = (uint32_t)input_len,
- .consumed = 0,
- .frame_recover = ESP_AUDIO_DEC_RECOVERY_NONE};
- esp_audio_dec_out_frame_t frame = {
- .buffer = (uint8_t *)output,
- .len = (uint32_t)(output_capacity_samples * channels * sizeof(int16_t)),
- .decoded_size = 0};
- esp_audio_dec_info_t dec_info = {0};
- esp_audio_err_t err =
- esp_alac_dec_decode(decoder->alac_decoder, &raw, &frame, &dec_info);
- if (err != ESP_AUDIO_ERR_OK) {
- return -1;
- }
- int dec_channels = dec_info.channel > 0 ? dec_info.channel : channels;
- if (dec_channels <= 0) {
- dec_channels = MAX_FALLBACK_CHANNELS;
- }
- size_t decoded_samples =
- frame.decoded_size / (dec_channels * sizeof(int16_t));
- if (decoded_samples > output_capacity_samples) {
- decoded_samples = output_capacity_samples;
- }
- if (info) {
- info->channels = dec_channels;
- }
- return (int)decoded_samples;
- }
- if (decoder->kind == AUDIO_DECODER_AAC) {
- if (!decoder->aac_decoder) {
- return -1;
- }
- const uint8_t *decode_data = input;
- size_t decode_len = input_len;
- if (!aac_has_adts_header(input, input_len)) {
- size_t needed = input_len + ADTS_HEADER_LEN;
- if (!decoder->aac_frame_buffer ||
- decoder->aac_frame_buffer_size < needed) {
- uint8_t *new_buf = realloc(decoder->aac_frame_buffer, needed);
- if (!new_buf) {
- return -1;
- }
- decoder->aac_frame_buffer = new_buf;
- decoder->aac_frame_buffer_size = needed;
- }
- build_adts_header(decoder->aac_frame_buffer, input_len,
- decoder->format.sample_rate, decoder->format.channels);
- memcpy(decoder->aac_frame_buffer + ADTS_HEADER_LEN, input, input_len);
- decode_data = decoder->aac_frame_buffer;
- decode_len = needed;
- }
- esp_audio_dec_in_raw_t raw = {.buffer = (uint8_t *)decode_data,
- .len = (uint32_t)decode_len,
- .consumed = 0,
- .frame_recover = ESP_AUDIO_DEC_RECOVERY_NONE};
- esp_audio_dec_out_frame_t frame = {
- .buffer = (uint8_t *)output,
- .len = (uint32_t)(output_capacity_samples * channels * sizeof(int16_t)),
- .decoded_size = 0};
- esp_audio_dec_info_t dec_info = {0};
- esp_audio_err_t err =
- esp_aac_dec_decode(decoder->aac_decoder, &raw, &frame, &dec_info);
- if (err != ESP_AUDIO_ERR_OK) {
- ESP_LOGW(TAG, "AAC decode error %d — resetting decoder", err);
- aac_decoder_reset(decoder);
- return -1;
- }
- int dec_channels = dec_info.channel > 0 ? dec_info.channel : channels;
- if (dec_channels <= 0) {
- dec_channels = MAX_FALLBACK_CHANNELS;
- }
- size_t decoded_samples =
- frame.decoded_size / (dec_channels * sizeof(int16_t));
- if (decoded_samples > output_capacity_samples) {
- decoded_samples = output_capacity_samples;
- }
- if (info) {
- info->channels = dec_channels;
- }
- return (int)decoded_samples;
- }
- return -1;
- }
- bool audio_decoder_is_aac(const audio_decoder_t *decoder) {
- return decoder && decoder->kind == AUDIO_DECODER_AAC;
- }
- bool audio_decoder_is_alac(const audio_decoder_t *decoder) {
- return decoder && decoder->kind == AUDIO_DECODER_ALAC;
- }
|