first
This commit is contained in:
169
cpu/br28/audio_hearing/audio_sidetone.c
Normal file
169
cpu/br28/audio_hearing/audio_sidetone.c
Normal file
@ -0,0 +1,169 @@
|
||||
#include "generic/typedef.h"
|
||||
#include "board_config.h"
|
||||
#include "media/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "sound_device.h"
|
||||
#include "audio_sidetone.h"
|
||||
#include "system/task.h"
|
||||
|
||||
#if TCFG_SIDETONE_ENABLE
|
||||
|
||||
extern struct audio_dac_hdl dac_hdl;
|
||||
#define SIDETONE_BUF_LEN 256
|
||||
#define SIDETONE_READBUF_LEN 64 //中断点数设为32,则每次数据长度为64
|
||||
static struct audio_sidetone_hdl {
|
||||
s16 *sidetone_buf;
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
s16 *sidetone_buf_lr;
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
cbuffer_t cbuf;
|
||||
OS_SEM sem;
|
||||
bool busy; //检测任务是否在阻塞态
|
||||
bool suspend; //暂停监听
|
||||
struct audio_dac_channel dac_ch;
|
||||
struct audio_dac_channel_attr attr;
|
||||
};
|
||||
static struct audio_sidetone_hdl *sidetone_hdl = NULL;
|
||||
|
||||
static inline void audio_pcm_mono_to_dual(s16 *dual_pcm, s16 *mono_pcm, int points)
|
||||
{
|
||||
s16 *mono = mono_pcm;
|
||||
int i = 0;
|
||||
u8 j = 0;
|
||||
|
||||
for (i = 0; i < points; i++, mono++) {
|
||||
*dual_pcm++ = *mono;
|
||||
*dual_pcm++ = *mono;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_sidetone_task(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
sidetone_hdl = zalloc(sizeof(struct audio_sidetone_hdl));
|
||||
if (!sidetone_hdl) {
|
||||
printf("zalloc sidetone_hdl err\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sidetone_hdl->suspend = 1;
|
||||
sidetone_hdl->sidetone_buf = zalloc(SIDETONE_BUF_LEN);
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
sidetone_hdl->sidetone_buf_lr = zalloc(SIDETONE_READBUF_LEN * 2);
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
cbuf_init(&sidetone_hdl->cbuf, sidetone_hdl->sidetone_buf, SIDETONE_BUF_LEN);
|
||||
os_sem_create(&sidetone_hdl->sem, 0);
|
||||
|
||||
audio_dac_new_channel(&dac_hdl, &sidetone_hdl->dac_ch);
|
||||
sidetone_hdl->attr.delay_time = 6;
|
||||
sidetone_hdl->attr.protect_time = 8;
|
||||
sidetone_hdl->attr.write_mode = WRITE_MODE_BLOCK;
|
||||
audio_dac_channel_set_attr(&sidetone_hdl->dac_ch, &sidetone_hdl->attr);
|
||||
sound_pcm_dev_start(&sidetone_hdl->dac_ch, 16000, app_audio_get_volume(APP_AUDIO_STATE_CALL));
|
||||
|
||||
while (1) {
|
||||
sidetone_hdl->busy = 0;
|
||||
os_sem_pend(&sidetone_hdl->sem, 0);
|
||||
sidetone_hdl->busy = 1;
|
||||
u16 rlen = cbuf_read(&sidetone_hdl->cbuf, sidetone_hdl->sidetone_buf, SIDETONE_READBUF_LEN);
|
||||
if (rlen != SIDETONE_READBUF_LEN) {
|
||||
printf("rlen err : %d\n", rlen);
|
||||
}
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
audio_pcm_mono_to_dual(sidetone_hdl->sidetone_buf_lr, sidetone_hdl->sidetone_buf, rlen >> 1);
|
||||
u16 wlen = sound_pcm_dev_write(&sidetone_hdl->dac_ch, sidetone_hdl->sidetone_buf_lr, rlen <<= 1);
|
||||
#else
|
||||
u16 wlen = sound_pcm_dev_write(&sidetone_hdl->dac_ch, sidetone_hdl->sidetone_buf, rlen);
|
||||
#endif
|
||||
if (wlen != rlen) {
|
||||
printf("wlen err : %d\n", wlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Inbuf
|
||||
* Description: 通话监听数据流输入
|
||||
* Arguments : data 输入数据地址
|
||||
* len 输入数据长度
|
||||
* Return : None.
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
void audio_sidetone_inbuf(s16 *data, u16 len)
|
||||
{
|
||||
if (sidetone_hdl && sidetone_hdl->suspend) {
|
||||
os_sem_post(&sidetone_hdl->sem);
|
||||
u16 wlen = cbuf_write(&sidetone_hdl->cbuf, data, len);
|
||||
if (wlen != len) {
|
||||
printf("wlen = %d, len = %d\n", wlen, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Open
|
||||
* Description: 打开通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_open(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
task_create(audio_sidetone_task, NULL, "sidetone");//创建监听任务
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Close
|
||||
* Description: 关闭通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_close(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
printf("sidetone already close\n");
|
||||
return -1;
|
||||
}
|
||||
if (!sidetone_hdl->busy) { //任务处于挂起态
|
||||
sound_pcm_dev_stop(&sidetone_hdl->dac_ch); //关闭监听
|
||||
task_kill("sidetone");
|
||||
free(sidetone_hdl->sidetone_buf);
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
free(sidetone_hdl->sidetone_buf_lr);
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
free(sidetone_hdl);
|
||||
sidetone_hdl = NULL;
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Suspend
|
||||
* Description: 暂停通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_suspend(void)
|
||||
{
|
||||
if (sidetone_hdl) {
|
||||
sidetone_hdl->suspend ? (sidetone_hdl->suspend = 0) : (sidetone_hdl->suspend = 1);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif/*TCFG_SIDETONE_ENABLE*/
|
||||
Reference in New Issue
Block a user