2025-05-10 11:44:51 +08:00

299 lines
7.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <components/system.h>
#include <os/os.h>
#include <os/mem.h>
#include <driver/audio_ring_buff.h>
#include "audio_transfer.h"
#include "agora_rtc.h"
#include "agora_config.h"
#include "modules/g711.h"
#define TAG "agora_audio_tras"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
typedef enum {
AUD_TRAS_TX_DATA = 0,
AUD_TRAS_EXIT,
} aud_tras_op_t;
typedef struct {
aud_tras_op_t op;
} aud_tras_msg_t;
static beken_thread_t agora_aud_thread_hdl = NULL;
static beken_queue_t agora_aud_msg_que = NULL;
static RingBufferContext mic_data_rb;
static uint8_t *mic_data_buffer = NULL;
#if defined(CONFIG_USE_G722_CODEC)
#define MIC_FRAME_SIZE 640
#elif defined(CONFIG_USE_G711U_CODEC) || defined(CONFIG_USE_G711A_CODEC)
#define MIC_FRAME_SIZE 320
#else
#define MIC_FRAME_SIZE 160
#endif
#define MIC_FRAME_NUM 10
static int send_agora_audio_frame(uint8_t *data, unsigned int len)
{
//LOGE("len->%d %2X %2X %2X \r\n",len, data[10],data[50],data[150]);
audio_frame_info_t info = { 0 };
#if defined(CONFIG_SEND_PCM_DATA)
info.data_type = AUDIO_DATA_TYPE_PCM;
#else
info.data_type = AUDIO_DATA_TYPE_PCMA;
#endif
//LOGE("S %2X %2X %2X %2X %2X %2X %2X %2X \r\n",data[20],data[40],data[60],data[70],data[80],data[100],data[120],data[150]);
int rval = bk_agora_rtc_audio_data_send(data, len, &info);
if (rval < 0) {
LOGE("Failed to send audio data, reason: %s\n", agora_rtc_err_2_str(rval));
return 0;
}
return len;
}
static bk_err_t agora_aud_send_msg(void)
{
bk_err_t ret;
aud_tras_msg_t msg;
msg.op = AUD_TRAS_TX_DATA;
if (agora_aud_msg_que) {
ret = rtos_push_to_queue(&agora_aud_msg_que, &msg, BEKEN_NO_WAIT);
if (kNoErr != ret) {
LOGE("audio send msg: AUD_TRAS_TX_DATA fail \r\n");
return kOverrunErr;
}
return ret;
}
return kNoResourcesErr;
}
int volume_adjust2(int16_t * in_buf, float in_vol)
{
int tmp;
// in_vol[0, 100]
float vol = in_vol - 98;
if(-98<vol && vol<0)
vol = 1/(vol*(-1));
else if(0<=vol && vol<=1)
vol = 1;
/*
else if(1<=vol && vol<=2)
vol = vol;
*/
else if(vol<=-98)
vol = 0;
else if(vol>=2)
vol = 8; //这个值可以根据你的实际情况去调整
tmp = (*in_buf)*vol; // 上面所有关于vol的判断其实都是为了此处*in_buf乘以一个倍数你可以根据自己的需要去修改
// 下面的code主要是为了溢出判断
if(tmp > 32767)
tmp = 32767;
else if(tmp < -32768)
tmp = -32768;
*in_buf = tmp;
return 0;
}
int16_t pcm[320];
unsigned char pcma[320];
int volume = 100;
int send_audio_data_to_agora(uint8_t *data, unsigned int len)
{
//LOGE("audio send msg: data -->%d \r\n",len);
//send_agora_audio_frame(data,160);
//send_agora_audio_frame(data+160,160);
//
int16_t decoder_temp = 0;
for(int i=0 ; i<len ;i++){
decoder_temp = alaw2linear(data[i]);
//增大音量
volume_adjust2(&decoder_temp,volume);
pcm[i] = decoder_temp;
}
//LOGE("pcm data -->%02X %02X %02X %02X %02X %02X \r\n",pcm[0],pcm[10],pcm[20],pcm[30],pcm[40],pcm[50]);
for(int j = 0 ; j < 320 ; j++){
int8_t encoder_temp = 0;
encoder_temp = linear2alaw(pcm[j]);
pcma[j]=encoder_temp;
}
//LOGE("pcma data -->%02X %02X %02X %02X %02X %02X \r\n",pcma[0],pcma[10],pcma[20],pcma[30],pcma[40],pcma[50]);
send_agora_audio_frame(pcma,160);
send_agora_audio_frame(pcma+160,160);
#if 0
if (ring_buffer_get_free_size(&mic_data_rb) >= len) {
//GLOBAL_INT_DECLARATION();
ring_buffer_write(&mic_data_rb, data, len);
//GLOBAL_INT_RESTORE();
} else {
LOGE("audio send full!!!\r\n");
return 0;
}
if (ring_buffer_get_fill_size(&mic_data_rb) >= MIC_FRAME_SIZE) {
// addAON_GPIO_Reg0x3 = 2;
agora_aud_send_msg();
// addAON_GPIO_Reg0x3 = 0;
}
#endif
return len;
}
static void agora_aud_tras_main(void)
{
bk_err_t ret = BK_OK;
GLOBAL_INT_DECLARATION();
uint32_t size = 0;
uint32_t count = 0;
uint8_t *mic_temp_buff = NULL;
while(1) {
aud_tras_msg_t msg;
ret = rtos_pop_from_queue(&agora_aud_msg_que, &msg, BEKEN_WAIT_FOREVER);
if (kNoErr == ret) {
switch (msg.op) {
case AUD_TRAS_TX_DATA:
size = ring_buffer_get_fill_size(&mic_data_rb);
if (size >= MIC_FRAME_SIZE) {
mic_temp_buff = psram_malloc(MIC_FRAME_SIZE);
if (mic_temp_buff != NULL) {
GLOBAL_INT_DISABLE();
count = ring_buffer_read(&mic_data_rb, mic_temp_buff, MIC_FRAME_SIZE);
GLOBAL_INT_RESTORE();
if (count == MIC_FRAME_SIZE) {
send_agora_audio_frame(mic_temp_buff, count);
} else {
LOGD("ring_buffer_read count(%d) != MIC_FRAME_SIZE(160) \r\n", count);
}
psram_free(mic_temp_buff);
}
rtos_delay_milliseconds(10);
agora_aud_send_msg();
}
break;
case AUD_TRAS_EXIT:
LOGD("goto: AUD_TRAS_EXIT \r\n");
goto aud_tras_exit;
break;
default:
break;
}
}
}
aud_tras_exit:
ring_buffer_clear(&mic_data_rb);
if (mic_data_buffer) {
psram_free(mic_data_buffer);
mic_data_buffer = NULL;
}
/* delete msg queue */
ret = rtos_deinit_queue(&agora_aud_msg_que);
if (ret != kNoErr) {
LOGE("delete message queue fail \r\n");
}
agora_aud_msg_que = NULL;
LOGI("delete message queue complete \r\n");
/* delete task */
agora_aud_thread_hdl = NULL;
rtos_delete_thread(NULL);
}
bk_err_t audio_tras_init(void)
{
bk_err_t ret = BK_OK;
mic_data_buffer = psram_malloc(MIC_FRAME_SIZE * MIC_FRAME_NUM);
if (mic_data_buffer == NULL) {
LOGE("malloc mic_data_buffer fail \n");
return BK_FAIL;
}
ring_buffer_init(&mic_data_rb, mic_data_buffer, MIC_FRAME_SIZE*MIC_FRAME_NUM, DMA_ID_MAX, RB_DMA_TYPE_NULL);
ret = rtos_init_queue(&agora_aud_msg_que,
"aud_int_que",
sizeof(aud_tras_msg_t),
60);
if (ret != kNoErr) {
LOGE("ceate agoar audio tras message queue fail \r\n");
goto audio_tras_init_fail;
}
LOGI("ceate audio asr message queue complete \r\n");
/* create task to asr */
ret = rtos_create_thread(&agora_aud_thread_hdl,
4,
"agora_audio_tras",
(beken_thread_function_t)agora_aud_tras_main,
2048,
NULL);
if (ret != kNoErr) {
LOGE("create audio transfer driver task fail \r\n");
rtos_deinit_queue(&agora_aud_msg_que);
agora_aud_msg_que= NULL;
agora_aud_thread_hdl = NULL;
goto audio_tras_init_fail;
}
LOGI("create audio transfer driver task complete \r\n");
return BK_OK;
audio_tras_init_fail:
if (mic_data_buffer) {
ring_buffer_clear(&mic_data_rb);
psram_free(mic_data_buffer);
mic_data_buffer = NULL;
}
return BK_FAIL;
}
bk_err_t audio_tras_deinit(void)
{
bk_err_t ret;
aud_tras_msg_t msg;
msg.op = AUD_TRAS_EXIT;
if (agora_aud_msg_que) {
ret = rtos_push_to_queue_front(&agora_aud_msg_que, &msg, BEKEN_NO_WAIT);
if (kNoErr != ret) {
LOGE("audio send msg: AUD_TRAS_EXIT fail \r\n");
return kOverrunErr;
}
return ret;
}
return kNoResourcesErr;
}