Noise issue when play two mp3 files with downmix from SD

KIM_SEJONG
Posts: 1
Joined: Fri May 14, 2021 7:40 am

Noise issue when play two mp3 files with downmix from SD

Postby KIM_SEJONG » Mon May 17, 2021 1:11 am

Hello,

I have a noise problem with my application. I need your help.

When one mp3 file from SD is already playing, if a new event occurs (such as button input), I want to mix and play another mp3 file in SD memory simultaneously.

So I tested it using the pipeline_audio_forge example provided by ESP-ADF and ESP32-LyraT-Mini board.
The example is basically implemented to play wav files.
I set up component_select only as AUDIO_FORGE_SELECT_DOWNMIX and tested it with wav files, it works fine without any noise problems.

But, I changed the code as below for playing mp3 files, and test it again, it causes a lot of noise.
Even when the first mp3 file is played before the event is generated, I can hear big noise.

I really want to solve this problem, but I don't know which part of the code I should change.
  1. /* Multiple pipeline playback with audio processing.
  2.  
  3.    This example code is in the Public Domain (or CC0 licensed, at your option.)
  4.  
  5.    Unless required by applicable law or agreed to in writing, this
  6.    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7.    CONDITIONS OF ANY KIND, either express or implied.
  8. */
  9.  
  10. #include <string.h>
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "freertos/event_groups.h"
  14. #include "esp_log.h"
  15. #include "nvs_flash.h"
  16.  
  17. #include "audio_element.h"
  18. #include "audio_pipeline.h"
  19. #include "audio_event_iface.h"
  20. #include "audio_common.h"
  21. #include "i2s_stream.h"
  22. #include "raw_stream.h"
  23. #include "fatfs_stream.h"
  24. #include "wav_decoder.h"
  25. #include "mp3_decoder.h"
  26. #include "audio_forge.h"
  27. #include "board.h"
  28. #include "esp_peripherals.h"
  29. #include "periph_sdcard.h"
  30. #include "periph_button.h"
  31.  
  32. static const char *TAG = "AUDIO_FORGE_PIPELINE";
  33.  
  34. #define DEFAULT_SAMPLERATE 48000
  35. #define DEFAULT_CHANNEL 2//1
  36. #define DEST_SAMPLERATE 48000//11025
  37. #define DEST_CHANNEL 1
  38. #define TRANSMITTIME 0
  39. #define MUSIC_GAIN_DB 0
  40. #define NUMBER_SOURCE_FILE 2
  41.  
  42. int audio_forge_wr_cb(audio_element_handle_t el, char *buf, int len, TickType_t wait_time, void *ctx)
  43. {
  44.     audio_element_handle_t i2s_wr = (audio_element_handle_t)ctx;
  45.     int ret = audio_element_output(i2s_wr, buf, len);
  46.     return ret;
  47. }
  48.  
  49. void app_main(void)
  50. {
  51.     audio_pipeline_handle_t pipeline[NUMBER_SOURCE_FILE] = {NULL};
  52.     audio_element_handle_t fats_rd_el[NUMBER_SOURCE_FILE] = {NULL};
  53.     audio_element_handle_t mp3_decoder[NUMBER_SOURCE_FILE] = {NULL};
  54.     audio_element_handle_t el_raw_write[NUMBER_SOURCE_FILE] = {NULL};
  55.  
  56.     esp_log_level_set("*", ESP_LOG_INFO);
  57.     esp_log_level_set(TAG, ESP_LOG_INFO);
  58.  
  59.     ESP_LOGI(TAG, "[1.0] Start audio codec chip");
  60.     audio_board_handle_t board_handle = audio_board_init();
  61.     audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);
  62.  
  63.     ESP_LOGI(TAG, "[2.0] Start and wait for SDCARD to mount");
  64.     esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
  65.     esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
  66.     audio_board_sdcard_init(set, SD_MODE_1_LINE);
  67.     audio_board_key_init(set);
  68.  
  69.     ESP_LOGI(TAG, "[3.0] Create pipeline_mix to mix");
  70.     audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
  71.     audio_pipeline_handle_t pipeline_mix = audio_pipeline_init(&pipeline_cfg);
  72.  
  73.     ESP_LOGI(TAG, "[3.1] Create audio_forge");
  74.     audio_forge_cfg_t audio_forge_cfg = AUDIO_FORGE_CFG_DEFAULT();
  75.     audio_forge_cfg.audio_forge.component_select = AUDIO_FORGE_SELECT_DOWNMIX;
  76.     //AUDIO_FORGE_SELECT_RESAMPLE | AUDIO_FORGE_SELECT_DOWNMIX | AUDIO_FORGE_SELECT_ALC | AUDIO_FORGE_SELECT_EQUALIZER | AUDIO_FORGE_SELECT_SONIC;
  77.     audio_forge_cfg.audio_forge.dest_samplerate = DEST_SAMPLERATE;
  78.     audio_forge_cfg.audio_forge.dest_channel = DEST_CHANNEL;
  79.     audio_forge_cfg.audio_forge.source_num = NUMBER_SOURCE_FILE;
  80.     audio_element_handle_t audio_forge = audio_forge_init(&audio_forge_cfg);
  81.     audio_forge_src_info_t source_information = {
  82.         .samplerate = DEFAULT_SAMPLERATE,
  83.         .channel = DEFAULT_CHANNEL,
  84.     };
  85.  
  86.     audio_forge_downmix_t downmix_information = {
  87.         .gain = {0, MUSIC_GAIN_DB},
  88.         .transit_time = TRANSMITTIME,
  89.     };
  90.     audio_forge_src_info_t source_info[NUMBER_SOURCE_FILE] = {0};
  91.     audio_forge_downmix_t downmix_info[NUMBER_SOURCE_FILE];
  92.     for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
  93.         source_info[i] = source_information;
  94.         downmix_info[i] = downmix_information;
  95.     }
  96.     audio_forge_source_info_init(audio_forge, source_info, downmix_info);
  97.  
  98.     ESP_LOGI(TAG, "[3.2] Create i2s stream to read audio data from codec chip");
  99.     i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
  100.     i2s_cfg.type = AUDIO_STREAM_WRITER;
  101.     i2s_cfg.task_stack = 0;
  102.     i2s_cfg.out_rb_size = 0;
  103.     i2s_cfg.i2s_config.tx_desc_auto_clear = true;
  104.     audio_element_handle_t i2s_writer = i2s_stream_init(&i2s_cfg);
  105.     i2s_stream_set_clk(i2s_writer, DEST_SAMPLERATE, 16, DEST_CHANNEL);
  106.  
  107.     ESP_LOGI(TAG, "[3.3] Link elements together audio_forge-->i2s_writer");
  108.     audio_pipeline_register(pipeline_mix, audio_forge, "audio_forge");
  109.     audio_element_set_write_cb(audio_forge, audio_forge_wr_cb, i2s_writer);
  110.     audio_element_process_init(i2s_writer);
  111.  
  112.  
  113.     ESP_LOGI(TAG, "[3.4] Link elements together audio_forge-->i2s_stream-->[codec_chip]");
  114.     audio_pipeline_link(pipeline_mix, (const char *[]) {"audio_forge"}, 1);
  115.  
  116.     ESP_LOGI(TAG, "[4.0] Create Fatfs stream to read input data");
  117.     fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
  118.     fatfs_cfg.type = AUDIO_STREAM_READER;
  119.  
  120.     // ESP_LOGI(TAG, "[4.1] Create wav decoder to decode wav file");
  121.     // wav_decoder_cfg_t wav_cfg = DEFAULT_WAV_DECODER_CONFIG();
  122.     // wav_cfg.task_core = 0;
  123.  
  124.     ESP_LOGI(TAG, "[4.1] Create mp3 decoder to decode wav file");
  125.     mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
  126.  
  127.     ESP_LOGI(TAG, "[4.2] Create raw stream of base wav to write data");
  128.     raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT();
  129.     raw_cfg.type = AUDIO_STREAM_WRITER;
  130.  
  131.     ESP_LOGI(TAG, "[5.0] Set up  event listener");
  132.     audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
  133.     audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
  134.  
  135.     char str_name[18] = "/sdcard/test";
  136.     char num = '1';
  137.     for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
  138.         pipeline[i] = audio_pipeline_init(&pipeline_cfg);
  139.         mem_assert(pipeline[i]);
  140.         fats_rd_el[i] = fatfs_stream_init(&fatfs_cfg);
  141.         str_name[12] = num + i;
  142.         str_name[13] = '.';
  143.         str_name[14] = 'm';
  144.         str_name[15] = 'p';
  145.         str_name[16] = '3';
  146.         audio_element_set_uri(fats_rd_el[i], str_name);
  147.         mp3_decoder[i] = mp3_decoder_init(&mp3_cfg);
  148.         el_raw_write[i] = raw_stream_init(&raw_cfg);
  149.         audio_pipeline_register(pipeline[i], fats_rd_el[i], "file");
  150.         audio_pipeline_register(pipeline[i], mp3_decoder[i], "mp3");
  151.         audio_pipeline_register(pipeline[i], el_raw_write[i], "raw");
  152.          
  153.         const char *link_tag[3] = {"file", "mp3", "raw"};
  154.         audio_pipeline_link(pipeline[i], &link_tag[0], 3);
  155.         ringbuf_handle_t rb = audio_element_get_input_ringbuf(el_raw_write[i]);
  156.         audio_element_set_multi_input_ringbuf(audio_forge, rb, i);
  157.         audio_pipeline_set_listener(pipeline[i], evt);
  158.     }
  159.     audio_pipeline_set_listener(pipeline_mix, evt);
  160.     ESP_LOGI(TAG, "[5.1] Listening event from peripherals");
  161.     audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);
  162.  
  163.     audio_pipeline_run(pipeline[0]);
  164.     audio_pipeline_run(pipeline_mix);
  165.    
  166.     while (1) {
  167.         audio_event_iface_msg_t msg;
  168.         esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
  169.         if (ret != ESP_OK) {
  170.             ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
  171.             continue;
  172.         }
  173.  
  174.         for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
  175.             if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *)mp3_decoder[i]
  176.                 && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) {
  177.                 audio_element_info_t music_info = {0};
  178.                 audio_element_getinfo(mp3_decoder[i], &music_info);
  179.                 ESP_LOGW(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d",
  180.                          music_info.sample_rates, music_info.bits, music_info.channels);
  181.                 audio_forge_set_src_info(audio_forge, music_info.sample_rates, music_info.channels, i);
  182.             }
  183.         }
  184.         if (((int)msg.data == get_input_mode_id()) && (msg.cmd == PERIPH_BUTTON_PRESSED)) {
  185.             ESP_LOGE(TAG, "audio_forge start");
  186.             // for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
  187.             //     ret = audio_pipeline_run(pipeline[i]);
  188.             // }
  189.             // audio_pipeline_run(pipeline_mix);
  190.             // audio_forge_downmix_set_input_rb_timeout(audio_forge, 50);
  191.  
  192.             audio_pipeline_run(pipeline[1]);
  193.             audio_forge_downmix_set_input_rb_timeout(audio_forge, 50);
  194.         }
  195.         /* Stop when the last pipeline element (fatfs_writer in this case) receives stop event */
  196.         if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT
  197.             && msg.source == (void *) audio_forge
  198.             && msg.cmd == AEL_MSG_CMD_REPORT_STATUS
  199.             && (((int)msg.data == AEL_STATUS_STATE_STOPPED)
  200.                 || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) {
  201.             break;
  202.         }
  203.     }
  204.  
  205.     ESP_LOGI(TAG, "[6.0] Stop pipelines");
  206.     for (int i = 0; i < NUMBER_SOURCE_FILE; i++) {
  207.         audio_pipeline_stop(pipeline[i]);
  208.         audio_pipeline_wait_for_stop(pipeline[i]);
  209.         audio_pipeline_terminate(pipeline[i]);
  210.         audio_pipeline_unregister_more(pipeline[i], fats_rd_el[i], mp3_decoder[i], el_raw_write[i], NULL);
  211.         audio_pipeline_remove_listener(pipeline[i]);
  212.         /* Release resources */
  213.         audio_pipeline_deinit(pipeline[i]);
  214.         audio_element_deinit(fats_rd_el[i]);
  215.         audio_element_deinit(mp3_decoder[i]);
  216.         audio_element_deinit(el_raw_write[i]);
  217.     }
  218.     audio_pipeline_stop(pipeline_mix);
  219.     audio_pipeline_wait_for_stop(pipeline_mix);
  220.     audio_pipeline_terminate(pipeline_mix);
  221.     audio_pipeline_unregister_more(pipeline_mix, audio_forge, NULL);
  222.     audio_pipeline_remove_listener(pipeline_mix);
  223.  
  224.     /* Stop all peripherals before removing the listener */
  225.     esp_periph_set_stop_all(set);
  226.     audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt);
  227.  
  228.     /* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */
  229.     audio_event_iface_destroy(evt);
  230.  
  231.     /* Release resources */
  232.     audio_pipeline_deinit(pipeline_mix);
  233.     audio_element_deinit(audio_forge);
  234.     audio_element_deinit(i2s_writer);
  235.     esp_periph_set_destroy(set);
  236. }

Who is online

Users browsing this forum: No registered users and 40 guests