/*
|
* audioproc.c
|
*
|
* Created on: 2021Äê11ÔÂ2ÈÕ
|
* Author: graydon
|
*/
|
#include <stdlib.h>
|
#include <stdio.h>
|
//#include <fstream>
|
#include "tob.h"
|
#include "crc.h"
|
#include "config.h"
|
#include "protocol.h"
|
#include "IModule.h"
|
#include "f2f.h"
|
#include "../drv/memory.h"
|
//#include "../lz/quicklz.h"
|
#include <string.h>
|
#include <cassert>
|
#include "scene.h"
|
|
|
ToB* ToB::tob = NULL;
|
//std::map<u32, convert_fn> ToB::ProcConvert = CreateProcConvert();
|
std::map<u32, ParamEntry*> ToB::ProcParamCtrl = CreateParamCtrl();
|
|
#define DEBUG_1
|
#ifdef 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
|
|
|
|
ToB::ToB(ubool dualDsp, u32 dspIndex )
|
: dual_dsp(dualDsp), dsp_index(dspIndex),mList(32)
|
{
|
if(tob != NULL) {
|
delete tob;
|
}
|
tob = this;
|
frames = NULL;
|
processed = ufalse;
|
mModuleNum =0;
|
}
|
|
ToB::~ToB()
|
{
|
toClear();
|
tob = NULL;
|
}
|
|
uvoid ToB::SetMute(ubool mute)
|
{
|
processed = (mute==0);
|
}
|
|
ErrStatus ToB::toClear()
|
{
|
processed = ufalse;
|
for (std::vector<IModule*>::iterator iter = mList.begin();
|
iter != mList.end() ;iter++) {
|
delete *iter;
|
}
|
mList.clear();
|
mModuleIndex.clear();
|
|
if(frames != NULL) {
|
delete frames;
|
}
|
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)
|
{
|
// extern uvoid SetNumOfChannels(u16 rxNum, u16 txNum);
|
// extern uvoid SetRxChannelPtr(u32 channel ,ufloat* rxBuffer);
|
// extern uvoid SetTxChannelPtr(u32 channel, ufloat* txBuffer);
|
// FlowChartHead* head = (FlowChartHead*)bin;
|
//
|
// //check crc
|
// u32 tmp_crc ,crc = head->crcLsb|(head->crcMsb<<16);
|
// head->crcLsb = head->crcMsb = 0;
|
// tmp_crc = CRC::crc32(bin, nbytes);
|
// if (tmp_crc != crc) {
|
// dbg_printf("flowchar crc check fail.\n");
|
// return ERR_PARAM;
|
// }
|
// dbg_printf("modules num %d, DSP1 Buffer %d,DSP2 Buffer %d.\n"
|
// ,head->module_num
|
// ,head->dsp_buffer_num[0]
|
// ,dual_dsp?head->dsp_buffer_num[1]:0);
|
//
|
// u32 size = sizeof(FlowChartHead);
|
// u32 nPhyInput =0 ,nPhyOutput=0;
|
//
|
// processed = ufalse;
|
//
|
// 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);
|
//
|
//#ifdef DEBUG
|
// printf("Module ID %d type %s rxnum %d txnum %d. \n",pmod->mID ,type_string[pmod->mType], pmod->mRxNum,pmod->mTxNum);
|
//#endif
|
// if (/*dual_dsp &&*/ pmod->mDsp != dsp_index) {
|
// dbg_printf("Module ID %d dsp index %d do not match %d .\n", pmod->mID,pmod->mDsp,dsp_index);
|
// continue;
|
// }
|
//
|
// ubool bInput=ufalse,bOutput=ufalse;
|
// if(pmod->mPhyModule == ModuleInterfaceType::PHY_INPUT) {
|
// bInput = utrue;
|
// }
|
// else if(pmod->mPhyModule == ModuleInterfaceType::PHY_OUTPUT) {
|
// bOutput = utrue;
|
// }
|
//
|
// IModule* m = CreateBaseModule(pmod->mType,pmod->mTag, pmod->mRxNum,pmod->mTxNum);
|
// if(!m) {
|
// dbg_printf("Module ID Create fail.\n", pmod->mID);
|
// continue;
|
// }
|
//
|
// //if(pmod->mType == PROC_DELAY) 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; i++){
|
// if (mTxbufID[i] > 0) {
|
// Frame* pcm = frames->GetFrame(mTxbufID[i]-1);
|
// m->SetOutputChannelDataPtr(i, pcm);
|
// if (bOutput) {
|
// SetTxChannelPtr(nPhyOutput++, pcm->Data());
|
// }
|
// }
|
// else {
|
// m->SetOutputChannelDataPtr(i, 0);
|
// }
|
// }
|
//
|
// for (size_t i = 0; i < pmod->mRxNum ; i++) {
|
// if (mRxbufID[i] > 0) {
|
// Frame* pcm = frames->GetFrame(mRxbufID[i]-1);
|
// m->SetInputChannelDataPtr(i, pcm);
|
// if (bInput) {
|
// SetRxChannelPtr(nPhyInput++, pcm->Data());
|
// }
|
// }
|
// 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(nPhyInput, nPhyOutput);
|
//processed = utrue;
|
|
return ErrStatus::SUCCESS;
|
}
|
#define DBG() do{ static int cnt = 0; printf("%s: %d\n", __FUNCTION__, ++cnt); }while(0)
|
ErrStatus ToB::CreateModule(const u8* bin, u32 nbytes, const u8 *scene_bin)
|
{
|
extern uvoid SetNumOfChannels(u16 rxNum, u16 txNum);
|
extern uvoid SetRxChannelPtr(u32 channel ,ufloat* rxBuffer);
|
extern uvoid SetTxChannelPtr(u32 channel, ufloat* txBuffer);
|
|
FlowChartHead* head = (FlowChartHead*)bin;
|
|
//check crc
|
u32 tmp_crc ,crc = head->crcLsb|(head->crcMsb<<16);
|
head->crcLsb = head->crcMsb = 0;
|
tmp_crc = CRC::crc32(bin, nbytes);
|
if (tmp_crc != crc) {
|
dbg_printf("flowchar crc check fail.\n");
|
return ERR_PARAM;
|
}
|
dbg_printf("modules num %d, DSP1 Buffer %d,DSP2 Buffer %d.\n"
|
,head->module_num
|
,head->dsp_buffer_num[0]
|
,dual_dsp?head->dsp_buffer_num[1]:0);
|
|
u32 size = sizeof(FlowChartHead);
|
u32 nPhyInput =0 ,nPhyOutput=0;
|
|
//u32 offset = sizeof(scenehead);
|
int plen;
|
|
processed = ufalse;
|
|
frames = new Frames(head->dsp_buffer_num[dsp_index]);
|
|
do {
|
ModuleParam* pmod = (ModuleParam*)(bin+ size);
|
size += sizeof(ModuleParam);
|
u16* mRxbufID = (u16*)(bin + size); size += pmod->mRxNum * sizeof(u16);
|
u16* mTxbufID = (u16*)(bin + size); size += pmod->mTxNum * sizeof(u16);
|
|
#ifdef DEBUG
|
printf("Module ID %d type %s rxnum %d txnum %d. \n",pmod->mID ,type_string[pmod->mType], pmod->mRxNum,pmod->mTxNum);
|
#endif
|
|
if (/*dual_dsp &&*/ pmod->mDsp != dsp_index) {
|
dbg_printf("Module ID %d dsp index %d do not match %d .\n", pmod->mID,pmod->mDsp,dsp_index);
|
continue;
|
}
|
|
ubool bInput=ufalse,bOutput=ufalse;
|
if(pmod->mPhyModule == ModuleInterfaceType::PHY_INPUT) {
|
bInput = utrue;
|
}
|
else if(pmod->mPhyModule == ModuleInterfaceType::PHY_OUTPUT) {
|
bOutput = utrue;
|
}
|
|
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);
|
m->SetParamDataPtr(pmod->handle);
|
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; i++){
|
if (mTxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mTxbufID[i]-1);
|
m->SetOutputChannelDataPtr(i, pcm);
|
if (bOutput) {
|
SetTxChannelPtr(nPhyOutput++, pcm->Data());
|
}
|
}
|
else {
|
m->SetOutputChannelDataPtr(i, 0);
|
}
|
}
|
|
for (size_t i = 0; i < pmod->mRxNum ; i++) {
|
if (mRxbufID[i] > 0) {
|
Frame* pcm = frames->GetFrame(mRxbufID[i]-1);
|
m->SetInputChannelDataPtr(i, pcm);
|
if (bInput) {
|
SetRxChannelPtr(nPhyInput++, pcm->Data());
|
}
|
}
|
else {
|
m->SetInputChannelDataPtr(i, 0);
|
}
|
}
|
|
m->Init();
|
|
ToB::ProcParamCtrl[pmod->mType]->GetParamEntry()(m, pmod->handle, plen);
|
//offset += plen;
|
|
} while (size < nbytes);
|
//DBG();
|
if (size != nbytes) {
|
dbg_printf("check flowchart some error!\n");
|
}
|
dbg_printf("Phy InputNum %d, Output Num %d\n",nPhyInput,nPhyOutput);
|
|
Frame* UsbRx = frames->GetFrame(nPhyInput+1);
|
Frame* UsbTx = frames->GetFrame(nPhyOutput);
|
|
SetRxChannelPtr(nPhyInput+1, UsbRx->Data());
|
SetTxChannelPtr(nPhyOutput, UsbTx->Data());
|
|
SetNumOfChannels(nPhyInput+2, nPhyOutput+1);
|
|
processed = utrue;
|
|
return ErrStatus::SUCCESS;
|
}
|
|
ErrStatus ToB::toProc()
|
{
|
if(processed) {
|
for (std::vector<IModule*>::iterator iter = mList.begin();
|
iter != mList.end() ;iter++) {
|
//if((*iter)->GetModuleType() != PROC_ANS && (*iter)->GetModuleType() != PROC_AEC){
|
(*iter)->Proc();
|
//}
|
}
|
}
|
else {
|
MuteOutput();
|
}
|
return ErrStatus::SUCCESS;
|
}
|
#define NORMALIZE(X) (((X)&0x8000)?(-((~(X))&0xffff)-1):(X)) //»¹Ô·ûºÅλ
|
ErrStatus ToB::toCtrl(u32 mID, u32 pID, s16* val, u32 num)
|
{
|
// if(mID >= mModuleIndex.size() || mModuleIndex[mID] == 0) {
|
// return ErrStatus::ERR_PARAM;
|
// }
|
//
|
// IModule* m = mList[mModuleIndex[mID]-1];
|
// if( m != NULL) {
|
// for(u32 i=0; i < num; i++){
|
// val[i] = NORMALIZE(val[i]);
|
// }
|
// m->Ctrl(pID, val, num);
|
// }
|
|
return ErrStatus::SUCCESS;
|
}
|
|
ErrStatus ToB::toCtrl(u32 mID, u32 pID, s16* val)
|
{
|
if(mID >= MAX_MODULE_NUM) {
|
return ErrStatus::ERR_PARAM;
|
}
|
|
u32 proc_type = scene_get_proc_type(mID);
|
|
if(proc_type == PROC_INPUT && (pID == INPUT_TYPE || pID == INPUT_FREQ || pID == INPUT_LEVEL)){
|
proc_type = PROC_SIGNALGEN;
|
mID = 300;
|
}
|
else if(proc_type == PROC_DUCKER && pID == DUCKER_MIX){
|
proc_type = PROC_MIXER;
|
mID = mID + 320;
|
}
|
|
IModule* m = mList[mModuleIndex[mID]-1];
|
if( m != NULL) {
|
ToB::ProcParamCtrl[proc_type]->GetCtrlEntry()(m, pID, val);
|
}
|
return ErrStatus::SUCCESS;
|
}
|
|
#if 0
|
ErrStatus ToB::toCtrl(const u8* bin , u32 nbytes)
|
{
|
struct scenehead* head = (struct scenehead*)bin;
|
u32 compressLen;
|
u32 tmp_crc = 0xffffffff;
|
u32 crc = (head->crc[1] << 16) | (head->crc[0] & 0xffff);
|
head->crc[1] = head->crc[0] = 0;
|
//tmp_crc = CRC::crc32(bin, nbytes);
|
int size = sizeof(struct scenehead);
|
int tmp = 2048;
|
while(size < nbytes)
|
{
|
tmp_crc = CRC::ssh_crc32_block(tmp_crc, bin+size, tmp);
|
size += tmp;
|
if((nbytes-size) < tmp)
|
{
|
tmp = (nbytes-size);
|
}
|
}
|
if (tmp_crc != crc) {
|
dbg_printf("flowchar crc check fail.\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
|
|
size = sizeof(struct scenehead);
|
u8* bin_scene = (u8*)DDRMalloc(nbytes*4);
|
assert(bin_scene != NULL);
|
int offset = 0;
|
int datalen = 0;
|
short plen = 0;
|
|
for(std::vector<IModule*>::iterator iter = mList.begin();iter != mList.end() ;iter++) {
|
datalen = ToB::ProcConvert[(*iter)->GetModuleType()]((void *)(bin+size),(*iter)->GetModuleID(), bin_scene+offset, &plen);
|
//printf("%s\n",type_string[(*iter)->GetModuleType()]);
|
size +=plen;
|
offset +=datalen;
|
}
|
|
if(size != nbytes) {
|
dbg_printf("Parameter conversion error!\n");
|
//printf("Parameter conversion error!\n");
|
}
|
|
bin = bin_scene;
|
size = 0;
|
|
while(size < offset) {
|
Param* h = (Param*)(bin+size);
|
size += sizeof(Param);
|
s16* val = (s16*)(bin+size);
|
|
toCtrl(h->mID, h->pID, val, h->num);
|
size += h->num*sizeof(s16);
|
}
|
|
if(size != offset) {
|
dbg_printf("check preset has some error!\n");
|
//printf("check preset has some error!\n");
|
}
|
|
//DDRFree((uvoid*)bin);
|
DDRFree((uvoid*)bin_scene);
|
bin_scene = NULL;
|
|
processed = utrue;
|
return ErrStatus::SUCCESS;
|
}
|
#else
|
ErrStatus ToB::toCtrl(const u8* bin , u32 nbytes)
|
{
|
struct scenehead* head = (struct scenehead*)bin;
|
u32 compressLen;
|
u32 tmp_crc = 0xffffffff;
|
u32 crc = (head->crc[1] << 16) | (head->crc[0] & 0xffff);
|
head->crc[1] = head->crc[0] = 0;
|
int size = sizeof(struct scenehead);
|
int tmp = 2048;
|
while(size < nbytes)
|
{
|
tmp_crc = CRC::ssh_crc32_block(tmp_crc, bin+size, tmp);
|
size += tmp;
|
if((nbytes-size) < tmp)
|
{
|
tmp = (nbytes-size);
|
}
|
}
|
if (tmp_crc != crc) {
|
dbg_printf("flowchar crc check fail.\n");
|
return ErrStatus::ERR_PARAM;
|
}
|
|
|
size = sizeof(struct scenehead);
|
|
int offset = 0;
|
int result = 0;
|
int plen = 0;
|
|
for(std::vector<IModule*>::iterator iter = mList.begin();iter != mList.end() ;iter++) {
|
result = ToB::ProcParamCtrl[(*iter)->GetModuleType()]->GetParamEntry()(*iter, (void *)(bin+size), plen);
|
if(result != 0){
|
printf("error!\n");
|
}
|
size += plen;
|
}
|
|
if(size != nbytes) {
|
dbg_printf("Parameter conversion error!\n");
|
//printf("Parameter conversion error!\n");
|
}
|
|
|
processed = utrue;
|
return ErrStatus::SUCCESS;
|
}
|
#endif
|
|
uvoid ToB::SetModuleParam(u32 proc_type, u32 mID, void *handle)
|
{
|
int plen;
|
IModule* m = mList[mModuleIndex[mID]-1];
|
if( m != NULL) {
|
ToB::ProcParamCtrl[proc_type]->GetParamEntry()(m, handle, plen);
|
}
|
}
|
|
u32 ToB::GetLevels(s16 * buffer)
|
{
|
u32 n =0, size;
|
if( !processed ) {
|
return 0;
|
}
|
|
for (std::vector<IModule*>::iterator iter = mList.begin();
|
iter != mList.end() ; iter++) {
|
size = (*iter)->GetLevel(buffer + n );
|
//printf("%s:%d\n",type_string[(*iter)->GetModuleType()],size);
|
n += size;
|
}
|
mLevelNum = n;
|
|
return n;
|
}
|
|
|
u32 ToB::GetRuntime(u16 * buffer)
|
{
|
u32 n =0;
|
u32 cpu = SAMPLE_RATE*10000 /SAMPLE_NUM ;
|
|
if( !processed ) {
|
return 0;
|
}
|
|
for (std::vector<IModule*>::iterator iter = mList.begin();
|
iter != mList.end() ; iter++) {
|
ufloat time = (*iter)->GetRuntime() ;
|
buffer[n++] = (u16)(time* cpu); //percent*100.
|
}
|
|
return n;
|
}
|