Audio Quality Issues using ResamplePolyphaseFixed

Audio Quality Issues using ResamplePolyphaseFixed

Ritratto di Bob Kirnum

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

2 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

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

Accedere per lasciare un commento.