/* * audioproc.c * * Created on: 2021Äê11ÔÂ2ÈÕ * Author: graydon */ #include #include //#include //#include //#include #include "tob.h" #include "crc.h" #include "config.h" #include "protocol.h" #include "IModule.h" #include "f2f.h" #include "../drv/memory.h" static ToB* tob = NULL; ToB* ToB::GetInstance() { return tob; } 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; mLevelPacketNum =0; mModuleIndex.resize(0); } ToB::~ToB() { toClear(); tob = NULL; } uvoid ToB::SetMute(ubool mute) { processed = (mute==0); } ErrStatus ToB::toClear() { processed = ufalse; for (std::vector::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) { 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; } //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; 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); 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(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(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(nPhyInput, nPhyOutput); //processed = utrue; return ErrStatus::SUCCESS; } ErrStatus ToB::toProc() { if(processed) { for (auto iter = mList.begin(); iter != mList.end() ;iter++) { (*iter)->Proc(); } } else { MuteOutput(); } 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); } 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(Message* handle , MSG* pmsg) { u32 n =0,len =0; s8 buffer[MSG_DATA_LEN]; u32 packetNo =0; if( !processed ) { return 0; } for (std::vector::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; } //cpu = ms*SAMPLE_RATE/SAMPLE_NUM //cpu *100 -> u16 //cpu * 100 -> percent. u32 ToB::GetModuleCPU(Message* handle , MSG* pmsg) { u32 n =0; u32 cpu = (u32)(SAMPLE_RATE/SAMPLE_NUM*100000) ; u32* data = (u32*)pmsg->data; if( !processed ) { return 0; } for (std::vector::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: time = time / (rxNum * txNum ) ; break; case ModuleType::EQ: case ModuleType::NHS: time = time / (tag * rxNum) ; break; case ModuleType::SignalGenerator: case ModuleType::Ducker: case ModuleType::ContinuitySPL: time = time / txNum ; break; default: time = time / rxNum ; break; } data[n++] = ID; data[n++] = (u32)(time* cpu); 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; }