diff options
Diffstat (limited to 'libAACenc/src/intensity.cpp')
-rw-r--r-- | libAACenc/src/intensity.cpp | 761 |
1 files changed, 0 insertions, 761 deletions
diff --git a/libAACenc/src/intensity.cpp b/libAACenc/src/intensity.cpp deleted file mode 100644 index 6d807f7..0000000 --- a/libAACenc/src/intensity.cpp +++ /dev/null @@ -1,761 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. - - 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. - -2. COPYRIGHT LICENSE - -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: - -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. - -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your -modifications thereto to recipients of copies in binary form. - -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. - -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. - -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." - -3. NO PATENT LICENSE - -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. - -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. - -4. DISCLAIMER - -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** - - Initial author: A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) - contents/description: intensity stereo processing - -******************************************************************************/ - -#include "intensity.h" -#include "interface.h" -#include "psy_configuration.h" -#include "psy_const.h" -#include "qc_main.h" -#include "bit_cnt.h" - -/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH */ -#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) - -/* when expanding the IS region to more SFBs only accept an error that is - * not more than IS_TOTAL_ERROR_THRESH overall and - * not more than IS_LOCAL_ERROR_THRESH for the current SFB */ -#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) -#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) - -/* the maximum allowed change of the intensity direction (unit: IS scale) - scaled with factor 0.25 - */ -#define IS_DIRECTION_DEVIATION_THRESH_SF 2 -#define IS_DIRECTION_DEVIATION_THRESH FL2FXCONST_DBL(2.0f/(1<<IS_DIRECTION_DEVIATION_THRESH_SF)) - -/* IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ -#define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f) - -/* only perform IS if IS_MIN_SFBS neighboring SFBs can be processed */ -#define IS_MIN_SFBS 6 - -/* only do IS if - * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 / IS_LEFT_RIGHT_RATIO_THRESH - * -> no IS if the panning angle is not far from the middle, MS will do */ -/* this is equivalent to a scale of +/-1.02914634566 */ -#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) - -/* scalefactor of realScale */ -#define REAL_SCALE_SF 1 - -/* scalefactor overallLoudness */ -#define OVERALL_LOUDNESS_SF 6 - -/* scalefactor for sum over max samples per goup */ -#define MAX_SFB_PER_GROUP_SF 6 - -/* scalefactor for sum of mdct spectrum */ -#define MDCT_SPEC_SF 6 - - -typedef struct -{ - - FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel correlation is above corr_thresh */ - - FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'total_error_thresh' overall. */ - - FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'local_error_thresh' for the current SFB. */ - - FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the intensity direction (unit: IS scale) */ - - FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ - - INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be processed */ - - FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not far from the middle, MS will do */ - -} INTENSITY_PARAMETERS; - - -/***************************************************************************** - - functionname: calcSfbMaxScale - - description: Calc max value in scalefactor band - - input: *mdctSpectrum - l1 - l2 - - output: none - - returns: scalefactor - -*****************************************************************************/ -static INT -calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, - const INT l1, - const INT l2) -{ - INT i; - INT sfbMaxScale; - FIXP_DBL maxSpc; - - maxSpc = FL2FXCONST_DBL(0.0); - for (i=l1; i<l2; i++) { - FIXP_DBL tmp = fixp_abs((FIXP_DBL)mdctSpectrum[i]); - maxSpc = fixMax(maxSpc, tmp); - } - sfbMaxScale = (maxSpc==FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS-2) : CntLeadingZeros(maxSpc)-1; - - return sfbMaxScale; - } - - -/***************************************************************************** - - functionname: FDKaacEnc_initIsParams - - description: Initialization of intensity parameters - - input: isParams - - output: isParams - - returns: none - -*****************************************************************************/ -static void -FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) -{ - isParams->corr_thresh = IS_CORR_THRESH; - isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; - isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; - isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH; - isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; - isParams->min_is_sfbs = IS_MIN_SFBS; - isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH; -} - - -/***************************************************************************** - - functionname: FDKaacEnc_prepareIntensityDecision - - description: Prepares intensity decision - - input: sfbEnergyLeft - sfbEnergyRight - sfbEnergyLdDataLeft - sfbEnergyLdDataRight - mdctSpectrumLeft - sfbEnergyLdDataRight - isParams - - output: hrrErr scale: none - isMask scale: none - realScale scale: LD_DATA_SHIFT + REAL_SCALE_SF - normSfbLoudness scale: none - - returns: none - -*****************************************************************************/ -static void -FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, - const FIXP_DBL *sfbEnergyRight, - const FIXP_DBL *sfbEnergyLdDataLeft, - const FIXP_DBL *sfbEnergyLdDataRight, - const FIXP_DBL *mdctSpectrumLeft, - const FIXP_DBL *mdctSpectrumRight, - const INTENSITY_PARAMETERS *isParams, - FIXP_DBL *hrrErr, - INT *isMask, - FIXP_DBL *realScale, - FIXP_DBL *normSfbLoudness, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset) -{ - INT j,sfb,sfboffs; - INT grpCounter; - - /* temporary variables to compute loudness */ - FIXP_DBL overallLoudness[MAX_NO_OF_GROUPS]; - - /* temporary variables to compute correlation */ - FIXP_DBL channelCorr[MAX_GROUPED_SFB]; - FIXP_DBL ml, mr; - FIXP_DBL prod_lr; - FIXP_DBL square_l, square_r; - FIXP_DBL tmp_l, tmp_r; - FIXP_DBL inv_n; - - FDKmemclear(channelCorr, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS*sizeof(FIXP_DBL)); - FDKmemclear(realScale, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { - overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f); - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { - INT sL,sR,s; - FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb+sfboffs]-sfbEnergyLdDataRight[sfb+sfboffs]; - - /* delimitate intensity scale value to representable range */ - realScale[sfb + sfboffs] = fixMin(FL2FXCONST_DBL(60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), fixMax(FL2FXCONST_DBL(-60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), isValue)); - - sL = fixMax(0,(CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs])-1)); - sR = fixMax(0,(CntLeadingZeros(sfbEnergyRight[sfb + sfboffs])-1)); - s = (fixMin(sL,sR)>>2)<<2; - normSfbLoudness[sfb + sfboffs] = sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs]<<s) >> 1) + ((sfbEnergyRight[sfb + sfboffs]<<s) >> 1))) >> (s>>2); - - overallLoudness[grpCounter] += normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; - /* don't do intensity if - * - panning angle is too close to the middle or - * - one channel is non-existent or - * - if it is dual mono */ - if( (sfbEnergyLeft[sfb + sfboffs] >= fMult(isParams->left_right_ratio_threshold,sfbEnergyRight[sfb + sfboffs])) - && (fMult(isParams->left_right_ratio_threshold,sfbEnergyLeft[sfb + sfboffs]) <= sfbEnergyRight[sfb + sfboffs]) ) { - - /* this will prevent post processing from considering this SFB for merging */ - hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0/8.0); - } - } - } - - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { - INT invOverallLoudnessSF; - FIXP_DBL invOverallLoudness; - - if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) { - invOverallLoudness = FL2FXCONST_DBL(0.0); - invOverallLoudnessSF = 0; - } - else { - invOverallLoudness = fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],&invOverallLoudnessSF); - invOverallLoudnessSF = invOverallLoudnessSF - OVERALL_LOUDNESS_SF + 1; /* +1: compensate fMultDiv2() in subsequent loop */ - } - invOverallLoudnessSF = fixMin(fixMax(invOverallLoudnessSF,-(DFRACT_BITS-1)),DFRACT_BITS-1); - - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { - FIXP_DBL tmp; - - tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs]>>OVERALL_LOUDNESS_SF)<<OVERALL_LOUDNESS_SF,invOverallLoudness); - - normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF); - - channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); - - FDK_ASSERT(50 >= 49); - /* max width of scalefactorband is 96; width's are always even */ - /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent loops */ - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); - - if (inv_n > FL2FXCONST_DBL(0.0f)) { - INT s,sL,sR; - - /* correlation := Pearson's product-moment coefficient */ - /* compute correlation between channels and check if it is over threshold */ - ml = FL2FXCONST_DBL(0.0f); - mr = FL2FXCONST_DBL(0.0f); - prod_lr = FL2FXCONST_DBL(0.0f); - square_l = FL2FXCONST_DBL(0.0f); - square_r = FL2FXCONST_DBL(0.0f); - - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - s = fixMin(sL,sR); - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - ml += fMultDiv2((mdctSpectrumLeft[j] << s),inv_n); // scaled with mdctScale - s + inv_n - mr += fMultDiv2((mdctSpectrumRight[j] << s),inv_n); // scaled with mdctScale - s + inv_n - } - ml = fMultDiv2(ml,inv_n); // scaled with mdctScale - s + inv_n - mr = fMultDiv2(mr,inv_n); // scaled with mdctScale - s + inv_n - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s),inv_n) - ml; // scaled with mdctScale - s + inv_n - tmp_r = fMultDiv2((mdctSpectrumRight[j] << s),inv_n) - mr; // scaled with mdctScale - s + inv_n - - prod_lr += fMultDiv2(tmp_l,tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_l += fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_r += fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 - } - prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) - square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) - square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) - - if (square_l > FL2FXCONST_DBL(0.0f) && square_r > FL2FXCONST_DBL(0.0f)) { - INT channelCorrSF = 0; - - /* local scaling of square_l and square_r is compensated after sqrt calculation */ - sL = fixMax(0,(CntLeadingZeros(square_l)-1)); - sR = fixMax(0,(CntLeadingZeros(square_r)-1)); - s = ((sL + sR)>>1)<<1; - sL = fixMin(sL,s); - sR = s-sL; - tmp = fMult(square_l<<sL,square_r<<sR); - tmp = sqrtFixp(tmp); - - FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f)); - - /* numerator and denominator have the same scaling */ - if (prod_lr < FL2FXCONST_DBL(0.0f) ) { - channelCorr[sfb + sfboffs] = -(fDivNorm(-prod_lr,tmp,&channelCorrSF)); - - } - else { - channelCorr[sfb + sfboffs] = (fDivNorm( prod_lr,tmp,&channelCorrSF)); - } - channelCorrSF = fixMin(fixMax(( channelCorrSF + ((sL+sR)>>1)),-(DFRACT_BITS-1)),DFRACT_BITS-1); - - if (channelCorrSF < 0) { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] >> (-channelCorrSF); - } - else { - /* avoid overflows due to limited computational accuracy */ - if ( fAbs(channelCorr[sfb + sfboffs]) > (((FIXP_DBL)MAXVAL_DBL)>>channelCorrSF) ) { - if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) - channelCorr[sfb + sfboffs] = -(FIXP_DBL) MAXVAL_DBL; - else - channelCorr[sfb + sfboffs] = (FIXP_DBL) MAXVAL_DBL; - } - else { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] << channelCorrSF; - } - } - } - } - - /* for post processing: hrrErr is the error in terms of (too little) correlation - * weighted with the loudness of the SFB; SFBs with small hrrErr can be merged */ - if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0/8.0)) { - continue; - } - - hrrErr[sfb + sfboffs] = fMultDiv2((FL2FXCONST_DBL(0.25f)-(channelCorr[sfb + sfboffs]>>2)),normSfbLoudness[sfb + sfboffs]); - - /* set IS mask/vector to 1, if correlation is high enough */ - if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) { - isMask[sfb + sfboffs] = 1; - } - } - } -} - - -/***************************************************************************** - - functionname: FDKaacEnc_finalizeIntensityDecision - - description: Finalizes intensity decision - - input: isParams scale: none - hrrErr scale: none - realIsScale scale: LD_DATA_SHIFT + REAL_SCALE_SF - normSfbLoudness scale: none - - output: isMask scale: none - - returns: none - -*****************************************************************************/ -static void -FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, - INT *isMask, - const FIXP_DBL *realIsScale, - const FIXP_DBL *normSfbLoudness, - const INTENSITY_PARAMETERS *isParams, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup) -{ - INT sfb,sfboffs, j; - FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f); - INT isStartValueFound = 0; - - for (sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup) { - INT startIsSfb = 0; - INT inIsBlock = 0; - INT currentIsSfbCount = 0; - FIXP_DBL overallHrrError = FL2FXCONST_DBL(0.0f); - FIXP_DBL isRegionLoudness = FL2FXCONST_DBL(0.0f); - - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { - if (isMask[sfboffs + sfb] == 1) { - if (currentIsSfbCount == 0) { - startIsSfb = sfboffs + sfb; - } - if (isStartValueFound==0) { - isScaleLast = realIsScale[sfboffs + sfb]; - isStartValueFound = 1; - } - inIsBlock = 1; - currentIsSfbCount++; - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - } - else { - /* based on correlation, IS should not be used - * -> use it anyway, if overall error is below threshold - * and if local error does not exceed threshold - * otherwise: check if there are enough IS SFBs - */ - if (inIsBlock) { - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - - if ( (hrrErr[sfboffs + sfb] < (isParams->local_error_thresh>>3)) && (overallHrrError < (isParams->total_error_thresh>>MAX_SFB_PER_GROUP_SF)) ) { - currentIsSfbCount++; - /* overwrite correlation based decision */ - isMask[sfboffs + sfb] = 1; - } else { - inIsBlock = 0; - } - } - } - /* check for large direction deviation */ - if (inIsBlock) { - if( fAbs(isScaleLast-realIsScale[sfboffs + sfb]) < (isParams->direction_deviation_thresh>>(REAL_SCALE_SF+LD_DATA_SHIFT-IS_DIRECTION_DEVIATION_THRESH_SF)) ) { - isScaleLast = realIsScale[sfboffs + sfb]; - } - else{ - isMask[sfboffs + sfb] = 0; - inIsBlock = 0; - currentIsSfbCount--; - } - } - - if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) { - /* not enough SFBs -> do not use IS */ - if (currentIsSfbCount < isParams->min_is_sfbs || (isRegionLoudness < isParams->is_region_min_loudness>>MAX_SFB_PER_GROUP_SF)) { - for(j = startIsSfb; j <= sfboffs + sfb; j++) { - isMask[j] = 0; - } - isScaleLast = FL2FXCONST_DBL(0.0f); - isStartValueFound = 0; - for (j=0; j < startIsSfb; j++) { - if (isMask[j]!=0) { - isScaleLast = realIsScale[j]; - isStartValueFound = 1; - } - } - } - currentIsSfbCount = 0; - overallHrrError = FL2FXCONST_DBL(0.0f); - isRegionLoudness = FL2FXCONST_DBL(0.0f); - } - } - } -} - - -/***************************************************************************** - - functionname: FDKaacEnc_IntensityStereoProcessing - - description: Intensity stereo processing tool - - input: sfbEnergyLeft - sfbEnergyRight - mdctSpectrumLeft - mdctSpectrumRight - sfbThresholdLeft - sfbThresholdRight - sfbSpreadEnLeft - sfbSpreadEnRight - sfbEnergyLdDataLeft - sfbEnergyLdDataRight - - output: isBook - isScale - pnsData->pnsFlag - msDigest zeroed from start to sfbCnt - msMask zeroed from start to sfbCnt - mdctSpectrumRight zeroed where isBook!=0 - sfbEnergyRight zeroed where isBook!=0 - sfbSpreadEnRight zeroed where isBook!=0 - sfbThresholdRight zeroed where isBook!=0 - sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0 - sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where isBook!=0 - - returns: none - -*****************************************************************************/ -void FDKaacEnc_IntensityStereoProcessing( - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *mdctSpectrumLeft, - FIXP_DBL *mdctSpectrumRight, - FIXP_DBL *sfbThresholdLeft, - FIXP_DBL *sfbThresholdRight, - FIXP_DBL *sfbThresholdLdDataRight, - FIXP_DBL *sfbSpreadEnLeft, - FIXP_DBL *sfbSpreadEnRight, - FIXP_DBL *sfbEnergyLdDataLeft, - FIXP_DBL *sfbEnergyLdDataRight, - INT *msDigest, - INT *msMask, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset, - const INT allowIS, - INT *isBook, - INT *isScale, - PNS_DATA *RESTRICT pnsData[2] - ) -{ - INT sfb,sfboffs, j; - FIXP_DBL scale; - FIXP_DBL lr; - FIXP_DBL hrrErr[MAX_GROUPED_SFB]; - FIXP_DBL normSfbLoudness[MAX_GROUPED_SFB]; - FIXP_DBL realIsScale[MAX_GROUPED_SFB]; - INTENSITY_PARAMETERS isParams; - INT isMask[MAX_GROUPED_SFB]; - - FDKmemclear((void*)isBook,sfbCnt*sizeof(INT)); - FDKmemclear((void*)isMask,sfbCnt*sizeof(INT)); - FDKmemclear((void*)realIsScale,sfbCnt*sizeof(FIXP_DBL)); - FDKmemclear((void*)isScale,sfbCnt*sizeof(INT)); - FDKmemclear((void*)hrrErr,sfbCnt*sizeof(FIXP_DBL)); - - if (!allowIS) - return; - - FDKaacEnc_initIsParams(&isParams); - - /* compute / set the following values per SFB: - * - left/right ratio between channels - * - normalized loudness - * + loudness == average of energy in channels to 0.25 - * + normalization: division by sum of all SFB loudnesses - * - isMask (is set to 0 if channels are the same or one is 0) - */ - FDKaacEnc_prepareIntensityDecision(sfbEnergyLeft, - sfbEnergyRight, - sfbEnergyLdDataLeft, - sfbEnergyLdDataRight, - mdctSpectrumLeft, - mdctSpectrumRight, - &isParams, - hrrErr, - isMask, - realIsScale, - normSfbLoudness, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup, - sfbOffset); - - FDKaacEnc_finalizeIntensityDecision(hrrErr, - isMask, - realIsScale, - normSfbLoudness, - &isParams, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup); - - for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) { - for (sfboffs=0; sfboffs<maxSfbPerGroup; sfboffs++) { - INT sL, sR; - FIXP_DBL inv_n; - - msMask[sfb+sfboffs] = 0; - if (isMask[sfb+sfboffs] == 0) { - continue; - } - - if ( (sfbEnergyLeft[sfb+sfboffs] < sfbThresholdLeft[sfb+sfboffs]) - &&(fMult(FL2FXCONST_DBL(1.0f/1.5f),sfbEnergyRight[sfb+sfboffs]) > sfbThresholdRight[sfb+sfboffs]) ) { - continue; - } - /* NEW: if there is a big-enough IS region, switch off PNS */ - if (pnsData[0]) { - if(pnsData[0]->pnsFlag[sfb+sfboffs]) { - pnsData[0]->pnsFlag[sfb+sfboffs] = 0; - } - if(pnsData[1]->pnsFlag[sfb+sfboffs]) { - pnsData[1]->pnsFlag[sfb+sfboffs] = 0; - } - } - - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); // scaled with 2 to compensate fMultDiv2() in subsequent loop - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - - lr = FL2FXCONST_DBL(0.0f); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) - lr += fMultDiv2(fMultDiv2(mdctSpectrumLeft[j]<<sL,mdctSpectrumRight[j]<<sR),inv_n); - lr = lr<<1; - - if (lr < FL2FXCONST_DBL(0.0f)) { - /* This means OUT OF phase intensity stereo, cf. standard */ - INT s0, s1, s2; - FIXP_DBL tmp, d, ed = FL2FXCONST_DBL(0.0f); - - s0 = fixMin(sL,sR); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - d = ((mdctSpectrumLeft[j]<<s0)>>1) - ((mdctSpectrumRight[j]<<s0)>>1); - ed += fMultDiv2(d,d)>>(MDCT_SPEC_SF-1); - } - msMask[sfb+sfboffs] = 1; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],ed,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; - if (s2 & 1) { - tmp = tmp>>1; - s2 = s2+1; - } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); - scale = sqrtFixp(tmp); - if (s2 < 0) { - s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; - mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); - } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) << s2; - mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); - } - } - } - else { - /* This means IN phase intensity stereo, cf. standard */ - INT s0,s1,s2; - FIXP_DBL tmp, s, es = FL2FXCONST_DBL(0.0f); - - s0 = fixMin(sL,sR); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - s = ((mdctSpectrumLeft[j]<<s0)>>1) + ((mdctSpectrumRight[j]<<s0)>>1); - es += fMultDiv2(s,s)>>(MDCT_SPEC_SF-1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF - } - msMask[sfb+sfboffs] = 0; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],es,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; - if (s2 & 1) { - tmp = tmp>>1; - s2 = s2 + 1; - } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); - scale = sqrtFixp(tmp); - if (s2 < 0) { - s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; - mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); - } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) << s2; - mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); - } - } - } - - isBook[sfb+sfboffs] = CODE_BOOK_IS_IN_PHASE_NO; - - if ( realIsScale[sfb+sfboffs] < FL2FXCONST_DBL(0.0f) ) { - isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)-FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)) + 1; - } - else { - isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)+FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)); - } - - sfbEnergyRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbEnergyLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-1.0f); - sfbThresholdRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbThresholdLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-0.515625f); - sfbSpreadEnRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - - *msDigest = MS_SOME; - } - } -} - |