/* * audioproc.c * * Created on: 2021Äê11ÔÂ2ÈÕ * Author: graydon */ #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" //#include "../lz/quicklz.h" #include #include #include "scene.h" ToB* ToB::tob = NULL; //std::map ToB::ProcConvert = CreateProcConvert(); std::map 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::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::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::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::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::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::iterator iter = mList.begin(); iter != mList.end() ; iter++) { ufloat time = (*iter)->GetRuntime() ; buffer[n++] = (u16)(time* cpu); //percent*100. } return n; }