diff options
Diffstat (limited to 'libSBRenc/src/sbr_encoder.cpp')
-rw-r--r-- | libSBRenc/src/sbr_encoder.cpp | 2443 |
1 files changed, 0 insertions, 2443 deletions
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp deleted file mode 100644 index 71aab78..0000000 --- a/libSBRenc/src/sbr_encoder.cpp +++ /dev/null @@ -1,2443 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2015 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 ------------------------------------------------------------------------------------------------------------ */ - -/*************************** Fraunhofer IIS FDK Tools *********************** - - Author(s): Andreas Ehret, Tobias Chalupka - Description: SBR encoder top level processing. - -******************************************************************************/ - -#include "sbr_encoder.h" - -#include "sbr_ram.h" -#include "sbr_rom.h" -#include "sbrenc_freq_sca.h" -#include "env_bit.h" -#include "cmondata.h" -#include "sbr_misc.h" -#include "sbr.h" -#include "qmf.h" - -#include "ps_main.h" - -#define SBRENCODER_LIB_VL0 3 -#define SBRENCODER_LIB_VL1 3 -#define SBRENCODER_LIB_VL2 12 - - - -/***************************************************************************/ -/* - * SBR Delay balancing definitions. - */ - -/* - input buffer (1ch) - - |------------ 1537 -------------|-----|---------- 2048 -------------| - (core2sbr delay ) ds (read, core and ds area) -*/ - -#define SFB(dwnsmp) (32 << (dwnsmp-1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */ -#define STS(fl) (((fl)==1024)?32:30) /* SBR Time Slots: 32 for core frame length 1024, 30 for core frame length 960 */ - -#define DELAY_QMF_ANA(dwnsmp) ((320<<((dwnsmp)-1)) - (32<<((dwnsmp)-1))) /* Full bandwidth */ -#define DELAY_HYB_ANA (10*64) /* + 0.5 */ /* */ -#define DELAY_HYB_SYN (6*64 - 32) /* */ -#define DELAY_QMF_POSTPROC(dwnsmp) (32*(dwnsmp)) /* QMF postprocessing delay */ -#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp) ) /* Decoder QMF overlap */ -#define DELAY_QMF_SYN (2) /* NO_POLY/2=2.5, rounded down to 2 */ -#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */ - -/* Delay in QMF paths */ -#define DELAY_SBR(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp)*STS(fl) - 1) + DELAY_QMF_SYN) -#define DELAY_PS(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + (SFB(dwnsmp)*STS(fl)-1) + DELAY_HYB_SYN + DELAY_QMF_SYN) -#define DELAY_ELDSBR(fl,dwnsmp) ( ( ((fl)/2)*(dwnsmp) ) - 1 + DELAY_QMF_POSTPROC(dwnsmp) ) - -/* Delay differences for SBR and SBR+PS */ -#define MAX_DS_FILTER_DELAY (5) /* the additional max downsampler filter delay (source fs) */ -#define DELAY_AAC2SBR(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN) - DELAY_SBR((fl),(dwnsmp))) -#define DELAY_ELD2SBR(fl,dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)) - DELAY_ELDSBR(fl,dwnsmp)) -#define DELAY_AAC2PS(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_HYB_SYN + DELAY_QMF_SYN) - DELAY_PS(fl,dwnsmp)) /* 2048 - 463*2 */ - -/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller than the sample delay implied by DELAY_AAC2SBR */ -#define MAX_SAMPLE_DELAY (DELAY_AAC2SBR(1024,2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame length of 1024 and dual-rate sbr */ - -/***************************************************************************/ - - - -#define INVALID_TABLE_IDX -1 - -/***************************************************************************/ -/*! - - \brief Selects the SBR tuning settings to use dependent on number of - channels, bitrate, sample rate and core coder - - \return Index to the appropriate table - -****************************************************************************/ -#define DISTANCE_CEIL_VALUE 5000000 -static INT -getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ - UINT numChannels,/*! the number of channels for the core coder */ - UINT sampleRate, /*! the sampling rate of the core coder */ - AUDIO_OBJECT_TYPE core, - UINT *pBitRateClosest - ) -{ - int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0; - UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; - - #define isForThisCore(i) \ - ( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \ - ( sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD ) ) - - for (i=0; i < sbrTuningTableSize ; i++) { - if ( isForThisCore(i) ) /* tuning table is for this core codec */ - { - if ( numChannels == sbrTuningTable [i].numChannels - && sampleRate == sbrTuningTable [i].sampleRate ) - { - found = 1; - if ((bitrate >= sbrTuningTable [i].bitrateFrom) && - (bitrate < sbrTuningTable [i].bitrateTo)) { - bitRateClosestLower = bitrate; - bitRateClosestUpper = bitrate; - //FDKprintf("entry %d\n", i); - return i ; - } else { - if ( sbrTuningTable [i].bitrateFrom > bitrate ) { - if (sbrTuningTable [i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = sbrTuningTable [i].bitrateFrom; - bitRateClosestLowerIndex = i; - } - } - if ( sbrTuningTable [i].bitrateTo <= bitrate ) { - if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1; - bitRateClosestUpperIndex = i; - } - } - } - } - } - } - - if (pBitRateClosest != NULL) - { - /* If there was at least one matching tuning entry found then pick the least distance bit rate */ - if (found) - { - int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE; - if (bitRateClosestLowerIndex >= 0) { - distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate; - } - if (bitRateClosestUpperIndex >= 0) { - distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo; - } - if ( distanceUpper < distanceLower ) - { - *pBitRateClosest = bitRateClosestUpper; - } else { - *pBitRateClosest = bitRateClosestLower; - } - } else { - *pBitRateClosest = 0; - } - } - - return INVALID_TABLE_IDX; -} - -/***************************************************************************/ -/*! - - \brief Selects the PS tuning settings to use dependent on bitrate - and core coder - - \return Index to the appropriate table - -****************************************************************************/ -static INT -getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ - - INT i, paramSets = sizeof (psTuningTable) / sizeof (psTuningTable [0]); - int bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1; - UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; - - for (i = 0 ; i < paramSets ; i++) { - if ((bitrate >= psTuningTable [i].bitrateFrom) && - (bitrate < psTuningTable [i].bitrateTo)) { - return i ; - } else { - if ( psTuningTable [i].bitrateFrom > bitrate ) { - if (psTuningTable [i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = psTuningTable [i].bitrateFrom; - bitRateClosestLowerIndex = i; - } - } - if ( psTuningTable [i].bitrateTo <= bitrate ) { - if (psTuningTable [i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = psTuningTable [i].bitrateTo-1; - bitRateClosestUpperIndex = i; - } - } - } - } - - if (pBitRateClosest != NULL) - { - int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE; - if (bitRateClosestLowerIndex >= 0) { - distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate; - } - if (bitRateClosestUpperIndex >= 0) { - distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo; - } - if ( distanceUpper < distanceLower ) - { - *pBitRateClosest = bitRateClosestUpper; - } else { - *pBitRateClosest = bitRateClosestLower; - } - } - - return INVALID_TABLE_IDX; -} - -/***************************************************************************/ -/*! - - \brief In case of downsampled SBR we may need to lower the stop freq - of a tuning setting to fit into the lower half of the - spectrum ( which is sampleRate/4 ) - - \return the adapted stop frequency index (-1 -> error) - - \ingroup SbrEncCfg - -****************************************************************************/ -static INT -FDKsbrEnc_GetDownsampledStopFreq ( - const INT sampleRateCore, - const INT startFreq, - INT stopFreq, - const INT downSampleFactor - ) -{ - INT maxStopFreqRaw = sampleRateCore / 2; - INT startBand, stopBand; - HANDLE_ERROR_INFO err; - - while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) { - stopFreq--; - } - - if (FDKsbrEnc_getSbrStopFreqRAW( stopFreq, sampleRateCore) > maxStopFreqRaw) - return -1; - - err = FDKsbrEnc_FindStartAndStopBand ( - sampleRateCore<<(downSampleFactor-1), - sampleRateCore, - 32<<(downSampleFactor-1), - startFreq, - stopFreq, - &startBand, - &stopBand - ); - if (err) - return -1; - - return stopFreq; -} - - -/***************************************************************************/ -/*! - - \brief tells us, if for the given coreCoder, bitrate, number of channels - and input sampling rate an SBR setting is available. If yes, it - tells us also the core sampling rate we would need to run with - - \return a flag indicating success: yes (1) or no (0) - -****************************************************************************/ -static UINT -FDKsbrEnc_IsSbrSettingAvail ( - UINT bitrate, /*! the total bitrate in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ - UINT numOutputChannels, /*! the number of channels for the core coder */ - UINT sampleRateInput, /*! the input sample rate [in Hz] */ - UINT sampleRateCore, /*! the core's sampling rate */ - AUDIO_OBJECT_TYPE core - ) -{ - INT idx = INVALID_TABLE_IDX; - - if (sampleRateInput < 16000) - return 0; - - if (bitrate==0) { - /* map vbr quality to bitrate */ - if (vbrMode < 30) - bitrate = 24000; - else if (vbrMode < 40) - bitrate = 28000; - else if (vbrMode < 60) - bitrate = 32000; - else if (vbrMode < 75) - bitrate = 40000; - else - bitrate = 48000; - bitrate *= numOutputChannels; - } - - idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL); - - return (idx == INVALID_TABLE_IDX ? 0 : 1); -} - - -/***************************************************************************/ -/*! - - \brief Adjusts the SBR settings according to the chosen core coder - settings which are accessible via config->codecSettings - - \return A flag indicating success: yes (1) or no (0) - -****************************************************************************/ -static UINT -FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */ - UINT bitRate, /*! the total bitrate in bits/sec */ - UINT numChannels, /*! the core coder number of channels */ - UINT sampleRateCore, /*! the core coder sampling rate in Hz */ - UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */ - UINT transFac, /*! the short block to long block ratio */ - UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ - UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */ - UINT lcsMode, /*! the low complexity stereo mode */ - UINT bParametricStereo, /*!< use parametric stereo */ - AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ -{ - INT idx = INVALID_TABLE_IDX; - /* set the core codec settings */ - config->codecSettings.bitRate = bitRate; - config->codecSettings.nChannels = numChannels; - config->codecSettings.sampleFreq = sampleRateCore; - config->codecSettings.transFac = transFac; - config->codecSettings.standardBitrate = standardBitrate; - - if (bitRate < 28000) { - config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL; - config->threshold_AmpRes_FF_e = 7; - } - else if (bitRate >= 28000 && bitRate <= 48000) { - /* The float threshold is 75 - 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this - 2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2 - 128 compensates the necessary shiftfactor of 7 */ - config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f); - config->threshold_AmpRes_FF_e = 7; - } - else if (bitRate > 48000) { - config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0); - config->threshold_AmpRes_FF_e = 0; - } - - if (bitRate==0) { - /* map vbr quality to bitrate */ - if (vbrMode < 30) - bitRate = 24000; - else if (vbrMode < 40) - bitRate = 28000; - else if (vbrMode < 60) - bitRate = 32000; - else if (vbrMode < 75) - bitRate = 40000; - else - bitRate = 48000; - bitRate *= numChannels; - /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ - if (numChannels==1) { - if (sampleRateSbr==44100 || sampleRateSbr==48000) { - if (vbrMode<40) bitRate = 32000; - } - } - } - - idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL); - - if (idx != INVALID_TABLE_IDX) { - config->startFreq = sbrTuningTable[idx].startFreq ; - config->stopFreq = sbrTuningTable[idx].stopFreq ; - if (useSpeechConfig) { - config->startFreq = sbrTuningTable[idx].startFreqSpeech; - config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; - } - - /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */ - if (1 == config->downSampleFactor) { - INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq( - sampleRateCore, - config->startFreq, - config->stopFreq, - config->downSampleFactor - ); - if (dsStopFreq < 0) { - return 0; - } - - config->stopFreq = dsStopFreq; - } - - config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ; - if (core == AOT_ER_AAC_ELD) - config->init_amp_res_FF = SBR_AMP_RES_1_5; - config->noiseFloorOffset= sbrTuningTable[idx].noiseFloorOffset; - - config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel ; - config->stereoMode = sbrTuningTable[idx].stereoMode ; - config->freqScale = sbrTuningTable[idx].freqScale ; - - if (numChannels == 1) { - /* stereo case */ - switch (core) { - case AOT_AAC_LC: - if (bitRate <= (useSpeechConfig?24000U:20000U)) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ - } - break; - case AOT_ER_AAC_ELD: - if (bitRate < 36000) - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ - if (bitRate < 26000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */ - } - break; - default: - break; - } - } - else { - /* stereo case */ - switch (core) { - case AOT_AAC_LC: - if (bitRate <= 28000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ - } - break; - case AOT_ER_AAC_ELD: - if (bitRate < 72000) { - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ - } - if (bitRate < 52000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */ - } - break; - default: - break; - } - if (bitRate <= 28000) { - /* - additionally restrict frequency resolution in FIXFIX frames - to further reduce SBR payload size */ - config->freq_res_fixfix[0] = FREQ_RES_LOW; - config->freq_res_fixfix[1] = FREQ_RES_LOW; - } - } - - /* adjust usage of parametric coding dependent on bitrate and speech config flag */ - if (useSpeechConfig) - config->parametricCoding = 0; - - if (core == AOT_ER_AAC_ELD) { - if (bitRate < 28000) - config->init_amp_res_FF = SBR_AMP_RES_3_0; - config->SendHeaderDataTime = -1; - } - - if (numChannels == 1) { - if (bitRate < 16000) { - config->parametricCoding = 0; - } - } - else { - if (bitRate < 20000) { - config->parametricCoding = 0; - } - } - - config->useSpeechConfig = useSpeechConfig; - - /* PS settings */ - config->bParametricStereo = bParametricStereo; - - return 1 ; - } - else { - return 0 ; - } -} - -/***************************************************************************** - - functionname: FDKsbrEnc_InitializeSbrDefaults - description: initializes the SBR confifuration - returns: error status - input: - core codec type, - - factor of SBR to core frame length, - - core frame length - output: initialized SBR configuration - -*****************************************************************************/ -static UINT -FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, - INT downSampleFactor, - UINT codecGranuleLen - ,const INT isLowDelay - ) -{ - if ( (downSampleFactor < 1 || downSampleFactor > 2) || - (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) ) - return(0); /* error */ - - config->SendHeaderDataTime = 1000; - config->useWaveCoding = 0; - config->crcSbr = 0; - config->dynBwSupported = 1; - if (isLowDelay) - config->tran_thr = 6000; - else - config->tran_thr = 13000; - - config->parametricCoding = 1; - - config->sbrFrameSize = codecGranuleLen * downSampleFactor; - config->downSampleFactor = downSampleFactor; - - /* sbr default parameters */ - config->sbr_data_extra = 0; - config->amp_res = SBR_AMP_RES_3_0 ; - config->tran_fc = 0 ; - config->tran_det_mode = 1 ; - config->spread = 1 ; - config->stat = 0 ; - config->e = 1 ; - config->deltaTAcrossFrames = 1 ; - config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f) ; - config->dF_edge_incr = FL2FXCONST_DBL(0.3f) ; - - config->sbr_invf_mode = INVF_SWITCHED; - config->sbr_xpos_mode = XPOS_LC; - config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT; - config->sbr_xpos_level = 0; - config->useSaPan = 0; - config->dynBwEnabled = 0; - - - /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since - they are included in the tuning table */ - config->stereoMode = SBR_SWITCH_LRC; - config->ana_max_level = 6; - config->noiseFloorOffset = 0; - config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ - config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ - config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */ - config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */ - config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */ - - /* header_extra_1 */ - config->freqScale = SBR_FREQ_SCALE_DEFAULT; - config->alterScale = SBR_ALTER_SCALE_DEFAULT; - config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT; - - /* header_extra_2 */ - config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT; - config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT; - config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; - config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT; - - return 1; -} - - -/***************************************************************************** - - functionname: DeleteEnvChannel - description: frees memory of one SBR channel - returns: - - input: handle of channel - output: released handle - -*****************************************************************************/ -static void -deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut) -{ - if (hEnvCut) { - - FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr); - - FDKsbrEnc_deleteExtractSbrEnvelope (&hEnvCut->sbrExtractEnvelope); - } - -} - - -/***************************************************************************** - - functionname: sbrEncoder_ChannelClose - description: close the channel coding handle - returns: - input: phSbrChannel - output: - -*****************************************************************************/ -static void -sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) -{ - if (hSbrChannel != NULL) - { - deleteEnvChannel (&hSbrChannel->hEnvChannel); - } -} - -/***************************************************************************** - - functionname: sbrEncoder_ElementClose - description: close the channel coding handle - returns: - input: phSbrChannel - output: - -*****************************************************************************/ -static void -sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) -{ - HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement; - - if (hSbrElement!=NULL) { - if (hSbrElement->sbrConfigData.v_k_master) - FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master); - if (hSbrElement->sbrConfigData.freqBandTable[LO]) - FreeRam_Sbr_freqBandTableLO(&hSbrElement->sbrConfigData.freqBandTable[LO]); - if (hSbrElement->sbrConfigData.freqBandTable[HI]) - FreeRam_Sbr_freqBandTableHI(&hSbrElement->sbrConfigData.freqBandTable[HI]); - - FreeRam_SbrElement(phSbrElement); - } - return ; - -} - - -void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder) -{ - HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder; - - if (hSbrEncoder != NULL) - { - int el, ch; - - for (el=0; el<(8); el++) - { - if (hSbrEncoder->sbrElement[el]!=NULL) { - sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]); - } - } - - /* Close sbr Channels */ - for (ch=0; ch<(8); ch++) - { - if (hSbrEncoder->pSbrChannel[ch]) { - sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]); - FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]); - } - - if (hSbrEncoder->QmfAnalysis[ch].FilterStates) - FreeRam_Sbr_QmfStatesAnalysis((FIXP_QAS**)&hSbrEncoder->QmfAnalysis[ch].FilterStates); - - - } - - if (hSbrEncoder->hParametricStereo) - PSEnc_Destroy(&hSbrEncoder->hParametricStereo); - if (hSbrEncoder->qmfSynthesisPS.FilterStates) - FreeRam_PsQmfStatesSynthesis((FIXP_DBL**)&hSbrEncoder->qmfSynthesisPS.FilterStates); - - /* Release Overlay */ - FreeRam_SbrDynamic_RAM((FIXP_DBL**)&hSbrEncoder->pSBRdynamic_RAM); - - - FreeRam_SbrEncoder(phSbrEncoder); - } - -} - -/***************************************************************************** - - functionname: updateFreqBandTable - description: updates vk_master - returns: - - input: config handle - output: error info - -*****************************************************************************/ -static INT updateFreqBandTable( - HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - const INT downSampleFactor - ) -{ - INT k0, k2; - - if( FDKsbrEnc_FindStartAndStopBand ( - sbrConfigData->sampleFreq, - sbrConfigData->sampleFreq >> (downSampleFactor-1), - sbrConfigData->noQmfBands, - sbrHeaderData->sbr_start_frequency, - sbrHeaderData->sbr_stop_frequency, - &k0, - &k2 - ) - ) - return(1); - - - if( FDKsbrEnc_UpdateFreqScale( - sbrConfigData->v_k_master, - &sbrConfigData->num_Master, - k0, - k2, - sbrHeaderData->freqScale, - sbrHeaderData->alterScale - ) - ) - return(1); - - - sbrHeaderData->sbr_xover_band=0; - - - if( FDKsbrEnc_UpdateHiRes( - sbrConfigData->freqBandTable[HI], - &sbrConfigData->nSfb[HI], - sbrConfigData->v_k_master, - sbrConfigData->num_Master, - &sbrHeaderData->sbr_xover_band - ) - ) - return(1); - - - FDKsbrEnc_UpdateLoRes( - sbrConfigData->freqBandTable[LO], - &sbrConfigData->nSfb[LO], - sbrConfigData->freqBandTable[HI], - sbrConfigData->nSfb[HI] - ); - - - sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1; - - return (0); -} - - -/***************************************************************************** - - functionname: resetEnvChannel - description: resets parameters and allocates memory - returns: error status - input: - output: hEnv - -*****************************************************************************/ -static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv) -{ - /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function FDKsbrEnc_extractSbrEnvelope !!!*/ - hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = sbrHeaderData->sbr_noise_bands; - - - if(FDKsbrEnc_ResetTonCorrParamExtr(&hEnv->TonCorr, - sbrConfigData->xposCtrlSwitch, - sbrConfigData->freqBandTable[HI][0], - sbrConfigData->v_k_master, - sbrConfigData->num_Master, - sbrConfigData->sampleFreq, - sbrConfigData->freqBandTable, - sbrConfigData->nSfb, - sbrConfigData->noQmfBands)) - return(1); - - hEnv->sbrCodeNoiseFloor.nSfb[LO] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - hEnv->sbrCodeNoiseFloor.nSfb[HI] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - - hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO]; - hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI]; - - hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; - - hEnv->sbrCodeEnvelope.upDate = 0; - hEnv->sbrCodeNoiseFloor.upDate = 0; - - return (0); -} - -/* ****************************** FDKsbrEnc_SbrGetXOverFreq ******************************/ -/** - * @fn - * @brief calculates the closest possible crossover frequency - * @return the crossover frequency SBR accepts - * - */ -static INT -FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */ - INT xoverFreq) /*!< from core coder suggested crossover frequency */ -{ - INT band; - INT lastDiff, newDiff; - INT cutoffSb; - - UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master; - - /* Check if there is a matching cutoff frequency in the master table */ - cutoffSb = (4*xoverFreq * hEnv->sbrConfigData.noQmfBands / hEnv->sbrConfigData.sampleFreq + 1)>>1; - lastDiff = cutoffSb; - for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) { - - newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb); - - if(newDiff >= lastDiff) { - band--; - break; - } - - lastDiff = newDiff; - } - - return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq/hEnv->sbrConfigData.noQmfBands+1)>>1); -} - -/***************************************************************************** - - functionname: FDKsbrEnc_EnvEncodeFrame - description: performs the sbr envelope calculation for one element - returns: - input: - output: - -*****************************************************************************/ -INT -FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, - int iElement, - INT_PCM *samples, /*!< time samples, always interleaved */ - UINT timeInStride, /*!< time buffer channel interleaving stride */ - UINT *sbrDataBits, /*!< Size of SBR payload */ - UCHAR *sbrData, /*!< SBR payload */ - int clearOutput /*!< Do not consider any input signal */ - ) -{ - HANDLE_SBR_ELEMENT hSbrElement = NULL; - FDK_CRCINFO crcInfo; - INT crcReg; - INT ch; - INT band; - INT cutoffSb; - INT newXOver; - - if (hEnvEncoder == NULL) - return -1; - - hSbrElement = hEnvEncoder->sbrElement[iElement]; - - if (hSbrElement == NULL) - return -1; - - - /* header bitstream handling */ - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData; - - INT psHeaderActive = 0; - sbrBitstreamData->HeaderActive = 0; - - /* Anticipate PS header because of internal PS bitstream delay in order to be in sync with SBR header. */ - if ( sbrBitstreamData->CountSendHeaderData==(sbrBitstreamData->NrSendHeaderData-1) ) - { - psHeaderActive = 1; - } - - /* Signal SBR header to be written into bitstream */ - if ( sbrBitstreamData->CountSendHeaderData==0 ) - { - sbrBitstreamData->HeaderActive = 1; - } - - /* Increment header interval counter */ - if (sbrBitstreamData->NrSendHeaderData == 0) { - sbrBitstreamData->CountSendHeaderData = 1; - } - else { - if (sbrBitstreamData->CountSendHeaderData >= 0) { - sbrBitstreamData->CountSendHeaderData++; - sbrBitstreamData->CountSendHeaderData %= sbrBitstreamData->NrSendHeaderData; - } - } - - if (hSbrElement->CmonData.dynBwEnabled ) { - INT i; - for ( i = 4; i > 0; i-- ) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i-1]; - - hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc; - if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2]) - newXOver = hSbrElement->dynXOverFreqDelay[2]; - else - newXOver = hSbrElement->dynXOverFreqDelay[1]; - - /* has the crossover frequency changed? */ - if ( hSbrElement->sbrConfigData.dynXOverFreq != newXOver ) { - - /* get corresponding master band */ - cutoffSb = ((4* newXOver * hSbrElement->sbrConfigData.noQmfBands - / hSbrElement->sbrConfigData.sampleFreq)+1)>>1; - - for ( band = 0; band < hSbrElement->sbrConfigData.num_Master; band++ ) { - if ( cutoffSb == hSbrElement->sbrConfigData.v_k_master[band] ) - break; - } - FDK_ASSERT( band < hSbrElement->sbrConfigData.num_Master ); - - hSbrElement->sbrConfigData.dynXOverFreq = newXOver; - hSbrElement->sbrHeaderData.sbr_xover_band = band; - hSbrElement->sbrBitstreamData.HeaderActive=1; - psHeaderActive = 1; /* ps header is one frame delayed */ - - /* - update vk_master table - */ - if(updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - hEnvEncoder->downSampleFactor - )) - return(1); - - - /* reset SBR channels */ - INT nEnvCh = hSbrElement->sbrConfigData.nChannels; - for ( ch = 0; ch < nEnvCh; ch++ ) { - if(resetEnvChannel (&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrChannel[ch]->hEnvChannel)) - return(1); - - } - } - } - - /* - allocate space for dummy header and crc - */ - crcReg = FDKsbrEnc_InitSbrBitstream(&hSbrElement->CmonData, - hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay], - MAX_PAYLOAD_SIZE*sizeof(UCHAR), - &crcInfo, - hSbrElement->sbrConfigData.sbrSyntaxFlags); - - /* Temporal Envelope Data */ - SBR_FRAME_TEMP_DATA _fData; - SBR_FRAME_TEMP_DATA *fData = &_fData; - SBR_ENV_TEMP_DATA eData[MAX_NUM_CHANNELS]; - - /* Init Temporal Envelope Data */ - { - int i; - - FDKmemclear(&eData[0], sizeof(SBR_ENV_TEMP_DATA)); - FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA)); - FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA)); - - for(i=0; i<MAX_NUM_NOISE_VALUES; i++) - fData->res[i] = FREQ_RES_HIGH; - } - - - if (!clearOutput) - { - /* - * Transform audio data into QMF domain - */ - for(ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) - { - HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel; - HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope; - - if(hSbrElement->elInfo.fParametricStereo == 0) - { - QMF_SCALE_FACTOR tmpScale; - FIXP_DBL **pQmfReal, **pQmfImag; - C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) - - - /* Obtain pointers to QMF buffers. */ - pQmfReal = sbrExtrEnv->rBuffer; - pQmfImag = sbrExtrEnv->iBuffer; - - qmfAnalysisFiltering( hSbrElement->hQmfAnalysis[ch], - pQmfReal, - pQmfImag, - &tmpScale, - samples + hSbrElement->elInfo.ChannelIndex[ch], - timeInStride, - qmfWorkBuffer ); - - h_envChan->qmfScale = tmpScale.lb_scale + 7; - - - C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) - - } /* fParametricStereo == 0 */ - - - /* - Parametric Stereo processing - */ - if (hSbrElement->elInfo.fParametricStereo) - { - INT error = noError; - - - /* Limit Parametric Stereo to one instance */ - FDK_ASSERT(ch == 0); - - - if(error == noError){ - /* parametric stereo processing: - - input: - o left and right time domain samples - - processing: - o stereo qmf analysis - o stereo hybrid analysis - o ps parameter extraction - o downmix + hybrid synthesis - - output: - o downmixed qmf data is written to sbrExtrEnv->rBuffer and sbrExtrEnv->iBuffer - */ - SCHAR qmfScale; - INT_PCM* pSamples[2] = {samples + hSbrElement->elInfo.ChannelIndex[0],samples + hSbrElement->elInfo.ChannelIndex[1]}; - error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( hEnvEncoder->hParametricStereo, - pSamples, - timeInStride, - hSbrElement->hQmfAnalysis, - sbrExtrEnv->rBuffer, - sbrExtrEnv->iBuffer, - samples + hSbrElement->elInfo.ChannelIndex[ch], - &hEnvEncoder->qmfSynthesisPS, - &qmfScale, - psHeaderActive ); - if (noError != error) - { - error = handBack(error); - } - h_envChan->qmfScale = (int)qmfScale; - } - - - } /* if (hEnvEncoder->hParametricStereo) */ - - /* - - Extract Envelope relevant things from QMF data - - */ - FDKsbrEnc_extractSbrEnvelope1( - &hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrBitstreamData, - h_envChan, - &hSbrElement->CmonData, - &eData[ch], - fData - ); - - } /* hEnvEncoder->sbrConfigData.nChannels */ - } - - /* - Process Envelope relevant things and calculate envelope data and write payload - */ - FDKsbrEnc_extractSbrEnvelope2( - &hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo : NULL, - &hSbrElement->sbrBitstreamData, - &hSbrElement->sbrChannel[0]->hEnvChannel, - &hSbrElement->sbrChannel[1]->hEnvChannel, - &hSbrElement->CmonData, - eData, - fData, - clearOutput - ); - - /* - format payload, calculate crc - */ - FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, hSbrElement->sbrConfigData.sbrSyntaxFlags); - - /* - save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE - */ - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf); - - if(hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > (MAX_PAYLOAD_SIZE<<3)) - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay]=0; - - /* While filling the Delay lines, sbrData is NULL */ - if (sbrData) { - *sbrDataBits = hSbrElement->payloadDelayLineSize[0]; - FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], (hSbrElement->payloadDelayLineSize[0]+7)>>3); - - - } - - -/*******************************/ - - if (hEnvEncoder->fTimeDomainDownsampling) - { - int ch; - int nChannels = hSbrElement->sbrConfigData.nChannels; - - for (ch=0; ch < nChannels; ch++) - { - INT nOutSamples; - - FDKaacEnc_Downsample(&hSbrElement->sbrChannel[ch]->downSampler, - samples + hSbrElement->elInfo.ChannelIndex[ch] + hEnvEncoder->bufferOffset, - hSbrElement->sbrConfigData.frameSize, - timeInStride, - samples + hSbrElement->elInfo.ChannelIndex[ch], - &nOutSamples, - hEnvEncoder->nChannels); - } - } /* downsample */ - - - return (0); -} - -/***************************************************************************** - - functionname: createEnvChannel - description: initializes parameters and allocates memory - returns: error status - input: - output: hEnv - -*****************************************************************************/ - -static INT -createEnvChannel (HANDLE_ENV_CHANNEL hEnv, - INT channel - ,UCHAR* dynamic_RAM - ) -{ - FDKmemclear(hEnv,sizeof (struct ENV_CHANNEL)); - - if ( FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, - channel) ) - { - return(1); - } - - if ( FDKsbrEnc_CreateExtractSbrEnvelope (&hEnv->sbrExtractEnvelope, - channel - ,/*chan*/0 - ,dynamic_RAM - ) ) - { - return(1); - } - - return 0; -} - -/***************************************************************************** - - functionname: initEnvChannel - description: initializes parameters - returns: error status - input: - output: - -*****************************************************************************/ -static INT -initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv, - sbrConfigurationPtr params, - ULONG statesInitFlag - ,INT chanInEl - ,UCHAR* dynamic_RAM - ) -{ - int frameShift, tran_off=0; - INT e; - INT tran_fc; - INT timeSlots, timeStep, startIndex; - INT noiseBands[2] = { 3, 3 }; - - e = 1 << params->e; - - FDK_ASSERT(params->e >= 0); - - hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0]; - hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1]; - hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow; - - hEnv->fLevelProtect = 0; - - hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; - - hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode; - - if (hEnv->encEnvData.sbr_xpos_mode == XPOS_SWITCHED) { - /* - no other type than XPOS_MDCT or XPOS_SPEECH allowed, - but enable switching - */ - sbrConfigData->switchTransposers = TRUE; - hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT; - } - else { - sbrConfigData->switchTransposers = FALSE; - } - - hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl; - - - /* extended data */ - if(params->parametricCoding) { - hEnv->encEnvData.extended_data = 1; - } - else { - hEnv->encEnvData.extended_data = 0; - } - - hEnv->encEnvData.extension_size = 0; - - startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands; - - switch (params->sbrFrameSize) { - case 2304: - timeSlots = 18; - break; - case 2048: - case 1024: - case 512: - timeSlots = 16; - break; - case 1920: - case 960: - case 480: - timeSlots = 15; - break; - case 1152: - timeSlots = 9; - break; - default: - return (1); /* Illegal frame size */ - } - - timeStep = sbrConfigData->noQmfSlots / timeSlots; - - if ( FDKsbrEnc_InitTonCorrParamExtr(params->sbrFrameSize, - &hEnv->TonCorr, - sbrConfigData, - timeSlots, - params->sbr_xpos_ctrl, - params->ana_max_level, - sbrHeaderData->sbr_noise_bands, - params->noiseFloorOffset, - params->useSpeechConfig) ) - return(1); - - hEnv->encEnvData.noOfnoisebands = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - - noiseBands[0] = hEnv->encEnvData.noOfnoisebands; - noiseBands[1] = hEnv->encEnvData.noOfnoisebands; - - hEnv->encEnvData.sbr_invf_mode = (INVF_MODE)params->sbr_invf_mode; - - if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) { - hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL; - hEnv->TonCorr.switchInverseFilt = TRUE; - } - else { - hEnv->TonCorr.switchInverseFilt = FALSE; - } - - - tran_fc = params->tran_fc; - - if (tran_fc == 0) { - tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,params->codecSettings.sampleFreq)); - } - - tran_fc = (tran_fc*4*sbrConfigData->noQmfBands/sbrConfigData->sampleFreq + 1)>>1; - - if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - frameShift = LD_PRETRAN_OFF; - tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD*timeStep; - } else - { - frameShift = 0; - switch (timeSlots) { - /* The factor of 2 is by definition. */ - case NUMBER_TIME_SLOTS_2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break; - case NUMBER_TIME_SLOTS_1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break; - default: return 1; - } - } - if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope, - sbrConfigData->noQmfSlots, - sbrConfigData->noQmfBands, startIndex, - timeSlots, timeStep, tran_off, - statesInitFlag - ,chanInEl - ,dynamic_RAM - ,sbrConfigData->sbrSyntaxFlags - ) ) - return(1); - - if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeEnvelope, - sbrConfigData->nSfb, - params->deltaTAcrossFrames, - params->dF_edge_1stEnv, - params->dF_edge_incr)) - return(1); - - if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeNoiseFloor, - noiseBands, - params->deltaTAcrossFrames, - 0,0)) - return(1); - - sbrConfigData->initAmpResFF = params->init_amp_res_FF; - - if(FDKsbrEnc_InitSbrHuffmanTables (&hEnv->encEnvData, - &hEnv->sbrCodeEnvelope, - &hEnv->sbrCodeNoiseFloor, - sbrHeaderData->sbr_amp_res)) - return(1); - - FDKsbrEnc_initFrameInfoGenerator (&hEnv->SbrEnvFrame, - params->spread, - e, - params->stat, - timeSlots, - hEnv->encEnvData.freq_res_fixfix, - hEnv->encEnvData.fResTransIsLow, - hEnv->encEnvData.ldGrid - ); - - if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) - { - INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands); - if(FDKsbrEnc_InitSbrFastTransientDetector( - &hEnv->sbrFastTransientDetector, - sbrConfigData->noQmfSlots, - bandwidth_qmf_slot, - sbrConfigData->noQmfBands, - sbrConfigData->freqBandTable[0][0] - )) - return(1); - } - - /* The transient detector has to be initialized also if the fast transient - detector was active, because the values from the transient detector - structure are used. */ - if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector, - sbrConfigData->sbrSyntaxFlags, - sbrConfigData->frameSize, - sbrConfigData->sampleFreq, - params, - tran_fc, - sbrConfigData->noQmfSlots, - sbrConfigData->noQmfBands, - hEnv->sbrExtractEnvelope.YBufferWriteOffset, - hEnv->sbrExtractEnvelope.YBufferSzShift, - frameShift, - tran_off - )) - return(1); - - - sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl; - - hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; - hEnv->encEnvData.addHarmonicFlag = 0; - - return (0); -} - -INT sbrEncoder_Open( - HANDLE_SBR_ENCODER *phSbrEncoder, - INT nElements, - INT nChannels, - INT supportPS - ) -{ - INT i; - INT errorStatus = 1; - HANDLE_SBR_ENCODER hSbrEncoder = NULL; - - if (phSbrEncoder==NULL - ) - { - goto bail; - } - - hSbrEncoder = GetRam_SbrEncoder(); - if (hSbrEncoder==NULL) { - goto bail; - } - FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER)); - - hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM(); - hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; - - for (i=0; i<nElements; i++) { - hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i); - if (hSbrEncoder->sbrElement[i]==NULL) { - goto bail; - } - FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT)); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = GetRam_Sbr_freqBandTableLO(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = GetRam_Sbr_freqBandTableHI(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = GetRam_Sbr_v_k_master(i); - if ( (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO]==NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI]==NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master==NULL) ) - { - goto bail; - } - } - - for (i=0; i<nChannels; i++) { - hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i); - if (hSbrEncoder->pSbrChannel[i]==NULL) { - goto bail; - } - - if ( createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, - i - ,hSbrEncoder->dynamicRam - ) ) - { - goto bail; - } - - } - - for (i=0; i<fixMax(nChannels,(supportPS)?2:0); i++) { - hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i); - if (hSbrEncoder->QmfAnalysis[i].FilterStates==NULL) { - goto bail; - } - } - - if (supportPS) { - if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) - { - goto bail; - } - - hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis(); - if (hSbrEncoder->qmfSynthesisPS.FilterStates==NULL) { - goto bail; - } - } /* supportPS */ - - *phSbrEncoder = hSbrEncoder; - - errorStatus = 0; - return errorStatus; - -bail: - /* Close SBR encoder instance */ - sbrEncoder_Close(&hSbrEncoder); - return errorStatus; -} - -static -INT FDKsbrEnc_Reallocate( - HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], - const INT noElements) -{ - INT totalCh = 0; - INT totalQmf = 0; - INT coreEl; - INT el=-1; - - hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */ - - for (coreEl=0; coreEl<noElements; coreEl++) - { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { - el++; - } else { - if (elInfo[coreEl].elType == ID_LFE) { - hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0]; - } - continue; - } - - SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl]; - HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el]; - - int ch; - for ( ch = 0; ch < pelInfo->nChannelsInEl; ch++ ) { - hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh]; - totalCh++; - } - /* analysis QMF */ - for ( ch = 0; ch < ((pelInfo->fParametricStereo)?2:pelInfo->nChannelsInEl); ch++ ) { - hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch]; - hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++]; - } - - /* Copy Element info */ - hSbrElement->elInfo.elType = pelInfo->elType; - hSbrElement->elInfo.instanceTag = pelInfo->instanceTag; - hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl; - hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo; - } /* coreEl */ - - return 0; -} - - - -/***************************************************************************** - - functionname: FDKsbrEnc_EnvInit - description: initializes parameters - returns: error status - input: - output: hEnv - -*****************************************************************************/ -static -INT FDKsbrEnc_EnvInit ( - HANDLE_SBR_ELEMENT hSbrElement, - sbrConfigurationPtr params, - INT *coreBandWith, - AUDIO_OBJECT_TYPE aot, - int nBitstrDelay, - int nElement, - const int headerPeriod, - ULONG statesInitFlag, - int fTimeDomainDownsampling - ,UCHAR *dynamic_RAM - ) -{ - UCHAR *bitstreamBuffer; - int ch, i; - - if ((params->codecSettings.nChannels < 1) || (params->codecSettings.nChannels > MAX_NUM_CHANNELS)){ - return(1); - } - - /* initialize the encoder handle and structs*/ - bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay]; - - /* init and set syntax flags */ - hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; - - switch (aot) { - case AOT_ER_AAC_ELD: - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; - break; - default: - break; - } - if (params->crcSbr) { - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; - } - - hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS>>(2-params->downSampleFactor); - switch (hSbrElement->sbrConfigData.noQmfBands) - { - case 64: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6; - break; - case 32: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>5; - break; - default: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6; - return(2); - } - - FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, MAX_PAYLOAD_SIZE*sizeof(UCHAR), 0, BS_WRITER); - - /* - now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData, - */ - hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels; - - if(params->codecSettings.nChannels == 2) - hSbrElement->sbrConfigData.stereoMode = params->stereoMode; - else - hSbrElement->sbrConfigData.stereoMode = SBR_MONO; - - hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; - - hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq; - - hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; - if (params->SendHeaderDataTime > 0 ) { - - if (headerPeriod==-1) { - - hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq - / (1000 * hSbrElement->sbrConfigData.frameSize)); - hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData,1); - } - else { - /* assure header period at least once per second */ - hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(fixMax(headerPeriod,1),(hSbrElement->sbrConfigData.sampleFreq/hSbrElement->sbrConfigData.frameSize)); - } - } - else { - hSbrElement->sbrBitstreamData.NrSendHeaderData = 0; - } - - hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra; - hSbrElement->sbrBitstreamData.HeaderActive = 0; - hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq; - hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq; - hSbrElement->sbrHeaderData.sbr_xover_band = 0; - hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0; - - /* data_extra */ - if (params->sbr_xpos_ctrl!= SBR_XPOS_CTRL_DEFAULT) - hSbrElement->sbrHeaderData.sbr_data_extra = 1; - - hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res; - - /* header_extra_1 */ - hSbrElement->sbrHeaderData.freqScale = params->freqScale; - hSbrElement->sbrHeaderData.alterScale = params->alterScale; - hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands; - hSbrElement->sbrHeaderData.header_extra_1 = 0; - - if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) || - (params->alterScale != SBR_ALTER_SCALE_DEFAULT) || - (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) - { - hSbrElement->sbrHeaderData.header_extra_1 = 1; - } - - /* header_extra_2 */ - hSbrElement->sbrHeaderData.sbr_limiter_bands = params->sbr_limiter_bands; - hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains; - - if ((hSbrElement->sbrConfigData.sampleFreq > 48000) && - (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) - { - hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE; - } - - hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq; - hSbrElement->sbrHeaderData.sbr_smoothing_length = params->sbr_smoothing_length; - hSbrElement->sbrHeaderData.header_extra_2 = 0; - - if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) || - (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) || - (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) || - (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) - { - hSbrElement->sbrHeaderData.header_extra_2 = 1; - } - - /* other switches */ - hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; - hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; - hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m; - hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e; - - /* init freq band table */ - if(updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - params->downSampleFactor - )) - { - return(1); - } - - /* now create envelope ext and QMF for each available channel */ - for ( ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++ ) { - - if ( initEnvChannel(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrChannel[ch]->hEnvChannel, - params, - statesInitFlag - ,ch - ,dynamic_RAM - ) ) - { - return(1); - } - - - } /* nChannels */ - - /* reset and intialize analysis qmf */ - for ( ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)?2:hSbrElement->sbrConfigData.nChannels); ch++ ) - { - int err; - UINT qmfFlags = (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? QMF_FLAG_CLDFB : 0; - if (statesInitFlag) - qmfFlags &= ~QMF_FLAG_KEEP_STATES; - else - qmfFlags |= QMF_FLAG_KEEP_STATES; - - err = qmfInitAnalysisFilterBank( hSbrElement->hQmfAnalysis[ch], - (FIXP_QAS*)hSbrElement->hQmfAnalysis[ch]->FilterStates, - hSbrElement->sbrConfigData.noQmfSlots, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, - qmfFlags ); - if (0!=err) { - return err; - } - } - - /* */ - hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq; - hSbrElement->CmonData.dynBwEnabled = (params->dynBwSupported && params->dynBwEnabled); - hSbrElement->CmonData.dynXOverFreqEnc = FDKsbrEnc_SbrGetXOverFreq( hSbrElement, hSbrElement->CmonData.xOverFreq); - for ( i = 0; i < 5; i++ ) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc; - hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels; - hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq; - - /* Update Bandwith to be passed to the core encoder */ - *coreBandWith = hSbrElement->CmonData.xOverFreq; - - return(0); - } - -INT sbrEncoder_GetInBufferSize(int noChannels) -{ - INT temp; - - temp = (2048); - temp += 1024 + MAX_SAMPLE_DELAY; - temp *= noChannels; - temp *= sizeof(INT_PCM); - return temp; -} - -/* - * Encode Dummy SBR payload frames to fill the delay lines. - */ -static -INT FDKsbrEnc_DelayCompensation ( - HANDLE_SBR_ENCODER hEnvEnc, - INT_PCM *timeBuffer - ) -{ - int n, el; - - for (n=hEnvEnc->nBitstrDelay; n>0; n--) - { - for (el=0; el<hEnvEnc->noElements; el++) - { - if (FDKsbrEnc_EnvEncodeFrame( - hEnvEnc, - el, - timeBuffer + hEnvEnc->downsampledOffset, - hEnvEnc->sbrElement[el]->sbrConfigData.nChannels, - NULL, - NULL, - 1 - )) - return -1; - } - sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer); - } - return 0; -} - -UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) -{ - UINT newBitRate; - INT index; - - FDK_ASSERT(numChannels > 0 && numChannels <= 2); - if (aot == AOT_PS) { - if (numChannels == 2) { - index = getPsTuningTableIndex(bitRate, &newBitRate); - if (index == INVALID_TABLE_IDX) { - bitRate = newBitRate; - } - /* Set numChannels to 1 because for PS we need a SBR SCE (mono) element. */ - numChannels = 1; - } else { - return 0; - } - } - index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, &newBitRate); - if (index != INVALID_TABLE_IDX) { - newBitRate = bitRate; - } - - return newBitRate; -} - -UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) -{ - UINT isPossible=(AOT_PS==aot)?0:1; - return isPossible; -} - -INT sbrEncoder_Init( - HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], - int noElements, - INT_PCM *inputBuffer, - INT *coreBandwidth, - INT *inputBufferOffset, - INT *numChannels, - INT *coreSampleRate, - UINT *downSampleFactor, - INT *frameLength, - AUDIO_OBJECT_TYPE aot, - int *delay, - int transformFactor, - const int headerPeriod, - ULONG statesInitFlag - ) -{ - HANDLE_ERROR_INFO errorInfo = noError; - sbrConfiguration sbrConfig[(8)]; - INT error = 0; - INT lowestBandwidth; - /* Save input parameters */ - INT inputSampleRate = *coreSampleRate; - int coreFrameLength = *frameLength; - int inputBandWidth = *coreBandwidth; - int inputChannels = *numChannels; - - int downsampledOffset = 0; - int sbrOffset = 0; - int downsamplerDelay = 0; - int timeDomainDownsample = 0; - int nBitstrDelay = 0; - int highestSbrStartFreq, highestSbrStopFreq; - int lowDelay = 0; - int usePs = 0; - - /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ - if (!sbrEncoder_IsSingleRatePossible(aot)) { - *downSampleFactor = 2; - } - - - - if ( aot==AOT_PS ) { - usePs = 1; - } - if ( aot==AOT_ER_AAC_ELD ) { - lowDelay = 1; - } - else if ( aot==AOT_ER_AAC_LD ) { - error = 1; - goto bail; - } - - /* Parametric Stereo */ - if ( usePs ) { - if ( *numChannels == 2 && noElements == 1) { - /* Override Element type in case of Parametric stereo */ - elInfo[0].elType = ID_SCE; - elInfo[0].fParametricStereo = 1; - elInfo[0].nChannelsInEl = 1; - /* core encoder gets downmixed mono signal */ - *numChannels = 1; - } else { - error = 1; - goto bail; - } - } /* usePs */ - - /* set the core's sample rate */ - switch (*downSampleFactor) { - case 1: - *coreSampleRate = inputSampleRate; - break; - case 2: - *coreSampleRate = inputSampleRate>>1; - break; - default: - *coreSampleRate = inputSampleRate>>1; - return 0; /* return error */ - } - - /* check whether SBR setting is available for the current encoder configuration (bitrate, coreSampleRate) */ - { - int delayDiff = 0; - int el, coreEl; - - /* Check if every element config is feasible */ - for (coreEl=0; coreEl<noElements; coreEl++) - { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) { - continue; - } - /* check if desired configuration is available */ - if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) ) - { - error = 1; - goto bail; - } - } - - /* Determine Delay balancing and new encoder delay */ - if (lowDelay) { - { - delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor); - *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor); - } - } - else if (usePs) { - delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor); - *delay = DELAY_PS(coreFrameLength,*downSampleFactor); - } - else { - delayDiff = DELAY_AAC2SBR(coreFrameLength,*downSampleFactor); - delayDiff += (*delay * *downSampleFactor); - *delay = DELAY_SBR(coreFrameLength,*downSampleFactor); - } - - if (!usePs) { - timeDomainDownsample = *downSampleFactor-1; /* activate time domain downsampler when downSampleFactor is != 1 */ - } - - - /* Take care about downsampled data bound to the SBR path */ - if (!timeDomainDownsample && delayDiff > 0) { - /* - * We must tweak the balancing into a situation where the downsampled path - * is the one to be delayed, because delaying the QMF domain input, also delays - * the downsampled audio, counteracting to the purpose of delay balancing. - */ - while ( delayDiff > 0 ) - { - /* Encoder delay increases */ - { - *delay += coreFrameLength * *downSampleFactor; - /* Add one frame delay to SBR path */ - delayDiff -= coreFrameLength * *downSampleFactor; - } - nBitstrDelay += 1; - } - } else - { - *delay += fixp_abs(delayDiff); - } - - if (delayDiff < 0) { - /* Delay AAC data */ - delayDiff = -delayDiff; - /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */ - FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2); - downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1); - sbrOffset = 0; - } else { - /* Delay SBR input */ - if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor ) - { - /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */ - delayDiff -= coreFrameLength * *downSampleFactor; - nBitstrDelay = 1; - } - /* Multiply input offset by input channels */ - sbrOffset = delayDiff*(*numChannels); - downsampledOffset = 0; - } - hSbrEncoder->nBitstrDelay = nBitstrDelay; - hSbrEncoder->nChannels = *numChannels; - hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor; - hSbrEncoder->fTimeDomainDownsampling = timeDomainDownsample; - hSbrEncoder->downSampleFactor = *downSampleFactor; - hSbrEncoder->estimateBitrate = 0; - hSbrEncoder->inputDataDelay = 0; - - - /* Open SBR elements */ - el = -1; - highestSbrStartFreq = highestSbrStopFreq = 0; - lowestBandwidth = 99999; - - /* Loop through each core encoder element and get a matching SBR element config */ - for (coreEl=0; coreEl<noElements; coreEl++) - { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { - el++; - } else { - continue; - } - - /* Set parametric Stereo Flag. */ - if (usePs) { - elInfo[coreEl].fParametricStereo = 1; - } else { - elInfo[coreEl].fParametricStereo = 0; - } - - /* - * Init sbrConfig structure - */ - if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], - *downSampleFactor, - coreFrameLength, - IS_LOWDELAY(aot) - ) ) - { - error = 1; - goto bail; - } - - /* - * Modify sbrConfig structure according to Element parameters - */ - if ( ! FDKsbrEnc_AdjustSbrSettings (&sbrConfig[el], - elInfo[coreEl].bitRate, - elInfo[coreEl].nChannelsInEl, - *coreSampleRate, - inputSampleRate, - transformFactor, - 24000, - 0, - 0, /* useSpeechConfig */ - 0, /* lcsMode */ - usePs, /* bParametricStereo */ - aot) ) - { - error = 1; - goto bail; - } - - /* Find common frequency border for all SBR elements */ - highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); - highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); - - } /* first element loop */ - - /* Set element count (can be less than core encoder element count) */ - hSbrEncoder->noElements = el+1; - - FDKsbrEnc_Reallocate(hSbrEncoder, - elInfo, - noElements); - - for (el=0; el<hSbrEncoder->noElements; el++) { - - int bandwidth = *coreBandwidth; - - /* Use lowest common bandwidth */ - sbrConfig[el].startFreq = highestSbrStartFreq; - sbrConfig[el].stopFreq = highestSbrStopFreq; - - /* initialize SBR element, and get core bandwidth */ - error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], - &sbrConfig[el], - &bandwidth, - aot, - nBitstrDelay, - el, - headerPeriod, - statesInitFlag, - hSbrEncoder->fTimeDomainDownsampling - ,hSbrEncoder->dynamicRam - ); - - if (error != 0) { - error = 2; - goto bail; - } - - /* Get lowest core encoder bandwidth to be returned later. */ - lowestBandwidth = fixMin(lowestBandwidth, bandwidth); - - } /* second element loop */ - - /* Initialize a downsampler for each channel in each SBR element */ - if (hSbrEncoder->fTimeDomainDownsampling) - { - for (el=0; el<hSbrEncoder->noElements; el++) - { - HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el]; - INT Wc, ch; - - /* Calculated required normalized cutoff frequency (Wc = 1.0 -> lowestBandwidth = inputSampleRate/2) */ - Wc = (2*lowestBandwidth)*1000 / inputSampleRate; - - for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++) - { - FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor); - FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY); - } - - downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay; - } /* third element loop */ - - /* lfe */ - FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, *downSampleFactor); - - /* Add the resampler additional delay to get the final delay and buffer offset values. */ - if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) { - sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ; - *delay += downsamplerDelay - downsampledOffset; - downsampledOffset = 0; - } else { - downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1); - sbrOffset = 0; - } - - hSbrEncoder->inputDataDelay = downsamplerDelay; - } - - /* Assign core encoder Bandwidth */ - *coreBandwidth = lowestBandwidth; - - /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */ - hSbrEncoder->estimateBitrate += 2500 * (*numChannels); - - /* initialize parametric stereo */ - if (usePs) - { - PSENC_CONFIG psEncConfig; - FDK_ASSERT(hSbrEncoder->noElements == 1); - INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); - - psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize; - psEncConfig.qmfFilterMode = 0; - psEncConfig.sbrPsDelay = 0; - - /* tuning parameters */ - if (psTuningTableIdx != INVALID_TABLE_IDX) { - psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands; - psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes; - psEncConfig.iidQuantErrorThreshold = (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold; - - /* calculation is not quite linear, increased number of envelopes causes more bits */ - /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope configuration */ - hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize)); - - } else { - error = ERROR(CDI, "Invalid ps tuning table index."); - goto bail; - } - - qmfInitSynthesisFilterBank(&hSbrEncoder->qmfSynthesisPS, - (FIXP_DBL*)hSbrEncoder->qmfSynthesisPS.FilterStates, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES); - - if(errorInfo == noError){ - /* update delay */ - psEncConfig.sbrPsDelay = FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]->sbrChannel[0]->hEnvChannel.sbrExtractEnvelope); - - if(noError != (errorInfo = PSEnc_Init( hSbrEncoder->hParametricStereo, - &psEncConfig, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands - ,hSbrEncoder->dynamicRam - ))) - { - errorInfo = handBack(errorInfo); - } - } - - /* QMF analysis + Hybrid analysis + Hybrid synthesis + QMF synthesis + downsampled input buffer delay */ - hSbrEncoder->inputDataDelay = (64*10/2) + (6*64) + (0) + (64*10/2-64+1) + ((*downSampleFactor)*downsampledOffset); - } - - hSbrEncoder->downsampledOffset = downsampledOffset; - { - hSbrEncoder->downmixSize = coreFrameLength*(*numChannels); - } - - hSbrEncoder->bufferOffset = sbrOffset; - /* Delay Compensation: fill bitstream delay buffer with zero input signal */ - if ( hSbrEncoder->nBitstrDelay > 0 ) - { - error = FDKsbrEnc_DelayCompensation (hSbrEncoder, inputBuffer); - if (error != 0) - goto bail; - } - - /* Set Output frame length */ - *frameLength = coreFrameLength * *downSampleFactor; - /* Input buffer offset */ - *inputBufferOffset = fixMax(sbrOffset, downsampledOffset); - - - } - - return error; - -bail: - /* Restore input settings */ - *coreSampleRate = inputSampleRate; - *frameLength = coreFrameLength; - *numChannels = inputChannels; - *coreBandwidth = inputBandWidth; - - return error; - } - - -INT -sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *samples, - UINT timeInStride, - UINT sbrDataBits[(8)], - UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE] - ) -{ - INT error; - int el; - - for (el=0; el<hSbrEncoder->noElements; el++) - { - if (hSbrEncoder->sbrElement[el] != NULL) - { - error = FDKsbrEnc_EnvEncodeFrame( - hSbrEncoder, - el, - samples + hSbrEncoder->downsampledOffset, - timeInStride, - &sbrDataBits[el], - sbrData[el], - 0 - ); - if (error) - return error; - } - } - - if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) ) - { /* lfe downsampler */ - INT nOutSamples; - - FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, - samples + hSbrEncoder->downsampledOffset + hSbrEncoder->bufferOffset + hSbrEncoder->lfeChIdx, - hSbrEncoder->frameSize, - timeInStride, - samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx, - &nOutSamples, - hSbrEncoder->nChannels); - - - } - - return 0; -} - - -INT sbrEncoder_UpdateBuffers( - HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *timeBuffer - ) - { - if ( hSbrEncoder->downsampledOffset > 0 ) { - /* Move delayed downsampled data */ - FDKmemcpy ( timeBuffer, - timeBuffer + hSbrEncoder->downmixSize, - sizeof(INT_PCM) * (hSbrEncoder->downsampledOffset) ); - } else { - /* Move delayed input data */ - FDKmemcpy ( timeBuffer, - timeBuffer + hSbrEncoder->nChannels * hSbrEncoder->frameSize, - sizeof(INT_PCM) * hSbrEncoder->bufferOffset ); - } - if ( hSbrEncoder->nBitstrDelay > 0 ) - { - int el; - - for (el=0; el<hSbrEncoder->noElements; el++) - { - FDKmemmove ( hSbrEncoder->sbrElement[el]->payloadDelayLine[0], - hSbrEncoder->sbrElement[el]->payloadDelayLine[1], - sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay*MAX_PAYLOAD_SIZE) ); - - FDKmemmove( &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0], - &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1], - sizeof(UINT) * (hSbrEncoder->nBitstrDelay) ); - } - } - return 0; - } - - -INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) -{ - INT estimateBitrate = 0; - - if(hSbrEncoder) { - estimateBitrate += hSbrEncoder->estimateBitrate; - } - - return estimateBitrate; -} - -INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) -{ - INT delay = -1; - - if(hSbrEncoder) { - delay = hSbrEncoder->inputDataDelay; - } - return delay; -} - - -INT sbrEncoder_GetLibInfo( LIB_INFO *info ) -{ - int i; - - if (info == NULL) { - return -1; - } - /* search for next free tab */ - for (i = 0; i < FDK_MODULE_LAST; i++) { - if (info[i].module_id == FDK_NONE) break; - } - if (i == FDK_MODULE_LAST) { - return -1; - } - info += i; - - info->module_id = FDK_SBRENC; - info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); - LIB_VERSION_STRING(info); -#ifdef __ANDROID__ - info->build_date = ""; - info->build_time = ""; -#else - info->build_date = __DATE__; - info->build_time = __TIME__; -#endif - info->title = "SBR Encoder"; - - /* Set flags */ - info->flags = 0 - | CAPF_SBR_HQ - | CAPF_SBR_PS_MPEG - ; - /* End of flags */ - - return 0; -} |