299 lines
7.0 KiB
C
299 lines
7.0 KiB
C
![]() |
#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;
|
|||
|
}
|
|||
|
|
|||
|
|