Thank you for your replies, tempo.tian. With your hints I got it to work
the hacky way.
However, I'd prefer not to change code in the framework and use an `audio_element` to down-mix. Do you know which callback functions in `audio_element` are required to implement?
This is the code I have so far... parts that I expect to be unnecessary are omitted for brevity.
Code: Select all
mono_downmix.h/c:
#define DEFAULT_MONO_DOWNMIX_CFG() \
{ \
.buf_sz = MONO_DOWNMIX_BUF_SIZE, \
.out_rb_sz = MONO_DOWNMIX_RINGBUFFER_SIZE, \
.task_stack_sz = MONO_DOWNMIX_TASK_STACK, \
.task_core = MONO_DOWNMIX_TASK_CORE, \
.task_prio = MONO_DOWNMIX_TASK_PRIO, \
.stack_in_ext = false, \
}
...
static esp_err_t _mono_downmix_process(audio_element_handle_t self, char *in, int len)
{
ESP_LOGI(TAG, "%s", __func__);
int diff = 0;
if ((diff = len % 4) != 0)
{
ESP_LOGD(TAG, "Need to adapt buffer length %d to %d", len, len - diff);
}
int r_size = audio_element_input(self, in, len - diff);
if (r_size <= 0)
{
ESP_LOGE(TAG, "ALARM! %d", r_size);
return r_size;
}
if (r_size % 4 != 0)
{
ESP_LOGW(TAG, "Could not get full samples");
}
int new_len = r_size - (r_size % 4);
int num_samples = new_len / 4;
int_fast16_t *left = (int_fast16_t *)in;
while (num_samples > 0)
{
int_fast16_t val = left[0] * 0.5 + left[1] * 0.5;
left[0] = val;
left[1] = val;
left += 2;
--num_samples;
}
return audio_element_output(self, in, new_len);
}
...
audio_element_handle_t mono_downmix_init(mono_downmix_cfg_t *config)
{
ESP_LOGI(TAG, "%s", __func__);
if (config == NULL)
{
ESP_LOGE(TAG, "config is NULL. (line %d)", __LINE__);
return NULL;
}
audio_element_handle_t el;
audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
cfg.open = _mono_downmix_open; // do nothing - return ESP_OK
cfg.close = _mono_downmix_close; // do nothing - return ESP_OK
cfg.process = _mono_downmix_process;
cfg.destroy = _mono_downmix_destroy; // do nothing - return ESP_OK
cfg.task_stack = config->task_stack_sz;
cfg.task_prio = config->task_prio;
cfg.task_core = config->task_core;
cfg.out_rb_size = config->out_rb_sz;
cfg.buffer_len = config->buf_sz;
cfg.stack_in_ext = config->stack_in_ext;
cfg.tag = "downmix";
el = audio_element_init(&cfg);
AUDIO_MEM_CHECK(TAG, el, goto _mono_downmix_init_exit);
return el;
_mono_downmix_init_exit:
return NULL;
}
...
app_main:
const char *link_tag[2] = {"bt", "downmixer", "i2s"};
audio_pipeline_link(pipeline, &link_tag[0], 3);
Now the program keeps crashing while trying to link the elements in the pipeline...
Code: Select all
I (1508) MONO_DOWNMIX: mono_downmix_init
I (1508) AUDIO_PIPELINE: link el->rb, el:0x3ffd4140, tag:bt, rb:0x3ffd75a8
I (1518) AUDIO_PIPELINE: link el->rb, el:0x3ffd6fc4, tag:downmixer, rb:0x3ffd6c50
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400011f1 PS : 0x00060330 A0 : 0x800d92a6 A1 : 0x3ffbc370
A2 : 0x00000062 A3 : 0xa5a5a5a5 A4 : 0x3f402ea0 A5 : 0x000005ee
A6 : 0x3f402e04 A7 : 0x3ffd6fc4 A8 : 0x00000000 A9 : 0xa5a5a5a5
A10 : 0x00000082 A11 : 0x3ff96354 A12 : 0x3ffd67b0 A13 : 0x3ffbc360
A14 : 0x3ffbc340 A15 : 0x0000000c SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0xa5a5a5a5 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffd
Backtrace:0x400011ee:0x3ffbc3700x400d92a3:0x3ffbc390 0x400d988b:0x3ffbc3b0 0x400d70c8:0x3ffbc3d0 0x4017dfcd:0x3ffbc5e0 0x40093599:0x3ffbc600
Does anyone know what I could be missing here?