Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6712 Discussions

Audio Quality Issues using ResamplePolyphaseFixed

Bob_Kirnum
Beginner
217 Views

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.

<iframe src="http://www.slideshare.net/slideshow/embed_code/24532139" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

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);
}

0 Kudos
1 Reply
Igor_A_Intel
Employee
217 Views

Hi Bob,

you are trying to use functions from Speach Recognition Domain - so their quality is enough for their field of application - guess it is understandable that there always is a tradeoff between quality and performance. For better quality you can try this functionality with "Filter" suffix and set your own filter with better characteristics or use more complex algorithms.

regards, Igor

0 Kudos
Reply