| | |
| | | */ |
| | | #include <stdlib.h> |
| | | #include <stdio.h> |
| | | #include <heapnew> |
| | | #include "tob.h" |
| | | #include "crc.h" |
| | | #include "config.h" |
| | |
| | | #include "IModule.h" |
| | | #include "f2f.h" |
| | | #include "../drv/memory.h" |
| | | #include "param_ctrl.h" |
| | | |
| | | |
| | | |
| | | //#define DEBUG |
| | | #ifdef DEBUG |
| | |
| | | #define dbg_printf |
| | | #endif |
| | | |
| | | static ToB* tob = NULL; |
| | | //static ToB* tob = NULL; |
| | | |
| | | ToB* ToB::GetInstance() |
| | | { |
| | | return tob; |
| | | } |
| | | //ToB* ToB::GetInstance() |
| | | //{ |
| | | // return tob; |
| | | //} |
| | | |
| | | ToB::ToB(ubool dualDsp, u32 dspIndex ) |
| | | : dual_dsp(dualDsp), dsp_index(dspIndex),mList(32) |
| | | : dual_dsp(dualDsp), dsp_index(dspIndex) |
| | | { |
| | | if(tob != NULL) { |
| | | delete tob; |
| | | } |
| | | tob = this; |
| | | frames = NULL; |
| | | // if(tob != NULL) { |
| | | // delete tob; |
| | | // } |
| | | // tob = this; |
| | | frames = nullptr; |
| | | processed = ufalse; |
| | | mModuleNum =0; |
| | | mLevelPacketNum =0; |
| | | mModuleIndex.resize(0); |
| | | paramset = new(SRAM_DDR) tg_param_ctrl_t(); |
| | | } |
| | | |
| | | ToB::~ToB() |
| | | { |
| | | toClear(); |
| | | tob = NULL; |
| | | // tob = NULL; |
| | | delete paramset; |
| | | } |
| | | |
| | | uvoid ToB::SetMute(ubool mute) |
| | |
| | | ErrStatus ToB::toClear() |
| | | { |
| | | processed = ufalse; |
| | | int i = 0; |
| | | |
| | | for (std::vector<IModule*>::iterator iter = mList.begin(); |
| | | iter != mList.end() ;iter++) { |
| | | delete *iter; |
| | | // 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; |
| | | |
| | |
| | | |
| | | u32 size = sizeof(FlowChartHead); |
| | | u32 nPhyInput =0 ,nPhyOutput=0; |
| | | |
| | | frames = new Frames(head->dsp_buffer_num[dsp_index]); |
| | | |
| | | do { |
| | |
| | | mList.push_back(m); |
| | | |
| | | if(pmod->mID >= mModuleIndex.size()) { |
| | | mModuleIndex.resize(pmod->mID + 1,0); |
| | | mModuleIndex.resize(pmod->mID + 1, 0); |
| | | } |
| | | mModuleIndex[pmod->mID] = ++mModuleNum ; |
| | | |
| | |
| | | if (size != nbytes) { |
| | | dbg_printf("check flowchart some error!\n"); |
| | | } |
| | | dbg_printf("Phy InputNum %d, Output Num %d\n",nPhyInput,nPhyOutput); |
| | | // 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 ; |
| | | PhyPort* mPhyID; |
| | | ubool bInput=ufalse,bOutput=ufalse; |
| | | u16 mRxNum = pmod->mRxNum, mTxNum = pmod->mTxNum; |
| | | |
| | |
| | | |
| | | 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); |
| | | #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); |
| | | |
| | | 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); |
| | | |
| | | m->SetModuleInfo(pmod->mID ,pmod->mType, pmod->mTag); |
| | | mList.push_back(m); |
| | | |
| | | if(pmod->mID >= mModuleIndex.size()) { |
| | | mModuleIndex.resize(pmod->mID + 1,0); |
| | | mModuleIndex.resize(pmod->mID + 1, 0); |
| | | } |
| | | mModuleIndex[pmod->mID] = ++mModuleNum ; |
| | | 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 ); |
| | | Frame* pcm = frames->GetFrame(mTxbufID[i]-1); |
| | | m->SetOutputChannelDataPtr(i, pcm); |
| | | |
| | | if (bInput && mPhyID[i].mIntType < IntDataType::COUNT) { |
| | |
| | | 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(nPhyOutput[mPhyID[i].mIntType] < mPhyID[i].mPhyID) |
| | | nPhyOutput[mPhyID[i].mIntType] = mPhyID[i].mPhyID; |
| | | |
| | | pcm = frames->AllocFrame(); |
| | | //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"); |
| | |
| | | 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 |
| | | u32 tmp_crc ,crc = head->crcLsb|(head->crcMsb<<16); |
| | | head->crcLsb = head->crcMsb = 0; |
| | | s32 tmp_crc; |
| | | s32 crc = head->crc; |
| | | head->crc = 0; |
| | | tmp_crc = CRC::crc32(bin, nbytes); |
| | | if (tmp_crc != crc) { |
| | | //dbg_printf("flowchar crc check fail.\n"); |
| | | printf("flowchar crc check fail.\n"); |
| | | return ErrStatus::ERR_PARAM; |
| | | } |
| | | |
| | | processed = ufalse; |
| | | |
| | | if(head->version == 0) { |
| | |
| | | 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++) { |
| | | (*iter)->Proc(); |
| | | 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 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) { |
| | |
| | | |
| | | IModule* m = mList[mModuleIndex[mID]-1]; |
| | | if( m != NULL) { |
| | | m->Ctrl(pID, val, num); |
| | | // 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; |
| | | } |
| | | |
| | |
| | | FlowChartHead* head = (FlowChartHead*)bin; |
| | | |
| | | //check crc |
| | | u32 tmp_crc ,crc = head->crcLsb|(head->crcMsb<<16); |
| | | head->crcLsb = head->crcMsb = 0; |
| | | 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"); |
| | | dbg_printf("flowchar crc check fail.\n"); |
| | | return ErrStatus::ERR_PARAM; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | if(size != nbytes) { |
| | | //dbg_printf("check preset has some error!\n"); |
| | | dbg_printf("check preset has some error!\n"); |
| | | } |
| | | |
| | | processed = utrue; |
| | | return ErrStatus::SUCCESS; |
| | | } |
| | | |
| | | u32 ToB::GetLevels(Message* handle , MSG* pmsg) |
| | | |
| | | u32 ToB::GetLevels(s16* buffer) |
| | | { |
| | | u32 n =0,len =0; |
| | | s8 buffer[MSG_DATA_LEN]; |
| | | u32 packetNo =0; |
| | | u32 n =0,size =0; |
| | | |
| | | if( !processed ) { |
| | | return 0; |
| | | } |
| | | // |
| | | // for (std::vector<IModule*>::iterator iter = mList.begin(); |
| | | // iter != mList.end() ; iter++) { |
| | | // IModule* m = *iter; |
| | | // |
| | | // u32 ID = m->GetModuleID(); |
| | | // |
| | | // struct Level* p = (struct Level*)buffer; |
| | | // |
| | | // n = sizeof(struct Level); |
| | | // p->mID = ID; |
| | | // |
| | | // /*graydon-230905: 多通道模块会出现电平数量超出1024,比如32通道32点反馈抑制, |
| | | // * ps: 讨论决定多通道模块在界面做数量限制且过多多通道不符合应用需求. |
| | | // */ |
| | | // p->num = m->GetLevel((s16*)(buffer + n)); |
| | | // if(p->num == 0) continue; |
| | | // |
| | | // n += p->num*sizeof(s16); |
| | | // |
| | | // //过去的电平数量+当前的电平数量是否大于MSG_DATA_LEN |
| | | // if(len + n > MSG_DATA_LEN) { |
| | | // pmsg->pktNo = packetNo++; |
| | | // pmsg->totalPkts = mLevelPacketNum; |
| | | // pmsg->Enc(MsgType::MSG_LEVEL_GET_RES, 0, len); |
| | | // handle->Send(pmsg);//入队列 |
| | | // len = 0; |
| | | // } |
| | | // memcpy(pmsg->data+len, p , n); |
| | | // len += n; |
| | | // } |
| | | // |
| | | // if(len > 0) { |
| | | // pmsg->pktNo = packetNo++; |
| | | // pmsg->totalPkts = mLevelPacketNum; |
| | | // pmsg->Enc(MsgType::MSG_LEVEL_GET_RES, 0, len); |
| | | // handle->Send(pmsg); |
| | | // } |
| | | // |
| | | // if(packetNo > 0){ |
| | | // mLevelPacketNum = packetNo; |
| | | // } |
| | | // return n; |
| | | 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; |
| | | } |
| | | |
| | | |
| | | //cpu = time*SAMPLE_RATE/SAMPLE_NUM |
| | | //cpu *1000 -> s32 |
| | | //cpu * 100 -> percent. |
| | | u32 ToB::GetModuleCPU(Message* handle , MSG* pmsg) |
| | | { |
| | | // u32 n =0; |
| | | // const ufloat period_s = SAMPLE_NUM*1.f/SAMPLE_RATE; |
| | | // const u32 percent = 100000; |
| | | // ufloat module_cpu ; |
| | | // u32* data = (u32*)pmsg->data; |
| | | // |
| | | // if( !processed ) { |
| | | // return 0; |
| | | // } |
| | | // |
| | | // for (std::vector<IModule*>::iterator iter = mList.begin(); |
| | | // iter != mList.end() ; iter++) { |
| | | // IModule* m = *iter; |
| | | // ufloat time = m->GetRuntime(); |
| | | // ModuleType type = (ModuleType)m->GetModuleType(); |
| | | // u32 tag = m->GetModuleTag(); |
| | | // u16 rxNum = m->GetModuleInputNum(); |
| | | // u16 txNum = m->GetModuleOutputNum(); |
| | | // u32 ID = m->GetModuleID(); |
| | | // |
| | | // |
| | | // switch(type) { |
| | | // case ModuleType::Mixer: |
| | | // case ModuleType::SupperMatrix: |
| | | // time = time / rxNum ; |
| | | // module_cpu = time / period_s ; |
| | | // break; |
| | | // case ModuleType::GEQ: |
| | | // case ModuleType::EQ: |
| | | // case ModuleType::NHS: |
| | | // time = time / (tag * rxNum) ; |
| | | // module_cpu = time / period_s ; |
| | | // break; |
| | | // case ModuleType::SignalGenerator: |
| | | // case ModuleType::Ducker: |
| | | // case ModuleType::ContinuitySPL: |
| | | // time = time / txNum ; |
| | | // module_cpu = time / period_s ; |
| | | // break; |
| | | // case ModuleType::AEC: |
| | | // module_cpu = time / 0.01f ;//aec 10ms处理一次. |
| | | // break; |
| | | // default: |
| | | // time = time / rxNum ; |
| | | // module_cpu = time / period_s ; |
| | | // break; |
| | | // } |
| | | // data[n++] = ID; |
| | | // data[n++] = (u32)(module_cpu* percent); |
| | | // |
| | | // if(n*sizeof(u32) >= MSG_DATA_LEN) { |
| | | // pmsg->Enc(MsgType::MSG_MODULE_CPU_RES, 0, MSG_DATA_LEN); |
| | | // handle->Send(pmsg); |
| | | // n = 0; |
| | | // } |
| | | // } |
| | | // |
| | | // if(n > 0) { |
| | | // pmsg->Enc(MsgType::MSG_MODULE_CPU_RES, 0, n*sizeof(u32)); |
| | | // handle->Send(pmsg); |
| | | // } |
| | | |
| | | return 0; |
| | | return n; |
| | | } |
| | | |
| | | |