From 46ba3676b854acbc69a4c7845f578d4c2886377b Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 8 Apr 2016 10:52:42 -0700 Subject: AAC/SBR encoder improvements * AAC-Encoder - AAC-ELD core encoder audio quality tuning. Update tuning tables, configure bitreservoir size and adapt afterburner iteration value. Modified file(s): libAACenc/src/aacenc.h libAACenc/src/aacenc_lib.cpp libAACenc/src/adj_thr.cpp libAACenc/src/adj_thr.h libAACenc/src/adj_thr_data.h libAACenc/src/bandwidth.cpp libAACenc/src/pnsparam.cpp libAACenc/src/qc_main.cpp - Introduze dead zone quantizer for ELD to improve audio quality at certain configurations. Modified file(s): libAACenc/src/aacenc_lib.cpp libAACenc/src/adj_thr.cpp libAACenc/src/adj_thr.h libAACenc/src/qc_data.h libAACenc/src/qc_main.cpp libAACenc/src/quantize.cpp libAACenc/src/quantize.h libAACenc/src/sf_estim.cpp libAACenc/src/sf_estim.h - Revise TNS module to improve ELD audio quality. - Use new window function and separate prediction gain according TNS filters. - Add missing memory initilization to TNS configuration. Modified file(s): libAACenc/src/aacenc_lib.cpp libAACenc/src/aacenc_tns.cpp libAACenc/src/aacenc_tns.h libAACenc/src/psy_main.cpp libAACenc/src/tns_func.h * SBR-Encoder - Revise frequency resolution calculation and handle differently depending on number of envelopes and split frames decision. - Add and adjust ELD SBR tuning tables. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/fram_gen.cpp libSBRenc/src/fram_gen.h libSBRenc/src/mh_det.cpp libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/sbr_rom.cpp libSBRenc/src/tran_det.cpp - Replace ELD transient detector with fast implementation. Modified file(s): libSBRenc/src/env_est.cpp libSBRenc/src/env_est.h libSBRenc/src/fram_gen.cpp libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h * FDK-Library - Introduce generic compare function in tools library. Modified file(s): libFDK/include/fixpoint_math.h libFDK/src/FDK_core.cpp * SBR-Encoder - Revise ELD frame splitter to improve bit distribution. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/fram_gen.cpp libSBRenc/src/fram_gen.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h - Configure amplitude resolution according the tonality of the audio signal. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/nf_est.cpp libSBRenc/src/nf_est.h libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/ton_corr.cpp libSBRenc/src/ton_corr.h libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h Change-Id: Ie0672b989a06ee63b50240616b8d1d4b790b6cb2 --- libSBRenc/src/env_est.cpp | 175 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 168 insertions(+), 7 deletions(-) (limited to 'libSBRenc/src/env_est.cpp') diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp index 929f229..4fcda51 100644 --- a/libSBRenc/src/env_est.cpp +++ b/libSBRenc/src/env_est.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -103,6 +103,114 @@ static const UCHAR panTable[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24}, static const UCHAR maxIndex[2] = {9, 5}; +/****************************************************************************** + Functionname: FDKsbrEnc_GetTonality +******************************************************************************/ +/***************************************************************************/ +/*! + + \brief Calculates complete energy per band from the energy values + of the QMF subsamples. + + \brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas() + \brief noEstPerFrame - number of estimations per frame + \brief startIndex - start index for the quota matrix + \brief Energies - energy matrix + \brief startBand - start band + \brief stopBand - number of QMF bands + \brief numberCols - number of QMF subsamples + + \return mean tonality of the 5 bands with the highest energy + scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT + +****************************************************************************/ +static FIXP_DBL FDKsbrEnc_GetTonality( + const FIXP_DBL *const *quotaMatrix, + const INT noEstPerFrame, + const INT startIndex, + const FIXP_DBL *const *Energies, + const UCHAR startBand, + const INT stopBand, + const INT numberCols + ) +{ + UCHAR b, e, k; + INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = { -1, -1, -1, -1, -1 }; + FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) }; + FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */ + UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */ + FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) }; + FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f); + FIXP_DBL energyBand[QMF_CHANNELS]; + INT maxNEnergyValues; /* max. number of max. energy values */ + + /*** Sum up energies for each band ***/ + FDK_ASSERT(numberCols==15||numberCols==16); + /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the + energyBands are initialized with the [15]th column. + The rest of the column energies are added in the next step. */ + if (numberCols==15) { + for (b=startBand; b>4; + } + } + + for (k=0; k<15; k++) { + for (b=startBand; b>4; + } + } + + /*** Determine 5 highest band-energies ***/ + maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand-startBand); + + /* Get min. value in energyMax array */ + energyMaxMin = energyMax[0] = energyBand[startBand]; + no_enMaxBand[0] = startBand; + posEnergyMaxMin = 0; + for (k=1; k energyMax[k]) { + energyMaxMin = energyMax[k]; + posEnergyMaxMin = k; + } + } + + for (b=startBand+maxNEnergyValues; b energyMaxMin) { + energyMax[posEnergyMaxMin] = energyBand[b]; + no_enMaxBand[posEnergyMaxMin] = b; + + /* Again, get min. value in energyMax array */ + energyMaxMin = energyMax[0]; + posEnergyMaxMin = 0; + for (k=1; k energyMax[k]) { + energyMaxMin = energyMax[k]; + posEnergyMaxMin = k; + } + } + } + } + /*** End determine 5 highest band-energies ***/ + + /* Get tonality values for 5 highest energies */ + for (e=0; e> 1; + } + globalTonality += tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */ + } + + return globalTonality; +} + /***************************************************************************/ /*! @@ -919,10 +1027,42 @@ FDKsbrEnc_extractSbrEnvelope1 ( hEnvChan->qmfScale); + if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { + FIXP_DBL tonality = FDKsbrEnc_GetTonality ( + hEnvChan->TonCorr.quotaMatrix, + hEnvChan->TonCorr.numberOfEstimatesPerFrame, + hEnvChan->TonCorr.startIndexMatrix, + sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset, + h_con->freqBandTable[HI][0]+1, + h_con->noQmfBands, + sbrExtrEnv->no_cols + ); + + hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0]; + hEnvChan->encEnvData.ton_HF[0] = tonality; + + /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */ + hEnvChan->encEnvData.global_tonality = (hEnvChan->encEnvData.ton_HF[0]>>1) + (hEnvChan->encEnvData.ton_HF[1]>>1); + } + + /* Transient detection COEFF Transform OK */ + if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + { + FDKsbrEnc_fastTransientDetect( + &hEnvChan->sbrFastTransientDetector, + sbrExtrEnv->YBuffer, + sbrExtrEnv->YBufferScale, + sbrExtrEnv->YBufferWriteOffset, + eData->transient_info + ); + + } + else + { FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale, @@ -931,6 +1071,7 @@ FDKsbrEnc_extractSbrEnvelope1 ( sbrExtrEnv->YBufferSzShift, sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot); + } @@ -951,7 +1092,8 @@ FDKsbrEnc_extractSbrEnvelope1 ( sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step, - sbrExtrEnv->no_cols); + sbrExtrEnv->no_cols, + &hEnvChan->encEnvData.global_tonality); } @@ -1128,12 +1270,26 @@ FDKsbrEnc_extractSbrEnvelope2 ( && ( ed->nEnvelopes == 1 ) ) { - if (hEnvChan->encEnvData.ldGrid) - hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF; - else + if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + { + /* Note: global_tonaliy_float_value == ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0))); + threshold_float_value == ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); */ + /* decision of SBR_AMP_RES */ + if (fIsLessThan( /* global_tonality > threshold ? */ + h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e, + hEnvChan->encEnvData.global_tonality, RELAXATION_SHIFT+2 ) + ) + { + hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; + } + else { + hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0; + } + } else { hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; + } - if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) { + if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) { FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, @@ -1172,7 +1328,12 @@ FDKsbrEnc_extractSbrEnvelope2 ( } /* Low energy in low band fix */ - if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)) + if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy + && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03) + /* The fix needs the non-fast transient detector running. + It sets prevLowBandEnergy and prevHighBandEnergy. */ + && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + ) { int i; -- cgit v1.2.3