/* -----------------------------------------------------------------------------
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
----------------------------------------------------------------------------- */

/******************* Library for basic calculation routines ********************

   Author(s):   Matthias Hildenbrand

   Description: Module to efficiently handle QMF data for multiple channels and
                to share the data between e.g. SBR and MPS

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

#include "FDK_qmf_domain.h"

#include "common_fix.h"

#define WORKBUFFER1_TAG 0
#define WORKBUFFER2_TAG 1

#define WORKBUFFER3_TAG 4
#define WORKBUFFER4_TAG 5
#define WORKBUFFER5_TAG 6
#define WORKBUFFER6_TAG 7

C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L1, WORKBUFFER1_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L2, WORKBUFFER2_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L2, WORKBUFFER3_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L2, WORKBUFFER4_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L2, WORKBUFFER5_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
                    SECT_DATA_L2, WORKBUFFER6_TAG)

/*! Analysis states buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
             ((8) + (1)))

/*! Synthesis states buffer. <br>
    Dimension: #((8) + (1))                                                  */
C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
             ((8) + (1)))

/*! Pointer to real qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsReal, FIXP_DBL *,
             QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
             ((8) + (1)))

/*! Pointer to imaginary qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsImag, FIXP_DBL *,
             QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
             ((8) + (1)))

/*! QMF overlap buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
              2 * QMF_DOMAIN_MAX_OV_TIMESLOTS * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
              ((8) + (1)))

/*! Analysis states buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
             ((8) + (1)))

/*! Analysis states buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
             ((8) + (1)))

/*! Analysis states buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
             ((8) + (1)))

/*! Pointer to real qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsReal16, FIXP_DBL *,
             QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))

/*! Pointer to real qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsReal32, FIXP_DBL *,
             QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))

/*! Pointer to imaginary qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsImag16, FIXP_DBL *,
             QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))

/*! Pointer to imaginary qmf data for each time slot. <br>
    Dimension: #((8) + (1))                                                   */
C_ALLOC_MEM2(QmfSlotsImag32, FIXP_DBL *,
             QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))

/*! QMF overlap buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_AALLOC_MEM2(QmfOverlapBuffer16, FIXP_DBL,
              2 * QMF_DOMAIN_OV_TIMESLOTS_16 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
              ((8) + (1)))

/*! QMF overlap buffer. <br>
    Dimension: #((8) + (1))                                                   */
C_AALLOC_MEM2(QmfOverlapBuffer32, FIXP_DBL,
              2 * QMF_DOMAIN_OV_TIMESLOTS_32 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
              ((8) + (1)))

static int FDK_QmfDomain_FreePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
  int err = 0;
  int ch;

  for (ch = 0; ch < ((8) + (1)); ch++) {
    if (qd->QmfDomainIn[ch].pAnaQmfStates) {
      if (qd->globalConf.nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
        FreeAnaQmfStates16(&qd->QmfDomainIn[ch].pAnaQmfStates);
      } else if (qd->globalConf.nBandsAnalysis ==
                 QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
        FreeAnaQmfStates24(&qd->QmfDomainIn[ch].pAnaQmfStates);
      } else if (qd->globalConf.nBandsAnalysis ==
                 QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
        FreeAnaQmfStates32(&qd->QmfDomainIn[ch].pAnaQmfStates);
      } else {
        FreeAnaQmfStates(&qd->QmfDomainIn[ch].pAnaQmfStates);
      }
    }

    if (qd->QmfDomainIn[ch].pOverlapBuffer) {
      if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
        FreeQmfOverlapBuffer16(&qd->QmfDomainIn[ch].pOverlapBuffer);
      } else if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
        FreeQmfOverlapBuffer32(&qd->QmfDomainIn[ch].pOverlapBuffer);
      } else {
        FreeQmfOverlapBuffer(&qd->QmfDomainIn[ch].pOverlapBuffer);
      }
    }

    if (qd->QmfDomainIn[ch].hQmfSlotsReal) {
      if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
        FreeQmfSlotsReal16(&qd->QmfDomainIn[ch].hQmfSlotsReal);
      } else if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
        FreeQmfSlotsReal32(&qd->QmfDomainIn[ch].hQmfSlotsReal);
      } else {
        FreeQmfSlotsReal(&qd->QmfDomainIn[ch].hQmfSlotsReal);
      }
    }

    if (qd->QmfDomainIn[ch].hQmfSlotsImag) {
      if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
        FreeQmfSlotsImag16(&qd->QmfDomainIn[ch].hQmfSlotsImag);
      }
      if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
        FreeQmfSlotsImag32(&qd->QmfDomainIn[ch].hQmfSlotsImag);
      } else {
        FreeQmfSlotsImag(&qd->QmfDomainIn[ch].hQmfSlotsImag);
      }
    }
  }

  for (ch = 0; ch < ((8) + (1)); ch++) {
    if (qd->QmfDomainOut[ch].pSynQmfStates) {
      FreeSynQmfStates(&qd->QmfDomainOut[ch].pSynQmfStates);
    }
  }

  return err;
}

static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
  int err = 0;
  int ch;
  HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;

  if ((gc->nInputChannels > ((8) + (1))) || (gc->nOutputChannels > ((8) + (1))))
    return err = 1;
  for (ch = 0; ch < gc->nInputChannels; ch++) {
    int size;

    size = gc->nBandsAnalysis * 10;
    if (size > 0) {
      if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
        if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch)))
            goto bail;
        }
      } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
        if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch)))
            goto bail;
        }
      } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
        if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch)))
            goto bail;
        }
      } else {
        if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
          if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch)))
            goto bail;
        }
      }
    } else {
      qd->QmfDomainIn[ch].pAnaQmfStates = NULL;
    }

    size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots;
    if (size > 0) {
      if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
        if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch)))
            goto bail;
        }
        if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch)))
            goto bail;
        }
      } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
        if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch)))
            goto bail;
        }
        if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch)))
            goto bail;
        }
      } else {
        if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
          if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch)))
            goto bail;
        }
        if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
          if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch)))
            goto bail;
        }
      }
    } else {
      qd->QmfDomainIn[ch].hQmfSlotsReal = NULL;
      qd->QmfDomainIn[ch].hQmfSlotsImag = NULL;
    }

    size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
    if (size > 0) {
      if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
        if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch)))
            goto bail;
        }
      } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
        if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch)))
            goto bail;
        }
      } else {
        if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
          if (NULL ==
              (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch)))
            goto bail;
        }
      }
    } else {
      qd->QmfDomainIn[ch].pOverlapBuffer = NULL;
    }
  }

  for (ch = 0; ch < gc->nOutputChannels; ch++) {
    int size = gc->nBandsSynthesis * 9;
    if (size > 0) {
      if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) {
        if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch)))
          goto bail;
      }
    } else {
      qd->QmfDomainOut[ch].pSynQmfStates = NULL;
    }
  }

  return err;

bail:
  FDK_QmfDomain_FreePersistentMemory(qd);
  return -1;
}

QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(
    HANDLE_FDK_QMF_DOMAIN hqd) {
  QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
  int ch, size;
  if (hqd) {
    HANDLE_FDK_QMF_DOMAIN_GC gc = &hqd->globalConf;

    size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
    for (ch = 0; ch < gc->nInputChannels; ch++) {
      if (hqd->QmfDomainIn[ch].pOverlapBuffer) {
        FDKmemclear(hqd->QmfDomainIn[ch].pOverlapBuffer,
                    size * sizeof(FIXP_DBL));
      }
    }
    if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
      err = QMF_DOMAIN_INIT_ERROR;
    }
  } else {
    err = QMF_DOMAIN_INIT_ERROR;
  }
  return err;
}

/*
   FDK_getWorkBuffer

    Parameters:

    pWorkBuffer        i: array of pointers which point to different workbuffer
   sections workBufferOffset   i: offset in the workbuffer to the requested
   memory memSize            i: size of requested memory

    Function:

    The functions returns the address to the requested memory in the workbuffer.

    The overall workbuffer is divided into several sections. There are
   QMF_MAX_WB_SECTIONS sections of size QMF_WB_SECTION_SIZE. The function
   selects the workbuffer section with the help of the workBufferOffset and than
   it verifies whether the requested amount of memory fits into the selected
   workbuffer section.

    Returns:

    address to workbuffer
*/
static FIXP_DBL *FDK_getWorkBuffer(FIXP_DBL **pWorkBuffer,
                                   USHORT workBufferOffset,
                                   USHORT workBufferSectSize, USHORT memSize) {
  int idx1;
  int idx2;
  FIXP_DBL *pwb;

  /* a section must be a multiple of the number of processing bands (currently
   * always 64) */
  FDK_ASSERT((workBufferSectSize % 64) == 0);

  /* calculate offset within the section */
  idx2 = workBufferOffset % workBufferSectSize;
  /* calculate section number */
  idx1 = (workBufferOffset - idx2) / workBufferSectSize;
  /* maximum sectionnumber is QMF_MAX_WB_SECTIONS */
  FDK_ASSERT(idx1 < QMF_MAX_WB_SECTIONS);

  /* check, whether workbuffer is available  */
  FDK_ASSERT(pWorkBuffer[idx1] != NULL);

  /* check, whether buffer fits into selected section */
  FDK_ASSERT((idx2 + memSize) <= workBufferSectSize);

  /* get requested address to workbuffer */
  pwb = &pWorkBuffer[idx1][idx2];

  return pwb;
}

static int FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd, int ch,
                                        FIXP_DBL **pWorkBuffer,
                                        USHORT workBufferOffset,
                                        USHORT workBufferSectSize, int size) {
  int err = 0;
  int mem_needed;

  mem_needed = qd->QmfDomainIn[ch].workBuf_nBands *
               qd->QmfDomainIn[ch].workBuf_nTimeSlots * CMPLX_MOD;
  if (mem_needed > size) {
    return (err = 1);
  }
  qd->QmfDomainIn[ch].pWorkBuffer = pWorkBuffer;
  qd->QmfDomainIn[ch].workBufferOffset = workBufferOffset;
  qd->QmfDomainIn[ch].workBufferSectSize = workBufferSectSize;

  return err;
}

int FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd) {
  FDK_ASSERT(qd != NULL);
  return ((qd->QmfDomainIn[0].pAnaQmfStates == NULL) &&
          (qd->QmfDomainOut[0].pSynQmfStates == NULL))
             ? 0
             : 1;
}

int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
  FDK_ASSERT(qd != NULL);
  int err = 0;
  int ch, ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
  int noCols = gc->nQmfTimeSlots;
  int lsb = gc->nBandsAnalysis;
  int usb = fMin((INT)gc->nBandsSynthesis, 64);
  int nProcBands = gc->nQmfProcBands;
  FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);

  if (extra_flags & QMF_FLAG_MPSLDFB) {
    gc->flags &= ~QMF_FLAG_CLDFB;
    gc->flags |= QMF_FLAG_MPSLDFB;
  }
  for (ch = 0; ch < gc->nInputChannels; ch++) {
    /* distribute memory to slots array */
    FIXP_DBL *ptrOv =
        qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
    if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
      err = 1;
      return err;
    }
    /* This assumes the workbuffer defined for ch0 is the big one being used to
     * hold one full frame of QMF data. */
    FIXP_DBL **ptr =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .pWorkBuffer; /* non-persistent workbuffer */
    USHORT workBufferOffset =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferOffset;
    USHORT workBufferSectSize =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferSectSize;

    if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
      err = 1;
      return err;
    }

    qd->QmfDomainIn[ch].pGlobalConf = gc;
    for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
      ptrOv += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
      ptrOv += nProcBands;
    }
    for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
    }
    err |= qmfInitAnalysisFilterBank(
        &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
        (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
        (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
        gc->nBandsAnalysis, gc->flags | extra_flags);
  }

  for (ch = 0; ch < gc->nOutputChannels; ch++) {
    FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
    int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
    int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
    err |= qmfInitSynthesisFilterBank(
        &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
        (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
        (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
        gc->nBandsSynthesis, gc->flags | extra_flags);
    if (outGain_m != (FIXP_DBL)0) {
      qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
    }
    if (outScale) {
      qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
    }
  }

  return err;
}

void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset) {
  FDK_ASSERT(qd_ch != NULL);
  int ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  int ovSlots = gc->nQmfOvTimeSlots;
  int nCols = gc->nQmfTimeSlots;
  int nProcBands = gc->nQmfProcBands;
  FIXP_DBL **qmfReal = qd_ch->hQmfSlotsReal;
  FIXP_DBL **qmfImag = qd_ch->hQmfSlotsImag;
  QMF_SCALE_FACTOR *pScaling = &qd_ch->scaling;

  /* for high part it would be enough to save only used part of overlap area */
  if (qmfImag != NULL) {
    for (ts = offset; ts < ovSlots; ts++) {
      FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
      FDKmemcpy(qmfImag[ts], qmfImag[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
    }
  } else {
    for (ts = 0; ts < ovSlots; ts++) {
      FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
                sizeof(FIXP_DBL) * nProcBands);
    }
  }
  pScaling->ov_lb_scale = pScaling->lb_scale;
}

  /* Convert headroom bits to exponent */
#define SCALE2EXP(s) (15 - (s))
#define EXP2SCALE(e) (15 - (e))

void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
                           const int start_band, const int stop_band,
                           FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
                           const int exp_out) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(pQmfOutReal != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
  const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
  const int ovSlots = gc->nQmfOvTimeSlots;
  const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
                                              : qd_ch->scaling.lb_scale);
  const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
  const int lsb = qd_ch->fb.lsb;
  const int usb = qd_ch->fb.usb;
  int b = start_band;
  int lb_sf, hb_sf;

  int target_exp =
      ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;

  FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
  FDK_ASSERT(start_band >= 0);
  FDK_ASSERT(stop_band <= gc->nQmfProcBands);

  if (qd_ch->fb.no_channels == 24) {
    target_exp -= 1;
  }

  /* Limit scaling factors to maximum negative value to avoid faulty behaviour
     due to right-shifts. Corresponding asserts were observed during robustness
     testing.
   */
  lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
  FDK_ASSERT(lb_sf < 32);
  hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
  FDK_ASSERT(hb_sf < 32);

  if (pQmfOutImag == NULL) {
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
    }
  } else {
    FDK_ASSERT(imag != NULL);
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
      pQmfOutImag[b] = (FIXP_DBL)0;
    }
  }
}

void FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
                                 const int ts, FIXP_DBL **ppQmfReal,
                                 FIXP_DBL **ppQmfImag) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(ppQmfReal != NULL);
  FDK_ASSERT(ppQmfImag != NULL);
  const int bands = qd_ch->workBuf_nBands;
  FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
  USHORT workBufferOffset = qd_ch->workBufferOffset;
  USHORT workBufferSectSize = qd_ch->workBufferSectSize;

  FDK_ASSERT(bands > 0);
  FDK_ASSERT(ts < qd_ch->workBuf_nTimeSlots);

  *ppQmfReal = FDK_getWorkBuffer(
      pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 0) * bands,
      workBufferSectSize, bands);
  *ppQmfImag = FDK_getWorkBuffer(
      pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 1) * bands,
      workBufferSectSize, bands);
}

void FDK_QmfDomain_WorkBuffer2ProcChannel(
    const HANDLE_FDK_QMF_DOMAIN_IN qd_ch) {
  FDK_ASSERT(qd_ch != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
  USHORT workBufferOffset = qd_ch->workBufferOffset;
  USHORT workBufferSectSize = qd_ch->workBufferSectSize;

  if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
                        qd_ch->workBuf_nBands) ==
      qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {
    /* work buffer is part of processing channel => nothing to do */
    return;
  } else {
    /* copy parked new QMF data to processing channel */
    const int bands = qd_ch->workBuf_nBands;
    const int slots = qd_ch->workBuf_nTimeSlots;
    int ts;
    for (ts = 0; ts < slots; ts++) {
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);  // parkBuf_to_anaMatrix
      workBufferOffset += bands;
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);
      workBufferOffset += bands;
    }
  }
}

void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
                               FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(ppQmfReal != NULL);
  FDK_ASSERT(ppQmfImag != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
  USHORT workBufferOffset = qd_ch->workBufferOffset;
  USHORT workBufferSectSize = qd_ch->workBufferSectSize;

  if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
                        qd_ch->workBuf_nBands) ==
      qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {  // left channel (anaMatrix)
    int ts;
    const int bands = gc->nBandsAnalysis;
    const int slots = qd_ch->workBuf_nTimeSlots;
    FDK_ASSERT(bands <= 64);
    for (ts = 0; ts < slots; ts++) {
      /* copy current data of processing channel */
      FIXP_DBL tmp[64];  // one slot
      /* real */
      FDKmemcpy(tmp, qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
                sizeof(FIXP_DBL) * bands);  // anaMatrix_to_tmp
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
                sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
      FDKmemcpy(ppQmfReal[ts], tmp, sizeof(FIXP_DBL) * bands);  // tmp_to_HBE
      /* imag */
      FDKmemcpy(tmp, qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
                sizeof(FIXP_DBL) * bands);
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
                sizeof(FIXP_DBL) * bands);
      FDKmemcpy(ppQmfImag[ts], tmp, sizeof(FIXP_DBL) * bands);
    }
  } else {  // right channel (parkBuf)
    const int bands = qd_ch->workBuf_nBands;
    const int slots = qd_ch->workBuf_nTimeSlots;
    int ts;
    FDK_ASSERT(qd_ch->workBuf_nBands == gc->nBandsAnalysis);
    for (ts = 0; ts < slots; ts++) {
      /* copy HBE QMF data buffer to processing channel */
      FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
                sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
      FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
                sizeof(FIXP_DBL) * bands);
      /* copy parked new QMF data to HBE QMF data buffer */
      FDKmemcpy(ppQmfReal[ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);  // parkBuf_to_HBE
      workBufferOffset += bands;
      FDKmemcpy(ppQmfImag[ts],
                FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
                                  workBufferSectSize, bands),
                sizeof(FIXP_DBL) * bands);
      workBufferOffset += bands;
    }
  }
}

void FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
  hgc->qmfDomainExplicitConfig = 0;
  hgc->flags_requested = 0;
  hgc->nInputChannels_requested = 0;
  hgc->nOutputChannels_requested = 0;
  hgc->parkChannel_requested = 0;
  hgc->nBandsAnalysis_requested = 0;
  hgc->nBandsSynthesis_requested = 0;
  hgc->nQmfTimeSlots_requested = 0;
  hgc->nQmfOvTimeSlots_requested = 0;
  hgc->nQmfProcBands_requested = 0;
  hgc->nQmfProcChannels_requested = 0;
}

static void FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
  hgc->flags = 0;
  hgc->nInputChannels = 0;
  hgc->nOutputChannels = 0;
  hgc->parkChannel = 0;
  hgc->nBandsAnalysis = 0;
  hgc->nBandsSynthesis = 0;
  hgc->nQmfTimeSlots = 0;
  hgc->nQmfOvTimeSlots = 0;
  hgc->nQmfProcBands = 0;
  hgc->nQmfProcChannels = 0;
}

static void FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd) {
  int ch;

  for (ch = 0; ch < ((8) + (1)); ch++) {
    FDKmemclear(&hqd->QmfDomainIn[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
  }

  for (ch = 0; ch < ((8) + (1)); ch++) {
    FDKmemclear(&hqd->QmfDomainOut[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
  }
}

QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
  FDK_ASSERT(hqd != NULL);
  QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
  int i, size_main, size, size_temp = 0;

  HANDLE_FDK_QMF_DOMAIN_GC hgc = &hqd->globalConf;
  FIXP_DBL **pWorkBuffer = hgc->pWorkBuffer;

  int hasChanged = 0;

  if ((hgc->nQmfProcChannels_requested > 0) &&
      (hgc->nQmfProcBands_requested != 64)) {
    return QMF_DOMAIN_INIT_ERROR;
  }
  if (hgc->nBandsAnalysis_requested > hgc->nQmfProcBands_requested) {
    /* In general the output of the qmf analysis is written to QMF memory slots
       which size is defined by nQmfProcBands. nBandsSynthesis may be larger
       than nQmfProcBands. This is e.g. the case if the QMF based resampler is
       used.
    */
    return QMF_DOMAIN_INIT_ERROR;
  }

  /* 1. adjust change of processing channels by comparison of current and
   * requested parameters */
  if ((hgc->nQmfProcChannels != hgc->nQmfProcChannels_requested) ||
      (hgc->nQmfProcBands != hgc->nQmfProcBands_requested) ||
      (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested)) {
    for (i = 0; i < hgc->nQmfProcChannels_requested; i++) {
      hqd->QmfDomainIn[i].workBuf_nBands = hgc->nQmfProcBands_requested;
      hgc->nQmfProcBands = hgc->nQmfProcBands_requested;

      hqd->QmfDomainIn[i].workBuf_nTimeSlots = hgc->nQmfTimeSlots_requested;
    }

    hgc->nQmfProcChannels =
        hgc->nQmfProcChannels_requested; /* keep highest value encountered so
                                            far as allocated */

    hasChanged = 1;
  }

  /* 2. reallocate persistent memory if necessary (analysis state-buffers,
   * timeslot-pointer-array, overlap-buffers, synthesis state-buffers) */
  if ((hgc->nInputChannels != hgc->nInputChannels_requested) ||
      (hgc->nBandsAnalysis != hgc->nBandsAnalysis_requested) ||
      (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested) ||
      (hgc->nQmfOvTimeSlots != hgc->nQmfOvTimeSlots_requested) ||
      (hgc->nOutputChannels != hgc->nOutputChannels_requested) ||
      (hgc->nBandsSynthesis != hgc->nBandsSynthesis_requested) ||
      (hgc->parkChannel != hgc->parkChannel_requested)) {
    hgc->nInputChannels = hgc->nInputChannels_requested;
    hgc->nBandsAnalysis = hgc->nBandsAnalysis_requested;
    hgc->nQmfTimeSlots = hgc->nQmfTimeSlots_requested;
    hgc->nQmfOvTimeSlots = hgc->nQmfOvTimeSlots_requested;
    hgc->nOutputChannels = hgc->nOutputChannels_requested;
    hgc->nBandsSynthesis = hgc->nBandsSynthesis_requested;
    hgc->parkChannel = hgc->parkChannel_requested;

    if (FDK_QmfDomain_AllocatePersistentMemory(hqd)) {
      err = QMF_DOMAIN_OUT_OF_MEMORY;
      goto bail;
    }

    /* 3. set request-flag for downsampled SBR */
    if ((hgc->nBandsAnalysis == 32) && (hgc->nBandsSynthesis == 32) &&
        !(hgc->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
      hgc->flags_requested |= QMF_FLAG_DOWNSAMPLED;
    }

    hasChanged = 1;
  }

  /* 4. initialize tables and buffer for QMF-resampler */

  /* 5. set requested flags */
  if (hgc->flags != hgc->flags_requested) {
    if ((hgc->flags_requested & QMF_FLAG_MPSLDFB) &&
        (hgc->flags_requested & QMF_FLAG_CLDFB)) {
      hgc->flags_requested &= ~QMF_FLAG_CLDFB;
    }
    hgc->flags = hgc->flags_requested;
    hasChanged = 1;
  }

  if (hasChanged) {
    /* 6. recalculate and check size of required workbuffer-space */

    if (hgc->parkChannel && (hqd->globalConf.nQmfProcChannels == 1)) {
      /* configure temp QMF buffer for parking right channel MPS212 output,
       * (USAC stereoConfigIndex 3 only) */
      hqd->QmfDomainIn[1].workBuf_nBands = hqd->globalConf.nBandsAnalysis;
      hqd->QmfDomainIn[1].workBuf_nTimeSlots = hqd->globalConf.nQmfTimeSlots;
      size_temp = hqd->QmfDomainIn[1].workBuf_nBands *
                  hqd->QmfDomainIn[1].workBuf_nTimeSlots * CMPLX_MOD;
    }

    size_main = hqd->QmfDomainIn[0].workBuf_nBands *
                hqd->QmfDomainIn[0].workBuf_nTimeSlots * CMPLX_MOD;

    size = size_main * hgc->nQmfProcChannels + size_temp;

    if (size > (QMF_MAX_WB_SECTIONS * QMF_WB_SECTION_SIZE)) {
      err = QMF_DOMAIN_OUT_OF_MEMORY;
      goto bail;
    }

    /* 7. allocate additional workbuffer if necessary */
    if ((size > 0 /* *QMF_WB_SECTION_SIZE */) && (pWorkBuffer[0] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[0] = GetQmfWorkBufferCore6();
    }

    if ((size > 1 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[1] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[1] = GetQmfWorkBufferCore1();
    }

    if ((size > 2 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[2] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[2] = GetQmfWorkBufferCore3();
    }

    if ((size > 3 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[3] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[3] = GetQmfWorkBufferCore4();
    }

    if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[4] = GetQmfWorkBufferCore5();
    }

    /* 8. distribute workbuffer over processing channels */
    for (i = 0; i < hgc->nQmfProcChannels; i++) {
      FDK_QmfDomain_FeedWorkBuffer(hqd, i, pWorkBuffer, size_main * i,
                                   QMF_WB_SECTION_SIZE, size_main);
    }
    if (hgc->parkChannel) {
      for (; i < hgc->nInputChannels; i++) {
        FDK_QmfDomain_FeedWorkBuffer(hqd, 1, pWorkBuffer,
                                     size_main * hgc->nQmfProcChannels,
                                     QMF_WB_SECTION_SIZE, size_temp);
      }
    }

    /* 9. (re-)init filterbank */
    for (i = 0; i < hgc->nOutputChannels; i++) {
      if ((hqd->QmfDomainOut[i].fb.lsb == 0) &&
          (hqd->QmfDomainOut[i].fb.usb == 0)) {
        /* Although lsb and usb are set in the SBR module, they are initialized
         * at this point due to the case of using MPS without SBR. */
        hqd->QmfDomainOut[i].fb.lsb = hgc->nBandsAnalysis_requested;
        hqd->QmfDomainOut[i].fb.usb =
            fMin((INT)hgc->nBandsSynthesis_requested, 64);
      }
    }
    if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
      err = QMF_DOMAIN_INIT_ERROR;
    }
  }

bail:
  if (err) {
    FDK_QmfDomain_FreeMem(hqd);
  }
  return err;
}

static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
  FIXP_DBL **pWorkBuffer = hqd->globalConf.pWorkBuffer;

  if (pWorkBuffer[0]) FreeQmfWorkBufferCore6(&pWorkBuffer[0]);
  if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
  if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
  if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
  if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]);
}

void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
  FDK_QmfDomain_FreeWorkBuffer(hqd);

  FDK_QmfDomain_FreePersistentMemory(hqd);

  FDK_QmfDomain_ClearFilterBank(hqd);

  FDK_QmfDomain_ClearConfigured(&hqd->globalConf);

  FDK_QmfDomain_ClearRequested(&hqd->globalConf);
}

void FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd) {
  FDK_QmfDomain_FreeWorkBuffer(hqd);

  FDK_QmfDomain_FreePersistentMemory(hqd);
}
