251 lines
7.2 KiB
C
251 lines
7.2 KiB
C
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".dns_node.data.bss")
|
|
#pragma data_seg(".dns_node.data")
|
|
#pragma const_seg(".dns_node.text.const")
|
|
#pragma code_seg(".dns_node.text")
|
|
#endif
|
|
|
|
#include "jlstream.h"
|
|
#include "audio_config.h"
|
|
#include "media/audio_base.h"
|
|
#include "audio_ns.h"
|
|
#include "btstack/avctp_user.h"
|
|
#include "effects/effects_adj.h"
|
|
#include "frame_length_adaptive.h"
|
|
#include "app_config.h"
|
|
#include "overlay_code.h"
|
|
|
|
#if 1
|
|
#define ns_log printf
|
|
#else
|
|
#define ns_log(...)
|
|
#endif/*log_en*/
|
|
|
|
#if TCFG_DNS_NODE_ENABLE
|
|
|
|
extern void aec_code_movable_load(void);
|
|
extern void aec_code_movable_unload(void);
|
|
|
|
enum {
|
|
AUDIO_NS_TYPE_ESCO_DL = 1, //下行降噪类型
|
|
AUDIO_NS_TYPE_GENERAL, //通用类型
|
|
};
|
|
|
|
struct ns_cfg_t {
|
|
u8 ns_type;//降噪类型选择,通用降噪/通话下行降噪
|
|
u8 call_active_trigger;//接通电话触发标志, 只有通话下行降噪会使用
|
|
float aggressfactor; //降噪强度(越大越强:1~2)
|
|
float minsuppress; //降噪最小压制(越小越强:0~1)
|
|
float noiselevel; //初始噪声水平(评估初始噪声,加快收敛)
|
|
} __attribute__((packed));
|
|
|
|
struct dns_node_hdl {
|
|
u16 sr;
|
|
void *dns;
|
|
struct stream_frame *out_frame;
|
|
struct stream_node *node; //节点句柄
|
|
struct ns_cfg_t cfg;
|
|
struct frame_length_adaptive_hdl *olen_adaptive;//输出长度适配
|
|
};
|
|
|
|
extern int db2mag(int db, int dbQ, int magDQ);//10^db/20
|
|
int dns_param_cfg_read(struct stream_node *node)
|
|
{
|
|
struct ns_cfg_t config;
|
|
struct dns_node_hdl *hdl = (struct dns_node_hdl *)node->private_data;
|
|
int ret = 0;
|
|
if (!hdl) {
|
|
return -1 ;
|
|
}
|
|
/*
|
|
*获取配置文件内的参数,及名字
|
|
* */
|
|
ret = jlstream_read_node_data_new(NODE_UUID_DNS_NOISE_SUPPRESSOR, node->subid, (void *)&config, NULL);
|
|
if (ret != sizeof(config)) {
|
|
printf("%s, read node data err %d = %d\n", __FUNCTION__, ret, (int)sizeof(config));
|
|
return -1 ;
|
|
}
|
|
|
|
hdl->cfg = config;
|
|
|
|
ns_log("type %d\n", hdl->cfg.ns_type);
|
|
ns_log("call_active_trigger %d\n", hdl->cfg.call_active_trigger);
|
|
ns_log("aggressfactor %d/1000\n", (int)(hdl->cfg.aggressfactor * 1000.f));
|
|
ns_log("minsuppress %d/1000\n", (int)(hdl->cfg.minsuppress * 1000.f));
|
|
ns_log("noiselevel %d/1000\n", (int)(hdl->cfg.noiselevel * 1000.f));
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*节点输出回调处理,可处理数据或post信号量*/
|
|
static void dns_handle_frame(struct stream_iport *iport, struct stream_note *note)
|
|
{
|
|
struct dns_node_hdl *hdl = (struct dns_node_hdl *)iport->private_data;
|
|
struct stream_node *node = iport->node;
|
|
struct stream_frame *in_frame;
|
|
int wlen;
|
|
u8 trigger = 1;
|
|
int out_frame_len = 0;
|
|
|
|
out_frame_len = DNS_FRAME_SIZE;
|
|
|
|
while (1) {
|
|
in_frame = jlstream_pull_frame(iport, note); //从iport读取数据
|
|
if (!in_frame) {
|
|
break;
|
|
}
|
|
|
|
if (hdl->cfg.ns_type == AUDIO_NS_TYPE_ESCO_DL) {
|
|
if (hdl->cfg.call_active_trigger) {
|
|
if (bt_get_call_status() != BT_CALL_ACTIVE) {
|
|
trigger = 0;
|
|
}
|
|
}
|
|
}
|
|
if (trigger) {
|
|
/*接通的时候再开始做降噪*/
|
|
out_frame_len = in_frame->len > out_frame_len ? in_frame->len : out_frame_len;
|
|
if (!hdl->out_frame) {
|
|
hdl->out_frame = jlstream_get_frame(node->oport, out_frame_len);
|
|
if (!hdl->out_frame) {
|
|
jlstream_return_frame(iport, in_frame);
|
|
return;
|
|
}
|
|
}
|
|
wlen = audio_dns_run(hdl->dns, (s16 *)in_frame->data,
|
|
(s16 *)hdl->out_frame->data, in_frame->len);
|
|
|
|
if (!hdl->olen_adaptive) {
|
|
hdl->olen_adaptive = frame_length_adaptive_open(in_frame->len, out_frame_len);
|
|
}
|
|
int len = frame_length_adaptive_run(hdl->olen_adaptive, (s16 *)hdl->out_frame->data, (s16 *)hdl->out_frame->data, wlen);
|
|
|
|
if (len) {
|
|
hdl->out_frame->len = len;
|
|
jlstream_push_frame(node->oport, hdl->out_frame); //将数据推到oport
|
|
hdl->out_frame = NULL;
|
|
}
|
|
jlstream_free_frame(in_frame); //释放iport资源
|
|
} else {
|
|
jlstream_push_frame(node->oport, in_frame); //将数据推到oport
|
|
}
|
|
}
|
|
}
|
|
|
|
/*节点预处理-在ioctl之前*/
|
|
static int dns_adapter_bind(struct stream_node *node, u16 uuid)
|
|
{
|
|
struct dns_node_hdl *hdl = malloc(sizeof(*hdl));
|
|
|
|
memset(hdl, 0, sizeof(*hdl));
|
|
|
|
hdl->node = node;
|
|
node->private_data = hdl; //保存私有信息
|
|
dns_param_cfg_read(node);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*打开改节点输入接口*/
|
|
static void dns_ioc_open_iport(struct stream_iport *iport)
|
|
{
|
|
iport->handle_frame = dns_handle_frame; //注册输出回调
|
|
iport->private_data = iport->node->private_data; //保存节点私有句柄
|
|
}
|
|
|
|
/*节点参数协商*/
|
|
static int dns_ioc_negotiate(struct stream_iport *iport)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*节点start函数*/
|
|
static void dns_ioc_start(struct dns_node_hdl *hdl)
|
|
{
|
|
struct stream_fmt *fmt = &hdl->node->oport->fmt;
|
|
printf("dns node start");
|
|
|
|
dns_param_t param = {
|
|
.DNS_OverDrive = hdl->cfg.aggressfactor,
|
|
.DNS_GainFloor = hdl->cfg.minsuppress,
|
|
.DNS_NoiseLevel = hdl->cfg.noiselevel,
|
|
.DNS_highGain = 2.5f,
|
|
.DNS_rbRate = 0.3f,
|
|
.sample_rate = fmt->sample_rate,
|
|
};
|
|
overlay_load_code(OVERLAY_AEC);
|
|
aec_code_movable_load();
|
|
/*打开算法*/
|
|
hdl->dns = audio_dns_open(¶m);
|
|
}
|
|
|
|
/*节点stop函数*/
|
|
static void dns_ioc_stop(struct dns_node_hdl *hdl)
|
|
{
|
|
if (hdl->dns) {
|
|
audio_dns_close(hdl->dns);
|
|
hdl->dns = NULL;
|
|
aec_code_movable_unload();
|
|
}
|
|
if (hdl->olen_adaptive) {
|
|
frame_length_adaptive_close(hdl->olen_adaptive);
|
|
hdl->olen_adaptive = NULL;
|
|
}
|
|
if (hdl->out_frame) {
|
|
jlstream_free_frame(hdl->out_frame);
|
|
hdl->out_frame = NULL;
|
|
}
|
|
}
|
|
|
|
/*节点ioctl函数*/
|
|
static int dns_adapter_ioctl(struct stream_iport *iport, int cmd, int arg)
|
|
{
|
|
int ret = 0;
|
|
struct dns_node_hdl *hdl = (struct dns_node_hdl *)iport->private_data;
|
|
|
|
switch (cmd) {
|
|
case NODE_IOC_OPEN_IPORT:
|
|
dns_ioc_open_iport(iport);
|
|
break;
|
|
case NODE_IOC_NEGOTIATE:
|
|
*(int *)arg |= dns_ioc_negotiate(iport);
|
|
break;
|
|
case NODE_IOC_START:
|
|
dns_ioc_start(hdl);
|
|
break;
|
|
case NODE_IOC_SUSPEND:
|
|
case NODE_IOC_STOP:
|
|
dns_ioc_stop(hdl);
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*节点用完释放函数*/
|
|
static void dns_adapter_release(struct stream_node *node)
|
|
{
|
|
struct dns_node_hdl *hdl = (struct dns_node_hdl *)node->private_data;
|
|
if (!hdl) {
|
|
return;
|
|
}
|
|
free(hdl);
|
|
}
|
|
|
|
/*节点adapter 注意需要在sdk_used_list声明,否则会被优化*/
|
|
REGISTER_STREAM_NODE_ADAPTER(dns_node_adapter) = {
|
|
.name = "dns",
|
|
.uuid = NODE_UUID_DNS_NOISE_SUPPRESSOR,
|
|
.bind = dns_adapter_bind,
|
|
.ioctl = dns_adapter_ioctl,
|
|
.release = dns_adapter_release,
|
|
};
|
|
|
|
//注册工具在线调试
|
|
REGISTER_ONLINE_ADJUST_TARGET(dns_noise_suppressor) = {
|
|
.uuid = NODE_UUID_DNS_NOISE_SUPPRESSOR,
|
|
};
|
|
|
|
#endif/* TCFG_DNS_NODE_ENABLE*/
|
|
|