⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reverb_common.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2005-2006 Intel Corporation. All Rights Reserved.
//
*/

//  Description:
//              Additional internal functions for Reverberation filter
//
//              Reverberate()   performs reverberation (a cascade of filters)
//
/************************************************************************************************/

#include "umc_reverb_filter.h"
#include "reverb_tables.h"

namespace UMC
{

Ipp32s ReverbFilter::RevFIRFilterInit(ReverbState *pRevState)
{
  Ipp32f fscale = this->pRevState->eReflectScale;
  Ipp32s i, bufLen;
  FIRInfo *firState = &(pRevState->fir);
  Ipp32s sRate = pFileInfo->sRate;
  Ipp32s nchan = pFileInfo->nChannels;
  IppStatus ippStat;

  for (i = 0; i < FIR_NZTAP_NUM; i++) {
    firState->FIRTapPos[i] = (Ipp32s)(firDelays[i] * fscale * sRate * 0.001 + 0.5);
  }

  Ipp32s dLineLen = firState->FIRTapPos[FIR_NZTAP_NUM - 1];

  ippStat = ippsFIRSparseGetStateSize_32f(FIR_NZTAP_NUM, dLineLen, &bufLen);
  if (ippStat != ippStsNoErr) {
    return 1;
  }

  for (i = 0; i < nchan; i++) {
    firState->pData[i] = ippsMalloc_8u(bufLen);
    ippStat = ippsFIRSparseInit_32f(&(firState->pState[i]), firTaps, firState->FIRTapPos, FIR_NZTAP_NUM, NULL, firState->pData[i]);
    if (ippStat != ippStsNoErr) {
      return 1;
    }
  }
  return 0;
}

Ipp32s ReverbFilter::RevFIRFilterFree(ReverbState *pRevState)
{
  Ipp32s nchan = pFileInfo->nChannels;
  for (Ipp32s i = 0; i < nchan; i++) {
    ippsFree(pRevState->fir.pData[i]);
  }
  return 0;
}

Ipp32s ReverbFilter::RevCombFilterInit(ReverbState *pRevState)
{
  Ipp32s i, j, bufLen;
  IppStatus ippStat;
  Ipp32s sRate = pFileInfo->sRate;
  Ipp32s nchan = pFileInfo->nChannels;
  Ipp32s maxFrameLen = pRevState->maxFrameLen;

  pRevState->pCombBuf = ippsMalloc_32f(maxFrameLen);
  if (pRevState->pCombBuf == NULL) {
   return 1;
  }
  pRevState->pSumBuf = ippsMalloc_32f(maxFrameLen);
  if (pRevState->pSumBuf == NULL) {
   return 1;
  }

  for (i = 0; i < COMB_NUM; i++) {
    Ipp32s len = (Ipp32s)(combDelays[i] * sRate * 0.001 + 0.5);
    pRevState->comb[i].sLen = len + 1;
    pRevState->comb[i].dLen = len;

    ippStat = ippsIIRSparseGetStateSize_32f(COMBNZTAPSLEN1, COMBNZTAPSLEN2, pRevState->comb[i].sLen, pRevState->comb[i].dLen, &bufLen);
    if (ippStat != ippStsNoErr) {
      return 1;
    }

    Ipp32f G = 1 - 0.366f/(pRevState->decayTime);

    pRevState->comb[i].g1 = combGains25[i] + (sRate - 25000) * (combGains50[i] - combGains25[i]) / 25000;
    pRevState->comb[i].g2 = G * (1.f - pRevState->comb[i].g1);

    pRevState->comb[i].pNZTaps[0] = 1.f;
    pRevState->comb[i].pNZTaps[1] = -pRevState->comb[i].g1;
    pRevState->comb[i].pNZTaps[2] = pRevState->comb[i].g1;
    pRevState->comb[i].pNZTaps[3] = pRevState->comb[i].g2;
    pRevState->comb[i].pNZTapPos[0] = len;
    pRevState->comb[i].pNZTapPos[1] = len + 1;
    pRevState->comb[i].pNZTapPos[2] = 1;
    pRevState->comb[i].pNZTapPos[3] = len;

    for (j = 0; j < nchan; j++) {
      pRevState->comb[i].pData[j] = ippsMalloc_8u(bufLen);
      if (pRevState->comb[i].pData[j] == NULL) {
       return 1;
      }
      ippStat = ippsIIRSparseInit_32f(&(pRevState->comb[i].pState[j]), pRevState->comb[i].pNZTaps,
                                      pRevState->comb[i].pNZTapPos, COMBNZTAPSLEN1, COMBNZTAPSLEN2, NULL, pRevState->comb[i].pData[j]);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    }
  }

  return 0;
}

Ipp32s ReverbFilter::RevCombFilterFree(ReverbState *pRevState)
{
  Ipp32s nchan = pFileInfo->nChannels;
  Ipp32s i, j;

  ippsFree(pRevState->pCombBuf);
  ippsFree(pRevState->pSumBuf);

  for (i = 0; i < COMB_NUM; i++) {
    for (j = 0; j < nchan; j++) {
      ippsFree(pRevState->comb[i].pData[j]);
    }
  }
  return 0;
}

Ipp32s ReverbFilter::RevAPFilterInit(ReverbState *pRevState)
{
  Ipp32s i, bufLen;
  IppStatus ippStat;
  Ipp32s sRate = pFileInfo->sRate;
  Ipp32s nchan = pFileInfo->nChannels;

  Ipp32s aplen = (Ipp32s)(ALLPASS_DELAY * sRate * 0.001 + 0.5);
  pRevState->allpass.len = aplen;

  ippStat = ippsIIRSparseGetStateSize_32f(APNZTAPSLEN1, APNZTAPSLEN2, pRevState->allpass.len, pRevState->allpass.len, &bufLen);
  if (ippStat != ippStsNoErr) {
    return 1;
  }

  pRevState->allpass.pNZTaps[0] = ALLPASS_GAIN;
  pRevState->allpass.pNZTaps[1] = 1.f;
  pRevState->allpass.pNZTaps[2] = -ALLPASS_GAIN;
  pRevState->allpass.pNZTapPos[0] = 0;
  pRevState->allpass.pNZTapPos[1] = aplen;
  pRevState->allpass.pNZTapPos[2] = aplen;

  for (i = 0; i < nchan; i++) {
    pRevState->allpass.pData[i] = ippsMalloc_8u(bufLen);
    if (pRevState->allpass.pData[i] == NULL) {
     return 1;
    }
    ippStat = ippsIIRSparseInit_32f(&(pRevState->allpass.pState[i]), pRevState->allpass.pNZTaps, pRevState->allpass.pNZTapPos, APNZTAPSLEN1, APNZTAPSLEN2, NULL, pRevState->allpass.pData[i]);
    if (ippStat != ippStsNoErr) {
      return 1;
    }
  }
  return 0;
}

Ipp32s ReverbFilter::RevAPFilterFree(ReverbState *pRevState)
{
  Ipp32s nchan = pFileInfo->nChannels;

  for (Ipp32s i = 0; i < nchan; i++) {
    ippsFree(pRevState->allpass.pData[i]);
  }
  return 0;
}

Ipp32s ReverbFilter::RevExtraDelayInit(ReverbState *pRevState)
{
  Ipp32f fscale = this->pRevState->eReflectScale;
  Ipp32s sRate = pFileInfo->sRate;
  Ipp32s nchan = pFileInfo->nChannels;
  Ipp32s maxFrameLen = pRevState->maxFrameLen;
  IppStatus ippStat;

  Ipp32s delayLen = (Ipp32s)((firDelays[FIR_NZTAP_NUM - 1] - combDelays[0]) * fscale * sRate * 0.001 + 0.5);
  Ipp32s delayBufLen = ((delayLen / maxFrameLen) + 2) * maxFrameLen;
  Ipp32f* pFullDelayBuf = ippsMalloc_32f(delayBufLen * nchan);

  ippStat = ippsZero_32f(pFullDelayBuf, delayBufLen * nchan);
  if (ippStat != ippStsNoErr) {
    return 1;
  }

  pRevState->fullDelayLineLen = delayBufLen;
  pRevState->delay = delayLen;
  for (Ipp32s i = 0; i < nchan; i++) {
    pRevState->pFullDelayLine[i] = pFullDelayBuf + i * delayBufLen;
  }
  return 0;
}

Ipp32s ReverbFilter::RevExtraDelayFree(ReverbState *pRevState)
{
  ippsFree(pRevState->pFullDelayLine[0]);
  return 0;
}

Ipp32s ReverbFilter::Reverberate(Ipp32f **src, Ipp32f **dst, Ipp32s frameLen, ReverbState *)
{
  Ipp32s nchan = pFileInfo->nChannels;
  Ipp32s i, j;
  IppsFIRSparseState_32f** pFIRState = pRevState->fir.pState;
  Ipp32f* pLoad;
  Ipp32s fullDLineLen = pRevState->fullDelayLineLen;
  IppStatus ippStat;
  Ipp32f* pSum = pRevState->pSumBuf;
  Ipp32f* pComb = pRevState->pCombBuf;
  COMBInfo* Comb = pRevState->comb;
  APInfo AllPass = pRevState->allpass;
  Ipp32s delay = pRevState->delay;

  for (i = 0; i < nchan; i++) {
    Ipp32f* pBuf = pRevState->pFullDelayLine[i];
    pLoad = pBuf + fullDLineLen - frameLen;
    ippStat = ippsCopy_32f(pBuf + frameLen, pBuf, fullDLineLen - frameLen);
    if (ippStat != ippStsNoErr) {
      return 1;
    }
    ippStat = ippsZero_32f(pLoad, frameLen);
    if (ippStat != ippStsNoErr) {
      return 1;
    }

    if ((pRevState->eReflect) == true) {
/*      ippStat = ippsMulC_32f_I(pRevState->eReflectLevel, src[i], frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }*/
      ippStat = ippsFIRSparse_32f(src[i], pLoad, frameLen, pFIRState[i]);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    } else {
      ippStat = ippsCopy_32f(src[i], pLoad, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    }

    if (pRevState->lReflect == true) {
      ippStat = ippsZero_32f(pSum, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
      for (j = 0; j < COMB_NUM; j++) {
        ippStat = ippsZero_32f(pComb, frameLen);
        if (ippStat != ippStsNoErr) {
          return 1;
        }
        ippStat = ippsIIRSparse_32f(pLoad - delay, pComb, frameLen, Comb[j].pState[i]);
        if (ippStat != ippStsNoErr) {
          return 1;
        }
        ippStat = ippsAdd_32f_I(pComb, pSum, frameLen);
        if (ippStat != ippStsNoErr) {
          return 1;
        }
      }
      ippStat = ippsZero_32f(pComb, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
      ippStat = ippsIIRSparse_32f(pSum, pComb, frameLen, AllPass.pState[i]);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
      ippStat = ippsMulC_32f_I(pRevState->outputLevel, pComb, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
      ippStat = ippsCopy_32f(pComb, dst[i], frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    } else {
      ippStat = ippsMulC_32f_I(pRevState->outputLevel, pLoad, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
      ippStat = ippsCopy_32f(pLoad, dst[i], frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    }
    /* shifting delay line */
    for (Ipp32s k = frameLen; k < fullDLineLen; k += frameLen) {
      ippStat = ippsCopy_32f(pBuf + k, pBuf + k - frameLen, frameLen);
      if (ippStat != ippStsNoErr) {
        return 1;
      }
    }

  }
  return 0;
}

};  //namespace UMC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -