/*
|
* audioproc.c
|
*
|
* Created on: 2021Äê11ÔÂ2ÈÕ
|
* Author: graydon
|
*/
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <heapnew>
|
#include "tob.h"
|
#include "crc.h"
|
#include "config.h"
|
#include "protocol_internal.h"
|
#include "IModule.h"
|
#include "f2f.h"
|
#include "../drv/memory.h"
|
|
|
|
//#define DEBUG
|
#ifdef DEBUG
|
#define dbg_printf printf
|
#else
|
#define dbg_printf
|
#endif
|
|
//static ToB* tob = NULL;
|
|
//ToB* ToB::GetInstance()
|
//{
|
// return tob;
|
//}
|
|
ToB::ToB(ubool dualDsp, u32 dspIndex )
|
: dual_dsp(dualDsp), dsp_index(dspIndex)
|
{
|
// if(tob != NULL) {
|
// delete tob;
|
// }
|
// tob = this;
|
frames = nullptr;
|
processed = ufalse;
|
mModuleNum =0;
|
mModuleIndex.resize(0);
|
paramset = new(SRAM_DDR) tg_param_ctrl_t();
|
}
|
|
ToB::~ToB()
|
{
|
toClear();
|
// tob = NULL;
|
delete paramset;
|
}
|
|
uvoid ToB::SetMute(ubool mute)
|
{
|
processed = (mute==0);
|
}
|
ErrStatus ToB::toClear()
|
{
|
processed = ufalse;
|
int i = 0;
|
|
// for (std::vector<IModule*>::iterator iter = mList.begin(); iter != mList.end(); iter++, ++i) {
|
// delete *iter;
|
// *iter = nullptr;
|
// }
|
for (auto iter : mList) {
|
delete iter;
|
iter = nullptr;
|
}
|
|
mList.clear();
|
mModuleIndex.clear();
|
|
if(frames != NULL) {
|
delete frames;
|
frames = nullptr;
|
}
|
mModuleNum = 0;
|
|
return ErrStatus::SUCCESS;
|
}
|
|
IModule* ToB::CreateBaseModule(u32 moduleType, u16 tag ,u16 rxNum, u16 txNum)
|
{
|
ExportModules& em = ExportModules::Instance();
|
ModuleEntry* entry = em.GetModuleEntry(moduleType);
|
if (entry) {
|
Create create = entry->GetEntry();
|
if (create) {
|
return create(tag, entry->link_enable , SAMPLE_RATE, SAMPLE_NUM, rxNum, txNum);
|
}
|
}
|
return 0;//new IModule(SAMPLE_RATE, SAMPLE_NUM, rxNum, txNum);
|
}
|
|
ErrStatus ToB::CreateModule(const u8* bin, u32 nbytes)
|
{
|
FlowChartHead* head = (FlowChartHead*)bin;
|
//dbg_printf("modules num %d, DSP1 Buffer %d,DSP2 Buffer %d.\n"
|
// ,head->module_num,head->dsp1_buffer_num,head->dsp2_buffer_num);
|
|
u32 size = sizeof(FlowChartHead);
|
u32 nPhyInput =0 ,nPhyOutput=0;
|
frames = new Frames(head->dsp_buffer_num[dsp_index]);
|
|
do {
|
Module* pmod = (Module*)(bin+ size);
|
size += sizeof(Module);
|
u16* mRxbufID = (u16*)(bin + size); size += pmod->mRxNum * sizeof(u16);
|
u16* mTxbufID = (u16*)(bin + size); size += pmod->mTxNum * sizeof(u16);
|
u16* mPhyID ;
|
ubool bInput=ufalse,bOutput=ufalse;
|
u16 input_num =0 ,output_num =0;
|
|
if(pmod->mPhyModule == ModuleInterfaceType::PHY_INPUT){
|
pmod->mRxNum = pmod->mTxNum;
|
mPhyID = (u16*)(bin + size); size += pmod->mTxNum * sizeof(u16);
|
bInput = utrue;
|
}
|
else if(pmod->mPhyModule == ModuleInterfaceType::PHY_OUTPUT){
|
pmod->mTxNum = pmod->mRxNum ;
|
mPhyID = (u16*)(bin + size); size += pmod->mRxNum * sizeof(u16);
|
bOutput = utrue;
|
}
|
else {
|
mPhyID = NULL;
|
}
|
|
if (pmod->mDsp != dsp_index) continue;
|
|
#ifdef DEBUG
|
dbg_printf("Module ID %d type %d rxnum %d txnum %d. \n",pmod->mID ,pmod->mType, pmod->mRxNum,pmod->mTxNum);
|
#endif
|
// if(pmod->mID == 394) {
|
// int ddr = sram_free_space(SRAM_DDR);
|
// int ccm = sram_free_space(SRAM_CCM);
|
// int l1 = sram_free_space(SRAM_L1);
|
// printf("ddr %d ccm %d l1 %d.\n",ddr, ccm ,l1);
|
// }
|
IModule* m = CreateBaseModule(pmod->mType,pmod->mTag, pmod->mRxNum,pmod->mTxNum);
|
if(!m) {
|
dbg_printf("Module ID Create fail.\n", pmod->mID);
|
continue;
|
}
|
|
m->SetModuleInfo(pmod->mID ,pmod->mType,pmod->mTag);
|
mList.push_back(m);
|
|
if(pmod->mID >= mModuleIndex.size()) {
|
mModuleIndex.resize(pmod->mID + 1, 0);
|
}
|
mModuleIndex[pmod->mID] = ++mModuleNum ;
|
|
for (size_t i = 0; i < pmod->mTxNum && !bOutput; i++){
|
if (mTxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mTxbufID[i]-1 );
|
m->SetOutputChannelDataPtr(i, pcm);
|
|
if (bInput) {
|
if(nPhyInput < mPhyID[i]) nPhyInput = mPhyID[i];
|
m->SetInputChannelDataPtr(i, pcm);
|
SetRxChannelPtr(IntDataType::TDM , mPhyID[i]-1, pcm->Data());
|
}
|
output_num ++;
|
}
|
else {
|
m->SetOutputChannelDataPtr(i, 0);
|
}
|
}
|
for (size_t i = 0; i < pmod->mRxNum && !bInput; i++) {
|
if (mRxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mRxbufID[i]-1 );
|
m->SetInputChannelDataPtr(i, pcm);
|
|
if (bOutput) {
|
if(nPhyOutput < mPhyID[i]) nPhyOutput = mPhyID[i];
|
|
pcm = frames->AllocFrame();
|
m->SetOutputChannelDataPtr(i, pcm);
|
SetTxChannelPtr(IntDataType::TDM , mPhyID[i]-1, pcm->Data());
|
}
|
input_num ++;
|
}
|
else {
|
m->SetInputChannelDataPtr(i, 0);
|
}
|
}
|
|
m->Init();
|
} while (size < nbytes);
|
|
if (size != nbytes) {
|
dbg_printf("check flowchart some error!\n");
|
}
|
// dbg_printf("Phy InputNum %d, Output Num %d\n",nPhyInput,nPhyOutput);
|
SetNumOfChannels(IntDataType::TDM , nPhyInput, nPhyOutput);
|
|
return ErrStatus::SUCCESS;
|
}
|
#define DEBUG 0
|
#if 1//DEBUG
|
const s8* type_string[ModuleType::PROC_COUNT] = {
|
"none"
|
,"input"
|
,"meter"
|
,"peq"
|
,"expander"
|
,"compresser"
|
,"limiter"
|
,"mixer"
|
,"delay"
|
,"crossover"
|
,"output"
|
,"gain"
|
,"nhs"
|
,"gain sharing am"
|
,"agc"
|
,"aec"
|
,"ans"
|
,"sysctrl"
|
,"shelf"
|
,"selector"
|
,"gating am"
|
,"spl"
|
,"gating"
|
,"ducker"
|
,"reverb"
|
,"echo"
|
,"geq"
|
,"fir"
|
,"afc"
|
,"signal gen"
|
,"pitch"
|
,"route"
|
,"dummuy input"
|
,"dummy output"
|
};
|
#endif
|
ErrStatus ToB::CreateModuleV1(const u8* bin, u32 nbytes)
|
{
|
FlowChartHead* head = (FlowChartHead*)bin;
|
u32 size = sizeof(FlowChartHead);
|
u16 nPhyInput[IntDataType::COUNT] = { 0,0,0 }, nPhyOutput[IntDataType::COUNT] = { 0,0,0 };
|
s32 len =0;
|
frames = new Frames(head->dsp_buffer_num[dsp_index]);
|
|
do {
|
const Module* pmod = (Module*)(bin+ size); size += sizeof(Module);
|
const u16* mRxbufID = (u16*)(bin + size); size += pmod->mRxNum * sizeof(u16);
|
const u16* mTxbufID = (u16*)(bin + size); size += pmod->mTxNum * sizeof(u16);
|
PhyPort* mPhyID;
|
ubool bInput=ufalse,bOutput=ufalse;
|
u16 mRxNum = pmod->mRxNum, mTxNum = pmod->mTxNum;
|
|
if(pmod->mPhyModule == ModuleInterfaceType::PHY_INPUT){
|
mRxNum = pmod->mTxNum;
|
mPhyID = (PhyPort*)(bin + size); size += pmod->mTxNum * sizeof(PhyPort);
|
bInput = utrue;
|
}
|
else if(pmod->mPhyModule == ModuleInterfaceType::PHY_OUTPUT){
|
mTxNum = pmod->mRxNum ;
|
mPhyID = (PhyPort*)(bin + size); size += pmod->mRxNum * sizeof(PhyPort);
|
bOutput = utrue;
|
}
|
else {
|
mPhyID = NULL;
|
}
|
|
if (pmod->mDsp != dsp_index) continue;
|
|
#if DEBUG
|
//if (PROC_FIR == pmod->mType)
|
printf("Module ID %d type %d %s rxnum %d txnum %d tag %d. \n",pmod->mID ,pmod->mType, type_string[pmod->mType], pmod->mRxNum,pmod->mTxNum,pmod->mTag);
|
#endif
|
|
IModule* m = CreateBaseModule(pmod->mType, pmod->mTag, mRxNum, mTxNum);
|
if(!m) {
|
dbg_printf("Module ID Create fail.\n", pmod->mID);
|
continue;
|
}
|
|
m->SetModuleInfo(pmod->mID ,pmod->mType, pmod->mTag);
|
mList.push_back(m);
|
|
if(pmod->mID >= mModuleIndex.size()) {
|
mModuleIndex.resize(pmod->mID + 1, 0);
|
}
|
mModuleIndex[pmod->mID] = ++mModuleNum;
|
|
// printf("Module id:%d, Tx buffer id:", pmod->mID);
|
for (size_t i = 0; i < mTxNum && !bOutput; i++){
|
// printf("bid %d, ", mTxbufID[i]);
|
if (mTxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mTxbufID[i]-1);
|
m->SetOutputChannelDataPtr(i, pcm);
|
|
if (bInput && mPhyID[i].mIntType < IntDataType::COUNT) {
|
if(nPhyInput[mPhyID[i].mIntType] < mPhyID[i].mPhyID)
|
nPhyInput[mPhyID[i].mIntType] = mPhyID[i].mPhyID;
|
m->SetInputChannelDataPtr(i, pcm);
|
SetRxChannelPtr(static_cast<IntDataType>(mPhyID[i].mIntType), mPhyID[i].mPhyID-1, pcm->Data());
|
// printf("phy_id %d\n", mPhyID[i].mPhyID);
|
}
|
}
|
else {
|
m->SetOutputChannelDataPtr(i, 0);
|
}
|
}
|
// printf(";Rx buffer id:");
|
for (size_t i = 0; i < mRxNum && !bInput; i++) {
|
// printf("mID %d,bid %d\n", pmod->mID, mRxbufID[i]);
|
if (mRxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mRxbufID[i]-1 );
|
m->SetInputChannelDataPtr(i, pcm);
|
|
if (bOutput && mPhyID[i].mIntType < IntDataType::COUNT) {
|
if(nPhyOutput[mPhyID[i].mIntType] < mPhyID[i].mPhyID)
|
nPhyOutput[mPhyID[i].mIntType] = mPhyID[i].mPhyID;
|
|
//pcm = frames->AllocFrame(); // It is not necessary to be compatible with the AXE1208 series here, because the TOP architecture is different.
|
m->SetOutputChannelDataPtr(i, pcm);
|
SetTxChannelPtr(static_cast<IntDataType>(mPhyID[i].mIntType), mPhyID[i].mPhyID-1, pcm->Data());
|
// printf("mID %d,bid %d\n", pmod->mID, mPhyID[i].mPhyID-1);
|
// printf("phy_type %d, _id %d\n", mPhyID[i].mIntType, mPhyID[i].mPhyID);
|
}
|
}
|
else {
|
m->SetInputChannelDataPtr(i, 0);
|
}
|
}
|
// printf("\n");
|
|
m->Init();
|
|
// ´Ó paramset ÖлñÈ¡¶ÔÓ¦µÄ²ÎÊý¿ØÖƺ¯ÊýÖ¸Õë
|
ParamCtrl_fn paramEntry = paramset->GetParamEntry( m->GetModuleType());
|
if(paramEntry == NULL) {
|
printf("paramEntry is NULL!\n");
|
}
|
// µ÷ÓòÎÊý¿ØÖƺ¯Êý
|
u32 result = paramEntry(m, (uvoid*)pmod->mParamaddr, len);
|
|
} while (size < nbytes);
|
|
// int ddr = sram_free_space(SRAM_DDR,mem_any);
|
// int ccm = sram_free_space(SRAM_L2,mem_any);
|
// int l1 = sram_free_space(SRAM_L1,mem_heap);
|
// printf("mListAdd:0x%x, ddr %d ccm %d l1 %d.\n", &mList, ddr, ccm ,l1);
|
|
//for (auto pl : mList) {
|
// delete pl;
|
// int l2mem = sram_free_space(SRAM_L2, mem_any);
|
// printf("L2mem %d\n", l2mem);
|
//}
|
|
if (size != nbytes) {
|
dbg_printf("check flowchart some error!\n");
|
}
|
|
for(s32 i =0 ;i < IntDataType::COUNT;i++){
|
SetNumOfChannels(static_cast<IntDataType>(i) , nPhyInput[i], nPhyOutput[i]);
|
}
|
|
/*for (auto pt = mList.begin(); pt < mList.end(); pt++) {
|
IModule *p = *pt._Myptr;
|
static int i = 0;
|
printf("%d, id %d, type %d\n",i++, p->GetModuleID(), p->GetModuleType());
|
}*/
|
|
return ErrStatus::SUCCESS;
|
}
|
ErrStatus ToB::toAnalysis(const u8* bin, u32 nbytes)
|
{
|
FlowChartHead* head = (FlowChartHead*)bin;
|
ErrStatus ret = ErrStatus::ERR_METHOD;
|
//check crc
|
s32 tmp_crc;
|
s32 crc = head->crc;
|
head->crc = 0;
|
tmp_crc = CRC::crc32(bin, nbytes);
|
if (tmp_crc != crc) {
|
printf("flowchar crc check fail.\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
processed = ufalse;
|
|
if(head->version == 0) {
|
ret = CreateModule(bin, nbytes);
|
}
|
else if(head->version == 1) {
|
ret = CreateModuleV1(bin, nbytes);
|
}
|
processed = utrue;
|
return ret;
|
}
|
ErrStatus ToB::toProc()
|
{
|
if(processed) {
|
for (auto iter = mList.begin(); iter < mList.end(); iter++) {
|
// if(((*iter)->GetModuleType() >= 6) && ((*iter)->GetModuleType() <= 6)) {
|
// printf("%d ", (*iter)->GetModuleID());
|
(*iter)->Proc();
|
// }
|
}
|
// printf("\n");
|
}
|
else {
|
MuteOutput();
|
}
|
return ErrStatus::SUCCESS;
|
}
|
|
u32 ToB::GetModuleType(u32 mID)
|
{
|
if(mID >= mModuleIndex.size() || mModuleIndex[mID] == 0) {
|
return ErrStatus::ERR_PARAM;
|
}
|
IModule* m = mList[mModuleIndex[mID]-1];
|
if( m != NULL) {
|
return m->GetModuleType();
|
}
|
return 0;
|
}
|
|
/*ErrStatus ToB::toCtrl(u32 mID, u32 pID, const s16* val, u32 num)
|
{
|
if(mID >= mModuleIndex.size() || mModuleIndex[mID] == 0) {
|
printf("ToB::toCtrl mID Error!\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
|
IModule* m = mList[mModuleIndex[mID]-1];
|
if(!m) {
|
printf("ToB::toCtrl m Error!\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
|
auto entries = paramset->GetEntries(m->GetModuleType());
|
if(!entries.second) {
|
printf("ToB::toCtrl entries Error!\n");
|
return ErrStatus::ERR_METHOD;
|
}
|
|
entries.second(m, pID, const_cast<s16*>(val), num);
|
return ErrStatus::SUCCESS;
|
}*/
|
ErrStatus ToB::toCtrl(u32 mID, u32 pID, const s16* val, u32 num)
|
{
|
if(mID >= mModuleIndex.size() || mModuleIndex[mID] == 0) {
|
return ErrStatus::ERR_PARAM;
|
}
|
|
IModule* m = mList[mModuleIndex[mID]-1];
|
if( m != NULL) {
|
// m->Ctrl(pID, val, num);
|
paramset->GetCtrlEntry(m->GetModuleType())(m, pID, (s16*)val, num);
|
}
|
// printf("mID:%d pID:%d val[0]:%d val[1]:%d\n",mID, pID, val[0], val[1]);
|
return ErrStatus::SUCCESS;
|
}
|
|
ErrStatus ToB::toCtrl(const u8* bin , u32 nbytes)
|
{
|
FlowChartHead* head = (FlowChartHead*)bin;
|
|
//check crc
|
u32 tmp_crc ,crc = head->crc;
|
head->crc =0;
|
tmp_crc = CRC::crc32(bin, nbytes);
|
if (tmp_crc != crc) {
|
dbg_printf("flowchar crc check fail.\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
|
u32 size = sizeof(FlowChartHead);
|
|
while(size < nbytes) {
|
Param* h = (Param*)(bin+size);
|
size += sizeof(Param);
|
const s16* val = (const s16*)(bin+size);
|
|
toCtrl(h->mID, h->pID, val, h->num);
|
size += h->num*sizeof(s16);
|
}
|
|
if(size != nbytes) {
|
dbg_printf("check preset has some error!\n");
|
}
|
|
processed = utrue;
|
return ErrStatus::SUCCESS;
|
}
|
|
|
u32 ToB::GetLevels(s16* buffer)
|
{
|
u32 n =0,size =0;
|
|
if( !processed ) {
|
return 0;
|
}
|
for (std::vector<IModule*>::iterator iter = mList.begin();
|
iter != mList.end() ; iter++) {
|
size = (*iter)->GetLevel(buffer + n );
|
// printf("proc %s level num:%d\n",type_string[(*iter)->GetModuleType()],size);
|
n += size;
|
}
|
|
return n;
|
}
|