ESP32 Audio Kit passthrough example

dominik8054
Posts: 2
Joined: Sat Oct 05, 2024 2:16 pm

ESP32 Audio Kit passthrough example

Postby dominik8054 » Sat Oct 05, 2024 2:28 pm

Hello,
I have a problem with ESP32 Audio Kit (AI Thinker board, similar to Lyrat v4.3). I compile and flash code from example/audio_processing/pipeline_passthru, connect audio jack on input from smartphone and headphones on output and volume is very low. How to make it working louder? Where in code I can change the volume? I trying some functions but there is no effect.

The second thing I want to do some DSP filters. I create module filter.c based on equalizer example but when I apply this into pipeline there is no sound

  1. /* Audio bypass
  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 "esp_log.h"
  14. #include "audio_pipeline.h"
  15. #include "i2s_stream.h"
  16. #include "board.h"
  17. #include "filter.h"
  18.  
  19. static const char *TAG = "BYPASS";
  20.  
  21.  
  22. void app_main(void)
  23. {
  24.     audio_pipeline_handle_t pipeline;
  25.     audio_element_handle_t i2s_stream_writer, i2s_stream_reader, filter;
  26.  
  27.     esp_log_level_set("*", ESP_LOG_INFO);
  28.     esp_log_level_set(TAG, ESP_LOG_DEBUG);
  29.  
  30.     ESP_LOGI(TAG, "Start codec chip");
  31.     audio_board_handle_t board_handle = audio_board_init();
  32.  
  33.     audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
  34.     audio_hal_set_volume(board_handle->audio_hal, 100);
  35.  
  36.     ESP_LOGI(TAG, "Create i2s stream to read data from codec chip");
  37.     i2s_stream_cfg_t i2s_cfg_read = I2S_STREAM_CFG_DEFAULT();
  38.     i2s_cfg_read.type = AUDIO_STREAM_READER;
  39.     i2s_stream_reader = i2s_stream_init(&i2s_cfg_read);
  40.  
  41.     ESP_LOGI(TAG, "Create i2s stream to write data to codec chip");
  42.     i2s_stream_cfg_t i2s_cfg_write = I2S_STREAM_CFG_DEFAULT();
  43.     i2s_cfg_write.type = AUDIO_STREAM_WRITER;
  44.     i2s_stream_writer = i2s_stream_init(&i2s_cfg_write);
  45.  
  46.     ESP_LOGI(TAG, "Create filter");
  47.     filter_cfg_t cfg = DEFAULT_FILTER_CONFIG();
  48.     filter = filter_init(&cfg);
  49.  
  50.     ESP_LOGI(TAG, "Create audio pipeline for playback");
  51.     audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
  52.     pipeline = audio_pipeline_init(&pipeline_cfg);
  53.     mem_assert(pipeline);
  54.  
  55.     ESP_LOGI(TAG, "Register all elements to audio pipeline");
  56.     audio_pipeline_register(pipeline, i2s_stream_reader, "i2s_read");
  57.     audio_pipeline_register(pipeline, filter, "filter");
  58.     audio_pipeline_register(pipeline, i2s_stream_writer, "i2s_write");
  59.  
  60.     ESP_LOGI(TAG, "Link it together [codec_chip]-->i2s_stream_reader-->filter--->i2s_stream_writer-->[codec_chip]");
  61.     const char *link_tag[3] = {"i2s_read", "filter", "i2s_write"};
  62.     audio_pipeline_link(pipeline, &link_tag[0], 3);
  63.  
  64.     ESP_LOGI(TAG, "Start audio_pipeline");
  65.     audio_pipeline_run(pipeline);
  66.  
  67.     ESP_LOGI(TAG, "Starting ...");
  68.     while (1) {
  69.         vTaskDelay(2000);
  70.     }
  71.  
  72.     ESP_LOGI(TAG, "[ 7 ] Stop audio_pipeline");
  73.     audio_pipeline_stop(pipeline);
  74.     audio_pipeline_wait_for_stop(pipeline);
  75.     audio_pipeline_terminate(pipeline);
  76.  
  77.     audio_pipeline_unregister(pipeline, i2s_stream_reader);
  78.     audio_pipeline_unregister(pipeline, filter);
  79.     audio_pipeline_unregister(pipeline, i2s_stream_writer);
  80.  
  81.     /* Release all resources */
  82.     audio_pipeline_deinit(pipeline);
  83.     audio_element_deinit(i2s_stream_reader);
  84.     audio_element_deinit(i2s_stream_writer);
  85.     audio_element_deinit(filter);
  86. }
  87.  
  1. #include <string.h>
  2. #include "esp_log.h"
  3. #include "audio_error.h"
  4. #include "audio_mem.h"
  5. #include "audio_element.h"
  6. #include "audio_type_def.h"
  7. #include "filter.h"
  8.  
  9. static const char *TAG = "FILTER";
  10.  
  11.  
  12. typedef struct filter {
  13.     int  samplerate;
  14.     int  channel;
  15. } filter_t;
  16.  
  17.  
  18. static float convertToF32(uint16_t sample) {
  19.     float s = (float) sample;
  20.  
  21.     s -= 32768.0;
  22.     if (s > 0.0) {
  23.         return s / 32767.0;
  24.     }
  25.  
  26.     return s / 32768.0;
  27. }
  28.  
  29. static int16_t convertToInt16(float sample) {
  30.     if (sample > 0.0) {
  31.         sample *= 32767.0;
  32.     } else {
  33.         sample *= 32768.0;
  34.     }
  35.  
  36.     sample += 32768.0;
  37.  
  38.     return (int16_t) sample;
  39. }
  40.  
  41. static esp_err_t filter_destroy(audio_element_handle_t self)
  42. {
  43.     filter_t *filter = (filter_t *)audio_element_getdata(self);
  44.     audio_free(filter);
  45.     return ESP_OK;
  46. }
  47.  
  48. static esp_err_t filter_open(audio_element_handle_t self)
  49. {
  50.     ESP_LOGD(TAG, "filter_open");
  51.  
  52.     return ESP_OK;
  53. }
  54.  
  55. static esp_err_t filter_close(audio_element_handle_t self)
  56. {
  57.     ESP_LOGD(TAG, "filter_close");
  58.  
  59.     return ESP_OK;
  60. }
  61.  
  62. static int filter_process(audio_element_handle_t self, char *buf, int len) {
  63.     int rsize = audio_element_input(self, buf, len);
  64.  
  65.     if (len != rsize || (rsize % 4) != 0) {
  66.         ESP_LOGW(TAG, "unexpected rsize: %d, len: %d", rsize, len);
  67.     }
  68.  
  69.     int16_t lSample, rSample;
  70.     char * lSamplep = (char *) &lSample;
  71.     char * rSamplep = (char *) &rSample;
  72.     for (int i =0; i<rsize; i+=4) {
  73.         rSamplep[0] = buf[i];
  74.         rSamplep[1] = buf[i+1];
  75.  
  76.         lSamplep[0] = buf[i+2];
  77.         lSamplep[1] = buf[i+3];
  78.  
  79.         float a = convertToF32(rSample);
  80.         a *= 0.5;
  81.         rSample = convertToInt16(a);
  82.  
  83.         buf[i] = rSamplep[0];
  84.         buf[i+1] = rSamplep[1];
  85.  
  86.         buf[i+2] = lSamplep[0];
  87.         buf[i+3] = lSamplep[1];
  88.     }
  89.  
  90.     rsize = audio_element_output(self, buf, rsize);
  91.  
  92.     return rsize;
  93. }
  94.  
  95. audio_element_handle_t filter_init(filter_cfg_t *config)
  96. {
  97.     if (config == NULL) {
  98.         ESP_LOGE(TAG, "config is NULL. (line %d)", __LINE__);
  99.         return NULL;
  100.     }
  101.     filter_t *filter = audio_calloc(1, sizeof(filter_t));
  102.     AUDIO_MEM_CHECK(TAG, filter, return NULL);
  103.     if (filter == NULL) {
  104.         ESP_LOGE(TAG, "audio_calloc failed for filter. (line %d)", __LINE__);
  105.         return NULL;
  106.     }
  107.     audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
  108.     cfg.destroy = filter_destroy;
  109.     cfg.process = filter_process;
  110.     cfg.open = filter_open;
  111.     cfg.close = filter_close;
  112.     cfg.buffer_len = 0;
  113.     cfg.tag = "filter";
  114.     cfg.task_stack = config->task_stack;
  115.     cfg.task_prio = config->task_prio;
  116.     cfg.task_core = config->task_core;
  117.     cfg.out_rb_size = config->out_rb_size;
  118.     cfg.stack_in_ext = config->stack_in_ext;
  119.     audio_element_handle_t el = audio_element_init(&cfg);
  120.     AUDIO_MEM_CHECK(TAG, el, {audio_free(filter); return NULL;});
  121.     filter->samplerate = config->samplerate;
  122.     filter->channel = config->channel;
  123.     audio_element_setdata(el, filter);
  124.     audio_element_info_t info = {0};
  125.     audio_element_setinfo(el, &info);
  126.     ESP_LOGD(TAG, "filter_init");
  127.     return el;
  128. }
  1.  
  2.  
  3. typedef struct filter_cfg {
  4.     int samplerate;
  5.     int channel;
  6.     int out_rb_size;
  7.     int task_stack;
  8.     int task_core;
  9.     int task_prio;
  10.     bool stack_in_ext;
  11. } filter_cfg_t;
  12.  
  13. #define FILTER_TASK_STACK      (4 * 1024)
  14. #define FILTER_TASK_CORE       (0)
  15. #define FILTER_TASK_PRIO       (5)
  16. #define FILTER_RINGBUFFER_SIZE (64)
  17.  
  18. #define DEFAULT_FILTER_CONFIG() {            \
  19.     .samplerate   = 48000,                      \
  20.     .channel      = 1,                          \
  21.     .out_rb_size  = FILTER_RINGBUFFER_SIZE,  \
  22.     .task_stack   = FILTER_TASK_STACK,       \
  23.     .task_core    = FILTER_TASK_CORE,        \
  24.     .task_prio    = FILTER_TASK_PRIO,        \
  25.     .stack_in_ext = false,                       \
  26. }
  27.  
  28. audio_element_handle_t filter_init(filter_cfg_t *config);
  29.  
  30.  
Last edited by dominik8054 on Sat Oct 12, 2024 6:21 pm, edited 1 time in total.

dominik8054
Posts: 2
Joined: Sat Oct 05, 2024 2:16 pm

Re: ESP32 Audio Kit passthrough example

Postby dominik8054 » Fri Oct 11, 2024 5:01 pm

I resolve problem with low volume by change function esp_err_t es8388_set_voice_volume(int volume) in es8388.c

This function works:
  1. esp_err_t es8388_set_voice_volume(int volume)
  2. {
  3.     esp_err_t res = ESP_OK;
  4.     if (volume < 0)
  5.         volume = 0;
  6.     else if (volume > 100)
  7.         volume = 100;
  8.     volume /= 3;
  9.     res = es_write_reg(ES8388_ADDR, ES8388_DACCONTROL4, 0);
  10.     res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL5, 0);
  11.     // LOUT1 RLOUT1 volume: dataheet says only 6 bits
  12.     res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, volume);
  13.     res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL25, volume);
  14.     // DAC LDACVOL RDACVOL default 0 = 0DB; Default value 192 = – -96 dB
  15.     res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL26, volume);
  16.     res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL27, volume);
  17.     return res;
  18. }

Who is online

Users browsing this forum: No registered users and 29 guests