CX20709四进两出带回声消除多路音频子板[AB33EP]的演示程序
AB33EP音频板简介
该音频板采用Conexant
的CX20709
芯片来实现。最大可以支持4路输入,2路输出,内置回声消除算法。CX20709
SoC 内置了集成的音频/语音数字信号处理器(digital signal processor
,DSP
)、多位编解码器、数字和模拟输入/输出接口,以及极具功效的 D 类放大器。其主要功能包括科胜讯专有的能显著改善音频和语音质量的技术创新。这包括 BrightSound
、全面的参数均衡、动态压缩、可优化扬声器频率响应并在没有削峰的情况下提高声音响亮度的数字交叉算法。其他功能还包括子带回声消除、波束成形、端到端降噪、线路回声消除、3D
幻影扬声器及 3D
虚拟浸没。
源程序
完整工程
https://gitee.com/LinkPi/Audio
https://gitee.com/LinkPi/Audio/wikis/pages
main.cpp
#include <QCoreApplication>
#include "Link.h"
#include "Audio.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Link::init();
Audio audio;
audio.init();
audio.startStream();
return a.exec();
}
Audio.cpp
#include "Audio.h"
#include "Json.h"
Audio::Audio(QObject *parent) : QObject(parent)
{
}
void Audio::init()
{
QVariantMap data;
main=Link::create("InputAi");
data["interface"]="main";
main->start(data);
omni=Link::create("InputAi");
data["interface"]="omni";
omni->start(data);
output=Link::create("OutputAo");
data["interface"]="output";
output->start(data);
// monitor=Link::create("OutputAo");
// data["interface"]="monitor";
// monitor->start(data);
mix=Link::create("MixA");
data.clear();
data["main"]=main->name();
mix->start(data);
mixOut=Link::create("MixA");
data.clear();
data["main"]=main->name();
mixOut->start(data);
volMain=Link::create("Volume");
volMain->start();
volOmni=Link::create("Volume");
volOmni->start();
volMix=Link::create("Volume");
volMix->start();
volRemote=Link::create("Volume");
volRemote->start();
volOut=Link::create("Volume");
volOut->start();
vad=Link::create("Vad");
data.clear();
data["volume"]=volMain->name();
vad->start(data);
main->linkA(mix);
main->linkA(mixOut);
omni->linkA(vad)->linkA(mix);
main->linkA(volMain);
vad->linkA(volOmni);
mix->linkA(volMix);
net=Link::create("InputNet");
QVariantMap dataNet;
dataNet["path"]="rtsp://192.168.1.43/stream0";
net->start(dataNet);
decA=Link::create("DecodeA");
decA->start();
gain=Link::create("Gain");
gain->start();
res=Link::create("Resample");
res->start();
net->linkA(decA)->linkA(gain)->linkA(res)->linkA(output);
res->linkA(volRemote);
res->linkA(mixOut);
res->linkA(mix);
mixOut->linkA(volOut);
rpcServer=new jcon::JsonRpcWebSocketServer();
QObjectList list;
list<<this;
rpcServer->registerServices(list);
rpcServer->listen(6002);
config=Json::loadFile("/link/config/audio/audio.json").toMap();
main->invoke("setDrvData",config);
}
void Audio::startStream()
{
LinkObject *vi=Link::create("InputVi");
QVariantMap dataVi;
dataVi["interface"]="HDMI-A";
vi->start(dataVi);
LinkObject *encV=Link::create("EncodeV");
encV->start();
LinkObject *encA1=Link::create("EncodeA");
encA1->start();
LinkObject *encA2=Link::create("EncodeA");
encA2->start();
LinkObject *rtsp=Link::create("Rtsp");
rtsp->start();
LinkObject *mux1=Link::create("Mux");
QVariantMap dataMux;
dataMux["path"]="mem://test1";
dataMux["format"]="rtsp";
mux1->start(dataMux);
LinkObject *mux2=Link::create("Mux");
dataMux["path"]="mem://test2";
mux2->start(dataMux);
LinkObject *ai1=mix;
LinkObject *ai2=omni;
vi->linkV(encV)->linkV(mux1)->linkV(rtsp);
encV->linkV(mux2)->linkV(rtsp);
ai1->linkA(encA1)->linkA(mux1)->linkA(rtsp);
ai2->linkA(encA2)->linkA(mux2)->linkA(rtsp);
}
QVariantMap Audio::getVolume()
{
QVariantMap data;
data["Main"]=volMain->invoke("getVolume").toMap()["max"].toInt();
data["Omni"]=volOmni->invoke("getVolume").toMap()["max"].toInt();
data["Output"]=volOut->invoke("getVolume").toMap()["max"].toInt();
data["remote"]=volRemote->invoke("getVolume").toMap()["max"].toInt();
// qDebug()<<vad->getData()["active"].toBool();
if(vad->getData()["active"].toBool() || !vad->getData()["enable"].toBool())
data["active"]="main";
else
data["active"]="omni";
return data;
}
QVariantMap Audio::getAudio()
{
return config;
}
bool Audio::setAudio(QVariantMap cfg)
{
config=cfg;
Json::saveFile(config,"/link/config/audio/audio.json");
main->invoke("setDrvData",config);
QVariantMap dataOut=cfg["output"].toMap();
{
QVariantMap vol;
vol["mute"]=dataOut["mute0"].toBool();
vol["gain"]=dataOut["gain0"].toInt();
volOut->setData(vol);
}
QVariantMap dataMain=cfg["main"].toMap();
{
QVariantMap dataVad;
dataVad["level"]=4*dataMain["vad"].toInt();
dataVad["th"]=dataMain["vadth"].toInt();
if(dataMain["vad"].toInt()==0)
dataVad["enable"]=false;
else
dataVad["enable"]=true;
vad->setData(dataVad);
}
QVariantMap rem=cfg["remote"].toMap();
{
QVariantMap dataGain;
dataGain["mute"]=rem["mute"].toBool();
dataGain["gain"]=rem["gain"].toInt();
gain->setData(dataGain);
}
return true;
}
AB33EP外观
接口定义
内部定义
演示程序使用方法
- 登陆评估板后台网页
- 手动访问
/fac.php
将系统切换为lite_audio
类型,重启系统
- 再次登陆评估板后台网页
- 手动访问
/demo/audio.php
- 在该页面可以获取到各通道的音量,以及进行相关的设置。具体业务逻辑请查看程序及
web
源码。 - 所有输入的混音编码可以通过
rtsp://IP/test1
收听,单独麦克风输入的编码可以通过rtsp://IP/test2
收听 - 注意事项: 程序中调用
rtsp://192.168.1.43/stream0
的音频作为远端音源,您需要按照实际测试环境修改代码中的url
地址
芯片内部配置方法
- 自定义配置
- 解压网盘开发资料如下目录的压缩包:
'开发文档\公共资料\配件\AB33EP\Cx2070XEVK_v5.06.0.0a + FW_5.05.rar'
- 执行
Setup.exe
进行安装 - 连接音频板的
micro usb
口到pc
主机 - 运行
Cx2070X SPoC Configuration Toolbox
程序
- 点击
"finish"
- 进入配置页面
- 配置好之后,点击如下按钮将配置写入芯片
- 恢复配置
- 将资料中的
'开发文档\公共资料\配件\AB33EP\linkpi.f3cfg'
拷贝到'我的文档\Conexant'
- 选择
linkpi
配置,并导入,如下图
- 配置写入芯片