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:
Code: Untitled.c Select all
#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);
}
}