void AdjustThresholds(ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], PSY_OUT_ELEMENT *psyOutElement, float *chBitDistribution, float sfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB], const int nChannels, QC_OUT_ELEMENT *qcOE, const int avgBits, const int bitresBits, const int maxBitresBits, const float maxBitFac, const int sideInfoBits) { float noRedPe, grantedPe, grantedPeCorr; int curWindowSequence; PE_DATA peData; float bitFactor; int ch; COUNT_sub_start("AdjustThresholds"); INDIRECT(1); PTR_INIT(1); FUNC(5); preparePe(&peData, psyOutChannel, sfbFormFactor, nChannels, AdjThrStateElement->peOffset); PTR_INIT(1); FUNC(3); calcPe(&peData, psyOutChannel, nChannels); MOVE(1); noRedPe = peData.pe; MOVE(1); curWindowSequence = LONG_WINDOW; ADD(1); BRANCH(1); if (nChannels==2) { ADD(2); LOGIC(1); if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) || (psyOutChannel[1].windowSequence == SHORT_WINDOW)) { MOVE(1); curWindowSequence = SHORT_WINDOW; } } else { MOVE(1); curWindowSequence = psyOutChannel[0].windowSequence; } MULT(1); ADD(1); FUNC(8); bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe+5.0f*sideInfoBits, curWindowSequence, avgBits, maxBitFac, adjThrState, AdjThrStateElement); FUNC(1); MULT(1); grantedPe = bitFactor * bits2pe((float)avgBits); INDIRECT(3); ADD(1); BRANCH(1); MOVE(1); /* min() */ PTR_INIT(1); FUNC(4); calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor), min(grantedPe, noRedPe), AdjThrStateElement->peLast, AdjThrStateElement->dynBitsLast); INDIRECT(1); MULT(1); grantedPeCorr = grantedPe * AdjThrStateElement->peCorrectionFactor; ADD(1); BRANCH(1); if (grantedPeCorr < noRedPe) { INDIRECT(2); PTR_INIT(3); FUNC(7); adaptThresholdsToPe(psyOutChannel, psyOutElement, &peData, nChannels, grantedPeCorr, &AdjThrStateElement->ahParam, &AdjThrStateElement->minSnrAdaptParam); } PTR_INIT(2); /* pointers for chBitDistribution[], peData.peChannelData[] */ LOOP(1); for (ch=0; ch<nChannels; ch++) { BRANCH(1); if (peData.pe) { DIV(1); MULT(2); ADD(2); STORE(1); chBitDistribution[ch] = 0.2f + (float)(1.0f-nChannels*0.2f) * (peData.peChannelData[ch].pe/peData.pe); } else { MOVE(1); chBitDistribution[ch] = 0.2f; } } INDIRECT(1); MOVE(1); qcOE->pe= noRedPe; INDIRECT(1); MOVE(1); AdjThrStateElement->peLast = grantedPe; COUNT_sub_end(); }
void AdjustThresholds(ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], PSY_OUT_ELEMENT *psyOutElement, float *chBitDistribution, float sfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB], const int nChannels, QC_OUT_ELEMENT *qcOE, const int avgBits, const int bitresBits, const int maxBitresBits, const float maxBitFac, const int sideInfoBits) { float noRedPe, grantedPe, grantedPeCorr; int curWindowSequence; PE_DATA peData; float bitFactor; int ch; preparePe(&peData, psyOutChannel, sfbFormFactor, nChannels, AdjThrStateElement->peOffset); calcPe(&peData, psyOutChannel, nChannels); noRedPe = peData.pe; curWindowSequence = LONG_WINDOW; if (nChannels==2) { if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) || (psyOutChannel[1].windowSequence == SHORT_WINDOW)) { curWindowSequence = SHORT_WINDOW; } } else { curWindowSequence = psyOutChannel[0].windowSequence; } bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe+5.0f*sideInfoBits, curWindowSequence, avgBits, maxBitFac, adjThrState, AdjThrStateElement); grantedPe = bitFactor * bits2pe((float)avgBits); /* min() */ calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor), min(grantedPe, noRedPe), AdjThrStateElement->peLast, AdjThrStateElement->dynBitsLast); grantedPeCorr = grantedPe * AdjThrStateElement->peCorrectionFactor; if (grantedPeCorr < noRedPe) { adaptThresholdsToPe(psyOutChannel, psyOutElement, &peData, nChannels, grantedPeCorr, &AdjThrStateElement->ahParam, &AdjThrStateElement->minSnrAdaptParam); } /* pointers for chBitDistribution[], peData.peChannelData[] */ for (ch=0; ch<nChannels; ch++) { if (peData.pe) { chBitDistribution[ch] = 0.2f + (float)(1.0f-nChannels*0.2f) * (peData.peChannelData[ch].pe/peData.pe); } else { chBitDistribution[ch] = 0.2f; } } qcOE->pe= noRedPe; AdjThrStateElement->peLast = grantedPe; }
static void adaptThresholdsToPe(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], PSY_OUT_ELEMENT* psyOutElement, PE_DATA *peData, const int nChannels, const float desiredPe, AH_PARAM *ahParam, MINSNR_ADAPT_PARAM *msaParam) { float noRedPe, redPe, redPeNoAH; float constPart, constPartNoAH; float nActiveLines, nActiveLinesNoAH; float desiredPeNoAH; float avgThrExp, redVal; int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB]; float thrExp[MAX_CHANNELS][MAX_GROUPED_SFB]; int iter; COUNT_sub_start("adaptThresholdsToPe"); FUNC(3); calcThreshExp(thrExp, psyOutChannel, nChannels); FUNC(3); adaptMinSnr(psyOutChannel, msaParam, nChannels); FUNC(5); initAvoidHoleFlag(ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam); INDIRECT(3); MOVE(3); noRedPe = peData->pe; constPart = peData->constPart; nActiveLines = peData->nActiveLines; MULT(1); ADD(1); DIV(1); TRANS(1); avgThrExp = (float)pow(2.0f, (constPart - noRedPe)/(invRedExp*nActiveLines)); /* MULT(1); calculated above */ ADD(2); DIV(1); TRANS(1); redVal = (float)pow(2.0f, (constPart - desiredPe)/(invRedExp*nActiveLines)) - avgThrExp; BRANCH(1); MOVE(1); redVal = max(0.0f, redVal); FUNC(5); reduceThresholds(psyOutChannel, ahFlag, thrExp, nChannels, redVal); FUNC(3); calcPe(peData, psyOutChannel, nChannels); INDIRECT(1); MOVE(1); redPe = peData->pe; MOVE(1); iter = 0; LOOP(1); do { PTR_INIT(3); FUNC(7); calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData, ahFlag, psyOutChannel, nChannels); ADD(2); BRANCH(1); MOVE(1); desiredPeNoAH = max(desiredPe - (redPe - redPeNoAH), 0); BRANCH(1); if (nActiveLinesNoAH > 0) { MULT(1); ADD(1); DIV(1); TRANS(1); avgThrExp = (float)pow(2.0f, (constPartNoAH - redPeNoAH) / (invRedExp*nActiveLinesNoAH)); /* MULT(1); calculated above */ ADD(3); DIV(1); TRANS(1); redVal += (float)pow(2.0f, (constPartNoAH - desiredPeNoAH) / (invRedExp*nActiveLinesNoAH)) - avgThrExp; BRANCH(1); MOVE(1); redVal = max(0.0f, redVal); FUNC(5); reduceThresholds(psyOutChannel, ahFlag, thrExp, nChannels, redVal); } FUNC(3); calcPe(peData, psyOutChannel, nChannels); INDIRECT(1); MOVE(1); redPe = peData->pe; ADD(1); iter++; ADD(3); MISC(1); MULT(1); LOGIC(1); /* while() condition */ } while ((fabs(redPe - desiredPe) > (0.05f)*desiredPe) && (iter < 2)); MULT(1); ADD(1); BRANCH(1); if (redPe < 1.15f*desiredPe) { ADD(1); FUNC(7); correctThresh(psyOutChannel, ahFlag, peData, thrExp, redVal, nChannels, desiredPe - redPe); } else { MULT(1); FUNC(5); reduceMinSnr(psyOutChannel, peData, ahFlag, nChannels, 1.05f*desiredPe); MULT(1); FUNC(7); allowMoreHoles(psyOutChannel, psyOutElement, peData, ahFlag, ahParam, nChannels, 1.05f*desiredPe); } COUNT_sub_end(); }
static void adaptThresholdsToPe(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], PSY_OUT_ELEMENT* psyOutElement, PE_DATA *peData, const int nChannels, const float desiredPe, AH_PARAM *ahParam, MINSNR_ADAPT_PARAM *msaParam) { float noRedPe, redPe, redPeNoAH; float constPart, constPartNoAH; float nActiveLines, nActiveLinesNoAH; float desiredPeNoAH; float avgThrExp, redVal; int ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB]; float thrExp[MAX_CHANNELS][MAX_GROUPED_SFB]; int iter; calcThreshExp(thrExp, psyOutChannel, nChannels); adaptMinSnr(psyOutChannel, msaParam, nChannels); initAvoidHoleFlag(ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam); noRedPe = peData->pe; constPart = peData->constPart; nActiveLines = peData->nActiveLines; avgThrExp = (float)pow(2.0f, (constPart - noRedPe)/(invRedExp*nActiveLines)); /* calculated above */ redVal = (float)pow(2.0f, (constPart - desiredPe)/(invRedExp*nActiveLines)) - avgThrExp; redVal = max(0.0f, redVal); reduceThresholds(psyOutChannel, ahFlag, thrExp, nChannels, redVal); calcPe(peData, psyOutChannel, nChannels); redPe = peData->pe; iter = 0; do { calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData, ahFlag, psyOutChannel, nChannels); desiredPeNoAH = max(desiredPe - (redPe - redPeNoAH), 0); if (nActiveLinesNoAH > 0) { avgThrExp = (float)pow(2.0f, (constPartNoAH - redPeNoAH) / (invRedExp*nActiveLinesNoAH)); /* calculated above */ redVal += (float)pow(2.0f, (constPartNoAH - desiredPeNoAH) / (invRedExp*nActiveLinesNoAH)) - avgThrExp; redVal = max(0.0f, redVal); reduceThresholds(psyOutChannel, ahFlag, thrExp, nChannels, redVal); } calcPe(peData, psyOutChannel, nChannels); redPe = peData->pe; iter++; /* while() condition */ } while ((fabs(redPe - desiredPe) > (0.05f)*desiredPe) && (iter < 2)); if (redPe < 1.15f*desiredPe) { correctThresh(psyOutChannel, ahFlag, peData, thrExp, redVal, nChannels, desiredPe - redPe); } else { reduceMinSnr(psyOutChannel, peData, ahFlag, nChannels, 1.05f*desiredPe); allowMoreHoles(psyOutChannel, psyOutElement, peData, ahFlag, ahParam, nChannels, 1.05f*desiredPe); } }