I have tried to create task to play some audio file from SDCARD and then reload different file and play it again.
It seemed logical to have task do the playing, delete task, put another mp3 and then start the task for that mp3.
Stoping task didn't work, and it says:
So second time I start task it cannot read my file.(12928) STAGEFRIGHTMP3_DECODER: MP3 opened
E (12938) HTTP_CLIENT: REACHED END OF MP3 FILE
E (12938) STAGEFRIGHTMP3_DECODER: failed to read audio data (line 166)
E (12948) AUDIO_ELEMENT: [mp3] AEL_STATUS_ERROR_OPEN
I (12958) STAGEFRIGHTMP3_DECODER: Closed
Ok , so I tried workaround and use one task which would play and block after it stops, then when I send signal to it, it would again load file and play it again.
To test it, I have used two while loops, one that works forever and restarts every 3 second and one which plays file.
But again it stops at: "E (11333) HTTP_CLIENT: [ 4 ] Start audio_pipeline" and no sound comes out , also it stucks on that output.
Code below works for playing once , and it works without issues, restarting is an issue.
static int my_read_cb(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx)
{
static FILE *file;
if (file == NULL) {
file = fopen("/sdcard/some.mp3", "r");
if (!file) {
printf("Error opening file\n");
return -1;
}
}
int read_len = fread(buf, 1, len, file);
if (read_len == 0) {
ESP_LOGE(TAG, "REACHED END OF MP3 FILE");
fclose(file);
file = NULL;
read_len = AEL_IO_DONE;
}
return read_len;
}
static void play_task(void *pvParameters)
{
audio_element_handle_t i2s_stream_writer, mp3_decoder;
ringbuf_handle_t ringbuf;
QueueHandle_t i2s_queue, mp3_queue;
QueueSetHandle_t queue_set;
QueueSetMemberHandle_t queue_set_member;
audio_pipeline_handle_t pipeline;
ESP_LOGE(TAG, "[ 2 ] Create audio pipeline, add all elements to pipeline, and subscribe pipeline event");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
pipeline = audio_pipeline_init(&pipeline_cfg);
mem_assert(pipeline);
ESP_LOGE(TAG, "[3.0] Create i2s stream to write data to codec chip");
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_UDA1334A(); // I2S_STREAM_CFG_DEFAULT();
i2s_cfg.type = AUDIO_STREAM_WRITER;
i2s_stream_writer = i2s_stream_init(&i2s_cfg);
ESP_LOGE(TAG, "[3.1] Create mp3 decoder to decode mp3 data");
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
mp3_decoder = mp3_decoder_init(&mp3_cfg);
audio_element_set_read_cb(mp3_decoder, my_read_cb, NULL);
ESP_LOGE(TAG, "[2.3] Register all elements to audio pipeline");
audio_pipeline_register(pipeline, mp3_decoder, "mp3");
audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
audio_pipeline_link(pipeline, (const char *[]) {"mp3", "i2s"}, 2);
ESP_LOGE(TAG, "[ 3 ] 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);
ESP_LOGE(TAG, "[3.1] Listening event from all elements of pipeline");
audio_pipeline_set_listener(pipeline, evt);
while(1){ // Used to loop forever
ESP_LOGE(TAG, "[ 4 ] Start audio_pipeline");
audio_pipeline_run(pipeline);
while (1) {
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_LOGE(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
music_info.sample_rates, music_info.bits, music_info.channels);
audio_element_setinfo(i2s_stream_writer, &music_info);
continue;
}
/* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */
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) {
break;
}
}
ESP_LOGE(TAG, "NOVI WHAJL!");
audio_pipeline_wait_for_stop(pipeline);
vTaskDelay(3000 / portTICK_PERIOD_MS);
} // used for test - loop forever
ESP_LOGE(TAG, "[ 5 ] Stop audio_pipeline");
audio_pipeline_terminate(pipeline);
audio_pipeline_unregister(pipeline, mp3_decoder);
audio_pipeline_unregister(pipeline, i2s_stream_writer);
/* Terminate the pipeline before removing the listener */
audio_pipeline_remove_listener(pipeline);
/* Make sure audio_pipeline_remove_listener is called before destroying event_iface */
audio_event_iface_destroy(evt);
/* Release all resources */
audio_pipeline_unregister(pipeline, i2s_stream_writer);
audio_pipeline_unregister(pipeline, mp3_decoder);
audio_pipeline_deinit(pipeline);
audio_element_deinit(i2s_stream_writer);
audio_element_deinit(mp3_decoder);
ESP_LOGE(TAG, "FINISH PLAYING FILE!");
vTaskDelete( NULL );
}