录音机和录像机的输入通路SPELayer
来源:互联网 发布:js 雷达扫描效果 编辑:程序博客网 时间:2024/04/28 03:09
初始化SPELayer对象,
//speech enhancement setting and processbool SPELayer::Start(SPE_MODE mode) //for VOIP, both uplink/downlink{ Mutex::Autolock lock(mLock); if (mState == SPE_STATE_RUNNING) { ALOGD("%s already start!", __FUNCTION__); return false; } if ((mMode != SPE_MODE_NONE) && (mMode != mode)) { FlushBufferQ(); } // set mSph_Enh_ctrl parameters if (mode == SPE_MODE_REC)//普通录音 { mSph_Enh_ctrl.sample_rate = mRecordSampleRate; mSph_Enh_ctrl.frame_rate = mRecordFrameRate; mSph_Enh_ctrl.MIC_DG = mRecordMICDigitalGain; mSph_Enh_ctrl.Fea_Cfg_table = mRecordFea_Cfg_table; mSph_Enh_ctrl.App_table = mRecordApp_table; mSph_Enh_ctrl.MMI_ctrl = mMMI_ctrl_mask; mSph_Enh_ctrl.MMI_MIC_GAIN = mRecordULTotalGain; memcpy(&mSph_Enh_ctrl.enhance_pars, &mRecordEnhanceParas, EnhanceParasNum * sizeof(uWord32)); memcpy(&mSph_Enh_ctrl.DMNR_cal_data, &mRecordDMNRCalData, DMNRCalDataNum * sizeof(Word16)); memcpy(&mSph_Enh_ctrl.Compen_filter, &mRecordCompenFilter, CompenFilterNum * sizeof(Word16)); } else if ((mode == SPE_MODE_VOIP) || (mode == SPE_MODE_AECREC))//VOIP通话 { mSph_Enh_ctrl.sample_rate = mVoIPSampleRate; mSph_Enh_ctrl.frame_rate = mVoIPFrameRate; mSph_Enh_ctrl.MIC_DG = mVoIPMICDigitalGain; mSph_Enh_ctrl.Fea_Cfg_table = mVoIPFea_Cfg_table; mSph_Enh_ctrl.App_table = mVoIPApp_table; if (mode == SPE_MODE_AECREC) { mNormalModeVoIP = true; } mSph_Enh_ctrl.MMI_ctrl = mMMI_ctrl_mask; mSph_Enh_ctrl.MMI_MIC_GAIN = mVoIPULTotalGain; memcpy(&mSph_Enh_ctrl.enhance_pars, &mVoIPEnhanceParas, EnhanceParasNum * sizeof(uWord32)); memcpy(&mSph_Enh_ctrl.DMNR_cal_data, &mVoIPDMNRCalData, DMNRCalDataNum * sizeof(Word16)); memcpy(&mSph_Enh_ctrl.Compen_filter, &mVoIPCompenFilter, CompenFilterNum * sizeof(Word16)); mLatencyTime = mPlatformOffsetTime + GetVoIPLatencyTime(); if (mLatencyTime != 0) { mNeedDelayLatency = true; } if (mLatencyTime < 0) { mLatencyTime = abs(mLatencyTime); mLatencyDir = false; } mLatencySampleCount = mLatencyTime * mVoIPSampleRate / 1000; //Latency sample count mJitterSampleCount = mJitterBufferTime * mVoIPSampleRate / 1000; //Jitter buffer sample count, one channel if (mJitterBufferTime != 0) { mNeedJitterBuffer = true; } } else { ALOGD("%s, wrong mode", __FUNCTION__); return false; } mSph_Enh_ctrl.Device_mode = mRoute; if (mSphCtrlBuffer) { ALOGD("%s mSphCtrlBuffer already exist, delete and recreate", __FUNCTION__); mSphEnhOps.ENH_API_Free(&mSph_Enh_ctrl); free(mSphCtrlBuffer); mSphCtrlBuffer = NULL; } Word16 ver = mSphEnhOps.ENH_API_Get_Version(&mSph_Enh_ctrl);//获得音频处理库的版本号 uint32_t mem_size; mem_size = mSphEnhOps.ENH_API_Get_Memory(&mSph_Enh_ctrl); mSphCtrlBuffer = (int *) malloc(mem_size); memset(mSphCtrlBuffer, 0, mem_size); dump(); mSphEnhOps.ENH_API_Alloc(&mSph_Enh_ctrl, (Word32 *)mSphCtrlBuffer); mSphEnhOps.ENH_API_Rst(&mSph_Enh_ctrl); mMode = mode; mState = SPE_STATE_START; //set the address if (mMode == SPE_MODE_REC)//普通录音 { //frame rate = 20ms, buffer size 320*2, input/output use the same address if (mSph_Enh_ctrl.frame_rate == 20) //普通录音 { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0];//左声道 if (mSph_Enh_ctrl.sample_rate == 16000) { ALOGD("Start 16K record!!!"); mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec16KUL2BufStartAddr];//右声道 mSPEProcessBufSize = RecBufSize16K20ms * 2 * sizeof(short); //for 16k samplerate with 20ms frame rate (stereo) } else //48k sample rate,普通录音 { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec48KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize48K20ms * 2 * sizeof(short); //for 48k samplerate with 20ms frame rate (stereo) } } else if (mSph_Enh_ctrl.frame_rate == 10) //frame rate = 10ms, buffer size 480*2 { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0]; if (mSph_Enh_ctrl.sample_rate == 16000) { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec16KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize16K10ms * 2 * sizeof(short); //for 16k samplerate with 10ms frame rate (stereo) } else //48K samplerate { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec48KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize48K10ms * 2 * sizeof(short); //for 48k samplerate with 10ms frame rate (stereo) } } else if (mSph_Enh_ctrl.frame_rate == 5) //frame rate = 5ms { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0]; if (mSph_Enh_ctrl.sample_rate == 16000) { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec16KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize16K5ms * 2 * sizeof(short); //for 16k samplerate with 5ms frame rate (stereo) } else //48K samplerate { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec48KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize48K5ms * 2 * sizeof(short); //for 48k samplerate with 5ms frame rate (stereo) } } else if (mSph_Enh_ctrl.frame_rate == 3) //frame rate = 3ms { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0]; if (mSph_Enh_ctrl.sample_rate == 16000) { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec16KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize16K3ms * 2 * sizeof(short); //for 16k samplerate with 3ms frame rate (stereo) } else //48K samplerate { mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[Rec48KUL2BufStartAddr]; mSPEProcessBufSize = RecBufSize48K3ms * 2 * sizeof(short); //for 48k samplerate with 3ms frame rate (stereo) } } else { ALOGD("wrong mSph_Enh_ctrl.frame_rate setting %d", mSph_Enh_ctrl.frame_rate); } } else //VoIP mode { //only support 16K samplerate,VoIP通话 if (mSph_Enh_ctrl.frame_rate == 20) //frame rate = 20ms, buffer size 320*4 { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0];//左声道 mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[320];//右声道 mpSPEBufferDL = &mSph_Enh_ctrl.PCM_buffer[640]; mpSPEBufferDLDelay = &mSph_Enh_ctrl.PCM_buffer[960]; mSPEProcessBufSize = 320 * 2 * sizeof(short); //for 16k samplerate with 20ms frame rate (stereo) } else //frame rate = 10ms, buffer size 160*4 { mpSPEBufferUL1 = &mSph_Enh_ctrl.PCM_buffer[0]; mpSPEBufferUL2 = &mSph_Enh_ctrl.PCM_buffer[160]; mpSPEBufferDL = &mSph_Enh_ctrl.PCM_buffer[320]; mpSPEBufferDLDelay = &mSph_Enh_ctrl.PCM_buffer[480]; mSPEProcessBufSize = 160 * 2 * sizeof(short); //for 16k samplerate with 20ms frame rate (stereo) } mpSPEBufferNE = mpSPEBufferUL1; mpSPEBufferFE = mpSPEBufferDL; } mNsecPerSample = 1000000000 / mVoIPSampleRate; return true;}
int SPELayer::Process(InBufferInfo *InBufinfo){ mState = SPE_STATE_RUNNING; AddtoInputBuffer(UPLINK, InBufinfo);//添加未处理的数据 int inBufLength = InBufinfo->BufLen; short *inBuf = InBufinfo->pBufBase; int retSize = inBufLength; //process the input buffer queue if (mMode == SPE_MODE_REC) //普通录音 { mVoIPRunningbefore = false; retSize = Process_Record(inBuf, inBufLength);//对录音数据进行处理 } else //VoIP { mVoIPRunningbefore = true; Process_VoIP(inBuf, inBufLength);//对VoIP数据进行处理 } Dump_PCM_Out(UPLINK, inBuf, retSize); return retSize;}
void SPELayer::AddtoInputBuffer(SPE_DATA_DIRECTION dir, struct InBufferInfo *BInputInfo, bool prequeue){ //pthread_mutex_lock(&mBufMutex ); int inBufLen = BInputInfo->BufLen; short *inBufAddr = BInputInfo->pBufBase; bool bRemainInfo = BInputInfo->bHasRemainInfo; bool bPreQueue = prequeue; Dump_PCM_In(dir, inBufAddr, inBufLen); BufferInfo *newInBuffer = new BufferInfo; memset(newInBuffer, 0, sizeof(BufferInfo)); struct timespec tstamp_queue; newInBuffer->pBufBase = (short *) malloc(inBufLen); memcpy(newInBuffer->pBufBase, inBufAddr, inBufLen); tstamp_queue = BInputInfo->time_stamp_queued; newInBuffer->BufLen = inBufLen; newInBuffer->pRead = newInBuffer->pBufBase; newInBuffer->pWrite = newInBuffer->pBufBase; newInBuffer->time_stamp_queued = tstamp_queue; newInBuffer->time_stamp_process = {0}; newInBuffer->DLfirstBuf = false; if ((dir == UPLINK) && ((mMode == SPE_MODE_VOIP) || (mMode == SPE_MODE_AECREC)))//普通录音 { if (mFirstVoIPUplink) { mFirstVoIPUplink = false; if (bRemainInfo) { mPreUplinkEstTime.tv_sec = BInputInfo->time_stamp_predict.tv_sec; mPreUplinkEstTime.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; } else { mPreUplinkEstTime.tv_sec = mUplinkIntrStartTime.tv_sec; if (mUplinkIntrStartTime.tv_nsec + mULDropTime * 1000000 >= 1000000000) { mPreUplinkEstTime.tv_sec++; mPreUplinkEstTime.tv_nsec = mUplinkIntrStartTime.tv_nsec + mULDropTime * 1000000 - 1000000000; } else { mPreUplinkEstTime.tv_nsec = mUplinkIntrStartTime.tv_nsec + mULDropTime * 1000000; } } newInBuffer->time_stamp_estimate.tv_sec = mPreUplinkEstTime.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = mPreUplinkEstTime.tv_nsec; mPreULBufLen = inBufLen; } else { if (bRemainInfo) { struct timespec tempTime; tempTime.tv_sec = BInputInfo->time_stamp_predict.tv_sec; tempTime.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; mPreUplinkEstTime.tv_sec = BInputInfo->time_stamp_predict.tv_sec; mPreUplinkEstTime.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_predict.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; } else { struct timespec Esttstamp; unsigned long long ns = ((mPreULBufLen * (unsigned long long)1000000) / 64); Esttstamp.tv_sec = mPreUplinkEstTime.tv_sec; if (mPreUplinkEstTime.tv_nsec + ns >= 1000000000) { Esttstamp.tv_sec++; Esttstamp.tv_nsec = mPreUplinkEstTime.tv_nsec + ns - 1000000000; } else { Esttstamp.tv_nsec = mPreUplinkEstTime.tv_nsec + ns; } newInBuffer->time_stamp_estimate.tv_sec = Esttstamp.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = Esttstamp.tv_nsec; mPreUplinkEstTime.tv_sec = Esttstamp.tv_sec; mPreUplinkEstTime.tv_nsec = Esttstamp.tv_nsec; } mPreULBufLen = inBufLen; } } if (dir == DOWNLINK)//VoIP { if (mFirstVoIPDownlink) { mFirstVoIPDownlink = false; //downlink starts first time, the first DL buffer queue will earlier than interrupt enable, //it happens when output starts after input stream create if (mDLNewStart) { newInBuffer->DLfirstBuf = true; //need to modify the estimate start time again when downlink Interrupt set. newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_queued.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_queued.tv_nsec; if (mDLLatencyTime * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec >= 1000000000) { newInBuffer->time_stamp_estimate.tv_sec++; newInBuffer->time_stamp_estimate.tv_nsec = mDLLatencyTime * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec - 1000000000; } mPreDownlinkEstTime.tv_sec = newInBuffer->time_stamp_estimate.tv_sec; mPreDownlinkEstTime.tv_nsec = newInBuffer->time_stamp_estimate.tv_nsec; } else { //the first DL buffer queue after downlink already start, //it happens when input stream create after output is running if (bRemainInfo) { newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_predict.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; } else { //use DL hardware buffer latency for estimate? or buffer length? newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_queued.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_queued.tv_nsec; ALOGD("mDLLatencyTime=%d", mDLLatencyTime); if ((mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec >= 1000000000) { newInBuffer->time_stamp_estimate.tv_sec++; newInBuffer->time_stamp_estimate.tv_nsec = (mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec - 1000000000; } else { newInBuffer->time_stamp_estimate.tv_nsec = (mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec; } } mPreDownlinkEstTime.tv_sec = newInBuffer->time_stamp_estimate.tv_sec; mPreDownlinkEstTime.tv_nsec = newInBuffer->time_stamp_estimate.tv_nsec; mPreDownlinkQueueTime.tv_sec = BInputInfo->time_stamp_queued.tv_sec; mPreDownlinkQueueTime.tv_nsec = BInputInfo->time_stamp_queued.tv_nsec; } mPreDLBufLen = inBufLen; } else //not the first DL buffer queue, continuos queue { if (bRemainInfo) { newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_predict.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_predict.tv_nsec; } else { struct timespec Esttstamp; unsigned long long diffns = 0; unsigned long long ns = ((mPreDLBufLen * (unsigned long long)1000000) / 32); //downlink is mono data newInBuffer->time_stamp_estimate.tv_sec = BInputInfo->time_stamp_queued.tv_sec; newInBuffer->time_stamp_estimate.tv_nsec = BInputInfo->time_stamp_queued.tv_nsec; //when the latest DL buffer queue and this DL buffer queue interval longer than hardware buffer latency, //the new buffer will play directly and if the next buffer queue longer than half hardware buffer latency, //it will also play directly if (TimeDifference(BInputInfo->time_stamp_queued, mPreDownlinkQueueTime) > (mDLLatencyTime * (unsigned long long)1000000)) { //two downlink queue interval is larger than hardware buffer latency time, //this buffer is playing directly since no previous data in the hardware buffer ALOGD("downlink late time queue sec= %ld, nsec=%ld, mPreDownlinkQueueTime sec=%ld, nsec=%ld" , BInputInfo->time_stamp_queued.tv_sec, BInputInfo->time_stamp_queued.tv_nsec, mPreDownlinkQueueTime.tv_sec, mPreDownlinkQueueTime.tv_nsec); } else { if ((mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec >= 1000000000) { newInBuffer->time_stamp_estimate.tv_sec++; newInBuffer->time_stamp_estimate.tv_nsec = (mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec - 1000000000; } else { newInBuffer->time_stamp_estimate.tv_nsec = (mDLLatencyTime / 2) * 1000000 + newInBuffer->time_stamp_estimate.tv_nsec; } } } mPreDownlinkQueueTime.tv_sec = BInputInfo->time_stamp_queued.tv_sec; mPreDownlinkQueueTime.tv_nsec = BInputInfo->time_stamp_queued.tv_nsec; mPreDownlinkEstTime.tv_sec = newInBuffer->time_stamp_estimate.tv_sec; mPreDownlinkEstTime.tv_nsec = newInBuffer->time_stamp_estimate.tv_nsec; mPreDLBufLen = inBufLen; } } if (dir == UPLINK)//普通录音,将原生数据放入下行处理队列 { mULInBufferQ.add(newInBuffer); mULInBufQLenTotal += inBufLen; } else { //queue to the downlink input buffer queue, downlink data channel is mono mDLInBufferQ.add(newInBuffer); mDLInBufQLenTotal += inBufLen; //also add to delay buffer queue newInBuffer->BufLen4Delay = inBufLen; newInBuffer->pRead4Delay = newInBuffer->pBufBase; newInBuffer->pWrite4Delay = newInBuffer->pBufBase; mDLDelayBufferQ.add(newInBuffer); mDLDelayBufQLenTotal += inBufLen; if (bPreQueue) { //wait for uplink comes, only queue five buffer for reference if ((mDLPreQLimit) || (!mDLPreQLimit && mFirstVoIPUplink)) { while (mDLInBufferQ.size() > mDLPreQnum) { mDLInBufQLenTotal -= mDLInBufferQ[0]->BufLen; mDLInBufferQ.removeAt(0); } } else //uplink interrupt starts, remove previous queue { //for(int i; i<mDLInBufferQ.size(); i++) while (!mDLInBufferQ.isEmpty()) { uint32_t tempSec = mDLInBufferQ[0]->time_stamp_estimate.tv_sec; unsigned long long tempNSec = mDLInBufferQ[0]->time_stamp_estimate.tv_nsec; uint32_t tempsample = mDLInBufferQ[0]->BufLen / 2; unsigned long long tempdeltaNSec = tempsample * (unsigned long long)1000000 / 16; unsigned long long tempEndNSec = tempNSec + tempdeltaNSec; unsigned long long tempFinalNSec = 0; uint32_t tempFinalSec = tempSec; if (tempEndNSec > 1000000000) { tempFinalNSec = tempEndNSec - 1000000000; tempFinalSec = tempFinalSec + 1; } else { tempFinalNSec = tempEndNSec; } if (mUplinkIntrStartTime.tv_sec > tempFinalSec) { mDLInBufQLenTotal -= mDLInBufferQ[0]->BufLen; mDLInBufferQ.removeAt(0); } else if (mUplinkIntrStartTime.tv_sec == tempFinalSec) { if (mUplinkIntrStartTime.tv_nsec >= tempFinalNSec) { mDLInBufQLenTotal -= mDLInBufferQ[0]->BufLen; mDLInBufferQ.removeAt(0); } else { //remove previous data in this buffer queue, will do it in the prepare data? ALOGD("remove DL pre queue finish 1"); break; } } else { ALOGD("remove DL pre queue finish 2"); break; } } } //wait for uplink comes, only queue five buffer for if (mDLPreQLimit || (!mDLPreQLimit && mFirstVoIPUplink)) { while (mDLDelayBufferQ.size() > mDLPreQnum) { mDLDelayBufQLenTotal -= mDLDelayBufferQ[0]->BufLen4Delay; free(mDLDelayBufferQ[0]->pBufBase); delete mDLDelayBufferQ[0]; mDLDelayBufferQ.removeAt(0); } } else //uplink interrupt starts, remove previous queue { while (!mDLDelayBufferQ.isEmpty()) { uint32_t tempSec = mDLDelayBufferQ[0]->time_stamp_estimate.tv_sec; unsigned long long tempNSec = mDLDelayBufferQ[0]->time_stamp_estimate.tv_nsec; uint32_t tempsample = mDLDelayBufferQ[0]->BufLen / 2; unsigned long long tempdeltaNSec = tempsample * (unsigned long long)1000000 / 16; unsigned long long tempEndNSec = tempNSec + tempdeltaNSec; unsigned long long tempFinalNSec = 0; uint32_t tempFinalSec = tempSec; if (tempEndNSec > 1000000000) { tempFinalNSec = tempEndNSec - 1000000000; tempFinalSec = tempFinalSec + 1; } else { tempFinalNSec = tempEndNSec; } if (mUplinkIntrStartTime.tv_sec > tempFinalSec) { mDLDelayBufQLenTotal -= mDLDelayBufferQ[0]->BufLen; free(mDLDelayBufferQ[0]->pBufBase); delete mDLDelayBufferQ[0]; mDLDelayBufferQ.removeAt(0); } else if (mUplinkIntrStartTime.tv_sec == tempFinalSec) { if (mUplinkIntrStartTime.tv_nsec >= tempFinalNSec) { mDLDelayBufQLenTotal -= mDLDelayBufferQ[0]->BufLen; free(mDLDelayBufferQ[0]->pBufBase); delete mDLDelayBufferQ[0]; mDLDelayBufferQ.removeAt(0); } else { //remove previous data in this buffer queue, will do it in the prepare data? ALOGD("remove DL delay pre queue finish 1"); break; } } else { ALOGD("remove DL delay pre queue finish 2"); break; } } } } mBuf_Cond.signal(); }}
int SPELayer::Process_Record(short *inBuf, int inBufLength){ int retSize = inBufLength; //not enough UL buffer for process, and no processed uplink output buffer if ((mULInBufQLenTotal < mSPEProcessBufSize) && (mULOutBufferQ.size() == 0)) { ALOGD("%s,going memset 0 inBuf=%p,inBufLength=%d", __FUNCTION__, inBuf, inBufLength); memset(inBuf, 0, inBufLength); //clear the buffer data as zero retSize = 0; return retSize; //return the processed buffer size } //process input data in the buffer queue while (mULInBufQLenTotal >= mSPEProcessBufSize) { int tmpSPEProcessBufSize = mSPEProcessBufSize; int indexIn = 0; int tempULIncopysize = mULInBufferQ[0]->BufLen >> 2; //fill in the data to the process buffer while (tmpSPEProcessBufSize) { if (tempULIncopysize > 0) //get the buffer data from the first uplink input buffer queue { *(mpSPEBufferUL1 + indexIn) = *(mULInBufferQ[0]->pRead); //left channel *(mpSPEBufferUL2 + indexIn) = *(mULInBufferQ[0]->pRead + 1); //right channel mULInBufferQ[0]->pRead += 2; tempULIncopysize--; indexIn++; tmpSPEProcessBufSize -= 4; mULInBufQLenTotal -= 4; //int and short transform mULInBufferQ[0]->BufLen -= 4; //record the buffer you consumed } else //consume all the data in first queue buffer { free(mULInBufferQ[0]->pBufBase); delete mULInBufferQ[0]; mULInBufferQ.removeAt(0); tempULIncopysize = mULInBufferQ[0]->BufLen >> 2; } } //process the fill in buffer mSphEnhOps.ENH_API_Process(&mSph_Enh_ctrl);//MTK音频处理库 Dump_EPL(&mSph_Enh_ctrl.EPL_buffer, EPLBufSize * sizeof(short)); EPLTransVMDump(); BufferInfo *newOutBuffer = new BufferInfo; newOutBuffer->pBufBase = (short *) malloc(mSPEProcessBufSize); newOutBuffer->BufLen = mSPEProcessBufSize; newOutBuffer->pRead = newOutBuffer->pBufBase; newOutBuffer->pWrite = newOutBuffer->pBufBase; int indexOut = 0; int copysize = newOutBuffer->BufLen >> 2; while (copysize) { *(newOutBuffer->pWrite) = *(mpSPEBufferUL1 + indexOut); //left channel *(newOutBuffer->pWrite + 1) = *(mpSPEBufferUL2 + indexOut); //right channel newOutBuffer->pWrite += 2; indexOut++; copysize--; } Dump_PCM_Process(UPLINK, newOutBuffer->pBufBase, newOutBuffer->BufLen); mULOutBufferQ.add(newOutBuffer); mULOutBufQLenTotal += newOutBuffer->BufLen; } //process the processed output buffer queue if (mULOutBufferQ.isEmpty()) { ALOGD("%s, not enought UL output buffer", __FUNCTION__); memset(inBuf, 0, inBufLength); //return in same input buffer address retSize = 0; return retSize; //return the processed buffer size } int tmpInBufLength = inBufLength; if (mULOutBufQLenTotal < inBufLength) { tmpInBufLength = mULOutBufQLenTotal; } retSize = tmpInBufLength; int count = 0; int tempULCopy = mULOutBufferQ[0]->BufLen >> 2; while (tmpInBufLength) { if (tempULCopy > 0) //get the buffer data from the first uplink input buffer queue { *(inBuf + count) = *(mULOutBufferQ[0]->pRead); *(inBuf + count + 1) = *(mULOutBufferQ[0]->pRead + 1); mULOutBufferQ[0]->pRead += 2; tmpInBufLength -= 4; //int and short transform tempULCopy--; count += 2; mULOutBufQLenTotal -= 4; //int and short transform mULOutBufferQ[0]->BufLen -= 4; } else //consume all the data in first queue buffer { free(mULOutBufferQ[0]->pBufBase); delete mULOutBufferQ[0]; mULOutBufferQ.removeAt(0); tempULCopy = mULOutBufferQ[0]->BufLen >> 2; } } return retSize;}
阅读全文
0 0
- 录音机和录像机的输入通路SPELayer
- 录音机和录像机的输入通路
- 误差输入点和原始信号输入点之间的通路增益对系统的影响 自动控制原理
- 关于Android手机调用系统照相机和录像机的问题
- 4路车载录像机的组成选购和安装
- 简易的自定义录像机
- MediaRecorder制作的录像机
- Linux下的屏幕录像机
- 基于wince的录音机
- vc 做的录音机
- 录音机的一些问题
- 录音机的实现
- 录音机
- 录音机
- 第一个项目--修改视频播放器和录像机的界面
- python 题目一,给出一张数组map,输入起点和终点,找一通路
- EJB3.0中JNDI的绑定和多通路传输
- 计算图顶点之间的通路数 和 连通性
- Datatable 函数
- 转载自http://www.cnblogs.com/whgk/p/6074930.html 本文hibernate教程
- oracle 触发器
- 马云纽约演讲全文:再不改革教育,年轻人都要失业
- 【安全牛学习笔记】SQLMAP自动注入-INHECTION、DETECTION、TECHNIQUES、FINGERPRINT
- 录音机和录像机的输入通路SPELayer
- 最短路径及最大树的应用
- CMake 基本语法(Mastering CMake 笔记)
- <安彦>Linux上JDK、mysql、tomcat、redis等软件安装部署
- 类加载器
- 9月29日云栖精选夜读:武装到“牙齿”!阿里云发布史上最强企业云安全架构 11层防护
- 操作大数据集
- 使用Vegas怎么制作倒影效果?
- 9月29日云栖精选夜读:武装到“牙齿”!阿里云发布史上最强企业云安全架构 11层防护