Custom Audio Element Problem
Posted: Thu Apr 01, 2021 3:07 pm
Hello,
I'm trying to write my own audio element. The board I'm using is LyraT v4.3. I created a pipeline i2s_stream_reader -> my_element -> i2s_stream_writer. In the process function of 'my_element', if I forward the samples without doing anything with them, I can hear my voice from the headphones without a problem. If I multiply the samples with 0.5 before forwarding them to i2s_stream_writer, all I hear is very loud noise. Aren't the samples provided to my process function raw audio samples? Should I add some kind of decode element between i2s_stream_reader and my_element?
Here is my code for reference:
P.S: I have checked out a similar post but the example code shared in that post doesn't change the samples so it doesn't answer my question.
I'm trying to write my own audio element. The board I'm using is LyraT v4.3. I created a pipeline i2s_stream_reader -> my_element -> i2s_stream_writer. In the process function of 'my_element', if I forward the samples without doing anything with them, I can hear my voice from the headphones without a problem. If I multiply the samples with 0.5 before forwarding them to i2s_stream_writer, all I hear is very loud noise. Aren't the samples provided to my process function raw audio samples? Should I add some kind of decode element between i2s_stream_reader and my_element?
Here is my code for reference:
- #include <string.h>
- #include "board.h"
- #include "esp_log.h"
- #include "audio_pipeline.h"
- #include "audio_element.h"
- #include "i2s_stream.h"
- static const char *TAG = "ELEMENTEXAMPLE";
- static esp_err_t el_open(audio_element_handle_t self) {
- ESP_LOGI(TAG, "open");
- return ESP_OK;
- }
- static int el_process(audio_element_handle_t self, char *buf, int len) {
- int rsize = audio_element_input(self, buf, len);
- for (int i =0; i<rsize; i+=4) {
- // convert bytes to samples
- uint16_t lSample = ((((uint16_t) buf[i]) << 8) & 0xFF00) + buf[i+1];
- uint16_t rSample = ((((uint16_t) buf[i+2]) << 8) & 0xFF00) + buf[i+3];
- // if i comment out these two lines it works as expected
- lSample *= 0.5;
- rSample *= 0.5;
- // convert samples to byte
- buf[i] = (char) (((lSample & 0xFF00) >> 8) & 0xFF);
- buf[i+1] = (char) (lSample & 0xFF);
- buf[i+2] = (char) (((rSample & 0xFF00) >> 8) & 0xFF);
- buf[i+3] = (char) (rSample & 0xFF);
- }
- rsize = audio_element_output(self, buf, rsize);
- return rsize;
- }
- void app_main() {
- audio_pipeline_handle_t pipeline;
- audio_element_handle_t i2s_stream_reader, i2s_stream_writer, my_el;
- esp_log_level_set("*", ESP_LOG_INFO);
- ESP_LOGI(TAG, "[1.0] 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, "[2.0] Create i2s stream to read audio data from codec chip");
- i2s_stream_cfg_t i2sr_cfg = I2S_STREAM_CFG_DEFAULT();
- i2sr_cfg.type = AUDIO_STREAM_READER;
- i2s_stream_reader = i2s_stream_init(&i2sr_cfg);
- ESP_LOGI(TAG, "[3.0] Create i2s stream to write audio data to codec chip");
- i2s_stream_cfg_t i2sw_cfg = I2S_STREAM_CFG_DEFAULT();
- i2sw_cfg.type = AUDIO_STREAM_WRITER;
- i2s_stream_writer = i2s_stream_init(&i2sw_cfg);
- ESP_LOGI(TAG, "[4.0] Init Element");
- audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
- cfg.open = el_open;
- cfg.process = el_process;
- cfg.tag = "my_el";
- my_el = audio_element_init(&cfg);
- ESP_LOGI(TAG, "[5.0] Create pipeline");
- audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
- pipeline = audio_pipeline_init(&pipeline_cfg);
- mem_assert(pipeline);
- audio_pipeline_register(pipeline, my_el, "my_el");
- audio_pipeline_register(pipeline, i2s_stream_reader, "i2sr");
- audio_pipeline_register(pipeline, i2s_stream_writer, "i2sw");
- const char *link_tag[3] = {"i2sr", "my_el", "i2sw"};
- audio_pipeline_link(pipeline, link_tag, 3);
- ESP_LOGI(TAG, "[6.0] Run pipeline");
- audio_pipeline_run(pipeline);
- ESP_LOGI(TAG, "[ * ] Starting ...");
- while (1) {
- vTaskDelay(2000);
- }
- }