libpeer
libpeer copied to clipboard
I would like an Audio 2 Way example using the OPUS encoder and decoder.
I just started using ESP-IDF. I'm trying it myself, but I get an error.
#include "driver/i2s_pdm.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_audio_enc.h"
#include "esp_audio_enc_default.h"
#include "esp_audio_enc_reg.h"
#include "esp_g711_enc.h"
#include "esp_opus_enc.h"
#include "peer_connection.h"
#define I2S_CLK_GPIO 42
#define I2S_DATA_GPIO 41
static const char* TAG = "AUDIO";
extern PeerConnection* g_pc;
extern PeerConnectionState eState;
extern int get_timestamp();
i2s_chan_handle_t rx_handle = NULL;
esp_audio_enc_handle_t enc_handle = NULL;
esp_audio_enc_in_frame_t aenc_in_frame = {0};
esp_audio_enc_out_frame_t aenc_out_frame = {0};
// esp_g711_enc_config_t g711_cfg;
esp_opus_enc_config_t opus_cfg;
esp_audio_enc_config_t enc_cfg;
esp_err_t audio_codec_init() {
uint8_t* read_buf = NULL;
uint8_t* write_buf = NULL;
int read_size = 0;
int out_size = 0;
esp_audio_err_t ret = ESP_AUDIO_ERR_OK;
esp_audio_enc_register_default();
// g711_cfg.sample_rate = ESP_AUDIO_SAMPLE_RATE_8K;
// g711_cfg.channel = ESP_AUDIO_MONO;
// g711_cfg.bits_per_sample = ESP_AUDIO_BIT16;
// enc_cfg.type = ESP_AUDIO_TYPE_G711A;
// enc_cfg.cfg = &g711_cfg;
// enc_cfg.cfg_sz = sizeof(g711_cfg);
// ret = esp_audio_enc_open(&enc_cfg, &enc_handle);
// if (ret != ESP_AUDIO_ERR_OK) {
// ESP_LOGE(TAG, "audio encoder open failed");
// return ESP_FAIL;
// }
// int frame_size = (g711_cfg.bits_per_sample * g711_cfg.channel) >> 3;
opus_cfg.sample_rate = ESP_AUDIO_SAMPLE_RATE_8K;
opus_cfg.channel = ESP_AUDIO_DUAL;
opus_cfg.bits_per_sample = ESP_AUDIO_BIT16;
opus_cfg.bitrate = 256;
opus_cfg.frame_duration = ESP_OPUS_ENC_FRAME_DURATION_20_MS;
opus_cfg.application_mode = ESP_OPUS_ENC_APPLICATION_VOIP;
opus_cfg.complexity = 0;
opus_cfg.enable_fec = false;
opus_cfg.enable_dtx = false;
enc_cfg.type = ESP_AUDIO_TYPE_OPUS;
enc_cfg.cfg = &opus_cfg;
enc_cfg.cfg_sz = sizeof(opus_cfg);
ret = esp_opus_enc_open(&opus_cfg, sizeof(esp_opus_enc_config_t), &enc_handle);
if (ret != ESP_AUDIO_ERR_OK) {
ESP_LOGE(TAG, "audio encoder open failed");
return ESP_FAIL;
}
int frame_size = (opus_cfg.bits_per_sample * opus_cfg.channel) >> 3;
ret = esp_opus_enc_get_frame_size(enc_handle, &read_size, &out_size);
if (frame_size == read_size) {
read_size *= 256;
out_size *= 256;
}
if (ret != ESP_AUDIO_ERR_OK) {
ESP_LOGE(TAG, "audio encoder get frame size failed");
return ESP_FAIL;
}
read_buf = malloc(read_size);
if (!read_buf) {
ESP_LOGE(TAG, "read_buf malloc failed");
return ESP_FAIL;
}
write_buf = malloc(out_size);
if (!write_buf) {
ESP_LOGE(TAG, "write_buf malloc failed");
return ESP_FAIL;
}
aenc_in_frame.buffer = read_buf;
aenc_in_frame.len = read_size;
aenc_out_frame.buffer = write_buf;
aenc_out_frame.len = out_size;
ESP_LOGI(TAG, "audio codec init done. in buffer size: %d, out buffer size: %d", read_size, out_size);
return 0;
}
esp_err_t audio_init(void) {
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle));
i2s_pdm_rx_config_t pdm_rx_cfg = {
.clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(8000),
.slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.clk = I2S_CLK_GPIO,
.din = I2S_DATA_GPIO,
.invert_flags = {
.clk_inv = false,
},
},
};
ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
return audio_codec_init();
}
void audio_deinit(void) {
ESP_ERROR_CHECK(i2s_channel_disable(rx_handle));
ESP_ERROR_CHECK(i2s_del_channel(rx_handle));
}
int32_t audio_get_samples(uint8_t* buf, size_t size) {
size_t bytes_read;
if (i2s_channel_read(rx_handle, (char*)buf, size, &bytes_read, 1000) != ESP_OK) {
ESP_LOGE(TAG, "i2s read error");
}
return bytes_read;
}
void audio_task(void* arg) {
int ret;
static int64_t last_time;
int64_t curr_time;
float bytes = 0;
last_time = get_timestamp();
ESP_LOGI(TAG, "audio task started");
for (;;) {
if (eState == PEER_CONNECTION_COMPLETED) {
ret = audio_get_samples(aenc_in_frame.buffer, aenc_in_frame.len);
if (ret == aenc_in_frame.len) {
if (esp_audio_enc_process(enc_handle, &aenc_in_frame, &aenc_out_frame) == ESP_AUDIO_ERR_OK) {
peer_connection_send_audio(g_pc, aenc_out_frame.buffer, aenc_out_frame.encoded_bytes);
bytes += aenc_out_frame.encoded_bytes;
// if (bytes > 50000) {
// curr_time = get_timestamp();
// ESP_LOGI(TAG, "audio bitrate: %.1f bps", 1000.0 * (bytes * 8.0 / (float)(curr_time - last_time)));
// last_time = curr_time;
// bytes = 0;
// }
} else {
ESP_LOGI(TAG, "esp_audio_enc_process error");
}
}
vTaskDelay(pdMS_TO_TICKS(5));
} else {
vTaskDelay(pdMS_TO_TICKS(100));
}
}
}
--- 0x4200b485: esp_audio_enc_process at /builds/adf/esp-adf-libs-source/esp_audio_codec/codec-interface/src/esp_audio_enc.c:110
A2 : 0x3fcdc9ec A3 : 0x3fca15e8 A4 : 0x3fca15d0 A5 : 0x00001d29
A6 : 0x3c0f5e04 A7 : 0x00000000 A8 : 0x00001f40 A9 : 0x3c1520a0
A10 : 0x3c140e0c A11 : 0x3fca15e8 A12 : 0x3fca15d0 A13 : 0x3c1520d0
A14 : 0x00000280 A15 : 0x3c140c30 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00001f4c LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0x00000000
--- 0x40056f5c: memcpy in ROM
0x40056f72: memcpy in ROM
hello, can you try to allocate more stack size for audio_task?