初版
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".agc_node.data.bss")
|
||||
#pragma data_seg(".agc_node.data")
|
||||
#pragma const_seg(".agc_node.text.const")
|
||||
#pragma code_seg(".agc_node.text")
|
||||
#endif
|
||||
#include "jlstream.h"
|
||||
#include "app_config.h"
|
||||
#include "audio_config.h"
|
||||
#include "effects/effects_adj.h"
|
||||
#include "frame_length_adaptive.h"
|
||||
#include "audio_agc.h"
|
||||
|
||||
|
||||
#if 1
|
||||
#define agc_log printf
|
||||
#else
|
||||
#define agc_log(...)
|
||||
#endif/*log_en*/
|
||||
|
||||
#define AGC_FRAME_SIZE 128
|
||||
|
||||
#if TCFG_AGC_NODE_ENABLE
|
||||
|
||||
struct agc_cfg_t {
|
||||
float AGC_max_lvl; //最大幅度压制,range[0 : -90] dB
|
||||
float AGC_fade_in_step; //淡入步进,range[0.1 : 5] dB
|
||||
float AGC_fade_out_step; //淡出步进,range[0.1 : 5] dB
|
||||
float AGC_max_gain; //放大上限, range[-90 : 40] dB
|
||||
float AGC_min_gain; //放大下限, range[-90 : 40] dB
|
||||
float AGC_speech_thr; //放大阈值, range[-70 : -40] dB
|
||||
} __attribute__((packed));
|
||||
|
||||
struct agc_node_hdl {
|
||||
u16 sr;
|
||||
void *agc;
|
||||
struct stream_frame *out_frame;
|
||||
struct stream_node *node; //节点句柄
|
||||
agc_param_t parm;
|
||||
struct frame_length_adaptive_hdl *olen_adaptive;//输出长度适配
|
||||
};
|
||||
|
||||
int agc_param_cfg_read(struct stream_node *node)
|
||||
{
|
||||
struct agc_cfg_t config;
|
||||
struct agc_node_hdl *hdl = (struct agc_node_hdl *)node->private_data;
|
||||
if (!hdl) {
|
||||
return -1 ;
|
||||
}
|
||||
/*
|
||||
*获取配置文件内的参数,及名字
|
||||
* */
|
||||
if (!jlstream_read_node_data_new(NODE_UUID_AGC, node->subid, (void *)&config, NULL)) {
|
||||
printf("%s, read node data err\n", __FUNCTION__);
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
memcpy(&hdl->parm, &config, sizeof(config));
|
||||
|
||||
agc_log("AGC_max_lvl %d/10\n", (int)(hdl->parm.AGC_max_lvl * 10));
|
||||
agc_log("AGC_fade_in_step %d/10\n", (int)(hdl->parm.AGC_fade_in_step * 10));
|
||||
agc_log("AGC_fade_out_step %d/10\n", (int)(hdl->parm.AGC_fade_out_step * 10));
|
||||
agc_log("AGC_max_gain %d/10\n", (int)(hdl->parm.AGC_max_gain * 10));
|
||||
agc_log("AGC_min_gain %d/10\n", (int)(hdl->parm.AGC_min_gain * 10));
|
||||
agc_log("AGC_speech_thr %d/10\n", (int)(hdl->parm.AGC_speech_thr * 10));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*节点输出回调处理,可处理数据或post信号量*/
|
||||
static void agc_handle_frame(struct stream_iport *iport, struct stream_note *note)
|
||||
{
|
||||
struct agc_node_hdl *hdl = (struct agc_node_hdl *)iport->private_data;
|
||||
struct stream_node *node = iport->node;
|
||||
struct stream_frame *in_frame;
|
||||
int wlen;
|
||||
|
||||
while (1) {
|
||||
in_frame = jlstream_pull_frame(iport, note); //从iport读取数据
|
||||
if (!in_frame) {
|
||||
break;
|
||||
}
|
||||
int out_frame_len = in_frame->len > (hdl->parm.AGC_frame_size << 1) ?
|
||||
in_frame->len : (hdl->parm.AGC_frame_size << 1);
|
||||
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_agc_run(hdl->agc, (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资源
|
||||
}
|
||||
}
|
||||
|
||||
/*节点预处理-在ioctl之前*/
|
||||
static int agc_adapter_bind(struct stream_node *node, u16 uuid)
|
||||
{
|
||||
struct agc_node_hdl *hdl = zalloc(sizeof(*hdl));
|
||||
|
||||
hdl->node = node;
|
||||
node->private_data = hdl; //保存私有信息
|
||||
agc_param_cfg_read(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*打开改节点输入接口*/
|
||||
static void agc_ioc_open_iport(struct stream_iport *iport)
|
||||
{
|
||||
iport->handle_frame = agc_handle_frame; //注册输出回调
|
||||
iport->private_data = iport->node->private_data; //保存节点私有句柄
|
||||
}
|
||||
|
||||
/*节点参数协商*/
|
||||
static int agc_ioc_negotiate(struct stream_iport *iport)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*节点start函数*/
|
||||
static void agc_ioc_start(struct agc_node_hdl *hdl)
|
||||
{
|
||||
struct stream_fmt *fmt = &hdl->node->oport->fmt;
|
||||
hdl->parm.AGC_samplerate = fmt->sample_rate;
|
||||
hdl->parm.AGC_frame_size = AGC_FRAME_SIZE;
|
||||
agc_log("AGC_samplerate : %d", hdl->parm.AGC_samplerate);
|
||||
agc_log("AGC_frame_size : %d", hdl->parm.AGC_frame_size);
|
||||
hdl->agc = audio_agc_open(&hdl->parm);
|
||||
}
|
||||
|
||||
/*节点stop函数*/
|
||||
static void agc_ioc_stop(struct agc_node_hdl *hdl)
|
||||
{
|
||||
if (hdl->agc) {
|
||||
audio_agc_close(hdl->agc);
|
||||
hdl->agc = NULL;
|
||||
}
|
||||
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 agc_adapter_ioctl(struct stream_iport *iport, int cmd, int arg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct agc_node_hdl *hdl = (struct agc_node_hdl *)iport->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case NODE_IOC_OPEN_IPORT:
|
||||
agc_ioc_open_iport(iport);
|
||||
break;
|
||||
case NODE_IOC_NEGOTIATE:
|
||||
*(int *)arg |= agc_ioc_negotiate(iport);
|
||||
break;
|
||||
case NODE_IOC_START:
|
||||
agc_ioc_start(hdl);
|
||||
break;
|
||||
case NODE_IOC_SUSPEND:
|
||||
case NODE_IOC_STOP:
|
||||
agc_ioc_stop(hdl);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*节点用完释放函数*/
|
||||
static void agc_adapter_release(struct stream_node *node)
|
||||
{
|
||||
struct agc_node_hdl *hdl = (struct agc_node_hdl *)node->private_data;
|
||||
if (!hdl) {
|
||||
return;
|
||||
}
|
||||
free(hdl);
|
||||
}
|
||||
|
||||
/*节点adapter 注意需要在sdk_used_list声明,否则会被优化*/
|
||||
REGISTER_STREAM_NODE_ADAPTER(agc_node_adapter) = {
|
||||
.name = "agc",
|
||||
.uuid = NODE_UUID_AGC,
|
||||
.bind = agc_adapter_bind,
|
||||
.ioctl = agc_adapter_ioctl,
|
||||
.release = agc_adapter_release,
|
||||
};
|
||||
|
||||
//注册工具在线调试
|
||||
REGISTER_ONLINE_ADJUST_TARGET(agc_process) = {
|
||||
.uuid = NODE_UUID_AGC,
|
||||
};
|
||||
|
||||
#endif /*TCFG_AGC_NODE_ENABLE*/
|
||||
|
||||
Reference in New Issue
Block a user