ten / esp32-client /main /audio_proc.c
3v324v23's picture
Зафиксирована рабочая версия TEN-Agent для HuggingFace Space
87337b1
raw
history blame
5.54 kB
#include <string.h>
#include <pthread.h>
#include "board.h"
#include "audio_element.h"
#include "audio_hal.h"
#include "audio_mem.h"
#include "audio_sys.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_pm.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "i2c_bus.h"
#include "filter_resample.h"
#include "algorithm_stream.h"
#include "i2s_stream.h"
#include "raw_stream.h"
#include "audio_thread.h"
#include "audio_pipeline.h"
#include "common.h"
#include "rtc_proc.h"
static audio_element_handle_t raw_read, element_algo, raw_write;
static audio_pipeline_handle_t recorder, player;
static SemaphoreHandle_t g_audio_capture_sem = NULL;
static audio_thread_t *g_audio_thread;
audio_board_handle_t board_handle;
int audio_sema_init(void)
{
g_audio_capture_sem = xSemaphoreCreateBinary();
if (NULL == g_audio_capture_sem) {
printf("Unable to create audio capture semaphore!\n");
return -1;
}
return 0;
}
void audio_sema_post(void)
{
xSemaphoreTake(g_audio_capture_sem, portMAX_DELAY);
}
void audio_sema_pend(void)
{
xSemaphoreGive(g_audio_capture_sem);
}
static esp_err_t recorder_pipeline_open(void)
{
audio_element_handle_t i2s_stream_reader;
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
recorder = audio_pipeline_init(&pipeline_cfg);
if (!recorder) {
return ESP_FAIL;
}
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT_WITH_PARA(CODEC_ADC_I2S_PORT, CONFIG_PCM_SAMPLE_RATE, AUDIO_I2S_BITS, AUDIO_STREAM_READER);
i2s_cfg.task_core = 0;
i2s_cfg.stack_in_ext = true;
i2s_stream_set_channel_type(&i2s_cfg, I2S_CHANNEL_TYPE_ONLY_LEFT);
// i2s_cfg.out_rb_size = 2 * 1024;
i2s_cfg.stack_in_ext = true;
i2s_stream_reader = i2s_stream_init(&i2s_cfg);
algorithm_stream_cfg_t algo_config = ALGORITHM_STREAM_CFG_DEFAULT();
algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE1;
algo_config.algo_mask = ALGORITHM_STREAM_USE_AEC;
algo_config.swap_ch = true;
element_algo = algo_stream_init(&algo_config);
audio_element_set_music_info(element_algo, CONFIG_PCM_SAMPLE_RATE, 1, 16);
raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT();
raw_cfg.type = AUDIO_STREAM_READER;
raw_cfg.out_rb_size = 2 * 1024;
raw_read = raw_stream_init(&raw_cfg);
audio_element_set_output_timeout(raw_read, portMAX_DELAY);
audio_pipeline_register(recorder, i2s_stream_reader, "i2s");
audio_pipeline_register(recorder, element_algo, "algo");
audio_pipeline_register(recorder, raw_read, "raw");
const char *link_tag[3] = { "i2s", "algo", "raw" };
audio_pipeline_link(recorder, &link_tag[0], 3);
printf("audio recorder has been created\n");
return ESP_OK;
}
static esp_err_t player_pipeline_open(void)
{
audio_element_handle_t i2s_stream_writer;
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
player = audio_pipeline_init(&pipeline_cfg);
if (!player) {
return ESP_FAIL;
}
raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT();
raw_cfg.type = AUDIO_STREAM_WRITER;
raw_cfg.out_rb_size = 8 * 1024;
raw_write = raw_stream_init(&raw_cfg);
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT_WITH_PARA(CODEC_ADC_I2S_PORT, CONFIG_PCM_SAMPLE_RATE, AUDIO_I2S_BITS, AUDIO_STREAM_WRITER);
i2s_cfg.need_expand = true;
i2s_stream_set_channel_type(&i2s_cfg, I2S_CHANNEL_TYPE_ONLY_LEFT);
i2s_cfg.stack_in_ext = true;
i2s_stream_writer = i2s_stream_init(&i2s_cfg);
audio_pipeline_register(player, raw_write, "raw");
audio_pipeline_register(player, i2s_stream_writer, "i2s");
const char *link_tag[2] = {"raw", "i2s"};
audio_pipeline_link(player, &link_tag[0], 2);
return ESP_OK;
}
static void _pipeline_close(audio_pipeline_handle_t handle)
{
audio_pipeline_stop(handle);
audio_pipeline_wait_for_stop(handle);
audio_pipeline_deinit(handle);
}
static void audio_send_thread(void *arg)
{
int ret = 0;
uint8_t *audio_pcm_buf = heap_caps_malloc(CONFIG_PCM_DATA_LEN, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (!audio_pcm_buf) {
printf("Failed to alloc audio buffer!\n");
goto THREAD_END;
}
recorder_pipeline_open();
player_pipeline_open();
audio_sema_post();
audio_pipeline_run(recorder);
audio_pipeline_run(player);
while (g_app.b_call_session_started) {
ret = raw_stream_read(raw_read, (char *)audio_pcm_buf, CONFIG_PCM_DATA_LEN);
if (ret != CONFIG_PCM_DATA_LEN) {
printf("read raw stream error, expect %d, but only %d\n", CONFIG_PCM_DATA_LEN, ret);
}
send_rtc_audio_frame(audio_pcm_buf, CONFIG_PCM_DATA_LEN);
}
//deinit
_pipeline_close(player);
_pipeline_close(recorder);
THREAD_END:
if (audio_pcm_buf) {
free(audio_pcm_buf);
}
vTaskDelete(NULL);
}
int playback_stream_write(char *data, int len)
{
return raw_stream_write(raw_write, data, len);
}
void setup_audio(void)
{
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, 85);
}
int audio_start_proc(void)
{
int rval = audio_thread_create(g_audio_thread, "audio_send_task", audio_send_thread, NULL, 4 * 1024, PRIO_TASK_FETCH, true, 0);
if (rval != ESP_OK) {
printf("Unable to create audio capture thread!\n");
return -1;
}
return rval;
}
int audio_get_volume(void)
{
int volume = 0;
audio_hal_get_volume(board_handle->audio_hal, &volume);
return volume;
}
void audio_set_volume(int volume)
{
audio_hal_set_volume(board_handle->audio_hal, volume);
}