Audio Pipline with MAX98357A issue.
Posted: Fri Jun 14, 2024 9:47 am
I have custom hardware and I can play sine tone on the speaker using ESP-IDF 5.2.1, But when I try to use ADF for Audio application to play MP3 I can not see any error on log or crash.
Am I missing some thing here I am attaching code and load.
Log is as per below
I (866) esp_psram: Adding pool of 4096K of PSRAM memory to heap allocator
I (874) spi_flash: detected chip: winbond
I (878) spi_flash: flash io: dio
I (882) main_task: Started on CPU0
I (892) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (892) main_task: Calling app_main()
I (892) main: [1] Initialize audio pipeline
I (902) main: [2] Create audio elements and set up callbacks
I (902) MP3_DECODER: MP3 init
I (912) main: [3] Register elements to audio pipeline
I (912) main: [4] Link elements together
I (922) AUDIO_PIPELINE: link el->rb, el:0x3f800a8c, tag:mp3, rb:0x3f801028
I (922) main: [5] Set up event listener
I (932) main: [6] Start audio_pipeline
I (932) AUDIO_THREAD: The mp3 task allocate stack on external memory
I (942) AUDIO_ELEMENT: [mp3-0x3f800a8c] Element task created
I (952) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (952) AUDIO_ELEMENT: [i2s-0x3f800cd4] Element task created
I (962) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:4439252 Bytes, Inter:340135 Bytes, Dram:286151 Bytes
I (972) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_RESUME,state:1
I (982) MP3_DECODER: MP3 opened
I (982) CODEC_ELEMENT_HELPER: The element is 0x3f800a8c. The reserve data 2 is 0x0.
I (1002) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1
I (1022) AUDIO_PIPELINE: Pipeline started
I (1022) main: [7] Test I2S stream with sine wave
I (18902) AUDIO_ELEMENT: IN-[mp3] AEL_IO_DONE,-2
I (19062) MP3_DECODER: Closed
I (19082) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2
I (19092) main: [7] Listen for events
I (19192) main: [ * ] Receive music info from mp3 decoder, sample_rates=44100, bits=16, ch=2
Am I missing some thing here I am attaching code and load.
Code: Select all
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "audio_element.h"
#include "audio_pipeline.h"
#include "audio_event_iface.h"
#include "audio_common.h"
#include "i2s_stream.h"
#include "mp3_decoder.h"
#define SAMPLE_RATE (44100)
#define PI (3.14159265)
static const char *TAG = "main";
// Define the MP3 file in flash memory
extern const uint8_t mp3_file_start[] asm("_binary_music_mp3_start");
extern const uint8_t mp3_file_end[] asm("_binary_music_mp3_end");
static struct
{
int pos;
const uint8_t *start;
const uint8_t *end;
} file_marker;
int mp3_music_read_cb(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx)
{
int read_size = file_marker.end - file_marker.start - file_marker.pos;
if (read_size == 0)
{
return AEL_IO_DONE;
}
else if (len < read_size)
{
read_size = len;
}
memcpy(buf, file_marker.start + file_marker.pos, read_size);
file_marker.pos += read_size;
ESP_LOGD(TAG, "Read %d bytes from MP3 file, total read: %d bytes", read_size, file_marker.pos);
return read_size;
}
void generate_sine_wave(int16_t *buffer, int sample_count, int frequency)
{
for (int i = 0; i < sample_count; i++)
{
buffer[i] = (int16_t)(sin(2.0 * PI * frequency * ((float)i / SAMPLE_RATE)) * INT16_MAX);
}
}
void test_sine_wave(audio_element_handle_t i2s_stream_writer)
{
const int sample_count = 1024;
int16_t samples[sample_count];
const int frequency = 440; // A4 note
generate_sine_wave(samples, sample_count, frequency);
int bytes_written = audio_element_output(i2s_stream_writer, samples, sample_count * sizeof(int16_t));
if (bytes_written <= 0)
{
ESP_LOGE(TAG, "Failed to write sine wave to I2S stream");
}
}
void app_main(void)
{
audio_pipeline_handle_t pipeline;
audio_element_handle_t i2s_stream_writer, mp3_decoder;
esp_log_level_set("*", ESP_LOG_VERBOSE);
esp_log_level_set(TAG, ESP_LOG_INFO);
ESP_LOGI(TAG, "[1] Initialize audio pipeline");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
pipeline = audio_pipeline_init(&pipeline_cfg);
mem_assert(pipeline);
ESP_LOGI(TAG, "[2] Create audio elements and set up callbacks");
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
mp3_decoder = mp3_decoder_init(&mp3_cfg);
audio_element_set_read_cb(mp3_decoder, mp3_music_read_cb, NULL);
// // Create I2S stream writer with detailed configuration
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), // Example sample rate
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = 26, // BCLK pin number
.ws = 25, // LRCLK pin number
.dout = 22, // Data Out pin number
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_cfg.type = AUDIO_STREAM_WRITER;
i2s_cfg.chan_cfg = chan_cfg;
i2s_cfg.std_cfg = std_cfg;
i2s_stream_writer = i2s_stream_init(&i2s_cfg);
if (!i2s_stream_writer)
{
ESP_LOGE(TAG, "Failed to create I2S stream writer");
return;
}
AUDIO_NULL_CHECK(TAG, i2s_stream_writer, return); // Check if initialization was successful
ESP_LOGI(TAG, "[3] Register elements to audio pipeline");
audio_pipeline_register(pipeline, mp3_decoder, "mp3");
audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
ESP_LOGI(TAG, "[4] Link elements together");
const char *link_tag[2] = {"mp3", "i2s"};
audio_pipeline_link(pipeline, &link_tag[0], 2);
ESP_LOGI(TAG, "[5] Set up event listener");
audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
audio_pipeline_set_listener(pipeline, evt);
ESP_LOGI(TAG, "[6] Start audio_pipeline");
file_marker.start = mp3_file_start;
file_marker.end = mp3_file_end;
file_marker.pos = 0;
audio_pipeline_run(pipeline);
ESP_LOGI(TAG, "[7] Test I2S stream with sine wave");
// Add a small delay to ensure the pipeline is running
vTaskDelay(pdMS_TO_TICKS(100));
test_sine_wave(i2s_stream_writer);
ESP_LOGI(TAG, "[7] Listen for events");
while (true)
{
audio_event_iface_msg_t msg;
esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
continue;
}
if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *)mp3_decoder && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO)
{
audio_element_info_t music_info = {0};
audio_element_getinfo(mp3_decoder, &music_info);
ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
music_info.sample_rates, music_info.bits, music_info.channels);
i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels);
continue;
}
if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *)i2s_stream_writer && msg.cmd == AEL_MSG_CMD_REPORT_STATUS && (int)msg.data == AEL_STATUS_STATE_STOPPED)
{
ESP_LOGW(TAG, "[ * ] Stop event received");
break;
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "[8] Stop and clean up");
audio_pipeline_stop(pipeline);
audio_pipeline_wait_for_stop(pipeline);
audio_pipeline_terminate(pipeline);
audio_pipeline_unregister(pipeline, mp3_decoder);
audio_pipeline_unregister(pipeline, i2s_stream_writer);
audio_pipeline_remove_listener(pipeline);
audio_event_iface_destroy(evt);
audio_pipeline_deinit(pipeline);
audio_element_deinit(mp3_decoder);
audio_element_deinit(i2s_stream_writer);
}
I (866) esp_psram: Adding pool of 4096K of PSRAM memory to heap allocator
I (874) spi_flash: detected chip: winbond
I (878) spi_flash: flash io: dio
I (882) main_task: Started on CPU0
I (892) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (892) main_task: Calling app_main()
I (892) main: [1] Initialize audio pipeline
I (902) main: [2] Create audio elements and set up callbacks
I (902) MP3_DECODER: MP3 init
I (912) main: [3] Register elements to audio pipeline
I (912) main: [4] Link elements together
I (922) AUDIO_PIPELINE: link el->rb, el:0x3f800a8c, tag:mp3, rb:0x3f801028
I (922) main: [5] Set up event listener
I (932) main: [6] Start audio_pipeline
I (932) AUDIO_THREAD: The mp3 task allocate stack on external memory
I (942) AUDIO_ELEMENT: [mp3-0x3f800a8c] Element task created
I (952) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (952) AUDIO_ELEMENT: [i2s-0x3f800cd4] Element task created
I (962) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:4439252 Bytes, Inter:340135 Bytes, Dram:286151 Bytes
I (972) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_RESUME,state:1
I (982) MP3_DECODER: MP3 opened
I (982) CODEC_ELEMENT_HELPER: The element is 0x3f800a8c. The reserve data 2 is 0x0.
I (1002) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1
I (1022) AUDIO_PIPELINE: Pipeline started
I (1022) main: [7] Test I2S stream with sine wave
I (18902) AUDIO_ELEMENT: IN-[mp3] AEL_IO_DONE,-2
I (19062) MP3_DECODER: Closed
I (19082) AUDIO_ELEMENT: IN-[i2s] AEL_IO_DONE,-2
I (19092) main: [7] Listen for events
I (19192) main: [ * ] Receive music info from mp3 decoder, sample_rates=44100, bits=16, ch=2