Skip to content

Crash when trying to playback M4A files, works fine with mp3 (AUD-5771) #1295

@nathan-swidget

Description

@nathan-swidget

Hey,

I seem to be unable to playback M4A audio files. I have tried samples provided by espressif, aswell as samples created with Audacity.

#include "audio_element.h"
#include "audio_pipeline.h"
#include "audio_event_iface.h"
#include "audio_mem.h"
#include "audio_common.h"
#include "i2s_stream.h"
#include "mp3_decoder.h"
#include "aac_decoder.h"
#include "board.h"
#include <string.h>

#define USE_M4A 1
#if USE_M4A
    extern const uint8_t audio_start_asm[] asm("_binary_test_m4a_start");
    extern const uint8_t audio_end_asm[] asm("_binary_test_m4a_end");
#else
    extern const uint8_t audio_start_asm[] asm("_binary_test_mp3_start");
    extern const uint8_t audio_end_asm[] asm("_binary_test_mp3_end");
#endif  // USE_M4A

static int bytesConsumed = 0;
extern "C" audio_element_err_t read_audio_from_flash(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx) {
    size_t remaining = audio_end_asm - audio_start_asm - bytesConsumed;
    int read_size = remaining;
    if (read_size == 0) {
        return AEL_IO_DONE;
    } else if (len < read_size) {
        read_size = len;
    }

    memcpy(buf, audio_start_asm + bytesConsumed, read_size);
    bytesConsumed += read_size;
    return (audio_element_err_t)read_size;
}

static i2s_stream_cfg_t getDefaultI2CConfig() {
    i2s_stream_cfg_t cfg{
        .type = AUDIO_STREAM_WRITER,
        .transmit_mode = I2S_COMM_MODE_STD,
        .chan_cfg = {
            .id = I2S_NUM_0,
            .role = I2S_ROLE_MASTER,
            .dma_desc_num = 3,
            .dma_frame_num = 312,
            .auto_clear = true
        },
        .std_cfg = {
            .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
            .slot_cfg = {
                .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT,
                .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO,
                .slot_mode = I2S_SLOT_MODE_MONO,
                .slot_mask = I2S_STD_SLOT_RIGHT,
                .ws_width = I2S_DATA_BIT_WIDTH_16BIT,
                .ws_pol = false,
                .bit_shift = true,
                #if SOC_I2S_HW_VERSION_1
                .msb_right = true,
                #else
                .left_align = true,
                .big_endian = false,
                .bit_order_lsb = false
                #endif
            },
            .gpio_cfg = { // this is loaded from custom board info
                .invert_flags = {
                    .mclk_inv = false,
                    .bclk_inv = false,
                }
            }
        },
        .use_alc = true,
        .volume = 100,
        .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,                                 
        .task_stack = I2S_STREAM_TASK_STACK,                                       
        .task_core = I2S_STREAM_TASK_CORE,                                         
        .task_prio = I2S_STREAM_TASK_PRIO,                                         
        .stack_in_ext = false,                                                     
        .multi_out_num = 0,                                                        
        .uninstall_drv = true,                                                     
        .need_expand = false,                                                      
        .buffer_len = I2S_STREAM_BUF_SIZE                                     
    };
    
    return cfg;
}


void app_main() {
    audio_board_handle_t board_handle = audio_board_init();
    audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);
    
    audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
    audio_pipeline_handle_t pipeline = audio_pipeline_init(&pipeline_cfg);
    

    i2s_stream_cfg_t i2s_cfg = getDefaultI2CConfig();
    audio_element_handle_t i2sWriter = i2s_stream_init(&i2s_cfg);
    i2s_stream_set_clk(i2sWriter, 16000, 16, 1);

    audio_element_handle_t decoder;
    #if USE_M4A
    aac_decoder_cfg_t aac_dec_cfg  = DEFAULT_AAC_DECODER_CONFIG();
    decoder = aac_decoder_init(&aac_dec_cfg);
    #else
    mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
    decoder = mp3_decoder_init(&mp3_cfg);
    #endif  // USE_M4A

    audio_element_set_read_cb(decoder, read_audio_from_flash, NULL);

    const char *link_tag[2] = {"dec",  "i2s"};

    audio_pipeline_register(pipeline, decoder, "dec");
    audio_pipeline_register(pipeline, i2sWriter, "i2s");

    audio_pipeline_link(pipeline, &link_tag[0], 2);
    audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
    audio_event_iface_handle_t eventHandle = audio_event_iface_init(&evt_cfg);
    audio_pipeline_set_listener(pipeline, eventHandle);
    audio_pipeline_run(pipeline);
    while(1) {
        audio_event_iface_msg_t msg;
        esp_err_t ret = audio_event_iface_listen(eventHandle, &msg, portMAX_DELAY);
        if (ret != ESP_OK) continue;
        if (msg.cmd == AEL_MSG_CMD_STOP) {
            break;
        }
        if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
            audio_element_info_t music_info = {0};
            audio_element_getinfo((audio_element_handle_t)msg.source, &music_info);
            i2s_stream_set_clk(i2sWriter, music_info.sample_rates, music_info.bits, music_info.channels);
            continue;
        }

        if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2sWriter
            && msg.cmd == AEL_MSG_CMD_REPORT_STATUS) {
            if ((int)msg.data == AEL_STATUS_STATE_FINISHED || (int)msg.data == AEL_STATUS_STATE_STOPPED) {
                break;
            }
        }
    }

    audio_pipeline_stop(pipeline);
    audio_pipeline_wait_for_stop(pipeline);
    audio_pipeline_unlink(pipeline);

    audio_pipeline_unregister(pipeline, i2sWriter);
    audio_element_deinit(i2sWriter);

    audio_pipeline_unregister(pipeline, decoder);
    audio_element_deinit(decoder);

    audio_pipeline_remove_listener(pipeline);
}

The above code works to play MP3 files, but not M4A (selected by changed the define)


D (1802) intr_alloc: Connected src 79 to int 3 (cpu 0)
D (1807) app_start: Starting scheduler on CPU0
D (1811) intr_alloc: Connected src 57 to int 5 (cpu 0)
D (1811) intr_alloc: Connected src 80 to int 0 (cpu 1)
D (1816) app_start: Starting scheduler on CPU1
D (1820) intr_alloc: Connected src 58 to int 1 (cpu 1)
I (1811) main_task: Started on CPU0
D (1829) heap_init: New heap initialised at 0x3fce9710
I (1833) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
D (1841) esp_psram: Allocating block of size 32768 bytes
I (1846) main_task: Calling app_main()
I (1850) new_codec: new_codec init
I (1853) AUDIO_HAL: Codec mode is 2, Ctrl:1
D (1857) i2s_common: tx channel is registered on I2S0 successfully
D (1863) i2s_common: DMA malloc info: dma_desc_num = 3, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = 624
D (1874) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 39 [mclk] 4096000 Hz [bdiv] 8 [bclk] 512000 Hz
D (1884) gdma: new group (0) at 0x3c1c0f8c
D (1887) gdma: new pair (0,0) at 0x3c1c1018
D (1891) gdma: new tx channel (0,0) at 0x3c1c0f54
D (1896) intr_alloc: Connected src 71 to int 8 (cpu 0)
D (1900) gdma: install interrupt service for tx channel (0,0)
D (1906) i2s_std: The tx channel on I2S0 has been initialized to STD mode successfully
D (1913) i2s_common: i2s tx channel enabled
D (1917) i2s_common: i2s tx channel disabled
D (1921) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 39 [mclk] 4096000 Hz [bdiv] 8 [bclk] 512000 Hz
D (1931) i2s_common: i2s tx channel enabled
I (1936) AUDIO_PIPELINE: link el->rb, el:0x3c1c10bc, tag:dec, rb:0x3c1c1218
D (1942) AUDIO_PIPELINE: FUNC:audio_pipeline_link, LINE:516
D (1947) AUDIO_PIPELINE: el-list: linked:1, kept:0, el:0x3c1c10bc,              dec, in_rb:0, out_rb:0x3c1c1218
D (1957) AUDIO_PIPELINE: el-list: linked:1, kept:0, el:0x3c1c0c40,              i2s, in_rb:0x3c1c1218, out_rb:0
D (1967) AUDIO_PIPELINE: rb-list: linked:1, kept:0, rb:0x3c1c1218, host_el:0x3c1c10bc,              dec
D (1976) AUDIO_PIPELINE: start el[             dec], linked:1, state:1,[0x3c1c10bc], 
I (1983) AUDIO_THREAD: The dec task allocate stack on external memory
I (1990) AUDIO_ELEMENT: [dec-0x3c1c10bc] Element task created
D (1995) AUDIO_PIPELINE: start el[             i2s], linked:1, state:1,[0x3c1c0c40], 
I (2003) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (2009) AUDIO_ELEMENT: [i2s-0x3c1c0c40] Element task created
I (2014) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:2402852 Bytes, Inter:353279 Bytes, Dram:353279 Bytes, Dram largest free:zuBytes

D (2027) AUDIO_PIPELINE: resume,linked:1, state:1,[dec-0x3c1c10bc]
I (2033) AUDIO_ELEMENT: [dec] AEL_MSG_CMD_RESUME,state:1
I (2039) CODEC_ELEMENT_HELPER: The element is 0x3c1c10bc. The reserve data 2 is 0.
I (2047) AAC_DECODER: A new song playing
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x42010838  PS      : 0x00060730  A0      : 0x82014e6c  A1      : 0x3c1c2a70  
A2      : 0x00000000  A3      : 0x3c1c2a90  A4      : 0x00000003  A5      : 0x00000001  
A6      : 0x00000000  A7      : 0x3c1c4568  A8      : 0x82010838  A9      : 0x3c1c2a20  
A10     : 0x00000010  A11     : 0x00000000  A12     : 0x3c1c3ce8  A13     : 0x00000001  
0x42010838: audio_element_abort_output_ringbuf at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_element.c:757

A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000020  LBEG    : 0x400570e8  LEND    : 0x400570f3  LCOUNT  : 0x00000000  


Backtrace: 0x42010835:0x3c1c2a70 0x42014e69:0x3c1c2a90 0x42014fbb:0x3c1c2ac0 0x4201590f:0x3c1c2b70 0x42012dd8:0x3c1c2bb0 0x42013045:0x3c1c2c50 0x42010344:0x3c1c2c70 0x420108b3:0x3c1c2ca0 0x42010a21:0x3c1c2cc0 0x420118fd:0x3c1c2cf0 0x42010aff:0x3c1c2d30
0x400570e8: memset in ROM
0x400570f3: memset in ROM

0x42010835: audio_element_abort_output_ringbuf at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_element.c:756
0x42014e69: mp4_parser_seek at /builds/adf/esp-adf-libs-source/esp_processing/esp-share/mp4_parser.c:762
0x42014fbb: mp4_parser_info_init at /builds/adf/esp-adf-libs-source/esp_processing/esp-share/mp4_parser.c:817
0x4201590f: mp4_parser_parse_header at /builds/adf/esp-adf-libs-source/esp_processing/esp-share/mp4_parser.c:1307
0x42012dd8: aac_decoder_open at /builds/adf/esp-adf-libs-source/esp_processing/esp-wrapper/aac_decoder.c:324
0x42013045: _aac_decoder_open at /builds/adf/esp-adf-libs-source/esp_processing/esp-wrapper/aac_decoder.c:798
0x42010344: audio_element_process_init at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_element.c:175
0x420108b3: audio_element_on_cmd_resume at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_element.c:279
0x42010a21: audio_element_on_cmd at /home/spades/projects/esp32/esp-adf/components/audio
_pipeline/audio_element.c:320
0x420118fd: audio_event_iface_waiting_cmd_msg at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_event_iface.c:246
0x42010aff: audio_element_task at /home/spades/projects/esp32/esp-adf/components/audio_pipeline/audio_element.c:473

I'm at a loss as to what the problem is.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions