/******************************************************************************* Functionname: cplxSynthesisQmfFiltering ******************************************************************************* Description: Performs inverse complex-valued subband filtering. Return: void *******************************************************************************/ void SynthesisQmfFiltering (float **sbrReal, float **sbrImag, float *timeOut, HANDLE_SBR_QMF_FILTER_BANK qmfBank) { int k, j, p; const float *p_filter = qmfBank->p_filter + 1; /* counting previous operations */ /* qmfBank->workBuffer */ for (k = 0; k < 32; k++) { inverseModulation ( *(sbrReal + k), *(sbrImag + k), qmfBank->workBuffer, qmfBank); /* qmfBank->timeBuffer[p * 64 + j] qmfBank->workBuffer[63 - j] p_filter[2 * (p * 64 + j)] */ for (p = 0; p < 4; p++) { for (j = 0; j < 64; j++) { qmfBank->timeBuffer[p * 64 + j] += p_filter[2 * (p * 64 + j)] * qmfBank->workBuffer[63 - j]; } } /* qmfBank->timeBuffer[p * L2 + j] qmfBank->workBuffer[L2 - 1 - j] p_filter[SYNTH_STRIDE * (p * L2 + j)] */ for (j = 0; j < 32; j++) { qmfBank->timeBuffer[p * 64 + j] += p_filter[2 * (p * 64 + j)] * qmfBank->workBuffer[63 - j]; } /* timeOut[31 - j] qmfBank->timeBuffer[p * 64 + 32 + j] qmfBank->workBuffer[31 - j] p_filter[2 * (p * 64 + 32 + j)] */ for (j = 0; j < 32; j++) { timeOut[31 - j] = qmfBank->timeBuffer[p * 64 + 32 + j] + p_filter[2 * (p * 64 + 32 + j)] * qmfBank->workBuffer[31 - j]; } timeOut += 32; memmove (qmfBank->timeBuffer + 32, qmfBank->timeBuffer, 288 * sizeof (float)); memset (qmfBank->timeBuffer, 0, 32 * sizeof (float)); } }
/* * * * \brief Perform complex-valued subband synthesis of the * low band and the high band and store the * time domain data in timeOut * */ void cplxSynthesisQmfFiltering( float **qmfReal, #ifndef LP_SBR_ONLY float **qmfImag, #endif float *timeOut, HANDLE_SBR_QMF_FILTER_BANK synQmf, int bUseLP, HANDLE_PS_DEC h_ps_dec, int active ) { int i, j; float *ptr_time_out; float *filterStates; float accu; int p; float qmfReal2[NO_ACTUAL_SYNTHESIS_CHANNELS]; float *imagSlot; int no_synthesis_channels; int qmf_filter_state_syn_size; float qmfRealTmp[NO_ACTUAL_SYNTHESIS_CHANNELS]; float qmfImagTmp[NO_ACTUAL_SYNTHESIS_CHANNELS]; int env; COUNT_sub_start("cplxSynthesisQmfFiltering"); MOVE(1); env = 0; FUNC(3); LOOP(1); PTR_INIT(1); MOVE(1); STORE(NO_ACTUAL_SYNTHESIS_CHANNELS); memset(qmfRealTmp,0,NO_ACTUAL_SYNTHESIS_CHANNELS*sizeof(float)); FUNC(3); LOOP(1); PTR_INIT(1); MOVE(1); STORE(NO_ACTUAL_SYNTHESIS_CHANNELS); memset(qmfImagTmp,0,NO_ACTUAL_SYNTHESIS_CHANNELS*sizeof(float)); INDIRECT(1); MOVE(1); no_synthesis_channels = synQmf->no_channels; INDIRECT(1); MOVE(1); qmf_filter_state_syn_size = synQmf->qmf_filter_state_size; INDIRECT(1); PTR_INIT(1); filterStates = synQmf->FilterStatesSyn; PTR_INIT(1); ptr_time_out = timeOut; INDIRECT(1); LOOP(1); for (i = 0; i < synQmf->no_col; i++) { const float *p_filter = synQmf->p_filter; INDIRECT(1); PTR_INIT(1); BRANCH(1); if (bUseLP) { PTR_INIT(1); imagSlot = qmfReal2; } #ifndef LP_SBR_ONLY else { PTR_INIT(1); imagSlot = *(qmfImag + i); } #endif #ifndef MONO_ONLY BRANCH(1); if(active){ ADD(1); INDIRECT(1); BRANCH(1); if(i == h_ps_dec-> aEnvStartStop[env]){ FUNC(3); INDIRECT(1); InitRotationEnvelope(h_ps_dec,env,synQmf->usb); env++; } FUNC(5); ApplyPsSlot(h_ps_dec, &qmfReal[i], &qmfImag[i], qmfRealTmp, qmfImagTmp); } #endif #ifndef LP_SBR_ONLY BRANCH(1); if(!bUseLP) { BRANCH(1); if(no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED){ PTR_INIT(4); /* pointers for qmfReal[i][j], imagSlot[j], synQmf->cos_twiddle_ds[j], synQmf->sin_twiddle_ds[j] */ LOOP(1); for (j = 0; j < no_synthesis_channels; j++){ float temp; MOVE(1); temp = qmfReal[i][j]; MULT(1); MAC(1); STORE(1); qmfReal[i][j] = synQmf->t_cos[j] * qmfReal[i][j] + synQmf->t_sin[j] * imagSlot[j]; MULT(2); ADD(1); STORE(1); imagSlot[j] = synQmf->t_cos[j] * imagSlot[j] - synQmf->t_sin[j] * temp; } } PTR_INIT(2); /* pointers for qmfReal[i][j], imagSlot[j], */ INDIRECT(1); LOOP(1); for (j = 0; j < synQmf->usb; j++) { MULT(2); STORE(2); qmfReal[i][j] *= -1.0; imagSlot[j] *= -1.0; } } #endif BRANCH(1); if (bUseLP) { FUNC(3); inverseModulationLP (qmfReal[i], imagSlot, synQmf); } #ifndef LP_SBR_ONLY else { FUNC(3); inverseModulation (qmfReal[i], imagSlot, synQmf); } #endif BRANCH(1); if (bUseLP) { PTR_INIT(2); /* pointers for qmfReal[i][j], imagSlot[j], */ LOOP(1); for (j = 0; j < no_synthesis_channels; j++) { MULT(2); STORE(2); qmfReal[i][j] = qmfReal[i][j] * 0.0625f; imagSlot[j] = imagSlot[j] * 0.0625f; } } #ifndef LP_SBR_ONLY else { PTR_INIT(2); /* pointers for qmfReal[i][j], imagSlot[j], */ LOOP(1); for (j = 0; j < no_synthesis_channels; j++) { MULT(2); STORE(2); qmfReal[i][j] = qmfReal[i][j] * 0.03125f; imagSlot[j] = imagSlot[j] * 0.03125f; } } #endif COUNT_sub_start("SynthesisPolyphaseFiltering"); MULT(1); PTR_INIT(2); /* pointers for filterStates[p * 2*no_synthesis_channels + j], imagSlot[no_synthesis_channels -1 - j] */ LOOP(1); for (j = 0; j < no_synthesis_channels; j++){ float newSample; MOVE(1); newSample = imagSlot[no_synthesis_channels -1 - j]; if(no_synthesis_channels == 32){ p_filter += NO_POLY; } LOOP(1); for (p = 0; p < NO_POLY; p++) { MAC(1); STORE(1); accu = filterStates[p * 2*no_synthesis_channels + j] + (*p_filter++) * newSample; filterStates[p * 2*no_synthesis_channels + j] = accu; } } MULT(2); PTR_INIT(1); /* pointer for filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1)] */ LOOP(1); for (p = 0; p < NO_POLY; p++) { MAC(1); STORE(1); accu = filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1) ] + (*p_filter++) * qmfReal[i][0]; filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + (no_synthesis_channels-1)] = accu; } MOVE(1); ptr_time_out[0] = accu; p_filter -= NO_POLY*2; MULT(2); PTR_INIT(2); /* pointers for filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j], qmfReal[no_synthesis_channels -1 - j] */ ADD(1); LOOP(1); for (j = 0; j < no_synthesis_channels-1; j++){ float newSample; MOVE(1); newSample = qmfReal[i][no_synthesis_channels -1 - j]; if(no_synthesis_channels == 32){ p_filter -= NO_POLY; } LOOP(1); for (p = 0; p < NO_POLY; p++) { MAC(1); STORE(1); accu = filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j] + (*--p_filter) * newSample; filterStates[p * 2*no_synthesis_channels + no_synthesis_channels + j] = accu; } MOVE(1); ptr_time_out[no_synthesis_channels - 1 - j] = accu; } ptr_time_out += no_synthesis_channels; /* Shift filter states Should be replaces by modulo operation if available */ /* FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE((qmf_filter_state_syn_size - no_synthesis_channels)); */ memmove (filterStates + no_synthesis_channels, filterStates, (qmf_filter_state_syn_size - no_synthesis_channels) * sizeof (float)); /* FUNC(2); LOOP(1); PTR_INIT(1); MOVE(1); STORE(no_synthesis_channels); */ memset (filterStates, 0, no_synthesis_channels * sizeof (float)); BRANCH(1); if(active){ FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE(no_synthesis_channels); memcpy(qmfReal[i],qmfRealTmp,sizeof(float)*no_synthesis_channels); #ifndef LP_SBR_ONLY FUNC(2); LOOP(1); PTR_INIT(2); MOVE(1); STORE(no_synthesis_channels); memcpy(qmfImag[i],qmfImagTmp,sizeof(float)*no_synthesis_channels); #endif } COUNT_sub_end(); } COUNT_sub_end(); }