170 lines
5.3 KiB
C
170 lines
5.3 KiB
C
#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*/
|