summaryrefslogtreecommitdiffstats
path: root/libSBRenc/src/sbr_encoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRenc/src/sbr_encoder.cpp')
-rw-r--r--libSBRenc/src/sbr_encoder.cpp2346
1 files changed, 0 insertions, 2346 deletions
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp
deleted file mode 100644
index 3e95d6b..0000000
--- a/libSBRenc/src/sbr_encoder.cpp
+++ /dev/null
@@ -1,2346 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
-
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
-
-/*************************** Fraunhofer IIS FDK Tools ***********************
-
- Author(s): Andreas Ehret, Tobias Chalupka
- Description: SBR encoder top level processing.
-
-******************************************************************************/
-
-#include "sbr_encoder.h"
-
-#include "sbr_ram.h"
-#include "sbr_rom.h"
-#include "sbrenc_freq_sca.h"
-#include "env_bit.h"
-#include "cmondata.h"
-#include "sbr_misc.h"
-#include "sbr.h"
-#include "qmf.h"
-
-#include "ps_main.h"
-
-#define SBRENCODER_LIB_VL0 3
-#define SBRENCODER_LIB_VL1 3
-#define SBRENCODER_LIB_VL2 4
-
-
-
-/***************************************************************************/
-/*
- * SBR Delay balancing definitions.
- */
-
-/*
- input buffer (1ch)
-
- |------------ 1537 -------------|-----|---------- 2048 -------------|
- (core2sbr delay ) ds (read, core and ds area)
-*/
-
-#define SFB(dwnsmp) (32 << (dwnsmp-1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */
-#define STS(fl) (((fl)==1024)?32:30) /* SBR Time Slots: 32 for core frame length 1024, 30 for core frame length 960 */
-
-#define DELAY_QMF_ANA(dwnsmp) ((320<<((dwnsmp)-1)) - (32<<((dwnsmp)-1))) /* Full bandwidth */
-#define DELAY_HYB_ANA (10*64) /* + 0.5 */ /* */
-#define DELAY_HYB_SYN (6*64 - 32) /* */
-#define DELAY_QMF_POSTPROC(dwnsmp) (32*(dwnsmp)) /* QMF postprocessing delay */
-#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp) ) /* Decoder QMF overlap */
-#define DELAY_QMF_SYN (2) /* NO_POLY/2=2.5, rounded down to 2 */
-#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
-
-/* Delay in QMF paths */
-#define DELAY_SBR(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp)*STS(fl) - 1) + DELAY_QMF_SYN)
-#define DELAY_PS(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + (SFB(dwnsmp)*STS(fl)-1) + DELAY_HYB_SYN + DELAY_QMF_SYN)
-#define DELAY_ELDSBR(fl,dwnsmp) ( ( ((fl)/2)*(dwnsmp) ) - 1 + DELAY_QMF_POSTPROC(dwnsmp) )
-
-/* Delay differences for SBR and SBR+PS */
-#define MAX_DS_FILTER_DELAY (5) /* the additional max downsampler filter delay (source fs) */
-#define DELAY_AAC2SBR(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN) - DELAY_SBR((fl),(dwnsmp)))
-#define DELAY_ELD2SBR(fl,dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)) - DELAY_ELDSBR(fl,dwnsmp))
-#define DELAY_AAC2PS(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_HYB_SYN + DELAY_QMF_SYN) - DELAY_PS(fl,dwnsmp)) /* 2048 - 463*2 */
-
-/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller than the sample delay implied by DELAY_AAC2SBR */
-#define MAX_SAMPLE_DELAY (DELAY_AAC2SBR(1024,2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame length of 1024 and dual-rate sbr */
-
-/***************************************************************************/
-
-
-
-#define INVALID_TABLE_IDX -1
-
-/***************************************************************************/
-/*!
-
- \brief Selects the SBR tuning settings to use dependent on number of
- channels, bitrate, sample rate and core coder
-
- \return Index to the appropriate table
-
-****************************************************************************/
-#define DISTANCE_CEIL_VALUE 5000000
-static INT
-getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
- UINT numChannels,/*! the number of channels for the core coder */
- UINT sampleRate, /*! the sampling rate of the core coder */
- AUDIO_OBJECT_TYPE core,
- UINT *pBitRateClosest
- )
-{
- int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0;
- UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
- int isforThisCodec=0;
-
- #define isForThisCore(i) \
- ( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \
- ( sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD ) )
-
- for (i=0; i < sbrTuningTableSize ; i++) {
- if ( isForThisCore(i) ) /* tuning table is for this core codec */
- {
- if ( numChannels == sbrTuningTable [i].numChannels
- && sampleRate == sbrTuningTable [i].sampleRate )
- {
- found = 1;
- if ((bitrate >= sbrTuningTable [i].bitrateFrom) &&
- (bitrate < sbrTuningTable [i].bitrateTo)) {
- bitRateClosestLower = bitrate;
- bitRateClosestUpper = bitrate;
- //FDKprintf("entry %d\n", i);
- return i ;
- } else {
- if ( sbrTuningTable [i].bitrateFrom > bitrate ) {
- if (sbrTuningTable [i].bitrateFrom < bitRateClosestLower) {
- bitRateClosestLower = sbrTuningTable [i].bitrateFrom;
- bitRateClosestLowerIndex = i;
- }
- }
- if ( sbrTuningTable [i].bitrateTo <= bitrate ) {
- if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) {
- bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1;
- bitRateClosestUpperIndex = i;
- }
- }
- }
- }
- }
- }
-
- if (pBitRateClosest != NULL)
- {
- /* If there was at least one matching tuning entry found then pick the least distance bit rate */
- if (found)
- {
- int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE;
- if (bitRateClosestLowerIndex >= 0) {
- distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate;
- }
- if (bitRateClosestUpperIndex >= 0) {
- distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo;
- }
- if ( distanceUpper < distanceLower )
- {
- *pBitRateClosest = bitRateClosestUpper;
- } else {
- *pBitRateClosest = bitRateClosestLower;
- }
- } else {
- *pBitRateClosest = 0;
- }
- }
-
- return INVALID_TABLE_IDX;
-}
-
-/***************************************************************************/
-/*!
-
- \brief Selects the PS tuning settings to use dependent on bitrate
- and core coder
-
- \return Index to the appropriate table
-
-****************************************************************************/
-static INT
-getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){
-
- INT i, paramSets = sizeof (psTuningTable) / sizeof (psTuningTable [0]);
- int bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1;
- UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
-
- for (i = 0 ; i < paramSets ; i++) {
- if ((bitrate >= psTuningTable [i].bitrateFrom) &&
- (bitrate < psTuningTable [i].bitrateTo)) {
- return i ;
- } else {
- if ( psTuningTable [i].bitrateFrom > bitrate ) {
- if (psTuningTable [i].bitrateFrom < bitRateClosestLower) {
- bitRateClosestLower = psTuningTable [i].bitrateFrom;
- bitRateClosestLowerIndex = i;
- }
- }
- if ( psTuningTable [i].bitrateTo <= bitrate ) {
- if (psTuningTable [i].bitrateTo > bitRateClosestUpper) {
- bitRateClosestUpper = psTuningTable [i].bitrateTo-1;
- bitRateClosestUpperIndex = i;
- }
- }
- }
- }
-
- if (pBitRateClosest != NULL)
- {
- int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE;
- if (bitRateClosestLowerIndex >= 0) {
- distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate;
- }
- if (bitRateClosestUpperIndex >= 0) {
- distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo;
- }
- if ( distanceUpper < distanceLower )
- {
- *pBitRateClosest = bitRateClosestUpper;
- } else {
- *pBitRateClosest = bitRateClosestLower;
- }
- }
-
- return INVALID_TABLE_IDX;
-}
-
-/***************************************************************************/
-/*!
-
- \brief In case of downsampled SBR we may need to lower the stop freq
- of a tuning setting to fit into the lower half of the
- spectrum ( which is sampleRate/4 )
-
- \return the adapted stop frequency index (-1 -> error)
-
- \ingroup SbrEncCfg
-
-****************************************************************************/
-static INT
-FDKsbrEnc_GetDownsampledStopFreq (
- const INT sampleRateCore,
- const INT startFreq,
- INT stopFreq,
- const INT downSampleFactor
- )
-{
- INT maxStopFreqRaw = sampleRateCore / 2;
- INT startBand, stopBand;
- HANDLE_ERROR_INFO err;
-
- while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) {
- stopFreq--;
- }
-
- if (FDKsbrEnc_getSbrStopFreqRAW( stopFreq, sampleRateCore) > maxStopFreqRaw)
- return -1;
-
- err = FDKsbrEnc_FindStartAndStopBand (
- sampleRateCore<<(downSampleFactor-1),
- sampleRateCore,
- 32<<(downSampleFactor-1),
- startFreq,
- stopFreq,
- &startBand,
- &stopBand
- );
- if (err)
- return -1;
-
- return stopFreq;
-}
-
-
-/***************************************************************************/
-/*!
-
- \brief tells us, if for the given coreCoder, bitrate, number of channels
- and input sampling rate an SBR setting is available. If yes, it
- tells us also the core sampling rate we would need to run with
-
- \return a flag indicating success: yes (1) or no (0)
-
-****************************************************************************/
-static UINT
-FDKsbrEnc_IsSbrSettingAvail (
- UINT bitrate, /*! the total bitrate in bits/sec */
- UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */
- UINT numOutputChannels, /*! the number of channels for the core coder */
- UINT sampleRateInput, /*! the input sample rate [in Hz] */
- UINT sampleRateCore, /*! the core's sampling rate */
- AUDIO_OBJECT_TYPE core
- )
-{
- INT idx = INVALID_TABLE_IDX;
-
- if (sampleRateInput < 16000)
- return 0;
-
- if (bitrate==0) {
- /* map vbr quality to bitrate */
- if (vbrMode < 30)
- bitrate = 24000;
- else if (vbrMode < 40)
- bitrate = 28000;
- else if (vbrMode < 60)
- bitrate = 32000;
- else if (vbrMode < 75)
- bitrate = 40000;
- else
- bitrate = 48000;
- bitrate *= numOutputChannels;
- }
-
- idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL);
-
- return (idx == INVALID_TABLE_IDX ? 0 : 1);
-}
-
-
-/***************************************************************************/
-/*!
-
- \brief Adjusts the SBR settings according to the chosen core coder
- settings which are accessible via config->codecSettings
-
- \return A flag indicating success: yes (1) or no (0)
-
-****************************************************************************/
-static UINT
-FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */
- UINT bitRate, /*! the total bitrate in bits/sec */
- UINT numChannels, /*! the core coder number of channels */
- UINT sampleRateCore, /*! the core coder sampling rate in Hz */
- UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */
- UINT transFac, /*! the short block to long block ratio */
- UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */
- UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/
- UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */
- UINT lcsMode, /*! the low complexity stereo mode */
- UINT bParametricStereo, /*!< use parametric stereo */
- AUDIO_OBJECT_TYPE core) /* Core audio codec object type */
-{
- INT idx = INVALID_TABLE_IDX;
- /* set the core codec settings */
- config->codecSettings.bitRate = bitRate;
- config->codecSettings.nChannels = numChannels;
- config->codecSettings.sampleFreq = sampleRateCore;
- config->codecSettings.transFac = transFac;
- config->codecSettings.standardBitrate = standardBitrate;
-
- if (bitRate==0) {
- /* map vbr quality to bitrate */
- if (vbrMode < 30)
- bitRate = 24000;
- else if (vbrMode < 40)
- bitRate = 28000;
- else if (vbrMode < 60)
- bitRate = 32000;
- else if (vbrMode < 75)
- bitRate = 40000;
- else
- bitRate = 48000;
- bitRate *= numChannels;
- /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */
- if (numChannels==1) {
- if (sampleRateSbr==44100 || sampleRateSbr==48000) {
- if (vbrMode<40) bitRate = 32000;
- }
- }
- }
-
- idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL);
-
- if (idx != INVALID_TABLE_IDX) {
- config->startFreq = sbrTuningTable[idx].startFreq ;
- config->stopFreq = sbrTuningTable[idx].stopFreq ;
- if (useSpeechConfig) {
- config->startFreq = sbrTuningTable[idx].startFreqSpeech;
- config->stopFreq = sbrTuningTable[idx].stopFreqSpeech;
- }
-
- /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */
- if (1 == config->downSampleFactor) {
- INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq(
- sampleRateCore,
- config->startFreq,
- config->stopFreq,
- config->downSampleFactor
- );
- if (dsStopFreq < 0) {
- return 0;
- }
-
- config->stopFreq = dsStopFreq;
- }
-
- config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ;
- if (core == AOT_ER_AAC_ELD)
- config->init_amp_res_FF = SBR_AMP_RES_1_5;
- config->noiseFloorOffset= sbrTuningTable[idx].noiseFloorOffset;
-
- config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel ;
- config->stereoMode = sbrTuningTable[idx].stereoMode ;
- config->freqScale = sbrTuningTable[idx].freqScale ;
-
- /* adjust usage of parametric coding dependent on bitrate and speech config flag */
- if (useSpeechConfig)
- config->parametricCoding = 0;
-
- if (core == AOT_ER_AAC_ELD) {
- if (bitRate < 28000)
- config->init_amp_res_FF = SBR_AMP_RES_3_0;
- config->SendHeaderDataTime = -1;
- }
-
- if (numChannels == 1) {
- if (bitRate < 16000) {
- config->parametricCoding = 0;
- }
- }
- else {
- if (bitRate < 20000) {
- config->parametricCoding = 0;
- }
- }
-
- config->useSpeechConfig = useSpeechConfig;
-
- /* PS settings */
- config->bParametricStereo = bParametricStereo;
-
- return 1 ;
- }
- else {
- return 0 ;
- }
-}
-
-/*****************************************************************************
-
- functionname: FDKsbrEnc_InitializeSbrDefaults
- description: initializes the SBR confifuration
- returns: error status
- input: - core codec type,
- - factor of SBR to core frame length,
- - core frame length
- output: initialized SBR configuration
-
-*****************************************************************************/
-static UINT
-FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
- INT downSampleFactor,
- UINT codecGranuleLen
- )
-{
- if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
- (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) )
- return(0); /* error */
-
- config->SendHeaderDataTime = 1000;
- config->useWaveCoding = 0;
- config->crcSbr = 0;
- config->dynBwSupported = 1;
- config->tran_thr = 13000;
- config->parametricCoding = 1;
-
- config->sbrFrameSize = codecGranuleLen * downSampleFactor;
- config->downSampleFactor = downSampleFactor;
-
- /* sbr default parameters */
- config->sbr_data_extra = 0;
- config->amp_res = SBR_AMP_RES_3_0 ;
- config->tran_fc = 0 ;
- config->tran_det_mode = 1 ;
- config->spread = 1 ;
- config->stat = 0 ;
- config->e = 1 ;
- config->deltaTAcrossFrames = 1 ;
- config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f) ;
- config->dF_edge_incr = FL2FXCONST_DBL(0.3f) ;
-
- config->sbr_invf_mode = INVF_SWITCHED;
- config->sbr_xpos_mode = XPOS_LC;
- config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT;
- config->sbr_xpos_level = 0;
- config->useSaPan = 0;
- config->dynBwEnabled = 0;
-
-
- /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since
- they are included in the tuning table */
- config->stereoMode = SBR_SWITCH_LRC;
- config->ana_max_level = 6;
- config->noiseFloorOffset = 0;
- config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
- config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
-
-
- /* header_extra_1 */
- config->freqScale = SBR_FREQ_SCALE_DEFAULT;
- config->alterScale = SBR_ALTER_SCALE_DEFAULT;
- config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT;
-
- /* header_extra_2 */
- config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT;
- config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT;
- config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT;
- config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT;
-
- return 1;
-}
-
-
-/*****************************************************************************
-
- functionname: DeleteEnvChannel
- description: frees memory of one SBR channel
- returns: -
- input: handle of channel
- output: released handle
-
-*****************************************************************************/
-static void
-deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut)
-{
- if (hEnvCut) {
-
- FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr);
-
- FDKsbrEnc_deleteExtractSbrEnvelope (&hEnvCut->sbrExtractEnvelope);
- }
-
-}
-
-
-/*****************************************************************************
-
- functionname: sbrEncoder_ChannelClose
- description: close the channel coding handle
- returns:
- input: phSbrChannel
- output:
-
-*****************************************************************************/
-static void
-sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel)
-{
- if (hSbrChannel != NULL)
- {
- deleteEnvChannel (&hSbrChannel->hEnvChannel);
- }
-}
-
-/*****************************************************************************
-
- functionname: sbrEncoder_ElementClose
- description: close the channel coding handle
- returns:
- input: phSbrChannel
- output:
-
-*****************************************************************************/
-static void
-sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement)
-{
- HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement;
-
- if (hSbrElement!=NULL) {
- if (hSbrElement->sbrConfigData.v_k_master)
- FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master);
- if (hSbrElement->sbrConfigData.freqBandTable[LO])
- FreeRam_Sbr_freqBandTableLO(&hSbrElement->sbrConfigData.freqBandTable[LO]);
- if (hSbrElement->sbrConfigData.freqBandTable[HI])
- FreeRam_Sbr_freqBandTableHI(&hSbrElement->sbrConfigData.freqBandTable[HI]);
-
- FreeRam_SbrElement(phSbrElement);
- }
- return ;
-
-}
-
-
-void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder)
-{
- HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder;
-
- if (hSbrEncoder != NULL)
- {
- int el, ch;
-
- for (el=0; el<(8); el++)
- {
- if (hSbrEncoder->sbrElement[el]!=NULL) {
- sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]);
- }
- }
-
- /* Close sbr Channels */
- for (ch=0; ch<(8); ch++)
- {
- if (hSbrEncoder->pSbrChannel[ch]) {
- sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]);
- FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]);
- }
-
- if (hSbrEncoder->QmfAnalysis[ch].FilterStates)
- FreeRam_Sbr_QmfStatesAnalysis((FIXP_QAS**)&hSbrEncoder->QmfAnalysis[ch].FilterStates);
-
-
- }
-
- if (hSbrEncoder->hParametricStereo)
- PSEnc_Destroy(&hSbrEncoder->hParametricStereo);
- if (hSbrEncoder->qmfSynthesisPS.FilterStates)
- FreeRam_PsQmfStatesSynthesis((FIXP_DBL**)&hSbrEncoder->qmfSynthesisPS.FilterStates);
-
- /* Release Overlay */
- FreeRam_SbrDynamic_RAM((FIXP_DBL**)&hSbrEncoder->pSBRdynamic_RAM);
-
-
- FreeRam_SbrEncoder(phSbrEncoder);
- }
-
-}
-
-/*****************************************************************************
-
- functionname: updateFreqBandTable
- description: updates vk_master
- returns: -
- input: config handle
- output: error info
-
-*****************************************************************************/
-static INT updateFreqBandTable(
- HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- const INT downSampleFactor
- )
-{
- INT k0, k2;
-
- if( FDKsbrEnc_FindStartAndStopBand (
- sbrConfigData->sampleFreq,
- sbrConfigData->sampleFreq >> (downSampleFactor-1),
- sbrConfigData->noQmfBands,
- sbrHeaderData->sbr_start_frequency,
- sbrHeaderData->sbr_stop_frequency,
- &k0,
- &k2
- )
- )
- return(1);
-
-
- if( FDKsbrEnc_UpdateFreqScale(
- sbrConfigData->v_k_master,
- &sbrConfigData->num_Master,
- k0,
- k2,
- sbrHeaderData->freqScale,
- sbrHeaderData->alterScale
- )
- )
- return(1);
-
-
- sbrHeaderData->sbr_xover_band=0;
-
-
- if( FDKsbrEnc_UpdateHiRes(
- sbrConfigData->freqBandTable[HI],
- &sbrConfigData->nSfb[HI],
- sbrConfigData->v_k_master,
- sbrConfigData->num_Master,
- &sbrHeaderData->sbr_xover_band
- )
- )
- return(1);
-
-
- FDKsbrEnc_UpdateLoRes(
- sbrConfigData->freqBandTable[LO],
- &sbrConfigData->nSfb[LO],
- sbrConfigData->freqBandTable[HI],
- sbrConfigData->nSfb[HI]
- );
-
-
- sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1;
-
- return (0);
-}
-
-
-/*****************************************************************************
-
- functionname: resetEnvChannel
- description: resets parameters and allocates memory
- returns: error status
- input:
- output: hEnv
-
-*****************************************************************************/
-static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_ENV_CHANNEL hEnv)
-{
- /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function FDKsbrEnc_extractSbrEnvelope !!!*/
- hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = sbrHeaderData->sbr_noise_bands;
-
-
- if(FDKsbrEnc_ResetTonCorrParamExtr(&hEnv->TonCorr,
- sbrConfigData->xposCtrlSwitch,
- sbrConfigData->freqBandTable[HI][0],
- sbrConfigData->v_k_master,
- sbrConfigData->num_Master,
- sbrConfigData->sampleFreq,
- sbrConfigData->freqBandTable,
- sbrConfigData->nSfb,
- sbrConfigData->noQmfBands))
- return(1);
-
- hEnv->sbrCodeNoiseFloor.nSfb[LO] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
- hEnv->sbrCodeNoiseFloor.nSfb[HI] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
-
- hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO];
- hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI];
-
- hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI];
-
- hEnv->sbrCodeEnvelope.upDate = 0;
- hEnv->sbrCodeNoiseFloor.upDate = 0;
-
- return (0);
-}
-
-/* ****************************** FDKsbrEnc_SbrGetXOverFreq ******************************/
-/**
- * @fn
- * @brief calculates the closest possible crossover frequency
- * @return the crossover frequency SBR accepts
- *
- */
-static INT
-FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */
- INT xoverFreq) /*!< from core coder suggested crossover frequency */
-{
- INT band;
- INT lastDiff, newDiff;
- INT cutoffSb;
-
- UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master;
-
- /* Check if there is a matching cutoff frequency in the master table */
- cutoffSb = (4*xoverFreq * hEnv->sbrConfigData.noQmfBands / hEnv->sbrConfigData.sampleFreq + 1)>>1;
- lastDiff = cutoffSb;
- for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) {
-
- newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb);
-
- if(newDiff >= lastDiff) {
- band--;
- break;
- }
-
- lastDiff = newDiff;
- }
-
- return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq/hEnv->sbrConfigData.noQmfBands+1)>>1);
-}
-
-/*****************************************************************************
-
- functionname: FDKsbrEnc_EnvEncodeFrame
- description: performs the sbr envelope calculation for one element
- returns:
- input:
- output:
-
-*****************************************************************************/
-INT
-FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
- int iElement,
- INT_PCM *samples, /*!< time samples, always interleaved */
- UINT timeInStride, /*!< time buffer channel interleaving stride */
- UINT *sbrDataBits, /*!< Size of SBR payload */
- UCHAR *sbrData, /*!< SBR payload */
- int clearOutput /*!< Do not consider any input signal */
- )
-{
- HANDLE_SBR_ELEMENT hSbrElement = hEnvEncoder->sbrElement[iElement];
- FDK_CRCINFO crcInfo;
- INT crcReg;
- INT ch;
- INT band;
- INT cutoffSb;
- INT newXOver;
-
- if (hEnvEncoder == NULL)
- return -1;
-
- hSbrElement = hEnvEncoder->sbrElement[iElement];
-
- if (hSbrElement == NULL)
- return -1;
-
-
- /* header bitstream handling */
- HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData;
-
- INT psHeaderActive = 0;
- sbrBitstreamData->HeaderActive = 0;
-
- /* Anticipate PS header because of internal PS bitstream delay in order to be in sync with SBR header. */
- if ( sbrBitstreamData->CountSendHeaderData==(sbrBitstreamData->NrSendHeaderData-1) )
- {
- psHeaderActive = 1;
- }
-
- /* Signal SBR header to be written into bitstream */
- if ( sbrBitstreamData->CountSendHeaderData==0 )
- {
- sbrBitstreamData->HeaderActive = 1;
- }
-
- /* Increment header interval counter */
- if (sbrBitstreamData->NrSendHeaderData == 0) {
- sbrBitstreamData->CountSendHeaderData = 1;
- }
- else {
- if (sbrBitstreamData->CountSendHeaderData >= 0) {
- sbrBitstreamData->CountSendHeaderData++;
- sbrBitstreamData->CountSendHeaderData %= sbrBitstreamData->NrSendHeaderData;
- }
- }
-
- if (hSbrElement->CmonData.dynBwEnabled ) {
- INT i;
- for ( i = 4; i > 0; i-- )
- hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i-1];
-
- hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc;
- if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2])
- newXOver = hSbrElement->dynXOverFreqDelay[2];
- else
- newXOver = hSbrElement->dynXOverFreqDelay[1];
-
- /* has the crossover frequency changed? */
- if ( hSbrElement->sbrConfigData.dynXOverFreq != newXOver ) {
-
- /* get corresponding master band */
- cutoffSb = ((4* newXOver * hSbrElement->sbrConfigData.noQmfBands
- / hSbrElement->sbrConfigData.sampleFreq)+1)>>1;
-
- for ( band = 0; band < hSbrElement->sbrConfigData.num_Master; band++ ) {
- if ( cutoffSb == hSbrElement->sbrConfigData.v_k_master[band] )
- break;
- }
- FDK_ASSERT( band < hSbrElement->sbrConfigData.num_Master );
-
- hSbrElement->sbrConfigData.dynXOverFreq = newXOver;
- hSbrElement->sbrHeaderData.sbr_xover_band = band;
- hSbrElement->sbrBitstreamData.HeaderActive=1;
- psHeaderActive = 1; /* ps header is one frame delayed */
-
- /*
- update vk_master table
- */
- if(updateFreqBandTable(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- hEnvEncoder->downSampleFactor
- ))
- return(1);
-
-
- /* reset SBR channels */
- INT nEnvCh = hSbrElement->sbrConfigData.nChannels;
- for ( ch = 0; ch < nEnvCh; ch++ ) {
- if(resetEnvChannel (&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- &hSbrElement->sbrChannel[ch]->hEnvChannel))
- return(1);
-
- }
- }
- }
-
- /*
- allocate space for dummy header and crc
- */
- crcReg = FDKsbrEnc_InitSbrBitstream(&hSbrElement->CmonData,
- hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay],
- MAX_PAYLOAD_SIZE*sizeof(UCHAR),
- &crcInfo,
- hSbrElement->sbrConfigData.sbrSyntaxFlags);
-
- /* Temporal Envelope Data */
- SBR_FRAME_TEMP_DATA _fData;
- SBR_FRAME_TEMP_DATA *fData = &_fData;
- SBR_ENV_TEMP_DATA eData[MAX_NUM_CHANNELS];
-
- /* Init Temporal Envelope Data */
- {
- int i;
-
- FDKmemclear(&eData[0], sizeof(SBR_ENV_TEMP_DATA));
- FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA));
- FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA));
-
- for(i=0; i<MAX_NUM_NOISE_VALUES; i++)
- fData->res[i] = FREQ_RES_HIGH;
- }
-
-
- if (!clearOutput)
- {
- /*
- * Transform audio data into QMF domain
- */
- for(ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++)
- {
- HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel;
- HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope;
-
- if(hSbrElement->elInfo.fParametricStereo == 0)
- {
- QMF_SCALE_FACTOR tmpScale;
- FIXP_DBL **pQmfReal, **pQmfImag;
- C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
-
-
- /* Obtain pointers to QMF buffers. */
- pQmfReal = sbrExtrEnv->rBuffer;
- pQmfImag = sbrExtrEnv->iBuffer;
-
- qmfAnalysisFiltering( hSbrElement->hQmfAnalysis[ch],
- pQmfReal,
- pQmfImag,
- &tmpScale,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- timeInStride,
- qmfWorkBuffer );
-
- h_envChan->qmfScale = tmpScale.lb_scale + 7;
-
-
- C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
-
- } /* fParametricStereo == 0 */
-
-
- /*
- Parametric Stereo processing
- */
- if (hSbrElement->elInfo.fParametricStereo)
- {
- INT error = noError;
-
-
- /* Limit Parametric Stereo to one instance */
- FDK_ASSERT(ch == 0);
-
-
- if(error == noError){
- /* parametric stereo processing:
- - input:
- o left and right time domain samples
- - processing:
- o stereo qmf analysis
- o stereo hybrid analysis
- o ps parameter extraction
- o downmix + hybrid synthesis
- - output:
- o downmixed qmf data is written to sbrExtrEnv->rBuffer and sbrExtrEnv->iBuffer
- */
- SCHAR qmfScale;
- INT_PCM* pSamples[2] = {samples + hSbrElement->elInfo.ChannelIndex[0],samples + hSbrElement->elInfo.ChannelIndex[1]};
- error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( hEnvEncoder->hParametricStereo,
- pSamples,
- timeInStride,
- hSbrElement->hQmfAnalysis,
- sbrExtrEnv->rBuffer,
- sbrExtrEnv->iBuffer,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- &hEnvEncoder->qmfSynthesisPS,
- &qmfScale,
- psHeaderActive );
- if (noError != error)
- {
- error = handBack(error);
- }
- h_envChan->qmfScale = (int)qmfScale;
- }
-
-
- } /* if (hEnvEncoder->hParametricStereo) */
-
- /*
-
- Extract Envelope relevant things from QMF data
-
- */
- FDKsbrEnc_extractSbrEnvelope1(
- &hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- &hSbrElement->sbrBitstreamData,
- h_envChan,
- &hSbrElement->CmonData,
- &eData[ch],
- fData
- );
-
- } /* hEnvEncoder->sbrConfigData.nChannels */
- }
-
- /*
- Process Envelope relevant things and calculate envelope data and write payload
- */
- FDKsbrEnc_extractSbrEnvelope2(
- &hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo : NULL,
- &hSbrElement->sbrBitstreamData,
- &hSbrElement->sbrChannel[0]->hEnvChannel,
- &hSbrElement->sbrChannel[1]->hEnvChannel,
- &hSbrElement->CmonData,
- eData,
- fData,
- clearOutput
- );
-
- /*
- format payload, calculate crc
- */
- FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, hSbrElement->sbrConfigData.sbrSyntaxFlags);
-
- /*
- save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE
- */
- hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf);
-
- if(hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > (MAX_PAYLOAD_SIZE<<3))
- hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay]=0;
-
- /* While filling the Delay lines, sbrData is NULL */
- if (sbrData) {
- *sbrDataBits = hSbrElement->payloadDelayLineSize[0];
- FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], (hSbrElement->payloadDelayLineSize[0]+7)>>3);
-
-
- }
-
-
-/*******************************/
-
- if (hEnvEncoder->fTimeDomainDownsampling)
- {
- int ch;
- int nChannels = hSbrElement->sbrConfigData.nChannels;
-
- for (ch=0; ch < nChannels; ch++)
- {
- INT nOutSamples;
-
- FDKaacEnc_Downsample(&hSbrElement->sbrChannel[ch]->downSampler,
- samples + hSbrElement->elInfo.ChannelIndex[ch] + hEnvEncoder->bufferOffset,
- hSbrElement->sbrConfigData.frameSize,
- timeInStride,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- &nOutSamples,
- hEnvEncoder->nChannels);
- }
- } /* downsample */
-
-
- return (0);
-}
-
-/*****************************************************************************
-
- functionname: createEnvChannel
- description: initializes parameters and allocates memory
- returns: error status
- input:
- output: hEnv
-
-*****************************************************************************/
-
-static INT
-createEnvChannel (HANDLE_ENV_CHANNEL hEnv,
- INT channel
- ,UCHAR* dynamic_RAM
- )
-{
- FDKmemclear(hEnv,sizeof (struct ENV_CHANNEL));
-
- if ( FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr,
- channel) )
- {
- return(1);
- }
-
- if ( FDKsbrEnc_CreateExtractSbrEnvelope (&hEnv->sbrExtractEnvelope,
- channel
- ,/*chan*/0
- ,dynamic_RAM
- ) )
- {
- return(1);
- }
-
- return 0;
-}
-
-/*****************************************************************************
-
- functionname: initEnvChannel
- description: initializes parameters
- returns: error status
- input:
- output:
-
-*****************************************************************************/
-static INT
-initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_ENV_CHANNEL hEnv,
- sbrConfigurationPtr params,
- ULONG statesInitFlag
- ,INT chanInEl
- ,UCHAR* dynamic_RAM
- )
-{
- int frameShift, tran_off=0;
- INT e;
- INT tran_fc;
- INT timeSlots, timeStep, startIndex;
- INT noiseBands[2] = { 3, 3 };
-
- e = 1 << params->e;
-
- FDK_ASSERT(params->e >= 0);
-
- hEnv->encEnvData.freq_res_fixfix = 1;
- hEnv->fLevelProtect = 0;
-
- hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
-
- hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode;
-
- if (hEnv->encEnvData.sbr_xpos_mode == XPOS_SWITCHED) {
- /*
- no other type than XPOS_MDCT or XPOS_SPEECH allowed,
- but enable switching
- */
- sbrConfigData->switchTransposers = TRUE;
- hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT;
- }
- else {
- sbrConfigData->switchTransposers = FALSE;
- }
-
- hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl;
-
-
- /* extended data */
- if(params->parametricCoding) {
- hEnv->encEnvData.extended_data = 1;
- }
- else {
- hEnv->encEnvData.extended_data = 0;
- }
-
- hEnv->encEnvData.extension_size = 0;
-
- startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands;
-
- switch (params->sbrFrameSize) {
- case 2304:
- timeSlots = 18;
- break;
- case 2048:
- case 1024:
- case 512:
- timeSlots = 16;
- break;
- case 1920:
- case 960:
- case 480:
- timeSlots = 15;
- break;
- case 1152:
- timeSlots = 9;
- break;
- default:
- return (1); /* Illegal frame size */
- }
-
- timeStep = sbrConfigData->noQmfSlots / timeSlots;
-
- if ( FDKsbrEnc_InitTonCorrParamExtr(params->sbrFrameSize,
- &hEnv->TonCorr,
- sbrConfigData,
- timeSlots,
- params->sbr_xpos_ctrl,
- params->ana_max_level,
- sbrHeaderData->sbr_noise_bands,
- params->noiseFloorOffset,
- params->useSpeechConfig) )
- return(1);
-
- hEnv->encEnvData.noOfnoisebands = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
-
- noiseBands[0] = hEnv->encEnvData.noOfnoisebands;
- noiseBands[1] = hEnv->encEnvData.noOfnoisebands;
-
- hEnv->encEnvData.sbr_invf_mode = (INVF_MODE)params->sbr_invf_mode;
-
- if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) {
- hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL;
- hEnv->TonCorr.switchInverseFilt = TRUE;
- }
- else {
- hEnv->TonCorr.switchInverseFilt = FALSE;
- }
-
-
- tran_fc = params->tran_fc;
-
- if (tran_fc == 0) {
- tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,params->codecSettings.sampleFreq));
- }
-
- tran_fc = (tran_fc*4*sbrConfigData->noQmfBands/sbrConfigData->sampleFreq + 1)>>1;
-
- if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
- frameShift = LD_PRETRAN_OFF;
- tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD*timeStep;
- } else
- {
- frameShift = 0;
- switch (timeSlots) {
- /* The factor of 2 is by definition. */
- case NUMBER_TIME_SLOTS_2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break;
- case NUMBER_TIME_SLOTS_1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break;
- default: return 1;
- }
- }
- if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope,
- sbrConfigData->noQmfSlots,
- sbrConfigData->noQmfBands, startIndex,
- timeSlots, timeStep, tran_off,
- statesInitFlag
- ,chanInEl
- ,dynamic_RAM
- ,sbrConfigData->sbrSyntaxFlags
- ) )
- return(1);
-
- if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeEnvelope,
- sbrConfigData->nSfb,
- params->deltaTAcrossFrames,
- params->dF_edge_1stEnv,
- params->dF_edge_incr))
- return(1);
-
- if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeNoiseFloor,
- noiseBands,
- params->deltaTAcrossFrames,
- 0,0))
- return(1);
-
- sbrConfigData->initAmpResFF = params->init_amp_res_FF;
-
- if(FDKsbrEnc_InitSbrHuffmanTables (&hEnv->encEnvData,
- &hEnv->sbrCodeEnvelope,
- &hEnv->sbrCodeNoiseFloor,
- sbrHeaderData->sbr_amp_res))
- return(1);
-
- FDKsbrEnc_initFrameInfoGenerator (&hEnv->SbrEnvFrame,
- params->spread,
- e,
- params->stat,
- timeSlots,
- hEnv->encEnvData.freq_res_fixfix
- ,hEnv->encEnvData.ldGrid
- );
-
- if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector,
- sbrConfigData->frameSize,
- sbrConfigData->sampleFreq,
- params,
- tran_fc,
- sbrConfigData->noQmfSlots,
- sbrConfigData->noQmfBands,
- hEnv->sbrExtractEnvelope.YBufferWriteOffset,
- hEnv->sbrExtractEnvelope.YBufferSzShift,
- frameShift,
- tran_off
- ))
- return(1);
-
-
- sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl;
-
- hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI];
- hEnv->encEnvData.addHarmonicFlag = 0;
-
- return (0);
-}
-
-INT sbrEncoder_Open(
- HANDLE_SBR_ENCODER *phSbrEncoder,
- INT nElements,
- INT nChannels,
- INT supportPS
- )
-{
- INT i;
- INT errorStatus = 1;
- HANDLE_SBR_ENCODER hSbrEncoder = NULL;
-
- if (phSbrEncoder==NULL
- )
- {
- goto bail;
- }
-
- hSbrEncoder = GetRam_SbrEncoder();
- if (hSbrEncoder==NULL) {
- goto bail;
- }
- FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER));
-
- hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM();
- hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM;
-
- for (i=0; i<nElements; i++) {
- hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i);
- if (hSbrEncoder->sbrElement[i]==NULL) {
- goto bail;
- }
- FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT));
- hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = GetRam_Sbr_freqBandTableLO(i);
- hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = GetRam_Sbr_freqBandTableHI(i);
- hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = GetRam_Sbr_v_k_master(i);
- if ( (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO]==NULL) ||
- (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI]==NULL) ||
- (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master==NULL) )
- {
- goto bail;
- }
- }
-
- for (i=0; i<nChannels; i++) {
- hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i);
- if (hSbrEncoder->pSbrChannel[i]==NULL) {
- goto bail;
- }
-
- if ( createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel,
- i
- ,hSbrEncoder->dynamicRam
- ) )
- {
- goto bail;
- }
-
- }
-
- for (i=0; i<fixMax(nChannels,(supportPS)?2:0); i++) {
- hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i);
- if (hSbrEncoder->QmfAnalysis[i].FilterStates==NULL) {
- goto bail;
- }
- }
-
- if (supportPS) {
- if (PSEnc_Create(&hSbrEncoder->hParametricStereo))
- {
- goto bail;
- }
-
- hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis();
- if (hSbrEncoder->qmfSynthesisPS.FilterStates==NULL) {
- goto bail;
- }
- } /* supportPS */
-
- *phSbrEncoder = hSbrEncoder;
-
- errorStatus = 0;
- return errorStatus;
-
-bail:
- /* Close SBR encoder instance */
- sbrEncoder_Close(&hSbrEncoder);
- return errorStatus;
-}
-
-static
-INT FDKsbrEnc_Reallocate(
- HANDLE_SBR_ENCODER hSbrEncoder,
- SBR_ELEMENT_INFO elInfo[(8)],
- const INT noElements)
-{
- INT totalCh = 0;
- INT totalQmf = 0;
- INT coreEl;
- INT el=-1;
-
- hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */
-
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
- /* SBR only handles SCE and CPE's */
- if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
- el++;
- } else {
- if (elInfo[coreEl].elType == ID_LFE) {
- hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0];
- }
- continue;
- }
-
- SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl];
- HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el];
-
- int ch;
- for ( ch = 0; ch < pelInfo->nChannelsInEl; ch++ ) {
- hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh];
- totalCh++;
- }
- /* analysis QMF */
- for ( ch = 0; ch < ((pelInfo->fParametricStereo)?2:pelInfo->nChannelsInEl); ch++ ) {
- hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch];
- hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++];
- }
-
- /* Copy Element info */
- hSbrElement->elInfo.elType = pelInfo->elType;
- hSbrElement->elInfo.instanceTag = pelInfo->instanceTag;
- hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl;
- hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo;
- } /* coreEl */
-
- return 0;
-}
-
-
-
-/*****************************************************************************
-
- functionname: FDKsbrEnc_EnvInit
- description: initializes parameters
- returns: error status
- input:
- output: hEnv
-
-*****************************************************************************/
-static
-INT FDKsbrEnc_EnvInit (
- HANDLE_SBR_ELEMENT hSbrElement,
- sbrConfigurationPtr params,
- INT *coreBandWith,
- AUDIO_OBJECT_TYPE aot,
- int nBitstrDelay,
- int nElement,
- const int headerPeriod,
- ULONG statesInitFlag,
- int fTimeDomainDownsampling
- ,UCHAR *dynamic_RAM
- )
-{
- UCHAR *bitstreamBuffer;
- int ch, i;
-
- if ((params->codecSettings.nChannels < 1) || (params->codecSettings.nChannels > MAX_NUM_CHANNELS)){
- return(1);
- }
-
- /* initialize the encoder handle and structs*/
- bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay];
-
- /* init and set syntax flags */
- hSbrElement->sbrConfigData.sbrSyntaxFlags = 0;
-
- switch (aot) {
- case AOT_DRM_MPEG_PS:
- case AOT_DRM_SBR:
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_SCALABLE;
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_DRM_CRC;
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
- break;
- case AOT_ER_AAC_ELD:
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
- break;
- default:
- break;
- }
- if (params->crcSbr) {
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
- }
-
- hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS>>(2-params->downSampleFactor);
- switch (hSbrElement->sbrConfigData.noQmfBands)
- {
- case 64: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6;
- break;
- case 32: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>5;
- break;
- default: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6;
- return(2);
- }
-
- FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, MAX_PAYLOAD_SIZE*sizeof(UCHAR), 0, BS_WRITER);
-
- /*
- now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData,
- */
- hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels;
-
- if(params->codecSettings.nChannels == 2)
- hSbrElement->sbrConfigData.stereoMode = params->stereoMode;
- else
- hSbrElement->sbrConfigData.stereoMode = SBR_MONO;
-
- hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize;
-
- hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq;
-
- hSbrElement->sbrBitstreamData.CountSendHeaderData = 0;
- if (params->SendHeaderDataTime > 0 ) {
-
- if (headerPeriod==-1) {
-
- hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq
- / (1000 * hSbrElement->sbrConfigData.frameSize));
- hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData,1);
- }
- else {
- /* assure header period at least once per second */
- hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(fixMax(headerPeriod,1),(hSbrElement->sbrConfigData.sampleFreq/hSbrElement->sbrConfigData.frameSize));
- }
- }
- else {
- hSbrElement->sbrBitstreamData.NrSendHeaderData = 0;
- }
-
- hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra;
- hSbrElement->sbrBitstreamData.HeaderActive = 0;
- hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq;
- hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq;
- hSbrElement->sbrHeaderData.sbr_xover_band = 0;
- hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0;
-
- /* data_extra */
- if (params->sbr_xpos_ctrl!= SBR_XPOS_CTRL_DEFAULT)
- hSbrElement->sbrHeaderData.sbr_data_extra = 1;
-
- hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res;
-
- /* header_extra_1 */
- hSbrElement->sbrHeaderData.freqScale = params->freqScale;
- hSbrElement->sbrHeaderData.alterScale = params->alterScale;
- hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands;
- hSbrElement->sbrHeaderData.header_extra_1 = 0;
-
- if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) ||
- (params->alterScale != SBR_ALTER_SCALE_DEFAULT) ||
- (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT))
- {
- hSbrElement->sbrHeaderData.header_extra_1 = 1;
- }
-
- /* header_extra_2 */
- hSbrElement->sbrHeaderData.sbr_limiter_bands = params->sbr_limiter_bands;
- hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains;
-
- if ((hSbrElement->sbrConfigData.sampleFreq > 48000) &&
- (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9))
- {
- hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE;
- }
-
- hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq;
- hSbrElement->sbrHeaderData.sbr_smoothing_length = params->sbr_smoothing_length;
- hSbrElement->sbrHeaderData.header_extra_2 = 0;
-
- if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) ||
- (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) ||
- (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) ||
- (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT))
- {
- hSbrElement->sbrHeaderData.header_extra_2 = 1;
- }
-
- /* other switches */
- hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
- hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
-
- /* init freq band table */
- if(updateFreqBandTable(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- params->downSampleFactor
- ))
- {
- return(1);
- }
-
- /* now create envelope ext and QMF for each available channel */
- for ( ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++ ) {
-
- if ( initEnvChannel(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- &hSbrElement->sbrChannel[ch]->hEnvChannel,
- params,
- statesInitFlag
- ,ch
- ,dynamic_RAM
- ) )
- {
- return(1);
- }
-
-
- } /* nChannels */
-
- /* reset and intialize analysis qmf */
- for ( ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)?2:hSbrElement->sbrConfigData.nChannels); ch++ )
- {
- int err;
- UINT qmfFlags = (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? QMF_FLAG_CLDFB : 0;
- if (statesInitFlag)
- qmfFlags &= ~QMF_FLAG_KEEP_STATES;
- else
- qmfFlags |= QMF_FLAG_KEEP_STATES;
-
- err = qmfInitAnalysisFilterBank( hSbrElement->hQmfAnalysis[ch],
- (FIXP_QAS*)hSbrElement->hQmfAnalysis[ch]->FilterStates,
- hSbrElement->sbrConfigData.noQmfSlots,
- hSbrElement->sbrConfigData.noQmfBands,
- hSbrElement->sbrConfigData.noQmfBands,
- hSbrElement->sbrConfigData.noQmfBands,
- qmfFlags );
- if (0!=err) {
- return err;
- }
- }
-
- /* */
- hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq;
- hSbrElement->CmonData.dynBwEnabled = (params->dynBwSupported && params->dynBwEnabled);
- hSbrElement->CmonData.dynXOverFreqEnc = FDKsbrEnc_SbrGetXOverFreq( hSbrElement, hSbrElement->CmonData.xOverFreq);
- for ( i = 0; i < 5; i++ )
- hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc;
- hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels;
- hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq;
-
- /* Update Bandwith to be passed to the core encoder */
- *coreBandWith = hSbrElement->CmonData.xOverFreq;
-
- return(0);
- }
-
-INT sbrEncoder_GetInBufferSize(int noChannels)
-{
- INT temp;
-
- temp = (2048);
- temp += 1024 + MAX_SAMPLE_DELAY;
- temp *= noChannels;
- temp *= sizeof(INT_PCM);
- return temp;
-}
-
-/*
- * Encode Dummy SBR payload frames to fill the delay lines.
- */
-static
-INT FDKsbrEnc_DelayCompensation (
- HANDLE_SBR_ENCODER hEnvEnc,
- INT_PCM *timeBuffer
- )
-{
- int n, el;
-
- for (n=hEnvEnc->nBitstrDelay; n>0; n--)
- {
- for (el=0; el<hEnvEnc->noElements; el++)
- {
- if (FDKsbrEnc_EnvEncodeFrame(
- hEnvEnc,
- el,
- timeBuffer + hEnvEnc->downsampledOffset,
- hEnvEnc->sbrElement[el]->sbrConfigData.nChannels,
- NULL,
- NULL,
- 1
- ))
- return -1;
- }
- sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer);
- }
- return 0;
-}
-
-UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot)
-{
- UINT newBitRate;
- INT index;
-
- FDK_ASSERT(numChannels > 0 && numChannels <= 2);
- if (aot == AOT_PS) {
- if (numChannels == 2) {
- index = getPsTuningTableIndex(bitRate, &newBitRate);
- if (index == INVALID_TABLE_IDX) {
- bitRate = newBitRate;
- }
- /* Set numChannels to 1 because for PS we need a SBR SCE (mono) element. */
- numChannels = 1;
- } else {
- return 0;
- }
- }
- index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, &newBitRate);
- if (index != INVALID_TABLE_IDX) {
- newBitRate = bitRate;
- }
-
- return newBitRate;
-}
-
-UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot)
-{
- UINT isPossible=(AOT_PS==aot)?0:1;
- return isPossible;
-}
-
-INT sbrEncoder_Init(
- HANDLE_SBR_ENCODER hSbrEncoder,
- SBR_ELEMENT_INFO elInfo[(8)],
- int noElements,
- INT_PCM *inputBuffer,
- INT *coreBandwidth,
- INT *inputBufferOffset,
- INT *numChannels,
- INT *coreSampleRate,
- UINT *downSampleFactor,
- INT *frameLength,
- AUDIO_OBJECT_TYPE aot,
- int *delay,
- int transformFactor,
- const int headerPeriod,
- ULONG statesInitFlag
- )
-{
- HANDLE_ERROR_INFO errorInfo = noError;
- sbrConfiguration sbrConfig[(8)];
- INT error = 0;
- INT lowestBandwidth;
- /* Save input parameters */
- INT inputSampleRate = *coreSampleRate;
- int coreFrameLength = *frameLength;
- int inputBandWidth = *coreBandwidth;
- int inputChannels = *numChannels;
-
- int downsampledOffset = 0;
- int sbrOffset = 0;
- int downsamplerDelay = 0;
- int timeDomainDownsample = 0;
- int nBitstrDelay = 0;
- int highestSbrStartFreq, highestSbrStopFreq;
- int lowDelay = 0;
- int usePs = 0;
-
- /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */
- if (!sbrEncoder_IsSingleRatePossible(aot)) {
- *downSampleFactor = 2;
- }
-
-
-
- if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) {
- usePs = 1;
- }
- if ( (aot==AOT_ER_AAC_ELD) ) {
- lowDelay = 1;
- }
- else if ( (aot==AOT_ER_AAC_LD) ) {
- error = 1;
- goto bail;
- }
-
- /* Parametric Stereo */
- if ( usePs ) {
- if ( *numChannels == 2 && noElements == 1) {
- /* Override Element type in case of Parametric stereo */
- elInfo[0].elType = ID_SCE;
- elInfo[0].fParametricStereo = 1;
- elInfo[0].nChannelsInEl = 1;
- /* core encoder gets downmixed mono signal */
- *numChannels = 1;
- } else {
- error = 1;
- goto bail;
- }
- } /* usePs */
-
- /* set the core's sample rate */
- switch (*downSampleFactor) {
- case 1:
- *coreSampleRate = inputSampleRate;
- break;
- case 2:
- *coreSampleRate = inputSampleRate>>1;
- break;
- default:
- *coreSampleRate = inputSampleRate>>1;
- return 0; /* return error */
- }
-
- /* check whether SBR setting is available for the current encoder configuration (bitrate, coreSampleRate) */
- {
- int delayDiff = 0;
- int el, coreEl;
-
- /* Check if every element config is feasible */
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
- /* SBR only handles SCE and CPE's */
- if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) {
- continue;
- }
- /* check if desired configuration is available */
- if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) )
- {
- error = 1;
- goto bail;
- }
- }
-
- /* Determine Delay balancing and new encoder delay */
- if (lowDelay) {
- {
- delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor);
- *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor);
- }
- }
- else if (usePs) {
- delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor);
- *delay = DELAY_PS(coreFrameLength,*downSampleFactor);
- }
- else {
- delayDiff = DELAY_AAC2SBR(coreFrameLength,*downSampleFactor);
- delayDiff += (*delay * *downSampleFactor);
- *delay = DELAY_SBR(coreFrameLength,*downSampleFactor);
- }
-
- if (!usePs) {
- timeDomainDownsample = *downSampleFactor-1; /* activate time domain downsampler when downSampleFactor is != 1 */
- }
-
-
- /* Take care about downsampled data bound to the SBR path */
- if (!timeDomainDownsample && delayDiff > 0) {
- /*
- * We must tweak the balancing into a situation where the downsampled path
- * is the one to be delayed, because delaying the QMF domain input, also delays
- * the downsampled audio, counteracting to the purpose of delay balancing.
- */
- while ( delayDiff > 0 )
- {
- /* Encoder delay increases */
- {
- *delay += coreFrameLength * *downSampleFactor;
- /* Add one frame delay to SBR path */
- delayDiff -= coreFrameLength * *downSampleFactor;
- }
- nBitstrDelay += 1;
- }
- } else
- {
- *delay += fixp_abs(delayDiff);
- }
-
- if (delayDiff < 0) {
- /* Delay AAC data */
- delayDiff = -delayDiff;
- /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */
- FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2);
- downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1);
- sbrOffset = 0;
- } else {
- /* Delay SBR input */
- if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor )
- {
- /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */
- delayDiff -= coreFrameLength * *downSampleFactor;
- nBitstrDelay = 1;
- }
- /* Multiply input offset by input channels */
- sbrOffset = delayDiff*(*numChannels);
- downsampledOffset = 0;
- }
- hSbrEncoder->nBitstrDelay = nBitstrDelay;
- hSbrEncoder->nChannels = *numChannels;
- hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor;
- hSbrEncoder->fTimeDomainDownsampling = timeDomainDownsample;
- hSbrEncoder->downSampleFactor = *downSampleFactor;
- hSbrEncoder->estimateBitrate = 0;
- hSbrEncoder->inputDataDelay = 0;
-
-
- /* Open SBR elements */
- el = -1;
- highestSbrStartFreq = highestSbrStopFreq = 0;
- lowestBandwidth = 99999;
-
- /* Loop through each core encoder element and get a matching SBR element config */
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
- /* SBR only handles SCE and CPE's */
- if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
- el++;
- } else {
- continue;
- }
-
- /* Set parametric Stereo Flag. */
- if (usePs) {
- elInfo[coreEl].fParametricStereo = 1;
- } else {
- elInfo[coreEl].fParametricStereo = 0;
- }
-
- /*
- * Init sbrConfig structure
- */
- if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
- *downSampleFactor,
- coreFrameLength
- ) )
- {
- error = 1;
- goto bail;
- }
-
- /*
- * Modify sbrConfig structure according to Element parameters
- */
- if ( ! FDKsbrEnc_AdjustSbrSettings (&sbrConfig[el],
- elInfo[coreEl].bitRate,
- elInfo[coreEl].nChannelsInEl,
- *coreSampleRate,
- inputSampleRate,
- transformFactor,
- 24000,
- 0,
- 0, /* useSpeechConfig */
- 0, /* lcsMode */
- usePs, /* bParametricStereo */
- aot) )
- {
- error = 1;
- goto bail;
- }
-
- /* Find common frequency border for all SBR elements */
- highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq);
- highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq);
-
- } /* first element loop */
-
- /* Set element count (can be less than core encoder element count) */
- hSbrEncoder->noElements = el+1;
-
- FDKsbrEnc_Reallocate(hSbrEncoder,
- elInfo,
- noElements);
-
- for (el=0; el<hSbrEncoder->noElements; el++) {
-
- int bandwidth = *coreBandwidth;
-
- /* Use lowest common bandwidth */
- sbrConfig[el].startFreq = highestSbrStartFreq;
- sbrConfig[el].stopFreq = highestSbrStopFreq;
-
- /* initialize SBR element, and get core bandwidth */
- error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el],
- &sbrConfig[el],
- &bandwidth,
- aot,
- nBitstrDelay,
- el,
- headerPeriod,
- statesInitFlag,
- hSbrEncoder->fTimeDomainDownsampling
- ,hSbrEncoder->dynamicRam
- );
-
- if (error != 0) {
- error = 2;
- goto bail;
- }
-
- /* Get lowest core encoder bandwidth to be returned later. */
- lowestBandwidth = fixMin(lowestBandwidth, bandwidth);
-
- } /* second element loop */
-
- /* Initialize a downsampler for each channel in each SBR element */
- if (hSbrEncoder->fTimeDomainDownsampling)
- {
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el];
- INT Wc, ch;
-
- /* Calculated required normalized cutoff frequency (Wc = 1.0 -> lowestBandwidth = inputSampleRate/2) */
- Wc = (2*lowestBandwidth)*1000 / inputSampleRate;
-
- for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++)
- {
- FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor);
- FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY);
- }
-
- downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay;
- } /* third element loop */
-
- /* lfe */
- FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, *downSampleFactor);
-
- /* Add the resampler additional delay to get the final delay and buffer offset values. */
- if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) {
- sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ;
- *delay += downsamplerDelay - downsampledOffset;
- downsampledOffset = 0;
- } else {
- downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1);
- sbrOffset = 0;
- }
-
- hSbrEncoder->inputDataDelay = downsamplerDelay;
- }
-
- /* Assign core encoder Bandwidth */
- *coreBandwidth = lowestBandwidth;
-
- /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */
- hSbrEncoder->estimateBitrate += 2500 * (*numChannels);
-
- /* initialize parametric stereo */
- if (usePs)
- {
- PSENC_CONFIG psEncConfig;
- FDK_ASSERT(hSbrEncoder->noElements == 1);
- INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL);
-
- psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize;
- psEncConfig.qmfFilterMode = 0;
- psEncConfig.sbrPsDelay = 0;
-
- /* tuning parameters */
- if (psTuningTableIdx != INVALID_TABLE_IDX) {
- psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands;
- psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes;
- psEncConfig.iidQuantErrorThreshold = (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold;
-
- /* calculation is not quite linear, increased number of envelopes causes more bits */
- /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope configuration */
- hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize));
-
- } else {
- error = ERROR(CDI, "Invalid ps tuning table index.");
- goto bail;
- }
-
- qmfInitSynthesisFilterBank(&hSbrEncoder->qmfSynthesisPS,
- (FIXP_DBL*)hSbrEncoder->qmfSynthesisPS.FilterStates,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES);
-
- if(errorInfo == noError){
- /* update delay */
- psEncConfig.sbrPsDelay = FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]->sbrChannel[0]->hEnvChannel.sbrExtractEnvelope);
-
- if(noError != (errorInfo = PSEnc_Init( hSbrEncoder->hParametricStereo,
- &psEncConfig,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands
- ,hSbrEncoder->dynamicRam
- )))
- {
- errorInfo = handBack(errorInfo);
- }
- }
-
- /* QMF analysis + Hybrid analysis + Hybrid synthesis + QMF synthesis + downsampled input buffer delay */
- hSbrEncoder->inputDataDelay = (64*10/2) + (6*64) + (0) + (64*10/2-64+1) + ((*downSampleFactor)*downsampledOffset);
- }
-
- hSbrEncoder->downsampledOffset = downsampledOffset;
- {
- hSbrEncoder->downmixSize = coreFrameLength*(*numChannels);
- }
-
- hSbrEncoder->bufferOffset = sbrOffset;
- /* Delay Compensation: fill bitstream delay buffer with zero input signal */
- if ( hSbrEncoder->nBitstrDelay > 0 )
- {
- error = FDKsbrEnc_DelayCompensation (hSbrEncoder, inputBuffer);
- if (error != 0)
- goto bail;
- }
-
- /* Set Output frame length */
- *frameLength = coreFrameLength * *downSampleFactor;
- /* Input buffer offset */
- *inputBufferOffset = fixMax(sbrOffset, downsampledOffset);
-
-
- }
-
- return error;
-
-bail:
- /* Restore input settings */
- *coreSampleRate = inputSampleRate;
- *frameLength = coreFrameLength;
- *numChannels = inputChannels;
- *coreBandwidth = inputBandWidth;
-
- return error;
- }
-
-
-INT
-sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder,
- INT_PCM *samples,
- UINT timeInStride,
- UINT sbrDataBits[(8)],
- UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]
- )
-{
- INT error;
- int el;
-
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- if (hSbrEncoder->sbrElement[el] != NULL)
- {
- error = FDKsbrEnc_EnvEncodeFrame(
- hSbrEncoder,
- el,
- samples + hSbrEncoder->downsampledOffset,
- timeInStride,
- &sbrDataBits[el],
- sbrData[el],
- 0
- );
- if (error)
- return error;
- }
- }
-
- if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) )
- { /* lfe downsampler */
- INT nOutSamples;
-
- FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler,
- samples + hSbrEncoder->downsampledOffset + hSbrEncoder->bufferOffset + hSbrEncoder->lfeChIdx,
- hSbrEncoder->frameSize,
- timeInStride,
- samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx,
- &nOutSamples,
- hSbrEncoder->nChannels);
-
-
- }
-
- return 0;
-}
-
-
-INT sbrEncoder_UpdateBuffers(
- HANDLE_SBR_ENCODER hSbrEncoder,
- INT_PCM *timeBuffer
- )
- {
- if ( hSbrEncoder->downsampledOffset > 0 ) {
- /* Move delayed downsampled data */
- FDKmemcpy ( timeBuffer,
- timeBuffer + hSbrEncoder->downmixSize,
- sizeof(INT_PCM) * (hSbrEncoder->downsampledOffset) );
- } else {
- /* Move delayed input data */
- FDKmemcpy ( timeBuffer,
- timeBuffer + hSbrEncoder->nChannels * hSbrEncoder->frameSize,
- sizeof(INT_PCM) * hSbrEncoder->bufferOffset );
- }
- if ( hSbrEncoder->nBitstrDelay > 0 )
- {
- int el;
-
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- FDKmemmove ( hSbrEncoder->sbrElement[el]->payloadDelayLine[0],
- hSbrEncoder->sbrElement[el]->payloadDelayLine[1],
- sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay*MAX_PAYLOAD_SIZE) );
-
- FDKmemmove( &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0],
- &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1],
- sizeof(UINT) * (hSbrEncoder->nBitstrDelay) );
- }
- }
- return 0;
- }
-
-
-INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder)
-{
- INT estimateBitrate = 0;
-
- if(hSbrEncoder) {
- estimateBitrate += hSbrEncoder->estimateBitrate;
- }
-
- return estimateBitrate;
-}
-
-INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder)
-{
- INT delay = -1;
-
- if(hSbrEncoder) {
- delay = hSbrEncoder->inputDataDelay;
- }
- return delay;
-}
-
-
-INT sbrEncoder_GetLibInfo( LIB_INFO *info )
-{
- int i;
-
- if (info == NULL) {
- return -1;
- }
- /* search for next free tab */
- for (i = 0; i < FDK_MODULE_LAST; i++) {
- if (info[i].module_id == FDK_NONE) break;
- }
- if (i == FDK_MODULE_LAST) {
- return -1;
- }
- info += i;
-
- info->module_id = FDK_SBRENC;
- info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
- LIB_VERSION_STRING(info);
- info->build_date = __DATE__;
- info->build_time = __TIME__;
- info->title = "SBR Encoder";
-
- /* Set flags */
- info->flags = 0
- | CAPF_SBR_HQ
- | CAPF_SBR_PS_MPEG
- ;
- /* End of flags */
-
- return 0;
-}