ESP32 Audio Kit passthrough example
Posted: 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
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
- /* Audio bypass
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include <string.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_log.h"
- #include "audio_pipeline.h"
- #include "i2s_stream.h"
- #include "board.h"
- #include "filter.h"
- static const char *TAG = "BYPASS";
- void app_main(void)
- {
- audio_pipeline_handle_t pipeline;
- audio_element_handle_t i2s_stream_writer, i2s_stream_reader, filter;
- esp_log_level_set("*", ESP_LOG_INFO);
- esp_log_level_set(TAG, ESP_LOG_DEBUG);
- ESP_LOGI(TAG, "Start codec chip");
- audio_board_handle_t board_handle = audio_board_init();
- audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
- audio_hal_set_volume(board_handle->audio_hal, 100);
- ESP_LOGI(TAG, "Create i2s stream to read data from codec chip");
- i2s_stream_cfg_t i2s_cfg_read = I2S_STREAM_CFG_DEFAULT();
- i2s_cfg_read.type = AUDIO_STREAM_READER;
- i2s_stream_reader = i2s_stream_init(&i2s_cfg_read);
- ESP_LOGI(TAG, "Create i2s stream to write data to codec chip");
- i2s_stream_cfg_t i2s_cfg_write = I2S_STREAM_CFG_DEFAULT();
- i2s_cfg_write.type = AUDIO_STREAM_WRITER;
- i2s_stream_writer = i2s_stream_init(&i2s_cfg_write);
- ESP_LOGI(TAG, "Create filter");
- filter_cfg_t cfg = DEFAULT_FILTER_CONFIG();
- filter = filter_init(&cfg);
- ESP_LOGI(TAG, "Create audio pipeline for playback");
- audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
- pipeline = audio_pipeline_init(&pipeline_cfg);
- mem_assert(pipeline);
- ESP_LOGI(TAG, "Register all elements to audio pipeline");
- audio_pipeline_register(pipeline, i2s_stream_reader, "i2s_read");
- audio_pipeline_register(pipeline, filter, "filter");
- audio_pipeline_register(pipeline, i2s_stream_writer, "i2s_write");
- ESP_LOGI(TAG, "Link it together [codec_chip]-->i2s_stream_reader-->filter--->i2s_stream_writer-->[codec_chip]");
- const char *link_tag[3] = {"i2s_read", "filter", "i2s_write"};
- audio_pipeline_link(pipeline, &link_tag[0], 3);
- ESP_LOGI(TAG, "Start audio_pipeline");
- audio_pipeline_run(pipeline);
- ESP_LOGI(TAG, "Starting ...");
- while (1) {
- vTaskDelay(2000);
- }
- ESP_LOGI(TAG, "[ 7 ] Stop audio_pipeline");
- audio_pipeline_stop(pipeline);
- audio_pipeline_wait_for_stop(pipeline);
- audio_pipeline_terminate(pipeline);
- audio_pipeline_unregister(pipeline, i2s_stream_reader);
- audio_pipeline_unregister(pipeline, filter);
- audio_pipeline_unregister(pipeline, i2s_stream_writer);
- /* Release all resources */
- audio_pipeline_deinit(pipeline);
- audio_element_deinit(i2s_stream_reader);
- audio_element_deinit(i2s_stream_writer);
- audio_element_deinit(filter);
- }
- #include <string.h>
- #include "esp_log.h"
- #include "audio_error.h"
- #include "audio_mem.h"
- #include "audio_element.h"
- #include "audio_type_def.h"
- #include "filter.h"
- static const char *TAG = "FILTER";
- typedef struct filter {
- int samplerate;
- int channel;
- } filter_t;
- static float convertToF32(uint16_t sample) {
- float s = (float) sample;
- s -= 32768.0;
- if (s > 0.0) {
- return s / 32767.0;
- }
- return s / 32768.0;
- }
- static int16_t convertToInt16(float sample) {
- if (sample > 0.0) {
- sample *= 32767.0;
- } else {
- sample *= 32768.0;
- }
- sample += 32768.0;
- return (int16_t) sample;
- }
- static esp_err_t filter_destroy(audio_element_handle_t self)
- {
- filter_t *filter = (filter_t *)audio_element_getdata(self);
- audio_free(filter);
- return ESP_OK;
- }
- static esp_err_t filter_open(audio_element_handle_t self)
- {
- ESP_LOGD(TAG, "filter_open");
- return ESP_OK;
- }
- static esp_err_t filter_close(audio_element_handle_t self)
- {
- ESP_LOGD(TAG, "filter_close");
- return ESP_OK;
- }
- static int filter_process(audio_element_handle_t self, char *buf, int len) {
- int rsize = audio_element_input(self, buf, len);
- if (len != rsize || (rsize % 4) != 0) {
- ESP_LOGW(TAG, "unexpected rsize: %d, len: %d", rsize, len);
- }
- int16_t lSample, rSample;
- char * lSamplep = (char *) &lSample;
- char * rSamplep = (char *) &rSample;
- for (int i =0; i<rsize; i+=4) {
- rSamplep[0] = buf[i];
- rSamplep[1] = buf[i+1];
- lSamplep[0] = buf[i+2];
- lSamplep[1] = buf[i+3];
- float a = convertToF32(rSample);
- a *= 0.5;
- rSample = convertToInt16(a);
- buf[i] = rSamplep[0];
- buf[i+1] = rSamplep[1];
- buf[i+2] = lSamplep[0];
- buf[i+3] = lSamplep[1];
- }
- rsize = audio_element_output(self, buf, rsize);
- return rsize;
- }
- audio_element_handle_t filter_init(filter_cfg_t *config)
- {
- if (config == NULL) {
- ESP_LOGE(TAG, "config is NULL. (line %d)", __LINE__);
- return NULL;
- }
- filter_t *filter = audio_calloc(1, sizeof(filter_t));
- AUDIO_MEM_CHECK(TAG, filter, return NULL);
- if (filter == NULL) {
- ESP_LOGE(TAG, "audio_calloc failed for filter. (line %d)", __LINE__);
- return NULL;
- }
- audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
- cfg.destroy = filter_destroy;
- cfg.process = filter_process;
- cfg.open = filter_open;
- cfg.close = filter_close;
- cfg.buffer_len = 0;
- cfg.tag = "filter";
- cfg.task_stack = config->task_stack;
- cfg.task_prio = config->task_prio;
- cfg.task_core = config->task_core;
- cfg.out_rb_size = config->out_rb_size;
- cfg.stack_in_ext = config->stack_in_ext;
- audio_element_handle_t el = audio_element_init(&cfg);
- AUDIO_MEM_CHECK(TAG, el, {audio_free(filter); return NULL;});
- filter->samplerate = config->samplerate;
- filter->channel = config->channel;
- audio_element_setdata(el, filter);
- audio_element_info_t info = {0};
- audio_element_setinfo(el, &info);
- ESP_LOGD(TAG, "filter_init");
- return el;
- }
- typedef struct filter_cfg {
- int samplerate;
- int channel;
- int out_rb_size;
- int task_stack;
- int task_core;
- int task_prio;
- bool stack_in_ext;
- } filter_cfg_t;
- #define FILTER_TASK_STACK (4 * 1024)
- #define FILTER_TASK_CORE (0)
- #define FILTER_TASK_PRIO (5)
- #define FILTER_RINGBUFFER_SIZE (64)
- #define DEFAULT_FILTER_CONFIG() { \
- .samplerate = 48000, \
- .channel = 1, \
- .out_rb_size = FILTER_RINGBUFFER_SIZE, \
- .task_stack = FILTER_TASK_STACK, \
- .task_core = FILTER_TASK_CORE, \
- .task_prio = FILTER_TASK_PRIO, \
- .stack_in_ext = false, \
- }
- audio_element_handle_t filter_init(filter_cfg_t *config);