espressif / esp-adf

Espressif Audio Development Framework
Other
1.52k stars 669 forks source link

Unable to Receive audio events from audio_pipeline_set_listener vs audio_event_iface_set_listener (AUD-4833) #1058

Open Zafeer opened 1 year ago

Zafeer commented 1 year ago

In the flexible pipeline example here , I am unable to receive events if I modify the code from

ESP_LOGI(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); audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);

to

ESP_LOGI(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); audio_pipeline_set_listener(pipeline, evt);

Why am I not allowed to use audio_pipeline_set_listener for this example . The other examples eg SD card playback use audio_pipeline_set_listener but the flexible pipeline sample code uses audio_event_iface_set_listener .

I need to use audio_pipeline_set_listener . How do we rectify this ?

jason-mao commented 1 year ago

Hi @Zafeer, audio_pipeline_set_listener is used to monitor linked element events,esp_err_t audio_event_iface_set_listener(audio_event_iface_handle_t evt, audio_event_iface_handle_t listener) just add a iface instance to another listener. Due to the https://github.com/espressif/esp-adf/blob/49f80aafefc31642ea98db78bf024e18688b8de9/examples/advanced_examples/flexible_pipeline/main/flexible_example_main.c#L137 is monitor the button's event to change the pipeline, is not monitor the linked element events.

Zafeer commented 1 year ago

Hi @jason-mao , As part of our application we need to pause the application audio currently playing, if it gets interrupted by a system sound to be played.

  1. Considering the button's event is not of importance for this use case but only the linked element's finished status using sample code below

    else if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer_el
      && msg.cmd == AEL_MSG_CMD_REPORT_STATUS) 
    {
      audio_element_state_t el_state = audio_element_get_state(i2s_stream_writer_el);
      if (el_state == AEL_STATE_FINISHED) 
      {
        //Allow to breakup , relink and play the paused audio
      }
    }

    should this not work with the audio_pipeline_listener only ??

    I did try this but it was not working. It seems the event is not being received at all for the subsequently newly linked elements. The event is received initially but the moment the pipeline is broken up and the new elements linked no event is received from the newly linked elements.

  2. Can you also please confirm if the implementation below is correct per my understanding.

    Our application uses 2 opus files at any time that may need to play. One is the application audio and the other is a system sound. If a system sound is received then that takes priority and the application audio must pause and continue once the system sound finishes execution.

       audio_pipeline_register(pipeline, fatfs_seed_reader_el, "seed_fatfs_reader");
       audio_pipeline_register(pipeline, fatfs_system_reader_el, "system_fatfs_reader");
       audio_pipeline_register(pipeline, opus_seed_decoder_el, "seed_opus_decoder");
       audio_pipeline_register(pipeline, opus_system_decoder_el, "system_opus_decoder");
       audio_pipeline_register(pipeline, i2s_stream_writer_el, "i2s_writer");
    

    What is the correct way a). To register the elements to pipeline b). Breakup the elements ?

    I understand that 2 file reader elements are needed definitely but are 2 opus decoder elements needed considering that both are opus files. ?

    Also is one i2s writer seems good like the example ?

    And the breakup elements audio_pipeline_breakup_elements(pipeline, NULL); only seems to work when NULL. However from the documentation it says that the element whose ctx needs to be maintained must be kept as the second parameter.

    What is the correct way/element to be kept to do this for our application use case ?

amirlazarovich commented 5 months ago

Hey @Zafeer, did you happen to find a solution for events not firing after relinking?