/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/************************* MPEG-D DRC decoder library **************************

   Author(s):   Andreas Hoelzer

   Description: DRC Set Selection

*******************************************************************************/

#include "drcDec_selectionProcess.h"
#include "drcDec_tools.h"

#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL

typedef enum {
  DETR_NONE = 0,
  DETR_NIGHT = 1,
  DETR_NOISY = 2,
  DETR_LIMITED = 3,
  DETR_LOWLEVEL = 4,
  DETR_DIALOG = 5,
  DETR_GENERAL_COMPR = 6,
  DETR_EXPAND = 7,
  DETR_ARTISTIC = 8,
  DETR_COUNT
} DRC_EFFECT_TYPE_REQUEST;

typedef enum {
  DFRT_EFFECT_TYPE,
  DFRT_DYNAMIC_RANGE,
  DFRT_DRC_CHARACTERISTIC
} DRC_FEATURE_REQUEST_TYPE;

typedef enum {
  MDR_DEFAULT = 0,
  MDR_PROGRAM_LOUDNESS = 1,
  MDR_ANCHOR_LOUDNESS = 2
} METHOD_DEFINITION_REQUEST;

typedef enum {
  MSR_DEFAULT = 0,
  MSR_BS_1770_4 = 1,
  MSR_USER = 2,
  MSR_EXPERT_PANEL = 3,
  MSR_RESERVED_A = 4,
  MSR_RESERVED_B = 5,
  MSR_RESERVED_C = 6,
  MSR_RESERVED_D = 7,
  MSR_RESERVED_E = 8
} MEASUREMENT_SYSTEM_REQUEST;

typedef enum {
  LPR_DEFAULT = 0,
  LPR_OFF = 1,
  LPR_HIGHPASS = 2
} LOUDNESS_PREPROCESSING_REQUEST;

typedef enum {
  DRMRT_SHORT_TERM_LOUDNESS_TO_AVG = 0,
  DRMRT_MOMENTARY_LOUDNESS_TO_AVG = 1,
  DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG = 2
} DYN_RANGE_MEASUREMENT_REQUEST_TYPE;

typedef enum {
  TCRT_DOWNMIX_ID = 0,
  TCRT_TARGET_LAYOUT = 1,
  TCRT_TARGET_CHANNEL_COUNT = 2
} TARGET_CONFIG_REQUEST_TYPE;

typedef shouldBeUnion {
  struct {
    UCHAR numRequests;
    UCHAR numRequestsDesired;
    DRC_EFFECT_TYPE_REQUEST request[MAX_REQUESTS_DRC_EFFECT_TYPE];
  } drcEffectType;
  struct {
    DYN_RANGE_MEASUREMENT_REQUEST_TYPE measurementRequestType;
    UCHAR requestedIsRange;
    FIXP_DBL requestValue;    /* e = 7 */
    FIXP_DBL requestValueMin; /* e = 7 */
    FIXP_DBL requestValueMax; /* e = 7 */
  } dynamicRange;
  UCHAR drcCharacteristic;
}
DRC_FEATURE_REQUEST;

typedef struct {
  /* system parameters */
  SCHAR baseChannelCount;
  SCHAR baseLayout; /* not supported */
  TARGET_CONFIG_REQUEST_TYPE targetConfigRequestType;
  UCHAR numDownmixIdRequests;
  UCHAR downmixIdRequested[MAX_REQUESTS_DOWNMIX_ID];
  UCHAR targetLayoutRequested;
  UCHAR targetChannelCountRequested;
  LONG audioSampleRate; /* needed for complexity estimation, currently not
                           supported */

  /* loudness normalization parameters */
  UCHAR loudnessNormalizationOn;
  FIXP_DBL targetLoudness; /* e = 7 */
  UCHAR albumMode;
  UCHAR peakLimiterPresent;
  UCHAR loudnessDeviationMax; /* resolution: 1 dB */
  METHOD_DEFINITION_REQUEST loudnessMeasurementMethod;
  MEASUREMENT_SYSTEM_REQUEST loudnessMeasurementSystem;
  LOUDNESS_PREPROCESSING_REQUEST loudnessMeasurementPreProc; /* not supported */
  LONG deviceCutOffFrequency;                                /* not supported */
  FIXP_DBL loudnessNormalizationGainDbMax;                   /* e = 7 */
  FIXP_DBL loudnessNormalizationGainModificationDb;          /* e = 7 */
  FIXP_DBL outputPeakLevelMax;                               /* e = 7 */

  /* dynamic range control parameters */
  UCHAR dynamicRangeControlOn;
  UCHAR numDrcFeatureRequests;
  DRC_FEATURE_REQUEST_TYPE drcFeatureRequestType[MAX_REQUESTS_DRC_FEATURE];
  DRC_FEATURE_REQUEST drcFeatureRequest[MAX_REQUESTS_DRC_FEATURE];

  /* other */
  FIXP_SGL boost;                /* e = 1 */
  FIXP_SGL compress;             /* e = 1 */
  UCHAR drcCharacteristicTarget; /* not supported */
} SEL_PROC_INPUT, *HANDLE_SEL_PROC_INPUT;

/* Table E.1 of ISO/IEC DIS 23003-4: Recommended order of fallback effect type
 * requests */
static DRC_EFFECT_TYPE_REQUEST fallbackEffectTypeRequests[6][5] = {
    /* Night */ {DETR_GENERAL_COMPR, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL,
                 DETR_DIALOG},
    /* Noisy */
    {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG},
    /* Limited */
    {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LOWLEVEL, DETR_DIALOG},
    /* LowLevel */
    {DETR_GENERAL_COMPR, DETR_NOISY, DETR_NIGHT, DETR_LIMITED, DETR_DIALOG},
    /* Dialog */
    {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL},
    /* General */
    {DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG}};

/*******************************************/
typedef struct {
  UCHAR selectionFlag;
  UCHAR downmixIdRequestIndex;
  FIXP_DBL outputPeakLevel;                     /* e = 7 */
  FIXP_DBL loudnessNormalizationGainDbAdjusted; /* e = 7 */
  FIXP_DBL outputLoudness;                      /* e = 7 */
  DRC_INSTRUCTIONS_UNI_DRC* pInst;

} DRCDEC_SELECTION_DATA;

typedef struct {
  UCHAR numData;
  DRCDEC_SELECTION_DATA data[(12 + 1 + 6)];

} DRCDEC_SELECTION;

/*******************************************/
/* helper functions                        */
/*******************************************/

static int _isError(int x) {
  if (x < DRCDEC_SELECTION_PROCESS_WARNING) {
    return 1;
  }

  return 0;
}

/* compare and assign */
static inline int _compAssign(UCHAR* dest, const UCHAR src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

static inline int _compAssign(SCHAR* dest, const SCHAR src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

static inline int _compAssign(FIXP_DBL* dest, const FIXP_DBL src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

static inline int _compAssign(FIXP_SGL* dest, const FIXP_SGL src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

static inline int _compAssign(TARGET_CONFIG_REQUEST_TYPE* dest, const int src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = (TARGET_CONFIG_REQUEST_TYPE)src;
  return diff;
}

static inline int _compAssign(METHOD_DEFINITION_REQUEST* dest, const int src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = (METHOD_DEFINITION_REQUEST)src;
  return diff;
}

static inline int _compAssign(DRC_FEATURE_REQUEST_TYPE* dest, const int src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = (DRC_FEATURE_REQUEST_TYPE)src;
  return diff;
}

static inline int _compAssign(DRC_EFFECT_TYPE_REQUEST* dest, const int src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = (DRC_EFFECT_TYPE_REQUEST)src;
  return diff;
}

static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
    DRCDEC_SELECTION* pSelection);

static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
    DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn);

static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection);

static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection);

static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num);

static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
    DRCDEC_SELECTION* pSelection, int at);

static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
                                  DRCDEC_SELECTION** ppCandidatesSelected);

static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
                          DRCDEC_SELECTION** ppCandidatesSelected);

/*******************************************/
/* declarations of static functions        */
/*******************************************/

static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
    HANDLE_SEL_PROC_INPUT hSelProcInput);

static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
    HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
    SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected);

static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
    UCHAR downmixIdRequested,
    DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
    int albumMode, int* peakToAveragePresent, FIXP_DBL* peakToAverage);

static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);

static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
    SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected);

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
    HANDLE_SEL_PROC_OUTPUT hSelProcOutput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);

static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
    METHOD_DEFINITION_REQUEST measurementMethodRequested,
    MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
    FIXP_DBL targetLoudness, int drcSetId, int downmixIdRequested,
    FIXP_DBL* pLoudnessNormalizationGain, FIXP_DBL* pLoudness);

static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
    int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel);

static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
    int downmixIdRequested, int* explicitPeakInformationPresent,
    FIXP_DBL* signalPeakLevelOut, /* e = 7 */
    SEL_PROC_CODEC_MODE codecMode);

static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
    LOUDNESS_INFO* loudnessInfo,
    DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
    int* pLoudnessPeakToAverageValuePresent,
    FIXP_DBL* pLoudnessPeakToAverageValue);

static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected);

static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
                                 int methodDefinition, int startIndex);

/*******************************************/
/* public functions                        */
/*******************************************/

struct s_drcdec_selection_process {
  SEL_PROC_CODEC_MODE codecMode;
  SEL_PROC_INPUT selProcInput;
  DRCDEC_SELECTION
  selectionData[2]; /* 2 instances, one before and one after selection */
};

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Create(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
  HANDLE_DRC_SELECTION_PROCESS hInstance;
  hInstance = (HANDLE_DRC_SELECTION_PROCESS)FDKcalloc(
      1, sizeof(struct s_drcdec_selection_process));

  if (!hInstance) return DRCDEC_SELECTION_PROCESS_OUTOFMEMORY;

  hInstance->codecMode = SEL_PROC_CODEC_MODE_UNDEFINED;

  *phInstance = hInstance;
  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Init(HANDLE_DRC_SELECTION_PROCESS hInstance) {
  if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;

  _initDefaultParams(&hInstance->selProcInput);
  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_SetCodecMode(HANDLE_DRC_SELECTION_PROCESS hInstance,
                                     const SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;

  switch (codecMode) {
    case SEL_PROC_MPEG_4_AAC:
    case SEL_PROC_MPEG_D_USAC:
    case SEL_PROC_TEST_TIME_DOMAIN:
    case SEL_PROC_TEST_QMF_DOMAIN:
    case SEL_PROC_TEST_STFT_DOMAIN:
      hInstance->codecMode = codecMode;
      break;

    case SEL_PROC_CODEC_MODE_UNDEFINED:
    default:
      return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  retVal = _initCodecModeParams(&(hInstance->selProcInput),
                                hInstance->codecMode = codecMode);

  return retVal;
}

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_SetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
                                 const SEL_PROC_USER_PARAM requestType,
                                 FIXP_DBL requestValue, int* pDiff) {
  INT requestValueInt = (INT)requestValue;
  int i, diff = 0;
  SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);

  switch (requestType) {
    case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
      if ((requestValueInt != 0) && (requestValueInt != 1))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |=
          _compAssign(&pSelProcInput->loudnessNormalizationOn, requestValueInt);
      break;
    case SEL_PROC_TARGET_LOUDNESS:
      /* Lower boundary: drcSetTargetLoudnessValueLower default value.
         Upper boundary: drcSetTargetLoudnessValueUpper default value */
      if ((requestValue < FL2FXCONST_DBL(-63.0f / (float)(1 << 7))) ||
          (requestValue > (FIXP_DBL)0))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      if (requestValue >
          FL2FXCONST_DBL(-10.0f /
                         (float)(1 << 7))) /* recommended maximum value */
        requestValue = FL2FXCONST_DBL(-10.0f / (float)(1 << 7));
      diff |= _compAssign(&pSelProcInput->targetLoudness, requestValue);
      break;
    case SEL_PROC_EFFECT_TYPE:
      if ((requestValueInt < -1) || (requestValueInt >= DETR_COUNT))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      /* Caution. This overrides all drcFeatureRequests requested so far! */
      if (requestValueInt == -1) {
        diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 0);
      } else if (requestValueInt == DETR_NONE) {
        diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
        diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 0);
      } else {
        diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
        diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 1);
        diff |= _compAssign(&pSelProcInput->drcFeatureRequestType[0],
                            DFRT_EFFECT_TYPE);
        diff |= _compAssign(&pSelProcInput->drcFeatureRequest[0]
                                 .drcEffectType.numRequestsDesired,
                            1);
        diff |= _compAssign(
            &pSelProcInput->drcFeatureRequest[0].drcEffectType.request[0],
            requestValueInt);
        if ((requestValueInt > DETR_NONE) &&
            (requestValueInt <= DETR_GENERAL_COMPR)) {
          /* use fallback effect type requests */
          for (i = 0; i < 5; i++) {
            diff |=
                _compAssign(&pSelProcInput->drcFeatureRequest[0]
                                 .drcEffectType.request[i + 1],
                            fallbackEffectTypeRequests[requestValueInt - 1][i]);
          }
          diff |= _compAssign(
              &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
              6);
        } else {
          diff |= _compAssign(
              &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
              1);
        }
      }
      break;
    case SEL_PROC_LOUDNESS_MEASUREMENT_METHOD:
      if ((requestValueInt < 0) || (requestValueInt > 2))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->loudnessMeasurementMethod,
                          requestValueInt);
      break;
    case SEL_PROC_DOWNMIX_ID:
      diff |=
          _compAssign(&pSelProcInput->targetConfigRequestType, TCRT_DOWNMIX_ID);
      if (requestValueInt < 0) { /* negative requests signal no downmixId */
        diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 0);
      } else {
        diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 1);
        diff |=
            _compAssign(&pSelProcInput->downmixIdRequested[0], requestValueInt);
      }
      break;
    case SEL_PROC_TARGET_LAYOUT:
      /* Request target layout according to ChannelConfiguration in ISO/IEC
       * 23001-8 (CICP) */
      if ((requestValueInt < 1) || (requestValueInt > 63))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
                          TCRT_TARGET_LAYOUT);
      diff |=
          _compAssign(&pSelProcInput->targetLayoutRequested, requestValueInt);
      break;
    case SEL_PROC_TARGET_CHANNEL_COUNT:
      if ((requestValueInt < 1) || (requestValueInt > 8))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
                          TCRT_TARGET_CHANNEL_COUNT);
      diff |= _compAssign(&pSelProcInput->targetChannelCountRequested,
                          requestValueInt);
      break;
    case SEL_PROC_BASE_CHANNEL_COUNT:
      if (requestValueInt < 0)
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->baseChannelCount, requestValueInt);
      break;
    case SEL_PROC_SAMPLE_RATE:
      if (requestValueInt < 0)
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->audioSampleRate, requestValueInt);
      break;
    case SEL_PROC_BOOST:
      if ((requestValue < (FIXP_DBL)0) ||
          (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |= _compAssign(&pSelProcInput->boost, FX_DBL2FX_SGL(requestValue));
      break;
    case SEL_PROC_COMPRESS:
      if ((requestValue < (FIXP_DBL)0) ||
          (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
        return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
      diff |=
          _compAssign(&pSelProcInput->compress, FX_DBL2FX_SGL(requestValue));
      break;
    default:
      return DRCDEC_SELECTION_PROCESS_INVALID_PARAM;
  }

  if (pDiff != NULL) {
    *pDiff |= diff;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

FIXP_DBL
drcDec_SelectionProcess_GetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
                                 const SEL_PROC_USER_PARAM requestType) {
  SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);

  switch (requestType) {
    case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
      return (FIXP_DBL)pSelProcInput->loudnessNormalizationOn;
    case SEL_PROC_DYNAMIC_RANGE_CONTROL_ON:
      return (FIXP_DBL)pSelProcInput->dynamicRangeControlOn;
    default:
      return (FIXP_DBL)0;
  }
}

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Delete(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
  if (phInstance == NULL || *phInstance == NULL)
    return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;

  FDKfree(*phInstance);
  *phInstance = NULL;
  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Process(HANDLE_DRC_SELECTION_PROCESS hInstance,
                                HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
                                HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
                                HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  DRCDEC_SELECTION* pCandidatesSelected;
  DRCDEC_SELECTION* pCandidatesPotential;

  if (hInstance == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;

  pCandidatesSelected = &(hInstance->selectionData[0]);
  pCandidatesPotential = &(hInstance->selectionData[1]);
  _drcdec_selection_setNumber(pCandidatesSelected, 0);
  _drcdec_selection_setNumber(pCandidatesPotential, 0);

  retVal = _generateVirtualDrcSets(&(hInstance->selProcInput), hUniDrcConfig,
                                   hInstance->codecMode);
  if (retVal) return (retVal);

  if (hInstance->selProcInput.baseChannelCount !=
      hUniDrcConfig->channelLayout.baseChannelCount) {
    hInstance->selProcInput.baseChannelCount =
        hUniDrcConfig->channelLayout.baseChannelCount;
  }

  if ((hInstance->selProcInput.targetConfigRequestType != 0) ||
      (hInstance->selProcInput.targetConfigRequestType == 0 &&
       hInstance->selProcInput.numDownmixIdRequests == 0)) {
    retVal = _channelLayoutToDownmixIdMapping(&(hInstance->selProcInput),
                                              hUniDrcConfig);

    if (_isError(retVal)) return (retVal);
  }

  retVal = _drcSetPreSelection(&(hInstance->selProcInput), hUniDrcConfig,
                               hLoudnessInfoSet, &pCandidatesPotential,
                               &pCandidatesSelected, hInstance->codecMode);
  if (retVal) return (retVal);

  if (hInstance->selProcInput.albumMode) {
    _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);

    retVal = _selectAlbumLoudness(hLoudnessInfoSet, pCandidatesPotential,
                                  pCandidatesSelected);
    if (retVal) return (retVal);

    if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
      _swapSelection(&pCandidatesPotential, &pCandidatesSelected);
    }
  }

  _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);

  retVal = _drcSetRequestSelection(&(hInstance->selProcInput), hUniDrcConfig,
                                   hLoudnessInfoSet, &pCandidatesPotential,
                                   &pCandidatesSelected);
  if (retVal) return (retVal);

  retVal = _drcSetFinalSelection(&(hInstance->selProcInput), hUniDrcConfig,
                                 &pCandidatesPotential, &pCandidatesSelected,
                                 hInstance->codecMode);
  if (retVal) return (retVal);

  retVal = _generateOutputInfo(
      &(hInstance->selProcInput), hSelProcOutput, hUniDrcConfig,
      hLoudnessInfoSet, &(pCandidatesSelected->data[0]), hInstance->codecMode);

  if (_isError(retVal)) return (retVal);

  retVal = _selectDownmixMatrix(hSelProcOutput, hUniDrcConfig);
  if (retVal) return (retVal);

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/
/* static functions                        */
/*******************************************/

static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
    HANDLE_SEL_PROC_INPUT hSelProcInput) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;

  /* system parameters */
  hSelProcInput->baseChannelCount = -1;
  hSelProcInput->baseLayout = -1;
  hSelProcInput->targetConfigRequestType = TCRT_DOWNMIX_ID;
  hSelProcInput->numDownmixIdRequests = 0;

  /* loudness normalization parameters */
  hSelProcInput->albumMode = 0;
  hSelProcInput->peakLimiterPresent = 0;
  hSelProcInput->loudnessNormalizationOn = 1;
  hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
  hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
  hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT;
  hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT;
  hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
  hSelProcInput->deviceCutOffFrequency = 500;
  hSelProcInput->loudnessNormalizationGainDbMax =
      (FIXP_DBL)MAXVAL_DBL; /* infinity as default */
  hSelProcInput->loudnessNormalizationGainModificationDb = (FIXP_DBL)0;
  hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
  if (hSelProcInput->peakLimiterPresent == 1) {
    hSelProcInput->outputPeakLevelMax = FL2FXCONST_DBL(6.0f / (float)(1 << 7));
  }

  /* dynamic range control parameters */
  hSelProcInput->dynamicRangeControlOn = 1;

  hSelProcInput->numDrcFeatureRequests = 0;

  /* other parameters */
  hSelProcInput->boost = FL2FXCONST_SGL(1.f / (float)(1 << 1));
  hSelProcInput->compress = FL2FXCONST_SGL(1.f / (float)(1 << 1));
  hSelProcInput->drcCharacteristicTarget = 0;

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
    HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;

  switch (codecMode) {
    case SEL_PROC_MPEG_H_3DA:
      hSelProcInput->loudnessDeviationMax = 0;
      hSelProcInput->peakLimiterPresent = 1; /* peak limiter is mandatory */
      /* The peak limiter also has to catch overshoots due to user
      interactivity, downmixing etc. Therefore the maximum output peak level is
      reduced to 0 dB. */
      hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
      break;
    case SEL_PROC_MPEG_4_AAC:
    case SEL_PROC_MPEG_D_USAC:
      hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
      hSelProcInput->peakLimiterPresent = 1;
      /* A peak limiter is present at the end of the decoder, therefore we can
       * allow for a maximum output peak level greater than full scale
       */
      hSelProcInput->outputPeakLevelMax =
          FL2FXCONST_DBL(6.0f / (float)(1 << 7));
      break;
    case SEL_PROC_TEST_TIME_DOMAIN:
    case SEL_PROC_TEST_QMF_DOMAIN:
    case SEL_PROC_TEST_STFT_DOMAIN:
      /* for testing, adapt to default settings in reference software */
      hSelProcInput->loudnessNormalizationOn = 0;
      hSelProcInput->dynamicRangeControlOn = 0;
      break;
    case SEL_PROC_CODEC_MODE_UNDEFINED:
    default:
      hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
      hSelProcInput->peakLimiterPresent = 0;
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  DOWNMIX_INSTRUCTIONS* pDown = NULL;

  int i;

  hSelProcInput->numDownmixIdRequests = 0;

  switch (hSelProcInput->targetConfigRequestType) {
    case TCRT_DOWNMIX_ID:
      if (hSelProcInput->numDownmixIdRequests == 0) {
        hSelProcInput->downmixIdRequested[0] = 0;
        hSelProcInput->numDownmixIdRequests = 1;
      }

      break;

    case TCRT_TARGET_LAYOUT:
      if (hSelProcInput->targetLayoutRequested == hSelProcInput->baseLayout) {
        hSelProcInput->downmixIdRequested[0] = 0;
        hSelProcInput->numDownmixIdRequests = 1;
      }

      if (hSelProcInput->numDownmixIdRequests == 0) {
        for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
          pDown = &(hUniDrcConfig->downmixInstructions[i]);

          if (hSelProcInput->targetLayoutRequested == pDown->targetLayout) {
            hSelProcInput
                ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
                pDown->downmixId;
            hSelProcInput->numDownmixIdRequests++;
          }
        }
      }

      if (hSelProcInput->baseLayout == -1) {
        retVal = DRCDEC_SELECTION_PROCESS_WARNING;
      }

      if (hSelProcInput->numDownmixIdRequests == 0) {
        hSelProcInput->downmixIdRequested[0] = 0;
        hSelProcInput->numDownmixIdRequests = 1;
        retVal = DRCDEC_SELECTION_PROCESS_WARNING;
      }

      break;

    case TCRT_TARGET_CHANNEL_COUNT:
      if (hSelProcInput->targetChannelCountRequested ==
          hSelProcInput->baseChannelCount) {
        hSelProcInput->downmixIdRequested[0] = 0;
        hSelProcInput->numDownmixIdRequests = 1;
      }

      if (hSelProcInput->numDownmixIdRequests == 0) {
        for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
          pDown = &(hUniDrcConfig->downmixInstructions[i]);

          if (hSelProcInput->targetChannelCountRequested ==
              pDown->targetChannelCount) {
            hSelProcInput
                ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
                pDown->downmixId;
            hSelProcInput->numDownmixIdRequests++;
          }
        }
      }

      if (hSelProcInput->baseChannelCount == -1) {
        retVal = DRCDEC_SELECTION_PROCESS_WARNING;
      }

      if (hSelProcInput->numDownmixIdRequests == 0) {
        retVal = DRCDEC_SELECTION_PROCESS_WARNING;
        hSelProcInput->downmixIdRequested[0] = 0;
        hSelProcInput->numDownmixIdRequests = 1;
      }

      break;

    default:
      return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  return retVal;
}

/*******************************************/

/* Note: Numbering of DRC pre-selection steps according to MPEG-D Part-4 DRC
 * Amd1 */

/* #1: DownmixId of DRC set matches the requested downmixId.
   #2: Output channel layout of DRC set matches the requested layout.
   #3: Channel count of DRC set matches the requested channel count. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement123(
    int nRequestedDownmixId, DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
    int* pMatchFound) {
  int i;
  *pMatchFound = 0;

  for (i = 0; i < pDrcInstructionUniDrc->downmixIdCount; i++) {
    if ((pDrcInstructionUniDrc->downmixId[i] == nRequestedDownmixId) ||
        (pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_ANY_DOWNMIX) ||
        ((pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_BASE_LAYOUT) &&
         (pDrcInstructionUniDrc->drcSetId > 0))) {
      *pMatchFound = 1;
      break;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/* #4: The DRC set is not a "Fade-" or "Ducking-" only DRC set. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int nDynamicRangeControlOn,
    int* pMatchFound) {
  *pMatchFound = 0;

  if (nDynamicRangeControlOn == 1) {
    if ((pDrcInstruction->drcSetEffect != EB_FADE) &&
        (pDrcInstruction->drcSetEffect != EB_DUCK_OTHER) &&
        (pDrcInstruction->drcSetEffect != EB_DUCK_SELF) &&
        (pDrcInstruction->drcSetEffect != 0 || pDrcInstruction->drcSetId < 0)) {
      *pMatchFound = 1;
    }
  } else {
    *pMatchFound = 1;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/* #5: The number of DRC bands is supported. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
    DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
  int i;

  *pMatchFound = 1;

  if (pCoef == NULL) /* check for parametricDRC */
  {
    *pMatchFound = 1;
    return DRCDEC_SELECTION_PROCESS_NO_ERROR;
  }

  for (i = 0; i < pDrcInstructionUniDrc->nDrcChannelGroups; i++) {
    int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
    int bandCount = 0;

    if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
    {
      *pMatchFound = 1;
      return DRCDEC_SELECTION_PROCESS_NO_ERROR;
    }

    GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
    bandCount = gainSet->bandCount;

    if (bandCount > 4) {
      *pMatchFound = 0;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/* #6: Independent use of DRC set is permitted.*/
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement6(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
  *pMatchFound = 0;

  if (((pDrcInstructionUniDrc->dependsOnDrcSetPresent == 0) &&
       (pDrcInstructionUniDrc->noIndependentUse == 0)) ||
      (pDrcInstructionUniDrc->dependsOnDrcSetPresent == 1)) {
    *pMatchFound = 1;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/* #7: DRC sets that require EQ are only permitted if EQ is supported. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement7(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
  *pMatchFound = 1;

  if (pDrcInstructionUniDrc->requiresEq) {
    /* EQ is not supported */
    *pMatchFound = 0;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static void _setSelectionDataInfo(
    DRCDEC_SELECTION_DATA* pData, FIXP_DBL loudness, /* e = 7 */
    FIXP_DBL loudnessNormalizationGainDb,            /* e = 7 */
    FIXP_DBL loudnessNormalizationGainDbMax,         /* e = 7 */
    FIXP_DBL loudnessDeviationMax,                   /* e = 7 */
    FIXP_DBL signalPeakLevel,                        /* e = 7 */
    FIXP_DBL outputPeakLevelMax,                     /* e = 7 */
    int applyAdjustment) {
  FIXP_DBL adjustment = 0; /* e = 8 */

  /* use e = 8 for all function parameters to prevent overflow */
  loudness >>= 1;
  loudnessNormalizationGainDb >>= 1;
  loudnessNormalizationGainDbMax >>= 1;
  loudnessDeviationMax >>= 1;
  signalPeakLevel >>= 1;
  outputPeakLevelMax >>= 1;

  if (applyAdjustment) {
    adjustment =
        fMax((FIXP_DBL)0, signalPeakLevel + loudnessNormalizationGainDb -
                              outputPeakLevelMax);
    adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));
  }

  pData->loudnessNormalizationGainDbAdjusted = fMin(
      loudnessNormalizationGainDb - adjustment, loudnessNormalizationGainDbMax);
  pData->outputLoudness = loudness + pData->loudnessNormalizationGainDbAdjusted;
  pData->outputPeakLevel =
      signalPeakLevel + pData->loudnessNormalizationGainDbAdjusted;

  /* shift back to e = 7 using saturation */
  pData->loudnessNormalizationGainDbAdjusted = SATURATE_LEFT_SHIFT(
      pData->loudnessNormalizationGainDbAdjusted, 1, DFRACT_BITS);
  pData->outputLoudness =
      SATURATE_LEFT_SHIFT(pData->outputLoudness, 1, DFRACT_BITS);
  pData->outputPeakLevel =
      SATURATE_LEFT_SHIFT(pData->outputPeakLevel, 1, DFRACT_BITS);
}

static int _targetLoudnessInRange(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, FIXP_DBL targetLoudness) {
  int retVal = 0;

  FIXP_DBL drcSetTargetLoudnessValueUpper =
      ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueUpper)
      << (DFRACT_BITS - 1 - 7);
  FIXP_DBL drcSetTargetLoudnessValueLower =
      ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueLower)
      << (DFRACT_BITS - 1 - 7);

  if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
      drcSetTargetLoudnessValueUpper >= targetLoudness &&
      drcSetTargetLoudnessValueLower < targetLoudness) {
    retVal = 1;
  }

  return retVal;
}

/* #8: The range of the target loudness specified for a DRC set has to include
 * the requested decoder target loudness. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
    SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int explicitPeakInformationPresent;
  FIXP_DBL signalPeakLevel;
  int addToCandidate = 0;

  FIXP_DBL loudnessNormalizationGainDb;
  FIXP_DBL loudness;

  FIXP_DBL loudnessDeviationMax =
      ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
  ;

  if (hSelProcInput->loudnessNormalizationOn) {
    retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
                          hSelProcInput->loudnessMeasurementMethod,
                          hSelProcInput->loudnessMeasurementSystem,
                          hSelProcInput->targetLoudness,
                          pDrcInstructionUniDrc->drcSetId,
                          hSelProcInput->downmixIdRequested[downmixIdIndex],
                          &loudnessNormalizationGainDb, &loudness);
    if (retVal) return (retVal);
  } else {
    loudnessNormalizationGainDb = (FIXP_DBL)0;
    loudness = UNDEFINED_LOUDNESS_VALUE;
  }

  retVal = _getSignalPeakLevel(
      hSelProcInput, hUniDrcConfig, hLoudnessInfoSet, pDrcInstructionUniDrc,
      hSelProcInput->downmixIdRequested[downmixIdIndex],
      &explicitPeakInformationPresent, &signalPeakLevel, codecMode

  );
  if (retVal) return (retVal);

  if (hSelProcInput->dynamicRangeControlOn) {
    if (explicitPeakInformationPresent == 0) {
      if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
          ((hSelProcInput->loudnessNormalizationOn &&
            _targetLoudnessInRange(pDrcInstructionUniDrc,
                                   hSelProcInput->targetLoudness)) ||
           !hSelProcInput->loudnessNormalizationOn)) {
        DRCDEC_SELECTION_DATA* pData =
            _drcdec_selection_addNew(pCandidatesSelected);
        if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

        _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
                              hSelProcInput->loudnessNormalizationGainDbMax,
                              loudnessDeviationMax, signalPeakLevel,
                              hSelProcInput->outputPeakLevelMax, 0);
        pData->downmixIdRequestIndex = downmixIdIndex;
        pData->pInst = pDrcInstructionUniDrc;
        pData->selectionFlag =
            1; /* signal pre-selection step dealing with drcSetTargetLoudness */

        if (hSelProcInput->loudnessNormalizationOn) {
          pData->outputPeakLevel =
              hSelProcInput->targetLoudness -
              (((FIXP_DBL)pData->pInst->drcSetTargetLoudnessValueUpper)
               << (DFRACT_BITS - 1 - 7));
        } else {
          pData->outputPeakLevel = (FIXP_DBL)0;
        }
      } else {
        if ((!hSelProcInput->loudnessNormalizationOn) ||
            (!pDrcInstructionUniDrc->drcSetTargetLoudnessPresent) ||
            (hSelProcInput->loudnessNormalizationOn &&
             _targetLoudnessInRange(pDrcInstructionUniDrc,
                                    hSelProcInput->targetLoudness))) {
          addToCandidate = 1;
        }
      }
    } else {
      addToCandidate = 1;
    }

    if (addToCandidate) {
      DRCDEC_SELECTION_DATA* pData =
          _drcdec_selection_addNew(pCandidatesPotential);
      if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
                            hSelProcInput->loudnessNormalizationGainDbMax,
                            loudnessDeviationMax, signalPeakLevel,
                            hSelProcInput->outputPeakLevelMax, 0);
      pData->downmixIdRequestIndex = downmixIdIndex;
      pData->pInst = pDrcInstructionUniDrc;
      pData->selectionFlag = 0;
    }
  } else {
    if (pDrcInstructionUniDrc->drcSetId < 0) {
      DRCDEC_SELECTION_DATA* pData =
          _drcdec_selection_addNew(pCandidatesSelected);
      if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
                            hSelProcInput->loudnessNormalizationGainDbMax,
                            loudnessDeviationMax, signalPeakLevel,
                            hSelProcInput->outputPeakLevelMax, 1);

      pData->downmixIdRequestIndex = downmixIdIndex;
      pData->pInst = pDrcInstructionUniDrc;
      pData->selectionFlag = 0;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/* #9: Clipping is minimized. */
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement9(
    SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    if (pCandidate->outputPeakLevel <= hSelProcInput->outputPeakLevelMax) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelectionSingleInstruction(
    SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int matchFound = 0;
  DRC_COEFFICIENTS_UNI_DRC* pCoef =
      selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);

  retVal = _preSelectionRequirement123(
      hSelProcInput->downmixIdRequested[downmixIdIndex], pDrcInstructionUniDrc,
      &matchFound);

  if (!retVal && matchFound)
    retVal = _preSelectionRequirement4(pDrcInstructionUniDrc,
                                       hSelProcInput->dynamicRangeControlOn,
                                       &matchFound);

  if (!retVal && matchFound)
    retVal =
        _preSelectionRequirement5(pDrcInstructionUniDrc, pCoef, &matchFound);

  if (!retVal && matchFound)
    retVal = _preSelectionRequirement6(pDrcInstructionUniDrc, &matchFound);

  if (!retVal && matchFound)
    retVal = _preSelectionRequirement7(pDrcInstructionUniDrc, &matchFound);

  if (!retVal && matchFound)
    retVal = _preSelectionRequirement8(
        hSelProcInput, downmixIdIndex, hUniDrcConfig, hLoudnessInfoSet,
        pDrcInstructionUniDrc, pCandidatesPotential, pCandidatesSelected,
        codecMode);

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetSelectionAddCandidates(
    SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int nHitCount = 0;
  int i;

  DRCDEC_SELECTION_DATA* pCandidate = NULL;
  DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    pDrcInstructionUniDrc = pCandidate->pInst;

    if (_targetLoudnessInRange(pDrcInstructionUniDrc,
                               hSelProcInput->targetLoudness)) {
      nHitCount++;
    }
  }

  if (nHitCount != 0) {
    for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
      pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
      if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      pDrcInstructionUniDrc = pCandidate->pInst;

      if (_targetLoudnessInRange(pDrcInstructionUniDrc,
                                 hSelProcInput->targetLoudness)) {
        if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }
    }
  } else {
    FIXP_DBL lowestPeakLevel = MAXVAL_DBL; /* e = 7 */
    FIXP_DBL peakLevel = 0;                /* e = 7 */

    for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
      pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
      if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      peakLevel = pCandidate->outputPeakLevel;

      if (peakLevel < lowestPeakLevel) {
        lowestPeakLevel = peakLevel;
      }
    }

    /* add all with lowest peak level or max 1dB above */
    for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
      FIXP_DBL loudnessDeviationMax =
          ((FIXP_DBL)hSelProcInput->loudnessDeviationMax)
          << (DFRACT_BITS - 1 - 7); /* e = 7 */

      pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
      if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      peakLevel = pCandidate->outputPeakLevel;

      if (peakLevel == lowestPeakLevel ||
          peakLevel <=
              lowestPeakLevel + FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
        FIXP_DBL adjustment =
            fMax((FIXP_DBL)0, peakLevel - hSelProcInput->outputPeakLevelMax);
        adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));

        pCandidate->loudnessNormalizationGainDbAdjusted -= adjustment;
        pCandidate->outputPeakLevel -= adjustment;
        pCandidate->outputLoudness -= adjustment;
        if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }
    }
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _dependentDrcInstruction(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_INSTRUCTIONS_UNI_DRC* pInst,
    DRC_INSTRUCTIONS_UNI_DRC** ppDrcInstructionsDependent) {
  int i;
  DRC_INSTRUCTIONS_UNI_DRC* pDependentDrc = NULL;

  for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
    pDependentDrc =
        (DRC_INSTRUCTIONS_UNI_DRC*)&(hUniDrcConfig->drcInstructionsUniDrc[i]);

    if (pDependentDrc->drcSetId == pInst->dependsOnDrcSet) {
      break;
    }
  }

  if (i == hUniDrcConfig->drcInstructionsUniDrcCount) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  if (pDependentDrc->dependsOnDrcSetPresent == 1) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  *ppDrcInstructionsDependent = pDependentDrc;

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcSetEffectNone(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    if ((pCandidate->pInst->drcSetEffect & 0xff) == 0) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleEffectType(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_EFFECT_TYPE_REQUEST effectType,
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  DRC_INSTRUCTIONS_UNI_DRC* pInst;
  DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionsDependent;

  if (effectType == DETR_NONE) {
    retVal = _selectDrcSetEffectNone(hUniDrcConfig, pCandidatesPotential,
                                     pCandidatesSelected);
    if (retVal) return (retVal);
  } else {
    int effectBitPosition = 1 << (effectType - 1);

    for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
      DRCDEC_SELECTION_DATA* pCandidate =
          _drcdec_selection_getAt(pCandidatesPotential, i);
      if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      pInst = pCandidate->pInst;

      if (!pInst->dependsOnDrcSetPresent) {
        if ((pInst->drcSetEffect & effectBitPosition)) {
          if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
            return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }
      } else {
        retVal = _dependentDrcInstruction(hUniDrcConfig, pInst,
                                          &pDrcInstructionsDependent);
        if (retVal) return (retVal);

        if (((pInst->drcSetEffect & effectBitPosition)) ||
            ((pDrcInstructionsDependent->drcSetEffect & effectBitPosition))) {
          if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
            return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }
      }
    }
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectEffectTypeFeature(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_FEATURE_REQUEST drcFeatureRequest,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int i;
  int desiredEffectTypeFound = 0;

  for (i = 0; i < drcFeatureRequest.drcEffectType.numRequestsDesired; i++) {
    retVal = _selectSingleEffectType(
        hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
        *ppCandidatesPotential, *ppCandidatesSelected);
    if (retVal) return (retVal);

    if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
      desiredEffectTypeFound = 1;
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
    }
  }

  if (!desiredEffectTypeFound) {
    for (i = drcFeatureRequest.drcEffectType.numRequestsDesired;
         i < drcFeatureRequest.drcEffectType.numRequests; i++) {
      retVal = _selectSingleEffectType(
          hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
          *ppCandidatesPotential, *ppCandidatesSelected);
      if (retVal) return (retVal);

      if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
        _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
        break;
      }
    }
  }

  _swapSelection(ppCandidatesPotential, ppCandidatesSelected);

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectDynamicRange(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRC_FEATURE_REQUEST drcFeatureRequest, UCHAR* pDownmixIdRequested,
    int albumMode, DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* ppCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int i;
  int peakToAveragePresent;
  FIXP_DBL peakToAverage;

  FIXP_DBL minVal = MAXVAL_DBL;
  FIXP_DBL val = 0;

  int numSelectedCandidates = _drcdec_selection_getNumber(ppCandidatesSelected);

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    retVal = _dynamicRangeMeasurement(
        hLoudnessInfoSet, pCandidate->pInst,
        pDownmixIdRequested[pCandidate->downmixIdRequestIndex],
        drcFeatureRequest.dynamicRange.measurementRequestType, albumMode,
        &peakToAveragePresent, &peakToAverage);
    if (retVal) return (retVal);

    if (peakToAveragePresent) {
      if (!drcFeatureRequest.dynamicRange.requestedIsRange) {
        val = fAbs(drcFeatureRequest.dynamicRange.requestValue - peakToAverage);

        if (minVal > val) {
          minVal = val;

          _drcdec_selection_setNumber(ppCandidatesSelected,
                                      numSelectedCandidates);
        }
        if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      } else {
        if ((peakToAverage >= drcFeatureRequest.dynamicRange.requestValueMin) &&
            (peakToAverage <= drcFeatureRequest.dynamicRange.requestValueMax)) {
          if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
            return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }
      }
    }
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleDrcCharacteristic(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int requestedDrcCharacteristic,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected) {
  int i, j, b;
  int hit = 0;

  DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
  DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
  GAIN_SET* pGainSet = NULL;

  if (requestedDrcCharacteristic < 1) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);

  if (pCoef == NULL) /* check for parametricDRC */
  {
    return DRCDEC_SELECTION_PROCESS_NO_ERROR;
  }

  for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(*ppCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    pInst = pCandidate->pInst;

    hit = 0;

    for (j = 0; j < pInst->nDrcChannelGroups; j++) {
      int bandCount = 0;
      int indexDrcCoeff = pInst->gainSetIndexForChannelGroup[j];

      if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
      {
        return DRCDEC_SELECTION_PROCESS_NO_ERROR;
      }

      pGainSet = &(pCoef->gainSet[indexDrcCoeff]);
      bandCount = pGainSet->bandCount;

      for (b = 0; b < bandCount; b++) {
        if ((pGainSet->drcCharacteristic[b].isCICP) &&
            (pGainSet->drcCharacteristic[b].cicpIndex ==
             requestedDrcCharacteristic)) {
          hit = 1;
          break;
        }
      }

      if (hit) break;
    }

    if (hit) {
      if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
    _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcCharacteristic(
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int drcCharacteristicRequested,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  const int secondTry[12] = {0, 2, 3, 4, 5, 6, 5, 9, 10, 7, 8, 10};

  retVal = _selectSingleDrcCharacteristic(
      hUniDrcConfig, drcCharacteristicRequested, ppCandidatesPotential,
      ppCandidatesSelected);
  if (retVal) return (retVal);

  if ((drcCharacteristicRequested <= 11) &&
      (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0)) {
    retVal = _selectSingleDrcCharacteristic(
        hUniDrcConfig, secondTry[drcCharacteristicRequested],
        ppCandidatesPotential, ppCandidatesSelected);
    if (retVal) return (retVal);
  }

  if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
    if ((drcCharacteristicRequested >= 2) &&
        (drcCharacteristicRequested <= 5)) {
      retVal = _selectSingleDrcCharacteristic(
          hUniDrcConfig, drcCharacteristicRequested - 1, ppCandidatesPotential,
          ppCandidatesSelected);
      if (retVal) return (retVal);
    } else if (drcCharacteristicRequested == 11) {
      retVal = _selectSingleDrcCharacteristic(
          hUniDrcConfig, 9, ppCandidatesPotential, ppCandidatesSelected);
      if (retVal) return (retVal);
    }
  }

  _swapSelection(ppCandidatesPotential, ppCandidatesSelected);

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    if (pCandidate->outputPeakLevel <= FIXP_DBL(0)) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_downmixId(
    HANDLE_SEL_PROC_INPUT hSelProcInput,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected) {
  int i, j;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;
  DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(*ppCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    pInst = pCandidate->pInst;

    for (j = 0; j < pInst->downmixIdCount; j++) {
      if (DOWNMIX_ID_BASE_LAYOUT != pInst->downmixId[j] &&
          DOWNMIX_ID_ANY_DOWNMIX != pInst->downmixId[j] &&
          hSelProcInput
                  ->downmixIdRequested[pCandidate->downmixIdRequestIndex] ==
              pInst->downmixId[j]) {
        if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }
    }
  }

  if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
    _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static int _crossSum(int value) {
  int sum = 0;

  while (value != 0) {
    if ((value & 1) == 1) {
      sum++;
    }

    value >>= 1;
  }

  return sum;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_effectTypes(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;
  int minNumEffects = 1000;
  int numEffects = 0;
  int effects = 0;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;
  DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    pInst = pCandidate->pInst;

    effects = pInst->drcSetEffect;
    effects &= 0xffff ^ (EB_GENERAL_COMPR);
    numEffects = _crossSum(effects);

    if (numEffects < minNumEffects) {
      minNumEffects = numEffects;
    }
  }

  /* add all with minimum number of effects */
  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    pInst = pCandidate->pInst;

    effects = pInst->drcSetEffect;
    effects &= 0xffff ^ (EB_GENERAL_COMPR);
    numEffects = _crossSum(effects);

    if (numEffects == minNumEffects) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectSmallestTargetLoudnessValueUpper(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;
  SCHAR minVal = 0x7F;
  SCHAR val = 0;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;

    if (val < minVal) {
      minVal = val;
    }
  }

  /* add all with same smallest drcSetTargetLoudnessValueUpper */
  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;

    if (val == minVal) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_targetLoudness(
    FIXP_DBL targetLoudness, DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int i;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    if (pCandidate->selectionFlag == 0) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
    retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
                                                     pCandidatesSelected);
    if (retVal) return (retVal);
  }

  if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;

    _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);

    for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
      pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
      if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

      pDrcInstructionUniDrc = pCandidate->pInst;

      if (_targetLoudnessInRange(pDrcInstructionUniDrc, targetLoudness)) {
        if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }
    }

    if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
      _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);

      retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
                                                       pCandidatesSelected);
      if (retVal) return (retVal);
    }
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValueLargest(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;
  FIXP_DBL largestPeakLevel = MINVAL_DBL;
  FIXP_DBL peakLevel = 0;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    peakLevel = pCandidate->outputPeakLevel;

    if (peakLevel > largestPeakLevel) {
      largestPeakLevel = peakLevel;
    }
  }

  /* add all with same largest peak level */
  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    peakLevel = pCandidate->outputPeakLevel;

    if (peakLevel == largestPeakLevel) {
      if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
        return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_drcSetId(
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i;
  int largestId = -1000;
  int id = 0;
  DRCDEC_SELECTION_DATA* pCandidate = NULL;
  DRCDEC_SELECTION_DATA* pCandidateSelected = NULL;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    id = pCandidate->pInst->drcSetId;

    if (id > largestId) {
      largestId = id;
      pCandidateSelected = pCandidate;
    }
  }

  if (pCandidateSelected != NULL) {
    if (_drcdec_selection_add(pCandidatesSelected, pCandidateSelected) == NULL)
      return DRCDEC_SELECTION_PROCESS_NOT_OK;
  } else {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  } else if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 1) {
    _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
    /* finished */
  } else /* > 1 */
  {
    retVal = _drcSetFinalSelection_peakValue0(*ppCandidatesPotential,
                                              *ppCandidatesSelected);
    if (retVal) return (retVal);

    if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
      retVal = _drcSetFinalSelection_downmixId(
          hSelProcInput, ppCandidatesPotential, ppCandidatesSelected);
      if (retVal) return (retVal);
    }

    if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
      retVal = _drcSetFinalSelection_effectTypes(*ppCandidatesPotential,
                                                 *ppCandidatesSelected);
      if (retVal) return (retVal);
    }

    if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
      retVal = _drcSetFinalSelection_targetLoudness(
          hSelProcInput->targetLoudness, *ppCandidatesPotential,
          *ppCandidatesSelected);
      if (retVal) return (retVal);
    }

    if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
      retVal = _drcSetFinalSelection_peakValueLargest(*ppCandidatesPotential,
                                                      *ppCandidatesSelected);
      if (retVal) return (retVal);
    }

    if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
      retVal = _drcSetFinalSelection_drcSetId(*ppCandidatesPotential,
                                              *ppCandidatesSelected);
      if (retVal) return (retVal);
    }
  }

  if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    SEL_PROC_CODEC_MODE codecMode) {
  int i;
  int nMixes = hUniDrcConfig->downmixInstructionsCount + 1;
  int index = hUniDrcConfig->drcInstructionsUniDrcCount;
  int indexVirtual = -1;
  DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
      &(hUniDrcConfig->drcInstructionsUniDrc[index]);

  if (codecMode == SEL_PROC_MPEG_H_3DA) {
    nMixes = 1;
  }

  if ((index + nMixes) > (12 + 1 + 6)) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));

  pDrcInstruction->drcSetId = indexVirtual;
  index++;
  indexVirtual--;
  pDrcInstruction->downmixIdCount = 1;

  if ((codecMode == SEL_PROC_MPEG_H_3DA) &&
      (hSelProcInput->numDownmixIdRequests)) {
    pDrcInstruction->downmixId[0] = hSelProcInput->downmixIdRequested[0];
  } else {
    pDrcInstruction->downmixId[0] = DOWNMIX_ID_BASE_LAYOUT;
  }

  for (i = 1; i < nMixes; i++) {
    pDrcInstruction = &(hUniDrcConfig->drcInstructionsUniDrc[index]);
    FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
    pDrcInstruction->drcSetId = indexVirtual;
    pDrcInstruction->downmixId[0] =
        hUniDrcConfig->downmixInstructions[i - 1].downmixId;
    pDrcInstruction->downmixIdCount = 1;
    index++;
    indexVirtual--;
  }

  hUniDrcConfig->drcInstructionsCountInclVirtual =
      hUniDrcConfig->drcInstructionsUniDrcCount + nMixes;

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  int i, j;
  int hasDependend = 0;
  int hasFading = 0;
  int hasDucking = 0;
  int selectedDrcSetIds;
  int selectedDownmixIds;
  FIXP_DBL mixingLevel = 0;
  int albumMode = hSelProcInput->albumMode;
  UCHAR* pDownmixIdRequested = hSelProcInput->downmixIdRequested;
  FIXP_SGL boost = hSelProcInput->boost;
  FIXP_SGL compress = hSelProcInput->compress;

  hSelProcOutput->numSelectedDrcSets = 1;
  hSelProcOutput->selectedDrcSetIds[0] = pSelectionData->pInst->drcSetId;
  hSelProcOutput->selectedDownmixIds[0] =
      pSelectionData->pInst->drcApplyToDownmix == 1
          ? pSelectionData->pInst->downmixId[0]
          : 0;
  hSelProcOutput->loudnessNormalizationGainDb =
      pSelectionData->loudnessNormalizationGainDbAdjusted +
      hSelProcInput->loudnessNormalizationGainModificationDb;
  hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;

  hSelProcOutput->boost = boost;
  hSelProcOutput->compress = compress;
  hSelProcOutput->baseChannelCount =
      hUniDrcConfig->channelLayout.baseChannelCount;
  hSelProcOutput->targetChannelCount =
      hUniDrcConfig->channelLayout.baseChannelCount;
  hSelProcOutput->activeDownmixId =
      pDownmixIdRequested[pSelectionData->downmixIdRequestIndex];

  _getMixingLevel(hLoudnessInfoSet, *pDownmixIdRequested,
                  hSelProcOutput->selectedDrcSetIds[0], albumMode,
                  &mixingLevel);
  hSelProcOutput->mixingLevel = mixingLevel;

  /*dependent*/
  if (pSelectionData->pInst->dependsOnDrcSetPresent) {
    int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;

    for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
      if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId ==
          dependsOnDrcSetID) {
        hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
            hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
        hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
            hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
                ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
                : 0;
        hSelProcOutput->numSelectedDrcSets++;
        hasDependend = 1;
        break;
      }
    }
  }

  /* fading */
  if (hSelProcInput->albumMode == 0) {
    for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
      DRC_INSTRUCTIONS_UNI_DRC* pInst =
          &(hUniDrcConfig->drcInstructionsUniDrc[i]);

      if (pInst->drcSetEffect & EB_FADE) {
        if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
          hSelProcOutput->numSelectedDrcSets = hasDependend + 1;
          hSelProcOutput
              ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
              hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
          hSelProcOutput
              ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
              hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
                  ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
                  : 0;
          hSelProcOutput->numSelectedDrcSets++;
          hasFading = 1;

        } else {
          retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
          if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }
      }
    }
  }

  /* ducking */
  for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
    DRC_INSTRUCTIONS_UNI_DRC* pInst =
        &(hUniDrcConfig->drcInstructionsUniDrc[i]);

    if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
      for (j = 0; j < pInst->downmixIdCount; j++) {
        if (pInst->downmixId[j] == hSelProcOutput->activeDownmixId) {
          hSelProcOutput->numSelectedDrcSets =
              hasDependend + 1; /* ducking overrides fading */

          hSelProcOutput
              ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
              hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
          /* force ducking DRC set to be processed on base layout */
          hSelProcOutput
              ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
          hSelProcOutput->numSelectedDrcSets++;
          hasDucking = 1;
        }
      }
    }
  }

  /* repeat for DOWNMIX_ID_BASE_LAYOUT if no ducking found*/

  if (!hasDucking) {
    for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
      DRC_INSTRUCTIONS_UNI_DRC* pInst =
          &(hUniDrcConfig->drcInstructionsUniDrc[i]);

      if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
        for (j = 0; j < pInst->downmixIdCount; j++) {
          if (pInst->downmixId[j] == DOWNMIX_ID_BASE_LAYOUT) {
            hSelProcOutput->numSelectedDrcSets = hasDependend + hasFading + 1;
            hSelProcOutput
                ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
                hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
            /* force ducking DRC set to be processed on base layout */
            hSelProcOutput
                ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
            hSelProcOutput->numSelectedDrcSets++;
          }
        }
      }
    }
  }

  if (hSelProcOutput->numSelectedDrcSets > 3) {
    /* maximum permitted number of applied DRC sets is 3, see section 6.3.5 of
     * ISO/IEC 23003-4 */
    hSelProcOutput->numSelectedDrcSets = 0;
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  /* sorting: Ducking/Fading -> Dependent -> Selected */
  if (hSelProcOutput->numSelectedDrcSets == 3) {
    selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
    selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
    hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[2];
    hSelProcOutput->selectedDownmixIds[0] =
        hSelProcOutput->selectedDownmixIds[2];
    hSelProcOutput->selectedDrcSetIds[2] = selectedDrcSetIds;
    hSelProcOutput->selectedDownmixIds[2] = selectedDownmixIds;
  } else if (hSelProcOutput->numSelectedDrcSets == 2) {
    selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
    selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
    hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[1];
    hSelProcOutput->selectedDownmixIds[0] =
        hSelProcOutput->selectedDownmixIds[1];
    hSelProcOutput->selectedDrcSetIds[1] = selectedDrcSetIds;
    hSelProcOutput->selectedDownmixIds[1] = selectedDownmixIds;
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
    HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
    HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  int i;
  hSelProcOutput->baseChannelCount =
      hUniDrcConfig->channelLayout.baseChannelCount;
  hSelProcOutput->targetChannelCount =
      hUniDrcConfig->channelLayout.baseChannelCount;
  hSelProcOutput->targetLayout = -1;
  hSelProcOutput->downmixMatrixPresent = 0;

  if (hSelProcOutput->activeDownmixId != 0) {
    for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
      DOWNMIX_INSTRUCTIONS* pDown = &(hUniDrcConfig->downmixInstructions[i]);

      if (hSelProcOutput->activeDownmixId == pDown->downmixId) {
        hSelProcOutput->targetChannelCount = pDown->targetChannelCount;
        hSelProcOutput->targetLayout = pDown->targetLayout;

        if (pDown->downmixCoefficientsPresent) {
          int j, k;
          FIXP_DBL downmixOffset = getDownmixOffset(
              pDown, hSelProcOutput->baseChannelCount); /* e = 1 */

          for (j = 0; j < hSelProcOutput->baseChannelCount; j++) {
            for (k = 0; k < hSelProcOutput->targetChannelCount; k++) {
              hSelProcOutput->downmixMatrix[j][k] =
                  fMultDiv2(
                      downmixOffset,
                      pDown->downmixCoefficient[j + k * hSelProcOutput
                                                            ->baseChannelCount])
                  << 2;
            }
          }

          hSelProcOutput->downmixMatrixPresent = 1;
        }
        break;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
    SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int i, j;

  for (i = 0; i < hSelProcInput->numDownmixIdRequests; i++) {
    for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
      DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
          &(hUniDrcConfig->drcInstructionsUniDrc[j]);
      retVal = _drcSetPreSelectionSingleInstruction(
          hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
          *ppCandidatesPotential, *ppCandidatesSelected, codecMode);
      if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
    }
  }

  retVal = _preSelectionRequirement9(hSelProcInput, *ppCandidatesPotential,
                                     *ppCandidatesSelected);
  if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;

  if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
    retVal = _drcSetSelectionAddCandidates(
        hSelProcInput, *ppCandidatesPotential, *ppCandidatesSelected);
    if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
    SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION** ppCandidatesPotential,
    DRCDEC_SELECTION** ppCandidatesSelected) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal;
  int i;

  if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
    retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
    if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  if (hSelProcInput->dynamicRangeControlOn) {
    if (hSelProcInput->numDrcFeatureRequests == 0) {
      retVal = _selectDrcSetEffectNone(hUniDrcConfig, *ppCandidatesPotential,
                                       *ppCandidatesSelected);
      if (retVal) return (retVal);

      if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
        DRC_FEATURE_REQUEST fallbackRequest;
        fallbackRequest.drcEffectType.numRequests = 5;
        fallbackRequest.drcEffectType.numRequestsDesired = 5;
        fallbackRequest.drcEffectType.request[0] = DETR_GENERAL_COMPR;
        fallbackRequest.drcEffectType.request[1] = DETR_NIGHT;
        fallbackRequest.drcEffectType.request[2] = DETR_NOISY;
        fallbackRequest.drcEffectType.request[3] = DETR_LIMITED;
        fallbackRequest.drcEffectType.request[4] = DETR_LOWLEVEL;

        retVal = _selectEffectTypeFeature(hUniDrcConfig, fallbackRequest,
                                          ppCandidatesPotential,
                                          ppCandidatesSelected);
        if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }

      _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
    } else {
      for (i = 0; i < hSelProcInput->numDrcFeatureRequests; i++) {
        if (hSelProcInput->drcFeatureRequestType[i] == DFRT_EFFECT_TYPE) {
          retVal = _selectEffectTypeFeature(
              hUniDrcConfig, hSelProcInput->drcFeatureRequest[i],
              ppCandidatesPotential, ppCandidatesSelected);

          _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
          if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }

        else if (hSelProcInput->drcFeatureRequestType[i] ==
                 DFRT_DYNAMIC_RANGE) {
          retVal = _selectDynamicRange(
              hUniDrcConfig, hLoudnessInfoSet,
              hSelProcInput->drcFeatureRequest[i],
              hSelProcInput->downmixIdRequested, hSelProcInput->albumMode,
              *ppCandidatesPotential, *ppCandidatesSelected);

          if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
            _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
          }
          if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
        } else if (hSelProcInput->drcFeatureRequestType[i] ==
                   DFRT_DRC_CHARACTERISTIC) {
          retVal = _selectDrcCharacteristic(
              hUniDrcConfig,
              hSelProcInput->drcFeatureRequest[i].drcCharacteristic,
              ppCandidatesPotential, ppCandidatesSelected);

          if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
            _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
          }
          if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
        }
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/
static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
    UCHAR downmixIdRequested,
    DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
    int albumMode, int* pPeakToAveragePresent, FIXP_DBL* pPeakToAverage) {
  int i;
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
  int drcSetId = fMax(0, pInst->drcSetId);

  *pPeakToAveragePresent = 0;

  if (albumMode) {
    for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCount; i++) {
      LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfoAlbum[i]);

      if (drcSetId == pLoudnessInfo->drcSetId) {
        if (downmixIdRequested == pLoudnessInfo->downmixId) {
          retVal = _extractLoudnessPeakToAverageValue(
              pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
              pPeakToAverage);
          if (retVal) return (retVal);
        }
      }
    }
  }

  if (*pPeakToAveragePresent == 0) {
    for (i = 0; i < hLoudnessInfoSet->loudnessInfoCount; i++) {
      LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfo[i]);

      if (drcSetId == pLoudnessInfo->drcSetId) {
        if (downmixIdRequested == pLoudnessInfo->downmixId) {
          retVal = _extractLoudnessPeakToAverageValue(
              pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
              pPeakToAverage);
          if (retVal) return (retVal);
        }
      }
    }
  }

  return retVal;
}
/*******************************************/

static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
    DRCDEC_SELECTION* pSelection) {
  if (pSelection->numData < (12 + 1 + 6)) {
    DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
    FDKmemset(pData, 0, sizeof(DRCDEC_SELECTION_DATA));
    pSelection->numData++;

    return pData;
  } else {
    return NULL;
  }
}

static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
    DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn) {
  if (pSelection->numData < (12 + 1 + 6)) {
    DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
    FDKmemcpy(pData, pDataIn, sizeof(DRCDEC_SELECTION_DATA));
    pSelection->numData++;
    return pData;
  } else {
    return NULL;
  }
}

static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection) {
  return pSelection->numData = 0;
}

static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection) {
  return pSelection->numData;
}

static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num) {
  if (num >= 0 && num < pSelection->numData) {
    return pSelection->numData = num;
  } else {
    return pSelection->numData;
  }
}

static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
    DRCDEC_SELECTION* pSelection, int at) {
  if (at >= 0 && at < (12 + 1 + 6)) {
    return &(pSelection->data[at]);
  } else {
    return NULL;
  }
}

static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
                                  DRCDEC_SELECTION** ppCandidatesSelected) {
  DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
  *ppCandidatesPotential = *ppCandidatesSelected;
  *ppCandidatesSelected = pTmp;
  _drcdec_selection_clear(*ppCandidatesSelected);
  return 0;
}

static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
                          DRCDEC_SELECTION** ppCandidatesSelected) {
  DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
  *ppCandidatesPotential = *ppCandidatesSelected;
  *ppCandidatesSelected = pTmp;
  return 0;
}

/*******************************************/

static LOUDNESS_INFO* _getLoudnessInfoStructure(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
    int albumMode) {
  int i, j;
  int count;

  LOUDNESS_INFO* pLoudnessInfo = NULL;

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
        (pLoudnessInfo[i].downmixId == downmixId)) {
      for (j = 0; j < pLoudnessInfo[i].measurementCount; j++) {
        if ((pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 1) ||
            (pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 2)) {
          return &pLoudnessInfo[i];
        }
      }
    }
  }

  return NULL;
}

static LOUDNESS_INFO* _getApplicableLoudnessInfoStructure(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId,
    int downmixIdRequested, int albumMode) {
  LOUDNESS_INFO* pLoudnessInfo = NULL;

  /* default value */
  pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId,
                                            downmixIdRequested, albumMode);

  /* fallback values */
  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0x7F, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F,
                                              downmixIdRequested, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0,
                                              downmixIdRequested, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0x7F, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0x7F, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0, albumMode);
  }

  if (pLoudnessInfo == NULL) {
    pLoudnessInfo =
        _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0, albumMode);
  }

  return pLoudnessInfo;
}

/*******************************************/

typedef struct {
  FIXP_DBL value;
  int order;
} VALUE_ORDER;

void _initValueOrder(VALUE_ORDER* pValue) {
  pValue->value = (FIXP_DBL)0;
  pValue->order = -1;
}

enum {
  MS_BONUS0 = 0,
  MS_BONUS1770,
  MS_BONUSUSER,
  MS_BONUSEXPERT,
  MS_RESA,
  MS_RESB,
  MS_RESC,
  MS_RESD,
  MS_RESE,
  MS_PROGRAMLOUDNESS,
  MS_PEAKLOUDNESS
};

static DRCDEC_SELECTION_PROCESS_RETURN _getMethodValue(
    VALUE_ORDER* pValueOrder, FIXP_DBL value, int measurementSystem,
    int measurementSystemRequested) {
  const int rows = 11;
  const int columns = 12;
  const int pOrdering[rows][columns] = {
      {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* default = bonus1770 */
      {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* bonus1770 */
      {0, 0, 1, 0, 8, 5, 0, 2, 3, 4, 6, 7}, /* bonusUser */
      {0, 0, 3, 0, 1, 8, 0, 4, 5, 6, 7, 2}, /* bonusExpert */
      {0, 0, 5, 0, 1, 3, 0, 8, 6, 7, 4, 2}, /* ResA */
      {0, 0, 5, 0, 1, 3, 0, 6, 8, 7, 4, 2}, /* ResB */
      {0, 0, 5, 0, 1, 3, 0, 6, 7, 8, 4, 2}, /* ResC */
      {0, 0, 3, 0, 1, 7, 0, 4, 5, 6, 8, 2}, /* ResD */
      {0, 0, 1, 0, 7, 5, 0, 2, 3, 4, 6, 8}, /* ResE */
      {0, 0, 1, 0, 0, 0, 0, 2, 3, 4, 0, 0}, /* ProgramLoudness */
      {0, 7, 0, 0, 0, 0, 6, 5, 4, 3, 2, 1}  /* PeakLoudness */
  };

  if (measurementSystemRequested < 0 || measurementSystemRequested >= rows ||
      measurementSystem < 0 || measurementSystem >= columns) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  if (pOrdering[measurementSystemRequested][measurementSystem] >
      pValueOrder->order) {
    pValueOrder->order =
        pOrdering[measurementSystemRequested][measurementSystem];
    pValueOrder->value = value;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/

static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
    METHOD_DEFINITION_REQUEST measurementMethodRequested,
    MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
    FIXP_DBL targetLoudness, /* e = 7 */
    int drcSetId, int downmixIdRequested,
    FIXP_DBL* pLoudnessNormalizationGain, /* e = 7 */
    FIXP_DBL* pLoudness)                  /* e = 7 */
{
  int index;

  LOUDNESS_INFO* pLoudnessInfo = NULL;
  VALUE_ORDER valueOrder;

  /* map MDR_DEFAULT to MDR_PROGRAM_LOUDNESS */
  METHOD_DEFINITION_REQUEST requestedMethodDefinition =
      measurementMethodRequested < MDR_ANCHOR_LOUDNESS ? MDR_PROGRAM_LOUDNESS
                                                       : MDR_ANCHOR_LOUDNESS;

  if (measurementMethodRequested > MDR_ANCHOR_LOUDNESS) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  }

  _initValueOrder(&valueOrder);

  *pLoudness = UNDEFINED_LOUDNESS_VALUE;
  *pLoudnessNormalizationGain = (FIXP_DBL)0;

  if (drcSetId < 0) {
    drcSetId = 0;
  }

  pLoudnessInfo = _getApplicableLoudnessInfoStructure(
      hLoudnessInfoSet, drcSetId, downmixIdRequested, albumMode);

  if (albumMode && (pLoudnessInfo == NULL)) {
    pLoudnessInfo = _getApplicableLoudnessInfoStructure(
        hLoudnessInfoSet, drcSetId, downmixIdRequested, 0);
  }

  if (pLoudnessInfo == NULL) {
    return DRCDEC_SELECTION_PROCESS_NO_ERROR;
  }

  index = -1;

  do {
    index = _findMethodDefinition(pLoudnessInfo, requestedMethodDefinition,
                                  index + 1);

    if (index >= 0) {
      _getMethodValue(
          &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
          pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
          measurementSystemRequested);
    }
  } while (index >= 0);

  /* repeat with other method definition */
  if (valueOrder.order == -1) {
    index = -1;

    do {
      index = _findMethodDefinition(
          pLoudnessInfo,
          requestedMethodDefinition == MDR_PROGRAM_LOUDNESS
              ? MDR_ANCHOR_LOUDNESS
              : MDR_PROGRAM_LOUDNESS,
          index + 1);

      if (index >= 0) {
        _getMethodValue(
            &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
            pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
            measurementSystemRequested);
      }
    } while (index >= 0);
  }

  if (valueOrder.order == -1) {
    return DRCDEC_SELECTION_PROCESS_NOT_OK;
  } else {
    *pLoudnessNormalizationGain = targetLoudness - valueOrder.value;
    *pLoudness = valueOrder.value;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/

static int _truePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
                                   int drcSetId, int downmixId, int albumMode) {
  int i;
  int count;
  LOUDNESS_INFO* pLoudnessInfo = NULL;

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
        (pLoudnessInfo[i].downmixId == downmixId)) {
      if (pLoudnessInfo[i].truePeakLevelPresent) return 1;
    }
  }

  return 0;
}

static DRCDEC_SELECTION_PROCESS_RETURN _getTruePeakLevel(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
    int albumMode, FIXP_DBL* pTruePeakLevel) {
  int i;
  int count;
  LOUDNESS_INFO* pLoudnessInfo = NULL;

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
        (pLoudnessInfo[i].downmixId == downmixId)) {
      if (pLoudnessInfo[i].truePeakLevelPresent) {
        *pTruePeakLevel = pLoudnessInfo[i].truePeakLevel;
        return DRCDEC_SELECTION_PROCESS_NO_ERROR;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NOT_OK;
}

static int _samplePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
                                     int drcSetId, int downmixId,
                                     int albumMode) {
  int i;
  int count;
  LOUDNESS_INFO* pLoudnessInfo = NULL;

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
        (pLoudnessInfo[i].downmixId == downmixId)) {
      if (pLoudnessInfo[i].samplePeakLevelPresent) return 1;
    }
  }

  return 0;
}

static DRCDEC_SELECTION_PROCESS_RETURN _getSamplePeakLevel(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
    int albumMode, FIXP_DBL* pSamplePeakLevel /* e = 7 */
) {
  int i;
  int count;
  LOUDNESS_INFO* pLoudnessInfo = NULL;

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
        (pLoudnessInfo[i].downmixId == downmixId)) {
      if (pLoudnessInfo[i].samplePeakLevelPresent) {
        *pSamplePeakLevel = pLoudnessInfo[i].samplePeakLevel;
        return DRCDEC_SELECTION_PROCESS_NO_ERROR;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NOT_OK;
}

static int _limiterPeakTargetIsPresent(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId) {
  int i;

  if (pDrcInstruction->limiterPeakTargetPresent) {
    if ((pDrcInstruction->downmixId[0] == downmixId) ||
        (pDrcInstruction->downmixId[0] == 0x7F)) {
      return 1;
    }

    for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
      if (pDrcInstruction->downmixId[i] == downmixId) {
        return 1;
      }
    }
  }

  return 0;
}

static DRCDEC_SELECTION_PROCESS_RETURN _getLimiterPeakTarget(
    DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId,
    FIXP_DBL* pLimiterPeakTarget) {
  int i;

  if (pDrcInstruction->limiterPeakTargetPresent) {
    if ((pDrcInstruction->downmixId[0] == downmixId) ||
        (pDrcInstruction->downmixId[0] == 0x7F)) {
      *pLimiterPeakTarget =
          ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
      return DRCDEC_SELECTION_PROCESS_NO_ERROR;
    }

    for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
      if (pDrcInstruction->downmixId[i] == downmixId) {
        *pLimiterPeakTarget =
            ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
        return DRCDEC_SELECTION_PROCESS_NO_ERROR;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NOT_OK;
}

static int _downmixCoefficientsArePresent(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
                                          int downmixId, int* pIndex) {
  int i;
  *pIndex = -1;

  for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
    if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) {
      if (hUniDrcConfig->downmixInstructions[i].downmixCoefficientsPresent) {
        *pIndex = i;
        return 1;
      }
    }
  }

  return 0;
}

static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
    HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
    int downmixIdRequested, int* explicitPeakInformationPresent,
    FIXP_DBL* signalPeakLevelOut, /* e = 7 */
    SEL_PROC_CODEC_MODE codecMode

) {
  DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;

  int albumMode = hSelProcInput->albumMode;

  FIXP_DBL signalPeakLevelTmp = (FIXP_DBL)0;
  FIXP_DBL signalPeakLevel = FIXP_DBL(0);

  int dmxId = downmixIdRequested;

  int drcSetId = pInst->drcSetId;

  if (drcSetId < 0) {
    drcSetId = 0;
  }

  *explicitPeakInformationPresent = 1;

  if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId, albumMode)) {
    retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
                               &signalPeakLevel);
    if (retVal) return (retVal);
  } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId,
                                       albumMode)) {
    retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
                                 &signalPeakLevel);
    if (retVal) return (retVal);
  } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
                                     albumMode)) {
    retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
                               &signalPeakLevel);
    if (retVal) return (retVal);
  } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
                                       albumMode)) {
    retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
                                 &signalPeakLevel);
    if (retVal) return (retVal);
  } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, dmxId)) {
    retVal = _getLimiterPeakTarget(pInst, drcSetId, dmxId, &signalPeakLevel);
    if (retVal) return (retVal);
  } else if (dmxId != 0) {
    int downmixInstructionIndex = 0;
    FIXP_DBL downmixPeakLevelDB = 0;

    *explicitPeakInformationPresent = 0;

    signalPeakLevelTmp = FIXP_DBL(0);

    if (_downmixCoefficientsArePresent(hUniDrcConfig, dmxId,
                                       &downmixInstructionIndex)) {
      FIXP_DBL dB_m;
      int dB_e;
      FIXP_DBL coeff;
      FIXP_DBL sum, maxSum; /* e = 7, so it is possible to sum up up to 32
                               downmix coefficients (with e = 2) */
      int i, j;
      DOWNMIX_INSTRUCTIONS* pDown =
          &(hUniDrcConfig->downmixInstructions[downmixInstructionIndex]);
      FIXP_DBL downmixOffset = getDownmixOffset(
          pDown, hUniDrcConfig->channelLayout.baseChannelCount); /* e = 1 */
      maxSum = (FIXP_DBL)0;

      for (i = 0; i < pDown->targetChannelCount; i++) {
        sum = (FIXP_DBL)0;
        for (j = 0; j < hUniDrcConfig->channelLayout.baseChannelCount; j++) {
          coeff = pDown->downmixCoefficient[j + i * hUniDrcConfig->channelLayout
                                                        .baseChannelCount];
          sum += coeff >> 5;
        }
        if (maxSum < sum) maxSum = sum;
      }

      maxSum = fMultDiv2(maxSum, downmixOffset) << 2;

      if (maxSum == FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
        downmixPeakLevelDB = (FIXP_DBL)0;
      } else {
        dB_m = lin2dB(maxSum, 7, &dB_e); /* e_maxSum = 7 */
        downmixPeakLevelDB =
            scaleValue(dB_m, dB_e - 7); /* e_downmixPeakLevelDB = 7 */
      }
    }

    if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0, albumMode)) {
      retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
                                 &signalPeakLevelTmp);
      if (retVal) return (retVal);
    } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0,
                                         albumMode)) {
      retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
                                   &signalPeakLevelTmp);
      if (retVal) return (retVal);
    } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0, albumMode)) {
      retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
                                 &signalPeakLevelTmp);
      if (retVal) return (retVal);
    } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0,
                                         albumMode)) {
      retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
                                   &signalPeakLevelTmp);
      if (retVal) return (retVal);
    } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, 0)) {
      retVal = _getLimiterPeakTarget(pInst, drcSetId, 0, &signalPeakLevelTmp);
      if (retVal) return (retVal);
    }

    signalPeakLevel = signalPeakLevelTmp + downmixPeakLevelDB;
  } else {
    signalPeakLevel = FIXP_DBL(0); /* worst case estimate */
    *explicitPeakInformationPresent = FIXP_DBL(0);
  }

  *signalPeakLevelOut = signalPeakLevel;

  return retVal;
}

static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
    LOUDNESS_INFO* loudnessInfo,
    DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
    int* pLoudnessPeakToAverageValuePresent,
    FIXP_DBL* pLoudnessPeakToAverageValue) {
  int i;

  VALUE_ORDER valueOrderLoudness;
  VALUE_ORDER valueOrderPeakLoudness;

  _initValueOrder(&valueOrderLoudness);
  _initValueOrder(&valueOrderPeakLoudness);

  LOUDNESS_MEASUREMENT* pLoudnessMeasure = NULL;

  *pLoudnessPeakToAverageValuePresent = 0;

  for (i = 0; i < loudnessInfo->measurementCount; i++) {
    pLoudnessMeasure = &(loudnessInfo->loudnessMeasurement[i]);

    if (pLoudnessMeasure->methodDefinition == MD_PROGRAM_LOUDNESS) {
      _getMethodValue(&valueOrderLoudness, pLoudnessMeasure->methodValue,
                      pLoudnessMeasure->measurementSystem, MS_PROGRAMLOUDNESS);
    }

    if ((dynamicRangeMeasurementType == DRMRT_SHORT_TERM_LOUDNESS_TO_AVG) &&
        (pLoudnessMeasure->methodDefinition == MD_SHORT_TERM_LOUDNESS_MAX)) {
      _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
                      pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
    }

    if ((dynamicRangeMeasurementType == DRMRT_MOMENTARY_LOUDNESS_TO_AVG) &&
        (pLoudnessMeasure->methodDefinition == MD_MOMENTARY_LOUDNESS_MAX)) {
      _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
                      pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
    }

    if ((dynamicRangeMeasurementType == DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG) &&
        (pLoudnessMeasure->methodDefinition == MD_MAX_OF_LOUDNESS_RANGE)) {
      _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
                      pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
    }
  }

  if ((valueOrderLoudness.order > -1) && (valueOrderPeakLoudness.order > -1)) {
    *pLoudnessPeakToAverageValue =
        valueOrderPeakLoudness.value - valueOrderLoudness.value;
    *pLoudnessPeakToAverageValuePresent = 1;
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/

static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    DRCDEC_SELECTION* pCandidatesPotential,
    DRCDEC_SELECTION* pCandidatesSelected) {
  int i, j;

  for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
    DRCDEC_SELECTION_DATA* pCandidate =
        _drcdec_selection_getAt(pCandidatesPotential, i);
    if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;

    for (j = 0; j < hLoudnessInfoSet->loudnessInfoAlbumCount; j++) {
      if (pCandidate->pInst->drcSetId ==
          hLoudnessInfoSet->loudnessInfoAlbum[j].drcSetId) {
        if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
          return DRCDEC_SELECTION_PROCESS_NOT_OK;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/

static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
                                 int methodDefinition, int startIndex) {
  int i;
  int index = -1;

  for (i = startIndex; i < pLoudnessInfo->measurementCount; i++) {
    if (pLoudnessInfo->loudnessMeasurement[i].methodDefinition ==
        methodDefinition) {
      index = i;
      break;
    }
  }

  return index;
}

/*******************************************/

static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
    HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
    int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel) {
  const FIXP_DBL mixingLevelDefault = FL2FXCONST_DBL(85.0f / (float)(1 << 7));

  int i;
  int count;

  LOUDNESS_INFO* pLoudnessInfo = NULL;

  *pMixingLevel = mixingLevelDefault;

  if (drcSetIdRequested < 0) {
    drcSetIdRequested = 0;
  }

  if (albumMode) {
    count = hLoudnessInfoSet->loudnessInfoAlbumCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
  } else {
    count = hLoudnessInfoSet->loudnessInfoCount;
    pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
  }

  for (i = 0; i < count; i++) {
    if ((drcSetIdRequested == pLoudnessInfo[i].drcSetId) &&
        ((downmixIdRequested == pLoudnessInfo[i].downmixId) ||
         (DOWNMIX_ID_ANY_DOWNMIX == pLoudnessInfo[i].downmixId))) {
      int index = _findMethodDefinition(&pLoudnessInfo[i], MD_MIXING_LEVEL, 0);

      if (index >= 0) {
        *pMixingLevel = pLoudnessInfo[i].loudnessMeasurement[index].methodValue;
        break;
      }
    }
  }

  return DRCDEC_SELECTION_PROCESS_NO_ERROR;
}

/*******************************************/
