/*! * * \brief Calculate max possible scale factor for input vector * * \return Maximum scale factor * * This function can constitute a significant amount of computational complexity - very much depending on the * bitrate. Since it is a rather small function, effective assembler optimization might be possible. * */ inline INT getScalefactor(const FIXP_DBL *vector, /*!< Pointer to input vector */ INT len) /*!< Length of input vector */ { INT i; FIXP_DBL maxVal = FL2FX_DBL(0.0f); for(i=len;i!=0;i--){ maxVal |= __builtin_mips_absq_s_w(*vector++); } return fixMax((INT)0,(CntLeadingZeros(maxVal) - 1)); }
/*! \brief resets sbr decoder structure \return errorCode, 0 if successful */ SBR_ERROR resetSbrDec (HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int useLP, const int downsampleFac ) { SBR_ERROR sbrError = SBRDEC_OK; int old_lsb = hSbrDec->SynthesisQMF.lsb; int new_lsb = hHeaderData->freqBandData.lowSubband; int l, startBand, stopBand, startSlot, size; int source_scale, target_scale, delta_scale, target_lsb, target_usb, reserve; FIXP_DBL maxVal; /* overlapBuffer point to first (6) slots */ FIXP_DBL **OverlapBufferReal = hSbrDec->QmfBufferReal; FIXP_DBL **OverlapBufferImag = hSbrDec->QmfBufferImag; /* assign qmf time slots */ assignTimeSlots( hSbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, useLP); resetSbrEnvelopeCalc (&hSbrDec->SbrCalculateEnvelope); hSbrDec->SynthesisQMF.lsb = hHeaderData->freqBandData.lowSubband; hSbrDec->SynthesisQMF.usb = fixMin((INT)hSbrDec->SynthesisQMF.no_channels, (INT)hHeaderData->freqBandData.highSubband); hSbrDec->AnalysiscQMF.lsb = hSbrDec->SynthesisQMF.lsb; hSbrDec->AnalysiscQMF.usb = hSbrDec->SynthesisQMF.usb; /* The following initialization of spectral data in the overlap buffer is required for dynamic x-over or a change of the start-freq for 2 reasons: 1. If the lowband gets _wider_, unadjusted data would remain 2. If the lowband becomes _smaller_, the highest bands of the old lowband must be cleared because the whitening would be affected */ startBand = old_lsb; stopBand = new_lsb; startSlot = hHeaderData->timeStep * (hPrevFrameData->stopPos - hHeaderData->numberTimeSlots); size = fixMax(0,stopBand-startBand); /* keep already adjusted data in the x-over-area */ if (!useLP) { for (l=startSlot; l<hSbrDec->LppTrans.pSettings->overlap; l++) { FDKmemclear(&OverlapBufferReal[l][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&OverlapBufferImag[l][startBand], size*sizeof(FIXP_DBL)); } } else for (l=startSlot; l<hSbrDec->LppTrans.pSettings->overlap ; l++) { FDKmemclear(&OverlapBufferReal[l][startBand], size*sizeof(FIXP_DBL)); } /* reset LPC filter states */ startBand = fixMin(old_lsb,new_lsb); stopBand = fixMax(old_lsb,new_lsb); size = fixMax(0,stopBand-startBand); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesReal[0][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesReal[1][startBand], size*sizeof(FIXP_DBL)); if (!useLP) { FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImag[0][startBand], size*sizeof(FIXP_DBL)); FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImag[1][startBand], size*sizeof(FIXP_DBL)); } /* Rescale already processed spectral data between old and new x-over frequency. This must be done because of the separate scalefactors for lowband and highband. */ startBand = fixMin(old_lsb,new_lsb); stopBand = fixMax(old_lsb,new_lsb); if (new_lsb > old_lsb) { /* The x-over-area was part of the highband before and will now belong to the lowband */ source_scale = hSbrDec->sbrScaleFactor.ov_hb_scale; target_scale = hSbrDec->sbrScaleFactor.ov_lb_scale; target_lsb = 0; target_usb = old_lsb; } else { /* The x-over-area was part of the lowband before and will now belong to the highband */ source_scale = hSbrDec->sbrScaleFactor.ov_lb_scale; target_scale = hSbrDec->sbrScaleFactor.ov_hb_scale; /* jdr: The values old_lsb and old_usb might be wrong because the previous frame might have been "upsamling". */ target_lsb = hSbrDec->SynthesisQMF.lsb; target_usb = hSbrDec->SynthesisQMF.usb; } /* Shift left all samples of the x-over-area as much as possible An unnecessary coarse scale could cause ov_lb_scale or ov_hb_scale to be adapted and the accuracy in the next frame would seriously suffer! */ maxVal = maxSubbandSample( OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, startBand, stopBand, 0, startSlot); reserve = CntLeadingZeros(maxVal)-1; reserve = fixMin(reserve,DFRACT_BITS-1-source_scale); rescaleSubbandSamples( OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, startBand, stopBand, 0, startSlot, reserve); source_scale += reserve; delta_scale = target_scale - source_scale; if (delta_scale > 0) { /* x-over-area is dominant */ delta_scale = -delta_scale; startBand = target_lsb; stopBand = target_usb; if (new_lsb > old_lsb) { /* The lowband has to be rescaled */ hSbrDec->sbrScaleFactor.ov_lb_scale = source_scale; } else { /* The highband has be be rescaled */ hSbrDec->sbrScaleFactor.ov_hb_scale = source_scale; } } FDK_ASSERT(startBand <= stopBand); if (!useLP) { for (l=0; l<startSlot; l++) { scaleValues( OverlapBufferReal[l] + startBand, stopBand-startBand, delta_scale ); scaleValues( OverlapBufferImag[l] + startBand, stopBand-startBand, delta_scale ); } } else for (l=0; l<startSlot; l++) { scaleValues( OverlapBufferReal[l] + startBand, stopBand-startBand, delta_scale ); } /* Initialize transposer and limiter */ sbrError = resetLppTransposer (&hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband, hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, hHeaderData->freqBandData.freqBandTableNoise, hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband, hHeaderData->sbrProcSmplRate); if (sbrError != SBRDEC_OK) return sbrError; sbrError = ResetLimiterBands ( hHeaderData->freqBandData.limiterBandTable, &hHeaderData->freqBandData.noLimiterBands, hHeaderData->freqBandData.freqBandTable[0], hHeaderData->freqBandData.nSfb[0], hSbrDec->LppTrans.pSettings->patchParam, hSbrDec->LppTrans.pSettings->noOfPatches, hHeaderData->bs_data.limiterBands); return sbrError; }
void sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ INT_PCM *timeIn, /*!< pointer to input time signal */ INT_PCM *timeOut, /*!< pointer to output time signal */ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ INT_PCM *timeOutRight, /*!< pointer to output time signal */ const int strideIn, /*!< Time data traversal strideIn */ const int strideOut, /*!< Time data traversal strideOut */ HANDLE_SBR_HEADER_DATA hHeaderData,/*!< Static control data */ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, const UINT flags ) { int i, slot, reserve; int saveLbScale; int ov_len; int lastSlotOffs; FIXP_DBL maxVal; /* 1+1/3 frames of spectral data: */ FIXP_DBL **QmfBufferReal = hSbrDec->QmfBufferReal; FIXP_DBL **QmfBufferImag = hSbrDec->QmfBufferImag; /* Number of QMF timeslots in the overlap buffer: */ ov_len = hSbrDec->LppTrans.pSettings->overlap; /* Number of QMF slots per frame */ int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; /* assign qmf time slots */ if ( ((flags & SBRDEC_LOW_POWER ) ? 1 : 0) != ((hSbrDec->SynthesisQMF.flags & QMF_FLAG_LP) ? 1 : 0) ) { assignTimeSlots( hSbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, flags & SBRDEC_LOW_POWER); } if (flags & SBRDEC_ELD_GRID) { /* Choose the right low delay filter bank */ changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 ); } /* low band codec signal subband filtering */ { C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2*(64)); qmfAnalysisFiltering( &hSbrDec->AnalysiscQMF, QmfBufferReal + ov_len, QmfBufferImag + ov_len, &hSbrDec->sbrScaleFactor, timeIn, strideIn, qmfTemp ); C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2*(64)); } /* Clear upper half of spectrum */ { int nAnalysisBands = hHeaderData->numberOfAnalysisBands; if (! (flags & SBRDEC_LOW_POWER)) { for (slot = ov_len; slot < noCols+ov_len; slot++) { FDKmemclear(&QmfBufferReal[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL)); FDKmemclear(&QmfBufferImag[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL)); } } else for (slot = ov_len; slot < noCols+ov_len; slot++) { FDKmemclear(&QmfBufferReal[slot][nAnalysisBands],((64)-nAnalysisBands)*sizeof(FIXP_DBL)); } } /* Shift spectral data left to gain accuracy in transposer and adjustor */ maxVal = maxSubbandSample( QmfBufferReal, (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag, 0, hSbrDec->AnalysiscQMF.lsb, ov_len, noCols+ov_len ); reserve = fixMax(0,CntLeadingZeros(maxVal)-1) ; reserve = fixMin(reserve,DFRACT_BITS-1-hSbrDec->sbrScaleFactor.lb_scale); /* If all data is zero, lb_scale could become too large */ rescaleSubbandSamples( QmfBufferReal, (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag, 0, hSbrDec->AnalysiscQMF.lsb, ov_len, noCols+ov_len, reserve); hSbrDec->sbrScaleFactor.lb_scale += reserve; /* save low band scale, wavecoding or parametric stereo may modify it */ saveLbScale = hSbrDec->sbrScaleFactor.lb_scale; if (applyProcessing) { UCHAR * borders = hFrameData->frameInfo.borders; lastSlotOffs = borders[hFrameData->frameInfo.nEnvelopes] - hHeaderData->numberTimeSlots; FIXP_DBL degreeAlias[(64)]; /* The transposer will override most values in degreeAlias[]. The array needs to be cleared at least from lowSubband to highSubband before. */ if (flags & SBRDEC_LOW_POWER) FDKmemclear(°reeAlias[hHeaderData->freqBandData.lowSubband], (hHeaderData->freqBandData.highSubband-hHeaderData->freqBandData.lowSubband)*sizeof(FIXP_DBL)); /* Inverse filtering of lowband and transposition into the SBR-frequency range */ lppTransposer ( &hSbrDec->LppTrans, &hSbrDec->sbrScaleFactor, QmfBufferReal, degreeAlias, // only used if useLP = 1 QmfBufferImag, flags & SBRDEC_LOW_POWER, hHeaderData->timeStep, borders[0], lastSlotOffs, hHeaderData->freqBandData.nInvfBands, hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode ); /* Adjust envelope of current frame. */ calculateSbrEnvelope (&hSbrDec->sbrScaleFactor, &hSbrDec->SbrCalculateEnvelope, hHeaderData, hFrameData, QmfBufferReal, QmfBufferImag, flags & SBRDEC_LOW_POWER, degreeAlias, flags, (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag)); /* Update hPrevFrameData (to be used in the next frame) */ for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) { hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i]; } hPrevFrameData->coupling = hFrameData->coupling; hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes]; hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame; } else { /* Reset hb_scale if no highband is present, because hb_scale is considered in the QMF-synthesis */ hSbrDec->sbrScaleFactor.hb_scale = saveLbScale; } for (i=0; i<LPC_ORDER; i++) { /* Store the unmodified qmf Slots values (required for LPC filtering) */ if (! (flags & SBRDEC_LOW_POWER)) { FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesReal[i], QmfBufferReal[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL)); FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImag[i], QmfBufferImag[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL)); } else FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesReal[i], QmfBufferReal[noCols-LPC_ORDER+i], hSbrDec->AnalysiscQMF.lsb*sizeof(FIXP_DBL)); } /* Synthesis subband filtering. */ if ( ! (flags & SBRDEC_PS_DECODED) ) { { int outScalefactor = 0; if (h_ps_d != NULL) { h_ps_d->procFrameBased = 1; /* we here do frame based processing */ } sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel, QmfBufferReal, (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag, hSbrDec->SynthesisQMF.no_col, &outScalefactor ); qmfChangeOutScalefactor(&hSbrDec->SynthesisQMF, outScalefactor ); { C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2*(64)); qmfSynthesisFiltering( &hSbrDec->SynthesisQMF, QmfBufferReal, (flags & SBRDEC_LOW_POWER) ? NULL : QmfBufferImag, &hSbrDec->sbrScaleFactor, hSbrDec->LppTrans.pSettings->overlap, timeOut, strideOut, qmfTemp); C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2*(64)); } } } else { /* (flags & SBRDEC_PS_DECODED) */ INT i, sdiff, outScalefactor, scaleFactorLowBand, scaleFactorHighBand; SCHAR scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->SynthesisQMF; HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->SynthesisQMF; /* adapt scaling */ sdiff = hSbrDec->sbrScaleFactor.lb_scale - reserve; /* Scaling difference */ scaleFactorHighBand = sdiff - hSbrDec->sbrScaleFactor.hb_scale; /* Scale of current high band */ scaleFactorLowBand_ov = sdiff - hSbrDec->sbrScaleFactor.ov_lb_scale; /* Scale of low band overlapping QMF data */ scaleFactorLowBand_no_ov = sdiff - hSbrDec->sbrScaleFactor.lb_scale; /* Scale of low band current QMF data */ outScalefactor = 0; /* Initial output scale */ if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot based processing copy filter states */ { /* procFrameBased will be unset later */ /* copy filter states from left to right */ FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, ((640)-(64))*sizeof(FIXP_QSS)); } /* scale ALL qmf vales ( real and imag ) of mono / left channel to the same scale factor ( ov_lb_sf, lb_sf and hq_sf ) */ scalFilterBankValues( h_ps_d, /* parametric stereo decoder handle */ QmfBufferReal, /* qmf filterbank values */ QmfBufferImag, /* qmf filterbank values */ synQmf->lsb, /* sbr start subband */ hSbrDec->sbrScaleFactor.ov_lb_scale, hSbrDec->sbrScaleFactor.lb_scale, &scaleFactorLowBand_ov, /* adapt scaling values */ &scaleFactorLowBand_no_ov, /* adapt scaling values */ hSbrDec->sbrScaleFactor.hb_scale, /* current frame ( highband ) */ &scaleFactorHighBand, synQmf->no_col); /* use the same synthese qmf values for left and right channel */ synQmfRight->no_col = synQmf->no_col; synQmfRight->lsb = synQmf->lsb; synQmfRight->usb = synQmf->usb; int env=0; outScalefactor += (SCAL_HEADROOM+1); /* psDiffScale! */ { C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 2*(64)); int maxShift = 0; if (hSbrDec->sbrDrcChannel.enable != 0) { if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) { maxShift = hSbrDec->sbrDrcChannel.prevFact_exp; } if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) { maxShift = hSbrDec->sbrDrcChannel.currFact_exp; } if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) { maxShift = hSbrDec->sbrDrcChannel.nextFact_exp; } } /* copy DRC data to right channel (with PS both channels use the same DRC gains) */ FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, sizeof(SBRDEC_DRC_CHANNEL)); for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ INT outScalefactorR, outScalefactorL; outScalefactorR = outScalefactorL = outScalefactor; /* qmf timeslot of right channel */ FIXP_DBL* rQmfReal = pWorkBuffer; FIXP_DBL* rQmfImag = pWorkBuffer + 64; { if ( i == h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env] ) { initSlotBasedRotation( h_ps_d, env, hHeaderData->freqBandData.highSubband ); env++; } ApplyPsSlot( h_ps_d, /* parametric stereo decoder handle */ (QmfBufferReal + i), /* one timeslot of left/mono channel */ (QmfBufferImag + i), /* one timeslot of left/mono channel */ rQmfReal, /* one timeslot or right channel */ rQmfImag); /* one timeslot or right channel */ } scaleFactorLowBand = (i<(6)) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov; sbrDecoder_drcApplySlot ( /* right channel */ &hSbrDecRight->sbrDrcChannel, rQmfReal, rQmfImag, i, synQmfRight->no_col, maxShift ); outScalefactorR += maxShift; sbrDecoder_drcApplySlot ( /* left channel */ &hSbrDec->sbrDrcChannel, *(QmfBufferReal + i), *(QmfBufferImag + i), i, synQmf->no_col, maxShift ); outScalefactorL += maxShift; /* scale filter states for left and right channel */ qmfChangeOutScalefactor( synQmf, outScalefactorL ); qmfChangeOutScalefactor( synQmfRight, outScalefactorR ); { qmfSynthesisFilteringSlot( synQmfRight, rQmfReal, /* QMF real buffer */ rQmfImag, /* QMF imag buffer */ scaleFactorLowBand, scaleFactorHighBand, timeOutRight+(i*synQmf->no_channels*strideOut), strideOut, pWorkBuffer); qmfSynthesisFilteringSlot( synQmf, *(QmfBufferReal + i), /* QMF real buffer */ *(QmfBufferImag + i), /* QMF imag buffer */ scaleFactorLowBand, scaleFactorHighBand, timeOut+(i*synQmf->no_channels*strideOut), strideOut, pWorkBuffer); } } /* no_col loop i */ /* scale back (6) timeslots look ahead for hybrid filterbank to original value */ rescalFilterBankValues( h_ps_d, QmfBufferReal, QmfBufferImag, synQmf->lsb, synQmf->no_col ); C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2*(64)); } } sbrDecoder_drcUpdateChannel( &hSbrDec->sbrDrcChannel ); /* Update overlap buffer Even bands above usb are copied to avoid outdated spectral data in case the stop frequency raises. */ if (hSbrDec->LppTrans.pSettings->overlap > 0) { if (! (flags & SBRDEC_LOW_POWER)) { for ( i=0; i<hSbrDec->LppTrans.pSettings->overlap; i++ ) { FDKmemcpy(QmfBufferReal[i], QmfBufferReal[i+noCols], (64)*sizeof(FIXP_DBL)); FDKmemcpy(QmfBufferImag[i], QmfBufferImag[i+noCols], (64)*sizeof(FIXP_DBL)); } } else for ( i=0; i<hSbrDec->LppTrans.pSettings->overlap; i++ ) { FDKmemcpy(QmfBufferReal[i], QmfBufferReal[i+noCols], (64)*sizeof(FIXP_DBL)); } } hSbrDec->sbrScaleFactor.ov_lb_scale = saveLbScale; /* Save current frame status */ hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag; } // sbr_dec()
static void CTns_Filter (FIXP_DBL *spec, int size, int inc, FIXP_TCC coeff [], int order) { // - Simple all-pole filter of order "order" defined by // y(n) = x(n) - a(2)*y(n-1) - ... - a(order+1)*y(n-order) // // - The state variables of the filter are initialized to zero every time // // - The output data is written over the input data ("in-place operation") // // - An input vector of "size" samples is processed and the index increment // to the next data sample is given by "inc" int i,j,N; FIXP_DBL *pSpec; FIXP_DBL maxVal=FL2FXCONST_DBL(0.0); INT s; FDK_ASSERT(order <= TNS_MAXIMUM_ORDER); C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER); FDKmemclear(state, order*sizeof(FIXP_DBL)); for (i=0; i<size; i++) { maxVal = fixMax(maxVal,fixp_abs(spec[i])); } if ( maxVal > FL2FXCONST_DBL(0.03125*0.70710678118) ) s = fixMax(CntLeadingZeros(maxVal)-6,0); else s = fixMax(CntLeadingZeros(maxVal)-5,0); s = fixMin(s,2); s = s-1; if (inc == -1) pSpec = &spec[size - 1]; else pSpec = &spec[0]; FIXP_TCC *pCoeff; #define FIRST_PART_FLTR \ FIXP_DBL x, *pState = state; \ pCoeff = coeff; \ \ if (s < 0) \ x = (pSpec [0]>>1) + fMultDiv2 (*pCoeff++, pState [0]) ; \ else \ x = (pSpec [0]<<s) + fMultDiv2 (*pCoeff++, pState [0]) ; #define INNER_FLTR_INLINE \ x = fMultAddDiv2 (x, *pCoeff, pState [1]); \ pState [0] = pState [1] - (fMultDiv2 (*pCoeff++, x) <<2) ; \ pState++; #define LAST_PART_FLTR \ if (s < 0) \ *pSpec = x << 1; \ else \ *pSpec = x >> s; \ *pState =(-x) << 1; \ pSpec += inc ; if (order>8) { N = (order-1)&7; for (i = size ; i != 0 ; i--) { FIRST_PART_FLTR for (j = N; j > 0 ; j--) { INNER_FLTR_INLINE } INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE LAST_PART_FLTR } } else if (order>4) {