Quantcast
Channel: Intel® Integrated Performance Primitives
Viewing all articles
Browse latest Browse all 1294

Audio Quality Issues using ResamplePolyphaseFixed

$
0
0

I am trying to replace a sample rate conversion implementation limited to converting between 8000Hz and 16000Hz 16 bit linear PCM with some thing more flexible.  Using IPP 7.1, the ResamplePolyphaseFixed API's and the example code (http://software.intel.com/sites/products/documentation/doclib/ipp_sa/71/ipp_manual/IPPS/ipps_ch6/functn_ResamplePolyphase.htm) I have something which works but the audio quality is not great.  Using DTMF tones to test basic quality, the input is 8000Hz / 16bit linear PCM being processed in 10msec chunks.  Tested output is 11025Hz and 16000Hz / 16bit linear PCM with fair quality.

I have tried tweaking the hardcoded parameters used in the example code but this has not yielded any noticable improvement.  My (abreviated) version of the example code . . . 

static const IppHintAlgorithm g_IppHintAlgorithm = ippAlgHintAccurate;

static void Create(int a_iSampleRateInp, int a_iSampleRateOut, Context* a_pResamplePCMContext)
{
  int l_iSize = 0;
  int l_iBufferLength = 0;
  Context* p = a_pResamplePCMContext; //For code brevity
  int l_iLength = 0;
  float l_fWindow = 0.0;
  double l_dFactor = 0.0;

  p->m_pState = NULL;
  p->m_iBufferLength = 0;
  p->m_pBuffer = NULL;
  p->m_iFilterLength = 0;
  p->m_iNumberOfFilters = 0;
  p->m_dTime = 0.0;
  p->m_iLastRead = 0;
  p->m_iSampleRateInp = 0;
  p->m_iSampleRateOut = 0;

  p->m_iBufferLengthBase = 4096; //From intel example code
  p->m_iHistory = 128; //From intel example code
  p->m_fFilterRollOff = 0.95f; //From intel example code
  p->m_fKaiserWindowAlpha = 9.0f; //From intel example code
  p->m_fNormFactor = 0.98f; //From intel example code

  ippsResamplePolyphaseFixedGetSize_16s(a_iSampleRateInp, a_iSampleRateOut, 2*(p->m_iHistory-1), &l_iSize, &p->m_iFilterLength, &p->m_iNumberOfFilters, g_IppHintAlgorithm);
  p->m_pState = (IppsResamlingPolyphaseFixed_16s*)ippsMalloc_8u(l_iSize);
  if (NULL == a_pResamplePCMContext->m_pState) return;
  ippsResamplePolyphaseFixedInit_16s(a_iSampleRateInp, a_iSampleRateOut, 2*(p->m_iHistory-1), p->m_fFilterRollOff, p->m_fKaiserWindowAlpha,   p->m_pState, g_IppHintAlgorithm);
  l_iBufferLength = (int)((p->m_iBufferLengthBase-p->m_iHistory)*a_iSampleRateOut/(float)a_iSampleRateInp+2);
  p->m_pBuffer = ippsMalloc_16s(l_iBufferLength);
  if (NULL == p->m_pBuffer) return;
  p->m_iBufferLength = l_iBufferLength;
  //Initialy, the residual length is the history length and we must 0 this portion out.
  p->m_dTime = (double)p->m_iHistory;
  p->m_iLastRead = p->m_iHistory;
  ippsZero_16s(p->m_pBuffer, p->m_iBufferLength);
  p->m_iSampleRateInp = a_iSampleRateInp;
  p->m_iSampleRateOut = a_iSampleRateOut;
}

static void Resample(Context_16s* a_pResamplePCMContext, short* a_p16BitInp, short* a_p16BitOut, unsigned int a_iLengthInp, unsigned int* a_piLengthOut)
{
  IppStatus l_IppStatus = ippStsNoErr;
  Context* p = a_pResamplePCMContext; //For code brevity
  double l_dTime;

  l_dTime = p->m_dTime;
  //Copy the new input samples to proper position in residual buffer
  ippsCopy_16s(a_p16BitInp, p->m_pBuffer+p->m_iLastRead, a_iLengthInp);
  p->m_iLastRead += a_iLengthInp;
  l_IppStatus = ippsResamplePolyphaseFixed_16s(p->m_pBuffer, a_iLengthInp, a_p16BitOut, p->m_fNormFactor, &p->m_dTime, (int*)a_piLengthOut, p->m_pState);
  if (ippStsNoErr != l_IppStatus)
  {
    return;
  }
  //Copy any residual input samples to head of residual / history buffer
  ippsMove_16s(a_p16BitInp+(int)p->m_dTime-p->m_iHistory, p->m_pBuffer, p->m_iLastRead+p->m_iHistory-(int)p->m_dTime);
  p->m_iLastRead -= ((int)p->m_dTime-p->m_iHistory);
  p->m_dTime -= (p->m_dTime-p->m_iHistory);
}


Viewing all articles
Browse latest Browse all 1294

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>