From 3aec97e388e29a1d03f0197b27b893bc6aaf8ac3 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Thu, 29 Aug 2013 12:24:04 -0700 Subject: Encoder downsampled SBR * AAC-Encoder - Introduce optional AACENC_SBR_RATIO encoder API parameter to configure dualrate or downsampled SBR explicitely. ELD makes use of downsampled SBR in default configuration. Modified file(s): documentation\aacEncoder.pdf libAACenc\include\aacenc_lib.h libAACenc\src\aacenc.h libAACenc\src\aacenc_lib.cpp * SBR-Encoder - Implement downsampled SBR feature. - Revise sbr tuning parameter selection. Modified file(s): libSBRenc\include\sbr_encoder.h libSBRenc\src\bit_sbr.h libSBRenc\src\env_est.cpp libSBRenc\src\mh_det.cpp libSBRenc\src\nf_est.cpp libSBRenc\src\ps_main.cpp libSBRenc\src\sbr.h libSBRenc\src\sbr_def.h libSBRenc\src\sbr_encoder.cpp libSBRenc\src\sbr_rom.cpp libSBRenc\src\sbr_rom.h libSBRenc\src\sbrenc_freq_sca.cpp libSBRenc\src\sbrenc_freq_sca.h libSBRenc\src\ton_corr.cpp Bug 9428126 Change-Id: I731720a10829272acaaf70b84525df00a09ff3d2 --- libSBRenc/include/sbr_encoder.h | 77 +++-- libSBRenc/src/bit_sbr.h | 5 - libSBRenc/src/env_est.cpp | 3 - libSBRenc/src/mh_det.cpp | 51 ++-- libSBRenc/src/nf_est.cpp | 34 ++- libSBRenc/src/ps_main.cpp | 10 +- libSBRenc/src/sbr.h | 14 +- libSBRenc/src/sbr_def.h | 7 - libSBRenc/src/sbr_encoder.cpp | 597 ++++++++++++++++++++++---------------- libSBRenc/src/sbr_rom.cpp | 371 +++++++++++++---------- libSBRenc/src/sbr_rom.h | 9 +- libSBRenc/src/sbrenc_freq_sca.cpp | 168 ++++++----- libSBRenc/src/sbrenc_freq_sca.h | 60 ++-- libSBRenc/src/ton_corr.cpp | 2 - 14 files changed, 808 insertions(+), 600 deletions(-) (limited to 'libSBRenc') diff --git a/libSBRenc/include/sbr_encoder.h b/libSBRenc/include/sbr_encoder.h index f8f2a5c..9d59ac7 100644 --- a/libSBRenc/include/sbr_encoder.h +++ b/libSBRenc/include/sbr_encoder.h @@ -101,6 +101,14 @@ amm-info@iis.fraunhofer.de #define MAX_CODEC_FRAME_RATIO 2 #define MAX_PAYLOAD_SIZE 256 +typedef enum codecType +{ + CODEC_AAC=0, + CODEC_AACLD=1, + CODEC_UNSPECIFIED=99 +} CODEC_TYPE; + + typedef struct { INT bitRate; @@ -129,10 +137,11 @@ enum typedef struct { + CODEC_TYPE coreCoder; /*!< LC or ELD */ UINT bitrateFrom; /*!< inclusive */ UINT bitrateTo; /*!< exclusive */ - USHORT sampleRate; /*!< */ + UINT sampleRate; /*!< */ UCHAR numChannels; /*!< */ UCHAR startFreq; /*!< bs_start_freq */ @@ -158,6 +167,7 @@ typedef struct sbrConfiguration INT crcSbr; /*!< Flag: usage of SBR-CRC. */ INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */ INT parametricCoding; /*!< Flag: usage of parametric coding tool. */ + INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */ int freq_res_fixfix[3]; /*!< Frequency resolution of envelopes in frame class FIXFIX 0=1 Env; 1=2 Env; 2=4 Env; */ /* @@ -194,7 +204,6 @@ typedef struct sbrConfiguration INT useSaPan; /*!< Flag: usage of SAPAN stereo. */ INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */ INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */ - INT bDownSampledSbr; /*!< Signal downsampled SBR is used. */ /* header_extra1 configuration @@ -214,7 +223,7 @@ typedef struct sbrConfiguration UCHAR init_amp_res_FF; } sbrConfiguration, *sbrConfigurationPtr ; -typedef struct +typedef struct SBR_CONFIG_DATA { UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */ INT nChannels; /**< Number of channels. */ @@ -240,9 +249,7 @@ typedef struct INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */ INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */ UCHAR initAmpResFF; -} SBR_CONFIG_DATA; - -typedef SBR_CONFIG_DATA *HANDLE_SBR_CONFIG_DATA; +} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA; typedef struct { MP4_ELEMENT_ID elType; @@ -275,15 +282,26 @@ INT sbrEncoder_Open( ); /** - * \brief get closest working bit rate to specified desired bit rate for a single SBR element - * \param bitRate the desired target bit rate - * \param numChannels the amount of audio channels - * \param coreSampleRate the sample rate of the core coder - * \param the current Audio Object Type - * \return closest working bit rate to bitRate value + * \brief Get closest working bitrate to specified desired + * bitrate for a single SBR element. + * \param bitRate The desired target bit rate + * \param numChannels The amount of audio channels + * \param coreSampleRate The sample rate of the core coder + * \param aot The current Audio Object Type + * \return Closest working bit rate to bitRate value */ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot); + +/** + * \brief Check whether downsampled SBR single rate is possible + * with given audio object type. + * \param aot The Audio object type. + * \return 0 when downsampled SBR is not possible, + * 1 when downsampled SBR is possible. + */ +UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot); + /** * \brief Initialize SBR Encoder instance. * \param phSbrEncoder Pointer to a SBR Encoder instance. @@ -294,6 +312,7 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate * \param bufferOffset Returns the offset for the audio input data in order to do delay balancing. * \param numChannels Input: Encoder input channels. output: core encoder channels. * \param sampleRate Input: Encoder samplerate. output core encoder samplerate. + * \param downSampleFactor Input: Relation between SBR and core coder sampling rate; * \param frameLength Input: Encoder frameLength. output core encoder frameLength. * \param aot Input: Desired AOT. output AOT to be used after parameter checking. * \param delay Input: core encoder delay. Output: total delay because of SBR. @@ -303,21 +322,23 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate * - (1-10) corresponds to header repetition rate in frames. * \return 0 on success, and non-zero if failed. */ -INT sbrEncoder_Init( HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(6)], - int noElements, - INT_PCM *inputBuffer, - INT *bandwidth, - INT *bufferOffset, - INT *numChannels, - INT *sampleRate, - INT *frameLength, - AUDIO_OBJECT_TYPE *aot, - int *delay, - int transformFactor, - const int headerPeriod, - ULONG statesInitFlag - ); +INT sbrEncoder_Init( + HANDLE_SBR_ENCODER hSbrEncoder, + SBR_ELEMENT_INFO elInfo[(6)], + int noElements, + INT_PCM *inputBuffer, + INT *coreBandwidth, + INT *inputBufferOffset, + INT *numChannels, + INT *sampleRate, + UINT *downSampleFactor, + INT *frameLength, + AUDIO_OBJECT_TYPE aot, + int *delay, + int transformFactor, + const int headerPeriod, + ULONG statesInitFlag + ); /** * \brief Do delay line buffers housekeeping. To be called after each encoded audio frame. @@ -360,7 +381,7 @@ INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, * \param fSendHeaders Flag indicating that the SBR encoder should send more headers in the SBR payload or not. * \return void */ -void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder, +void sbrEncoder_GetHeader(HANDLE_SBR_ENCODER sbrEncoder, HANDLE_FDK_BITSTREAM hBs, INT element_index, int fSendHeaders); diff --git a/libSBRenc/src/bit_sbr.h b/libSBRenc/src/bit_sbr.h index 0629202..1ce2c1e 100644 --- a/libSBRenc/src/bit_sbr.h +++ b/libSBRenc/src/bit_sbr.h @@ -124,11 +124,6 @@ struct SBR_HEADER_DATA INT alterScale; INT freqScale; - /* - element of sbrdata - */ - SR_MODE sampleRateMode; - /* element of channelpairelement */ diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp index 9924348..929f229 100644 --- a/libSBRenc/src/env_est.cpp +++ b/libSBRenc/src/env_est.cpp @@ -129,9 +129,6 @@ FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL **RESTRICT energyValues,/*!< the res /* Get Scratch buffer */ C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, QMF_CHANNELS*QMF_MAX_TIME_SLOTS/2); - FDK_ASSERT(numberBands <= QMF_CHANNELS); - FDK_ASSERT(numberCols <= QMF_MAX_TIME_SLOTS); - /* Get max possible scaling of QMF data */ scale = DFRACT_BITS; for (k=0; ktransientPosOffset = FRAME_MIDDLE_SLOT_2048; - hs->timeSlots = NUMBER_TIME_SLOTS_2048; - break; - case 1920: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920; - hs->timeSlots = NUMBER_TIME_SLOTS_1920; - break; - case 1024: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - hs->timeSlots = 16; - break; - case 960: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - hs->timeSlots = 15; - break; - default: - return -1; + if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + { + switch(frameSize){ + case 1024: + case 512: + hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; + hs->timeSlots = 16; + break; + case 960: + case 480: + hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; + hs->timeSlots = 15; + break; + default: + return -1; + } + } else + { + switch(frameSize){ + case 2048: + case 1024: + hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048; + hs->timeSlots = NUMBER_TIME_SLOTS_2048; + break; + case 1920: + case 960: + hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920; + hs->timeSlots = NUMBER_TIME_SLOTS_1920; + break; + default: + return -1; + } } if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { diff --git a/libSBRenc/src/nf_est.cpp b/libSBRenc/src/nf_est.cpp index 851584f..7a3c022 100644 --- a/libSBRenc/src/nf_est.cpp +++ b/libSBRenc/src/nf_est.cpp @@ -102,7 +102,7 @@ static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */ #define max(a,b) ( a > b ? a:b) #endif -#define NOISE_FLOOR_OFFSET_SCALING (3) +#define NOISE_FLOOR_OFFSET_SCALING (4) @@ -484,11 +484,13 @@ FDKsbrEnc_InitSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise tmp = ((FIXP_DBL)MAXVAL_DBL)>>NOISE_FLOOR_OFFSET_SCALING; } else { - FDK_ASSERT(noiseFloorOffset<=8); /* because of NOISE_FLOOR_OFFSET_SCALING */ + /* noiseFloorOffset has to be smaller than 12, because + the result of the calculation below must be smaller than 1: + (2^(noiseFloorOffset/3))*2^4<1 */ + FDK_ASSERT(noiseFloorOffset<12); - /* Assumes the noise floor offset in tuning table are in q31 */ - /* Currently the table contains only 0 for noise floor offset */ - /* Change the qformat here when non-zero values would be filled */ + /* Assumes the noise floor offset in tuning table are in q31 */ + /* Change the qformat here when non-zero values would be filled */ exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp); tmp = fPow(2, DFRACT_BITS-1, exp, qexp, &qtmp); tmp = scaleValue(tmp, qtmp-NOISE_FLOOR_OFFSET_SCALING); @@ -527,24 +529,30 @@ FDKsbrEnc_resetSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise h_sbrNoiseFloorEstimate->noNoiseBands = 1; } else{ - /* - * Calculate number of noise bands 1,2 or 3 bands/octave + /* + * Calculate number of noise bands 1,2 or 3 bands/octave ********************************************************/ FIXP_DBL tmp, ratio, lg2; - INT ratio_e, qlg2; + INT ratio_e, qlg2, nNoiseBands; ratio = fDivNorm(k2, kx, &ratio_e); lg2 = fLog2(ratio, ratio_e, &qlg2); tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands<<24), lg2); tmp = scaleValue(tmp, qlg2-23); - h_sbrNoiseFloorEstimate->noNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1); + nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1); + + + if (nNoiseBands > MAX_NUM_NOISE_COEFFS ) { + nNoiseBands = MAX_NUM_NOISE_COEFFS; + } + + if( nNoiseBands == 0 ) { + nNoiseBands = 1; + } - if (h_sbrNoiseFloorEstimate->noNoiseBands > MAX_NUM_NOISE_COEFFS) - h_sbrNoiseFloorEstimate->noNoiseBands = MAX_NUM_NOISE_COEFFS; + h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands; - if( h_sbrNoiseFloorEstimate->noNoiseBands==0) - h_sbrNoiseFloorEstimate->noNoiseBands=1; } diff --git a/libSBRenc/src/ps_main.cpp b/libSBRenc/src/ps_main.cpp index 76b759a..ab183e2 100644 --- a/libSBRenc/src/ps_main.cpp +++ b/libSBRenc/src/ps_main.cpp @@ -315,7 +315,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData( } else { int n, k; - C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, QMF_CHANNELS*2); + C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, 2*QMF_CHANNELS) /* define scalings */ int dynQmfScale = fixMax(0, hParametricStereo->dmxScale-1); /* scale one bit more for addition of left and right */ @@ -400,8 +400,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData( *qmfScale = -downmixScale + 7; - C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_QMF, QMF_CHANNELS*2); - + C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_QMF, 2*QMF_CHANNELS) { const INT noQmfSlots2 = hParametricStereo->noQmfSlots>>1; @@ -475,10 +474,9 @@ FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing( ) { FDK_PSENC_ERROR error = PSENC_OK; - INT noQmfBands = hParametricStereo->noQmfBands; INT psQmfScale[MAX_PS_CHANNELS] = {0}; int psCh, i; - C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, QMF_CHANNELS*4); + C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, 4*QMF_CHANNELS) for (psCh = 0; psCh= 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 ( 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 ( sbrTuningTable [i].bitrateTo <= bitrate ) { + if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) { + bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1; + bitRateClosestUpperIndex = i; + } } } } @@ -215,7 +209,7 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ if (pBitRateClosest != NULL) { - /* Is there was at least one matching tuning entry found then pick the least distance bit rate */ + /* 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; @@ -295,6 +289,52 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ 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; +} + /***************************************************************************/ /*! @@ -307,15 +347,16 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ ****************************************************************************/ 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] */ - AUDIO_OBJECT_TYPE core - ) +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; - UINT sampleRateCore; if (sampleRateInput < 16000) return 0; @@ -335,8 +376,6 @@ FDKsbrEnc_IsSbrSettingAvail (UINT bitrate, /*! the total bitrate in bit bitrate *= numOutputChannels; } - /* try DOWN_SMPL_FAC of the input sampling rate */ - sampleRateCore = sampleRateInput/DOWN_SMPL_FAC; idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL); return (idx == INVALID_TABLE_IDX ? 0 : 1); @@ -356,7 +395,8 @@ 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 fsCore, /*! the core coder sampling rate in Hz */ + 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*/ @@ -366,15 +406,12 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ { INT idx = INVALID_TABLE_IDX; - UINT sampleRate; - - /* set the codec settings */ + /* set the core codec settings */ config->codecSettings.bitRate = bitRate; config->codecSettings.nChannels = numChannels; - config->codecSettings.sampleFreq = fsCore; + config->codecSettings.sampleFreq = sampleRateCore; config->codecSettings.transFac = transFac; config->codecSettings.standardBitrate = standardBitrate; - sampleRate = fsCore * DOWN_SMPL_FAC; if (bitRate==0) { /* map vbr quality to bitrate */ @@ -391,13 +428,13 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif bitRate *= numChannels; /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ if (numChannels==1) { - if (sampleRate==44100 || sampleRate==48000) { + if (sampleRateSbr==44100 || sampleRateSbr==48000) { if (vbrMode<40) bitRate = 32000; } } } - idx = getSbrTuningTableIndex(bitRate,numChannels,fsCore, core, NULL); + idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL); if (idx != INVALID_TABLE_IDX) { config->startFreq = sbrTuningTable[idx].startFreq ; @@ -407,6 +444,21 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif 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; @@ -455,19 +507,20 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif description: initializes the SBR confifuration returns: error status input: - core codec type, - - fac of SBR to core frame length, + - factor of SBR to core frame length, - core frame length output: initialized SBR configuration *****************************************************************************/ static UINT FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, - INT coreSbrFrameLenFac, - UINT codecGranuleLen) + INT downSampleFactor, + UINT codecGranuleLen + ) { - if ( (coreSbrFrameLenFac != 2) || - (codecGranuleLen*coreSbrFrameLenFac > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) ) - return(1); + if ( (downSampleFactor < 1 || downSampleFactor > 2) || + (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) ) + return(0); /* error */ config->SendHeaderDataTime = 1000; config->useWaveCoding = 0; @@ -476,8 +529,8 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, config->tran_thr = 13000; config->parametricCoding = 1; - config->sbrFrameSize = codecGranuleLen * coreSbrFrameLenFac; - + config->sbrFrameSize = codecGranuleLen * downSampleFactor; + config->downSampleFactor = downSampleFactor; /* sbr default parameters */ config->sbr_data_extra = 0; @@ -497,7 +550,6 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, config->sbr_xpos_level = 0; config->useSaPan = 0; config->dynBwEnabled = 0; - config->bDownSampledSbr = 0; /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since @@ -645,46 +697,62 @@ void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder) output: error info *****************************************************************************/ -static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - INT noQmfChannels) +static INT updateFreqBandTable( + HANDLE_SBR_CONFIG_DATA sbrConfigData, + HANDLE_SBR_HEADER_DATA sbrHeaderData, + const INT downSampleFactor + ) { INT k0, k2; - if(FDKsbrEnc_FindStartAndStopBand(sbrConfigData->sampleFreq, - noQmfChannels, - sbrHeaderData->sbr_start_frequency, - sbrHeaderData->sbr_stop_frequency, - sbrHeaderData->sampleRateMode, - &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)) + 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, - sbrHeaderData->sampleRateMode, - noQmfChannels)) + 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]); + FDKsbrEnc_UpdateLoRes( + sbrConfigData->freqBandTable[LO], + &sbrConfigData->nSfb[LO], + sbrConfigData->freqBandTable[HI], + sbrConfigData->nSfb[HI] + ); + - sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / noQmfChannels+1)>>1; + sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1; return (0); } @@ -866,7 +934,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, */ if(updateFreqBandTable(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, - hSbrElement->sbrConfigData.noQmfBands)) + hEnvEncoder->downSampleFactor + )) return(1); @@ -891,8 +960,6 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, &crcInfo, hSbrElement->sbrConfigData.sbrSyntaxFlags); - INT error = noError; - /* Temporal Envelope Data */ SBR_FRAME_TEMP_DATA _fData; SBR_FRAME_TEMP_DATA *fData = &_fData; @@ -923,9 +990,9 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, if(hSbrElement->elInfo.fParametricStereo == 0) { - C_ALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2); QMF_SCALE_FACTOR tmpScale; FIXP_DBL **pQmfReal, **pQmfImag; + C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) /* Obtain pointers to QMF buffers. */ @@ -940,10 +1007,11 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, timeInStride, qmfWorkBuffer ); - C_ALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2); - h_envChan->qmfScale = tmpScale.lb_scale + 7; + + C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) + } /* fParametricStereo == 0 */ @@ -952,6 +1020,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, */ if (hSbrElement->elInfo.fParametricStereo) { + INT error = noError; + /* Limit Parametric Stereo to one instance */ FDK_ASSERT(ch == 0); @@ -1177,10 +1247,12 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, break; case 2048: case 1024: + case 512: timeSlots = 16; break; case 1920: case 960: + case 480: timeSlots = 15; break; case 1152: @@ -1221,9 +1293,9 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, tran_fc = params->tran_fc; - if (tran_fc == 0) - tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,64,sbrConfigData->sampleFreq)); - + 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; @@ -1233,11 +1305,11 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, } else { frameShift = 0; - switch (params->sbrFrameSize) { + switch (timeSlots) { /* The factor of 2 is by definition. */ - case 2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break; - case 1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break; - default: return 1; break; + 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, @@ -1330,7 +1402,6 @@ INT sbrEncoder_Open( hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM(); hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; - for (i=0; isbrElement[i] = GetRam_SbrElement(i); if (hSbrEncoder->sbrElement[i]==NULL) { @@ -1463,7 +1534,8 @@ INT FDKsbrEnc_EnvInit ( int nBitstrDelay, int nElement, const int headerPeriod, - ULONG statesInitFlag + ULONG statesInitFlag, + int fTimeDomainDownsampling ,UCHAR *dynamic_RAM ) { @@ -1497,8 +1569,16 @@ INT FDKsbrEnc_EnvInit ( hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; } - hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS; - hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize/hSbrElement->sbrConfigData.noQmfBands; + 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); @@ -1514,10 +1594,7 @@ INT FDKsbrEnc_EnvInit ( hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; - /* implicit rule for sampleRateMode */ - /* run in "multirate" mode where sbr fs is 2 * codec fs */ - hSbrElement->sbrHeaderData.sampleRateMode = DUAL_RATE; - hSbrElement->sbrConfigData.sampleFreq = 2 * params->codecSettings.sampleFreq; + hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq; hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; if (params->SendHeaderDataTime > 0 ) { @@ -1592,7 +1669,8 @@ INT FDKsbrEnc_EnvInit ( /* init freq band table */ if(updateFreqBandTable(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, - hSbrElement->sbrConfigData.noQmfBands)) + params->downSampleFactor + )) { return(1); } @@ -1632,6 +1710,9 @@ INT FDKsbrEnc_EnvInit ( hSbrElement->sbrConfigData.noQmfBands, hSbrElement->sbrConfigData.noQmfBands, qmfFlags ); + if (0!=err) { + return err; + } } /* */ @@ -1653,7 +1734,7 @@ INT sbrEncoder_GetInBufferSize(int noChannels) { INT temp; - temp = (1024*DOWN_SMPL_FAC); + temp = (2048); temp += 1024 + MAX_SAMPLE_DELAY; temp *= noChannels; temp *= sizeof(INT_PCM); @@ -1685,8 +1766,8 @@ INT FDKsbrEnc_DelayCompensation ( 1 )) return -1; - sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer); } + sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer); } return 0; } @@ -1717,30 +1798,36 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate 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[(6)], - int noElements, - INT_PCM *inputBuffer, - INT *coreBandwidth, - INT *inputBufferOffset, - INT *numChannels, - INT *sampleRate, - INT *frameLength, - AUDIO_OBJECT_TYPE *aot, - int *delay, - int transformFactor, - const int headerPeriod, - ULONG statesInitFlag - ) + HANDLE_SBR_ENCODER hSbrEncoder, + SBR_ELEMENT_INFO elInfo[(6)], + 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[(6)]; INT error = 0; INT lowestBandwidth; /* Save input parameters */ - INT inputSampleRate = *sampleRate; + INT inputSampleRate = *coreSampleRate; int coreFrameLength = *frameLength; int inputBandWidth = *coreBandwidth; int inputChannels = *numChannels; @@ -1748,20 +1835,26 @@ INT sbrEncoder_Init( int downsampledOffset = 0; int sbrOffset = 0; int downsamplerDelay = 0; - int downsample = 0; + int timeDomainDownsample = 0; int nBitstrDelay = 0; - int lowestSbrStartFreq, lowestSbrStopFreq; + int highestSbrStartFreq, highestSbrStopFreq; int lowDelay = 0; int usePs = 0; /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ - if ( (*aot==AOT_PS) || (*aot==AOT_MP2_PS) || (*aot==AOT_DABPLUS_PS) || (*aot==AOT_DRM_MPEG_PS) ) { + if (!sbrEncoder_IsSingleRatePossible(aot)) { + *downSampleFactor = 2; + } + + + + if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) { usePs = 1; } - if ( (*aot==AOT_ER_AAC_ELD) ) { + if ( (aot==AOT_ER_AAC_ELD) ) { lowDelay = 1; } - else if ( (*aot==AOT_ER_AAC_LD) ) { + else if ( (aot==AOT_ER_AAC_LD) ) { error = 1; goto bail; } @@ -1776,25 +1869,25 @@ INT sbrEncoder_Init( /* core encoder gets downmixed mono signal */ *numChannels = 1; } else { - switch (*aot) { - case AOT_MP2_PS: - *aot = AOT_MP2_SBR; - break; - case AOT_DABPLUS_PS: - *aot = AOT_DABPLUS_SBR; - break; - case AOT_DRM_MPEG_PS: - *aot = AOT_DRM_SBR; - break; - case AOT_PS: - default: - *aot = AOT_SBR; - } - usePs = 0; + error = 1; + goto bail; } } /* usePs */ - /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ + /* 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; @@ -1807,54 +1900,37 @@ INT sbrEncoder_Init( continue; } /* check if desired configuration is available */ - if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *aot) ) + if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) ) { - /* otherwise - change to AAC-LC */ - switch (*aot) { - case AOT_MP2_SBR: - case AOT_MP2_PS: - *aot = AOT_MP2_AAC_LC; - break; - case AOT_DABPLUS_SBR: - case AOT_DABPLUS_PS: - *aot = AOT_DABPLUS_AAC_LC; - break; - case AOT_DRM_SBR: - case AOT_DRM_MPEG_PS: - *aot = AOT_DRM_AAC; - break; - case AOT_ER_AAC_ELD: - break; - case AOT_SBR: - case AOT_PS: - default: - *aot = AOT_AAC_LC; - } error = 1; goto bail; } } - *sampleRate /= DOWN_SMPL_FAC; - /* Determine Delay balancing and new encoder delay */ if (lowDelay) { - downsample = 1; /* activate downsampler */ - delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_ELD2SBR(coreFrameLength); - *delay = DELAY_ELDSBR(coreFrameLength); + { + delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor); + *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor); + } } else if (usePs) { - delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_AAC2PS(coreFrameLength); - *delay = DELAY_PS(coreFrameLength); + delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor); + *delay = DELAY_PS(coreFrameLength,*downSampleFactor); } else { - downsample = 1; /* activate downsampler */ - delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_AAC2SBR(coreFrameLength); - *delay = DELAY_SBR(coreFrameLength); + 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 (!downsample && delayDiff > 0) { + 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 @@ -1863,12 +1939,15 @@ INT sbrEncoder_Init( while ( delayDiff > 0 ) { /* Encoder delay increases */ - *delay += coreFrameLength*DOWN_SMPL_FAC; - /* Add one frame delay to SBR path */ - delayDiff -= coreFrameLength*DOWN_SMPL_FAC; + { + *delay += coreFrameLength * *downSampleFactor; + /* Add one frame delay to SBR path */ + delayDiff -= coreFrameLength * *downSampleFactor; + } nBitstrDelay += 1; } - } else { + } else + { *delay += fixp_abs(delayDiff); } @@ -1876,32 +1955,33 @@ INT sbrEncoder_Init( /* Delay AAC data */ delayDiff = -delayDiff; /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */ - downsampledOffset = (delayDiff*(*numChannels))/DOWN_SMPL_FAC; + FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2); + downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1); sbrOffset = 0; } else { /* Delay SBR input */ - if ( delayDiff > (int)coreFrameLength*DOWN_SMPL_FAC ) + if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor ) { /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */ - delayDiff -= coreFrameLength*DOWN_SMPL_FAC; + delayDiff -= coreFrameLength * *downSampleFactor; nBitstrDelay = 1; } /* Multiply input offset by input channels */ sbrOffset = delayDiff*(*numChannels); downsampledOffset = 0; } - - hSbrEncoder->nBitstrDelay = nBitstrDelay; - hSbrEncoder->nChannels = *numChannels; - hSbrEncoder->frameSize = *frameLength*DOWN_SMPL_FAC; - hSbrEncoder->fTimeDomainDownsampling = downsample; - hSbrEncoder->estimateBitrate = 0; - hSbrEncoder->inputDataDelay = 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; - lowestSbrStartFreq = lowestSbrStopFreq = 9999; + highestSbrStartFreq = highestSbrStopFreq = 0; lowestBandwidth = 99999; /* Loop through each core encoder element and get a matching SBR element config */ @@ -1924,28 +2004,38 @@ INT sbrEncoder_Init( /* * Init sbrConfig structure */ - FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], - DOWN_SMPL_FAC, - coreFrameLength); + if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], + *downSampleFactor, + coreFrameLength + ) ) + { + error = 1; + goto bail; + } + /* * Modify sbrConfig structure according to Element parameters */ - FDKsbrEnc_AdjustSbrSettings ( &sbrConfig[el], - elInfo[coreEl].bitRate, - elInfo[coreEl].nChannelsInEl, - *sampleRate, - transformFactor, - 24000, - 0, - 0, /* useSpeechConfig */ - 0, /* lcsMode */ - usePs, /* bParametricStereo */ - *aot); + 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 */ - lowestSbrStartFreq = fixMin(lowestSbrStartFreq, sbrConfig[el].startFreq); - lowestSbrStopFreq = fixMin(lowestSbrStopFreq, sbrConfig[el].stopFreq); - + highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); + highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); } /* first element loop */ @@ -1961,22 +2051,24 @@ INT sbrEncoder_Init( int bandwidth = *coreBandwidth; /* Use lowest common bandwidth */ - sbrConfig[el].startFreq = lowestSbrStartFreq; - sbrConfig[el].stopFreq = lowestSbrStopFreq; + 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, + aot, nBitstrDelay, el, headerPeriod, - statesInitFlag + statesInitFlag, + hSbrEncoder->fTimeDomainDownsampling ,hSbrEncoder->dynamicRam ); if (error != 0) { + error = 2; goto bail; } @@ -1998,30 +2090,29 @@ INT sbrEncoder_Init( for (ch=0; chelInfo.nChannelsInEl; ch++) { - FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, DOWN_SMPL_FAC); + FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor); + FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY); } - FDK_ASSERT (hSbrEl->sbrChannel[0]->downSampler.delay <=MAX_DS_FILTER_DELAY && hSbrEl->sbrChannel[0]->downSampler.delay <=MAX_DS_FILTER_DELAY); downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay; } /* third element loop */ /* lfe */ - FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, DOWN_SMPL_FAC); + 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))/DOWN_SMPL_FAC)) { + if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) { sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ; *delay += downsamplerDelay - downsampledOffset; downsampledOffset = 0; } else { - downsampledOffset -= (downsamplerDelay * (*numChannels))/DOWN_SMPL_FAC; + downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1); sbrOffset = 0; } hSbrEncoder->inputDataDelay = downsamplerDelay; } - /* Assign core encoder Bandwidth */ *coreBandwidth = lowestBandwidth; @@ -2035,7 +2126,7 @@ INT sbrEncoder_Init( FDK_ASSERT(hSbrEncoder->noElements == 1); INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); - psEncConfig.frameSize = *frameLength; //sbrConfig.sbrFrameSize; + psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize; psEncConfig.qmfFilterMode = 0; psEncConfig.sbrPsDelay = 0; @@ -2047,7 +2138,7 @@ INT sbrEncoder_Init( /* 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 += ( (((*sampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize)); + hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize)); } else { error = ERROR(CDI, "Invalid ps tuning table index."); @@ -2076,10 +2167,16 @@ INT sbrEncoder_Init( 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->downmixSize = coreFrameLength*(*numChannels); + } + hSbrEncoder->bufferOffset = sbrOffset; /* Delay Compensation: fill bitstream delay buffer with zero input signal */ if ( hSbrEncoder->nBitstrDelay > 0 ) @@ -2090,7 +2187,7 @@ INT sbrEncoder_Init( } /* Set Output frame length */ - *frameLength = coreFrameLength*DOWN_SMPL_FAC; + *frameLength = coreFrameLength * *downSampleFactor; /* Input buffer offset */ *inputBufferOffset = fixMax(sbrOffset, downsampledOffset); @@ -2101,7 +2198,7 @@ INT sbrEncoder_Init( bail: /* Restore input settings */ - *sampleRate = inputSampleRate; + *coreSampleRate = inputSampleRate; *frameLength = coreFrameLength; *numChannels = inputChannels; *coreBandwidth = inputBandWidth; @@ -2139,8 +2236,8 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, } } - if ( (hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->fTimeDomainDownsampling) ) - { + if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) ) + { /* lfe downsampler */ INT nOutSamples; FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, @@ -2150,7 +2247,9 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx, &nOutSamples, hSbrEncoder->nChannels); - } /* lfe downsampler */ + + + } return 0; } diff --git a/libSBRenc/src/sbr_rom.cpp b/libSBRenc/src/sbr_rom.cpp index b1e3fb8..a2b6527 100644 --- a/libSBRenc/src/sbr_rom.cpp +++ b/libSBRenc/src/sbr_rom.cpp @@ -506,216 +506,277 @@ const UCHAR bookSbrNoiseBalanceL11T[25] = /* tuningTable */ -const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE] = +const sbrTuningTable_t sbrTuningTable[] = { + /* Some of the low bitrates are commented out here, this is because the + encoder could lose frames at those bitrates and throw an error because + it has insufficient bits to encode for some test items. + */ - /*** AAC ***/ + /*** HE-AAC section ***/ /* sf,sfsp,sf,sfsp,nnb,nfo,saml,SM,FS*/ /*** mono ***/ /* 8/16 kHz dual rate */ - { 8000, 10000, 8000, 1, 7, 6, 11,10, 1, 0, 6, SBR_MONO, 3 }, - { 10000, 12000, 8000, 1, 11, 7, 13,12, 1, 0, 6, SBR_MONO, 3 }, - { 12000, 16001, 8000, 1, 14,10, 13,13, 1, 0, 6, SBR_MONO, 3 }, - { 16000, 24000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 24000, 32000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 32000, 48001, 8000, 1, 14,11, 15,15, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ /* bitrates higher than 48000 not supported by AAC core */ + { CODEC_AAC, 8000, 10000, 8000, 1, 7, 6, 11,10, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 10000, 12000, 8000, 1, 11, 7, 13,12, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 12000, 16001, 8000, 1, 14,10, 13,13, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 16000, 24000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 24000, 32000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 32000, 48001, 8000, 1, 14,11, 15,15, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ /* bitrates higher than 48000 not supported by AAC core */ /* 11/22 kHz dual rate */ - { 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3 }, - { 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3 }, - { 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, - { 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* at such "high" bitrates it's better to upsample the input */ - { 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* signal by a factor of 2 before sending it into the encoder */ - { 24000, 32000, 11025, 1, 14,10, 14, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 32000, 48000, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 48000, 64001, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ + { CODEC_AAC, 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, + { CODEC_AAC, 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* at such "high" bitrates it's better to upsample the input */ + { CODEC_AAC, 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* signal by a factor of 2 before sending it into the encoder */ + { CODEC_AAC, 24000, 32000, 11025, 1, 14,10, 14, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 32000, 48000, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 48000, 64001, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ /* 12/24 kHz dual rate */ - { 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ - { 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ - { 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ - { 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ /* at such "high" bitrates it's better to upsample the input */ - { 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */ /* signal by a factor of 2 before sending it into the encoder */ - { 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 32000, 48000, 12000, 1, 14,10, 14,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ - { 48000, 64001, 12000, 1, 15,11, 15,11, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ + { CODEC_AAC, 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ + { CODEC_AAC, 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ + { CODEC_AAC, 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ + { CODEC_AAC, 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ /* at such "high" bitrates it's better to upsample the input */ + { CODEC_AAC, 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */ /* signal by a factor of 2 before sending it into the encoder */ + { CODEC_AAC, 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 32000, 48000, 12000, 1, 14,10, 14,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ + { CODEC_AAC, 48000, 64001, 12000, 1, 14,11, 15,11, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ /* 16/32 kHz dual rate */ - { 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ - { 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ - { 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ - { 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ - { 18000, 22000, 16000, 1, 6, 5,11, 7, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ - { 22000, 28000, 16000, 1, 10, 9,12, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 16000, 1, 12,12,13,13, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ - { 44000, 64001, 16000, 1, 15,15,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ + { CODEC_AAC, 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ + { CODEC_AAC, 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ + { CODEC_AAC, 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ + { CODEC_AAC, 18000, 22000, 16000, 1, 6, 5,11, 7, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 22000, 28000, 16000, 1, 10, 9,12, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 16000, 1, 12,12,13,13, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 64001, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ /* 22.05/44.1 kHz dual rate */ - /* { 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ - { 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ - { 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ - { 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ - { 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 22050, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 22050, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ - { 44000, 64001, 22050, 1, 13,13,12,12, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + /* { CODEC_AAC, 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ + { CODEC_AAC, 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ + { CODEC_AAC, 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ + { CODEC_AAC, 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 22050, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 22050, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 64001, 22050, 1, 13,13,12,12, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ /* 24/48 kHz dual rate */ - /* { 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ - { 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ - { 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ - { 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ - { 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 24000, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 24000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ - { 44000, 64001, 24000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + /* { CODEC_AAC, 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ + { CODEC_AAC, 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ + { CODEC_AAC, 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ + { CODEC_AAC, 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 24000, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 24000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 64001, 24000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ /* 32/64 kHz dual rate */ /* placebo settings */ - { 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */ - { 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */ - { 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ - { 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ - { 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ + { CODEC_AAC, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */ + { CODEC_AAC, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */ + { CODEC_AAC, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ + { CODEC_AAC, 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ + { CODEC_AAC, 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ /* 44.1/88.2 kHz dual rate */ /* placebo settings */ - { 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ - { 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range (multichannel rear) */ - { 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ - { 72000,100000, 44100, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ - { 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ + { CODEC_AAC, 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ + { CODEC_AAC, 72000,100000, 44100, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ + { CODEC_AAC, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ /* 48/96 kHz dual rate */ /* not yet finally tuned */ - { 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ - { 36000, 60000, 48000, 1, 7, 7,10,10, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ - { 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ - { 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ - { 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ + { CODEC_AAC, 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 36000, 60000, 48000, 1, 7, 7,10,10, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ + { CODEC_AAC, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ + { CODEC_AAC, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ + { CODEC_AAC, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ /*** stereo ***/ /* 08/16 kHz dual rate */ - { 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ - { 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 8000, 2, 13,11, 13,11, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 8000, 2, 14,12, 13,12, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ + { CODEC_AAC, 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 8000, 2, 13,11, 13,11, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 8000, 2, 14,12, 13,12, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 11/22 kHz dual rate */ - { 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ - { 24000, 28000, 11025, 2, 10, 8,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 11025, 2, 12, 8,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 11025, 2, 13, 9,13, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 11025, 2, 14,11,13,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ + { CODEC_AAC, 24000, 28000, 11025, 2, 10, 8,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 11025, 2, 12, 8,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 11025, 2, 13, 9,13, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 11025, 2, 14,11,13,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 12/24 kHz dual rate */ - { 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ - { 24000, 28000, 12000, 2, 9, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 12000, 2, 11, 7,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 12000, 2, 12, 9,12, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 12000, 2, 13,12,13,12, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 12000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 12000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ + { CODEC_AAC, 24000, 28000, 12000, 2, 9, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 12000, 2, 11, 7,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 12000, 2, 12, 9,12, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 12000, 2, 13,12,13,12, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 16/32 kHz dual rate */ - { 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ - { 24000, 28000, 16000, 2, 8, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 16000, 2, 15,15,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 24000, 28000, 16000, 2, 8, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 16000, 2, 14,14,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 22.05/44.1 kHz dual rate */ - { 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ - { 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 28 kbit/s */ - { 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 22050, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 22050, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 22050, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 28 kbit/s */ + { CODEC_AAC, 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 22050, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 22050, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 22050, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 24/48 kHz dual rate */ - { 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ - { 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 24000, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 24000, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 24000, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000,128001, 24000, 2, 15,15,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AAC, 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ + { CODEC_AAC, 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ + { CODEC_AAC, 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AAC, 36000, 44000, 24000, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AAC, 44000, 52000, 24000, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AAC, 52000, 60000, 24000, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AAC, 60000, 76000, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AAC, 76000,128001, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 32/64 kHz dual rate */ /* placebo settings */ - { 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ - { 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ - { 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ - { 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ - { 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ + { CODEC_AAC, 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ + { CODEC_AAC, 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ + { CODEC_AAC, 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ /* 44.1/88.2 kHz dual rate */ /* placebo settings */ - { 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ - { 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ - { 80000,112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ - { 112000,144000, 44100, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ - { 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ + { CODEC_AAC, 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 80000,112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ + { CODEC_AAC, 112000,144000, 44100, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ + { CODEC_AAC, 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ /* 48/96 kHz dual rate */ /* not yet finally tuned */ - { 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ - { 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */ - { 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */ - { 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */ - { 144000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 192 */ + { CODEC_AAC, 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ + { CODEC_AAC, 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */ + { CODEC_AAC, 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */ + { CODEC_AAC, 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */ + { CODEC_AAC, 144000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 192 */ + /** AAC LOW DELAY SECTION **/ + /*** mono ***/ + /* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/ + { CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s wrr: tuned */ + { CODEC_AACLD, 18000, 22000, 16000, 1, 7, 7,12,12, 1, 6, 9, SBR_MONO, 3 }, /* nominal: 20 kbit/s wrr: tuned */ + { CODEC_AACLD, 22000, 28000, 16000, 1, 6, 6, 9, 9, 2, 3, 6, SBR_MONO, 3 }, /* nominal: 24 kbit/s wrr: tuned */ + { CODEC_AACLD, 28000, 36000, 16000, 1, 8, 8,12, 7, 2, 9,12, SBR_MONO, 3 }, /* jgr: special */ /* wrr: tuned */ + { CODEC_AACLD, 36000, 44000, 16000, 1, 10,14,12,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 44000, 64001, 16000, 1, 11,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + /* 22.05/44.1 kHz dual rate */ - { 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ - { 22000, 28000, 22050, 1, 4, 4, 6, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 22050, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ - { 52000, 64001, 22050, 1, 12,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AACLD, 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */ + { CODEC_AACLD, 22000, 28000, 22050, 1, 5, 5, 6, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ + { CODEC_AACLD, 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AACLD, 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 44000, 52000, 22050, 1, 12,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + { CODEC_AACLD, 52000, 64001, 22050, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */ /* 24/48 kHz dual rate */ - { 20000, 22000, 24000, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ - { 22000, 28000, 24000, 1, 4, 4, 6, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ - { 28000, 36000, 24000, 1, 6, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 24000, 1, 12,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ - { 52000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ + { CODEC_AACLD, 20000, 22000, 24000, 1, 4, 1, 8, 4, 2, 3, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ + { CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ + { CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */ + + /* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */ + { CODEC_AACLD, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */ + { CODEC_AACLD, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */ + { CODEC_AACLD, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ + { CODEC_AACLD, 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ + { CODEC_AACLD, 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ + + /* 44/88 kHz dual rate */ /* not yet finally tuned */ + { CODEC_AACLD, 36000, 60000, 44100, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ + { CODEC_AACLD, 60000, 72000, 44100, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ + { CODEC_AACLD, 72000,100000, 44100, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ + { CODEC_AACLD, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ + + /* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR */ + { CODEC_AACLD, 36000, 60000, 48000, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ + { CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ + { CODEC_AACLD, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ + { CODEC_AACLD, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ + + /*** stereo ***/ + /* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/ + { CODEC_AACLD, 32000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AACLD, 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 44000, 52000, 16000, 2, 10, 9,11, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* tune12 nominal: 48 kbit/s */ + { CODEC_AACLD, 52000, 60000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AACLD, 60000, 76000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AACLD, 76000,128001, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 22.05/44.1 kHz dual rate */ - { 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 22050, 2, 7,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 22050, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 22050, 2, 10,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000, 82000, 22050, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ - { 82000,128001, 22050, 2, 13,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AACLD, 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AACLD, 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 44000, 52000, 22050, 2, 7,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AACLD, 52000, 60000, 22050, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AACLD, 60000, 76000, 22050, 2, 10,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AACLD, 76000, 82000, 22050, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AACLD, 82000,128001, 22050, 2, 13,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ /* 24/48 kHz dual rate */ - { 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ - { 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ - { 44000, 52000, 24000, 2, 6,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ - { 52000, 60000, 24000, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ - { 60000, 76000, 24000, 2, 11,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ - { 76000, 88000, 24000, 2, 12,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ - { 88000,128001, 24000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 92 kbit/s */ - + { CODEC_AACLD, 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ + { CODEC_AACLD, 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ + { CODEC_AACLD, 44000, 52000, 24000, 2, 6,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ + { CODEC_AACLD, 52000, 60000, 24000, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ + { CODEC_AACLD, 60000, 76000, 24000, 2, 11,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ + { CODEC_AACLD, 76000, 88000, 24000, 2, 12,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ + { CODEC_AACLD, 88000,128001, 24000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 92 kbit/s */ + + /* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */ + { CODEC_AACLD, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ + { CODEC_AACLD, 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ + { CODEC_AACLD, 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ + { CODEC_AACLD, 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ + + /* 44.1/88.2 kHz dual rate */ /* placebo settings */ /*wrr: new, copy from CODEC_AAC */ + { CODEC_AACLD, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ + { CODEC_AACLD, 80000,112000, 44100, 2, 10,10, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 11-08-29 */ + { CODEC_AACLD, 112000,144000, 44100, 2, 12,12,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 11-08-29 */ + { CODEC_AACLD, 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ + + /* 48/96 kHz dual rate */ /* not yet finally tuned */ /*wrr: new, copy from CODEC_AAC */ + { CODEC_AACLD, 60000, 80000, 48000, 2, 7, 7,10,10, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */ + { CODEC_AACLD, 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */ + { CODEC_AACLD, 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */ + { CODEC_AACLD, 144000,176000, 48000, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 09-10-19 */ + { CODEC_AACLD, 176000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 09-10-19 */ }; +const int sbrTuningTableSize = sizeof(sbrTuningTable)/sizeof(sbrTuningTable[0]); + const psTuningTable_t psTuningTable[4] = { { 8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1, FL2FXCONST_DBL(3.0f/4.0f) }, diff --git a/libSBRenc/src/sbr_rom.h b/libSBRenc/src/sbr_rom.h index fbbdbba..afa924e 100644 --- a/libSBRenc/src/sbr_rom.h +++ b/libSBRenc/src/sbr_rom.h @@ -118,13 +118,8 @@ extern const UCHAR v_Huff_NoiseLevelL11T[63]; extern const INT bookSbrNoiseBalanceC11T[25]; extern const UCHAR bookSbrNoiseBalanceL11T[25]; -#define SBRENC_AACLC_TUNING_SIZE 124 -#define SBRENC_AACELD_TUNING_SIZE (26) -#define SBRENC_AACELD2_TUNING_SIZE (26) - -#define SBRENC_TUNING_SIZE (SBRENC_AACLC_TUNING_SIZE + SBRENC_AACELD_TUNING_SIZE) - -extern const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE]; +extern const sbrTuningTable_t sbrTuningTable[]; +extern const int sbrTuningTableSize; extern const psTuningTable_t psTuningTable[4]; diff --git a/libSBRenc/src/sbrenc_freq_sca.cpp b/libSBRenc/src/sbrenc_freq_sca.cpp index b0b04fa..30bc5ca 100644 --- a/libSBRenc/src/sbrenc_freq_sca.cpp +++ b/libSBRenc/src/sbrenc_freq_sca.cpp @@ -84,6 +84,7 @@ amm-info@iis.fraunhofer.de /*! \file \brief frequency scale + \author Tobias Chalupka */ #include "sbrenc_freq_sca.h" @@ -92,10 +93,10 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" /* StartFreq */ -static INT getStartFreq(INT fs, const INT start_freq); +static INT getStartFreq(INT fsCore, const INT start_freq); /* StopFreq */ -static INT getStopFreq(INT fs, const INT stop_freq, const INT noChannels); +static INT getStopFreq(INT fsCore, const INT stop_freq); static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); static void CalcBands(INT * diff, INT start , INT stop , INT num_bands); @@ -115,7 +116,7 @@ static void cumSum(INT start_value, INT* diff, INT length, UCHAR *start_adress) *******************************************************************************/ INT -FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) +FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT fsCore) { INT result; @@ -123,9 +124,9 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) return -1; } /* Update startFreq struct */ - result = getStartFreq(fs, startFreq); + result = getStartFreq(fsCore, startFreq); - result = (result*fs/QMFbands+1)>>1; + result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */ return (result); @@ -141,17 +142,16 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) Return: *******************************************************************************/ -INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs) +INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT fsCore) { INT result; if ( stopFreq < 0 || stopFreq > 13) return -1; - /* Uppdate stopFreq struct */ - result = getStopFreq( fs, stopFreq, QMFbands); - result = (result*fs/QMFbands+1)>>1; + result = getStopFreq(fsCore, stopFreq); + result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */ return (result); } /* End getSbrStopFreq */ @@ -162,69 +162,73 @@ INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs) ******************************************************************************* Description: - Arguments: + Arguments: fsCore - core sampling rate + Return: *******************************************************************************/ static INT -getStartFreq(INT fs, const INT start_freq) +getStartFreq(INT fsCore, const INT start_freq) { INT k0_min; - switch(fs){ - case 16000: k0_min = 24; + switch(fsCore){ + case 8000: k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 22050: k0_min = 17; + case 11025: k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 24000: k0_min = 16; + case 12000: k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 32000: k0_min = 16; + case 16000: k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 44100: k0_min = 12; + case 22050: k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 48000: k0_min = 11; + case 24000: k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 64000: k0_min = 10; + case 32000: k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 88200: k0_min = 7; + case 44100: k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ break; - case 96000: k0_min = 7; + case 48000: k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ + break; + case 96000: k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ break; default: k0_min=11; /* illegal fs */ } - switch (fs) { + switch (fsCore) { - case 16000: + case 8000: { INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; return (k0_min + v_offset[start_freq]); } - case 22050: + case 11025: { INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; return (k0_min + v_offset[start_freq]); } - case 24000: + case 12000: { INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; return (k0_min + v_offset[start_freq]); } - case 32000: + case 16000: { INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; return (k0_min + v_offset[start_freq]); } - case 44100: - case 48000: - case 64000: + case 22050: + case 24000: + case 32000: { INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; return (k0_min + v_offset[start_freq]); } - case 88200: + case 44100: + case 48000: case 96000: { INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; @@ -249,13 +253,12 @@ getStartFreq(INT fs, const INT start_freq) Return: *******************************************************************************/ static INT -getStopFreq(INT fs, const INT stop_freq, const INT noChannels) +getStopFreq(INT fsCore, const INT stop_freq) { INT result,i; INT k1_min; INT v_dstop[13]; - INT *v_stop_freq = NULL; INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64}; INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64}; @@ -266,40 +269,45 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels) INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64}; INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64}; INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64}; + INT v_stop_freq_192[14] = {7, 8,10,12,14,16,19,23,27,32,38,46,54,64}; - switch(fs){ - case 16000: k1_min = 48; + switch(fsCore){ + case 8000: k1_min = 48; v_stop_freq =v_stop_freq_16; break; - case 22050: k1_min = 35; + case 11025: k1_min = 35; v_stop_freq =v_stop_freq_22; break; - case 24000: k1_min = 32; + case 12000: k1_min = 32; v_stop_freq =v_stop_freq_24; break; - case 32000: k1_min = 32; + case 16000: k1_min = 32; v_stop_freq =v_stop_freq_32; break; - case 44100: k1_min = 23; + case 22050: k1_min = 23; v_stop_freq =v_stop_freq_44; break; - case 48000: k1_min = 21; + case 24000: k1_min = 21; v_stop_freq =v_stop_freq_48; break; - case 64000: k1_min = 20; + case 32000: k1_min = 20; v_stop_freq =v_stop_freq_64; break; - case 88200: k1_min = 15; + case 44100: k1_min = 15; v_stop_freq =v_stop_freq_88; break; - case 96000: k1_min = 13; + case 48000: k1_min = 13; v_stop_freq =v_stop_freq_96; break; + case 96000: k1_min = 7; + v_stop_freq =v_stop_freq_192; + break; default: k1_min = 21; /* illegal fs */ } - + /* if no valid core samplingrate is used this loop produces + a segfault, because v_stop_freq is not initialized */ /* Ensure increasing bandwidth */ for(i = 0; i <= 12; i++) { v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i]; @@ -322,34 +330,41 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels) ******************************************************************************* Description: - Arguments: + Arguments: srSbr SBR sampling freqency + srCore AAC core sampling freqency + noChannels Number of QMF channels + startFreq SBR start frequency in QMF bands + stopFreq SBR start frequency in QMF bands - Return: + *k0 Output parameter + *k2 Output parameter + + Return: Error code (0 is OK) *******************************************************************************/ INT -FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, - const INT noChannels, - const INT startFreq, - const INT stopFreq, - const SR_MODE sampleRateMode, - INT *k0, - INT *k2) +FDKsbrEnc_FindStartAndStopBand( + const INT srSbr, + const INT srCore, + const INT noChannels, + const INT startFreq, + const INT stopFreq, + INT *k0, + INT *k2 + ) { /* Update startFreq struct */ - *k0 = getStartFreq(samplingFreq, startFreq); + *k0 = getStartFreq(srCore, startFreq); /* Test if start freq is outside corecoder range */ - if( ( sampleRateMode == 1 ) && - ( samplingFreq*noChannels < - 2**k0 * samplingFreq) ) { + if( srSbr*noChannels < *k0 * srCore ) { return (1); /* raise the cross-over frequency and/or lower the number of target bands per octave (or lower the sampling frequency) */ } /*Update stopFreq struct */ if ( stopFreq < 14 ) { - *k2 = getStopFreq(samplingFreq, stopFreq, noChannels); + *k2 = getStopFreq(srCore, stopFreq); } else if( stopFreq == 14 ) { *k2 = 2 * *k0; } else { @@ -364,10 +379,10 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, /* Test for invalid k0 k2 combinations */ - if ( (samplingFreq == 44100) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) ) + if ( (srCore == 22050) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) ) return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */ - if ( (samplingFreq >= 48000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) ) + if ( (srCore >= 24000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) ) return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */ if ((*k2 - *k0) > MAX_FREQ_COEFFS) @@ -390,15 +405,19 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, Return: *******************************************************************************/ INT -FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, - const INT k0, const INT k2, - const INT freqScale, - const INT alterScale) +FDKsbrEnc_UpdateFreqScale( + UCHAR *v_k_master, + INT *h_num_bands, + const INT k0, + const INT k2, + const INT freqScale, + const INT alterScale + ) { INT b_p_o = 0; /* bands_per_octave */ - FIXP_DBL warp = FL2FXCONST_DBL(0.0f); + FIXP_DBL warp = FL2FXCONST_DBL(0.0f); INT dk = 0; /* Internal variables */ @@ -426,7 +445,7 @@ FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, warp = FL2FXCONST_DBL(1.0f/2.6f); /* 1.0/(1.3*2.0); */ - if(4*k2 >= 9*k0) /*two or more regions*/ + if(4*k2 >= 9*k0) /*two or more regions (how many times the basis band is copied)*/ { k1=2*k0; @@ -592,30 +611,31 @@ modifyBands(INT max_band_previous, INT * diff, INT length) ******************************************************************************* Description: + Arguments: Return: *******************************************************************************/ INT -FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires,UCHAR * v_k_master, - INT num_master , INT *xover_band, SR_MODE drOrSr, - INT noQMFChannels) +FDKsbrEnc_UpdateHiRes( + UCHAR *h_hires, + INT *num_hires, + UCHAR *v_k_master, + INT num_master, + INT *xover_band + ) { INT i; - INT divider; INT max1,max2; - /* Check if we use a Dual rate => diver=2 else 1 */ - divider = (drOrSr == DUAL_RATE) ? 2 : 1; - - if( (v_k_master[*xover_band] > (noQMFChannels/divider) ) || + if( (v_k_master[*xover_band] > 32 ) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */ ( *xover_band > num_master ) ) { /* xover_band error, too big for this startFreq. Will be clipped */ /* Calculate maximum value for xover_band */ max1=0; max2=num_master; - while( (v_k_master[max1+1] < (noQMFChannels/divider)) && + while( (v_k_master[max1+1] < 32 ) && /* noQMFChannels(dualRate)/divider */ ( (max1+1) < max2) ) { max1++; diff --git a/libSBRenc/src/sbrenc_freq_sca.h b/libSBRenc/src/sbrenc_freq_sca.h index 51ed688..6f2bb84 100644 --- a/libSBRenc/src/sbrenc_freq_sca.h +++ b/libSBRenc/src/sbrenc_freq_sca.h @@ -96,34 +96,42 @@ amm-info@iis.fraunhofer.de INT -FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, - const INT k0, const INT k2, - const INT freq_scale, - const INT alter_scale); +FDKsbrEnc_UpdateFreqScale( + UCHAR *v_k_master, + INT *h_num_bands, + const INT k0, + const INT k2, + const INT freq_scale, + const INT alter_scale + ); INT -FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, - INT *num_hires, - UCHAR *v_k_master, - INT num_master , - INT *xover_band, - SR_MODE drOrSr, - INT noQMFChannels); - -void FDKsbrEnc_UpdateLoRes(UCHAR * v_lores, - INT *num_lores, - UCHAR * v_hires, - INT num_hires); +FDKsbrEnc_UpdateHiRes( + UCHAR *h_hires, + INT *num_hires, + UCHAR *v_k_master, + INT num_master, + INT *xover_band + ); + +void FDKsbrEnc_UpdateLoRes( + UCHAR *v_lores, + INT *num_lores, + UCHAR *v_hires, + INT num_hires + ); INT -FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, - const INT noChannels, - const INT startFreq, - const INT stop_freq, - const SR_MODE sampleRateMode, - INT *k0, - INT *k2); - -INT FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs ); -INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs); +FDKsbrEnc_FindStartAndStopBand( + const INT srSbr, + const INT srCore, + const INT noChannels, + const INT startFreq, + const INT stop_freq, + INT *k0, + INT *k2 + ); + +INT FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT fsCore); +INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT fsCore); #endif diff --git a/libSBRenc/src/ton_corr.cpp b/libSBRenc/src/ton_corr.cpp index 134a916..224da11 100644 --- a/libSBRenc/src/ton_corr.cpp +++ b/libSBRenc/src/ton_corr.cpp @@ -303,8 +303,6 @@ FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< H } } - FDK_ASSERT(noEstPerFrame == 2); - C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE); C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1); -- cgit v1.2.3