[SOLVED] How to restart pipline?

__vnv__
Posts: 14
Joined: Sat Feb 16, 2019 9:42 pm

[SOLVED] How to restart pipline?

Postby __vnv__ » Tue Apr 16, 2019 11:20 am

Hello,

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:
(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
So second time I start task it cannot read my file.

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 );

}
Last edited by __vnv__ on Wed Apr 17, 2019 7:18 pm, edited 1 time in total.

__vnv__
Posts: 14
Joined: Sat Feb 16, 2019 9:42 pm

Re: How to restart pipline?

Postby __vnv__ » Wed Apr 17, 2019 7:17 pm

Hello everyone,

ok, so not looking at right place was the issue. I want to post answer so if anyone gets stuck can benefit at least something from my troubles :geek:

First, there is a good example at: https://github.com/espressif/esp-adf/tr ... p3_control

In that example there is part which looks like:
case USER_ID_SET:
ESP_LOGI(TAG, "[ * ] [Set] input key event");
audio_pipeline_terminate(pipeline);
ESP_LOGI(TAG, "[ * ] Stopped, advancing to the next song");
get_file(NEXT);
audio_pipeline_run(pipeline);
break;
So we can see that if you want to advance you have to terminate and then load some new file and then run again.
And that is the answer, just terminate and run it again, it WORKS!

Who is online

Users browsing this forum: No registered users and 3 guests