Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.5 KiB

  1. /******************************************************************************
  2. * resample.cpp *
  3. *--------------*
  4. *
  5. *------------------------------------------------------------------------------
  6. * Copyright (C) 1999 Entropic, Inc
  7. * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00
  8. * All Rights Reserved
  9. *
  10. ********************************************************************* PACOG ***/
  11. #include "sigprocInt.h"
  12. #define FILTER_LEN_2 .005 //(sec)
  13. static double* WindowedLowPass (double dCutOff, double dGain, int iHalfLen);
  14. static void FindResampleFactors (int iInSampFreq, int iOutSampFreq,
  15. int* piUpFactor, int* piDownFactor);
  16. /*****************************************************************************
  17. * Resample *
  18. *----------*
  19. * Description:
  20. *
  21. ******************************************************************* PACOG ***/
  22. int Resample (double* pdOriginal, int iNumOrig, int iInSampFreq, int iOutSampFreq,
  23. double** ppdResampled, int* piNumResamp)
  24. {
  25. int iUpFactor;
  26. int iDownFactor;
  27. int iLimitFactor;
  28. double* pdFilterCoef;
  29. int iHalfLen;
  30. int iFilterLen;
  31. double dAcum;
  32. int iPhase;
  33. int i;
  34. int j;
  35. int n;
  36. assert (pdOriginal);
  37. assert (iNumOrig >0);
  38. assert (ppdResampled);
  39. assert (piNumResamp);
  40. assert (iInSampFreq >0);
  41. assert (iOutSampFreq >0);
  42. FindResampleFactors (iInSampFreq, iOutSampFreq, &iUpFactor, &iDownFactor);
  43. iLimitFactor = (iUpFactor>iDownFactor)? iUpFactor: iDownFactor;
  44. iHalfLen = (int)(iInSampFreq * iLimitFactor * FILTER_LEN_2);
  45. iFilterLen = 2 * iHalfLen + 1;
  46. if (! (pdFilterCoef = WindowedLowPass(.5/iLimitFactor, iUpFactor, iHalfLen)))
  47. {
  48. return false;
  49. }
  50. *piNumResamp = (iNumOrig * iUpFactor) / iDownFactor;
  51. *ppdResampled = new double[*piNumResamp];
  52. if (*ppdResampled == 0)
  53. {
  54. fprintf (stderr, "Memory error\n");
  55. return false;
  56. }
  57. for (i=0; i<*piNumResamp; i++)
  58. {
  59. dAcum = 0.0;
  60. n = (int )((i * iDownFactor - iHalfLen) / (double)iUpFactor);
  61. iPhase = (i*iDownFactor) - (n*iUpFactor + iHalfLen);
  62. for (j=0; j<iFilterLen/iUpFactor; j++)
  63. {
  64. if ( (n+j >=0) && (n+j < iNumOrig) && (iUpFactor*j > iPhase))
  65. {
  66. dAcum += pdOriginal[n + j] * pdFilterCoef[iUpFactor * j - iPhase];
  67. }
  68. }
  69. (*ppdResampled)[i] = dAcum;
  70. }
  71. return true;
  72. }
  73. /*****************************************************************************
  74. * WindowedLowPass *
  75. *-----------------*
  76. * Description:
  77. * Creates a low pass filter using the windowing method.
  78. * CutOff is spec. in normalized frequency
  79. ******************************************************************* PACOG ***/
  80. double* WindowedLowPass (double dCutOff, double dGain, int iHalfLen)
  81. {
  82. double* pdCoeffs;
  83. double* pdWindow;
  84. double dArg;
  85. double dSinc;
  86. int iFilterLen = iHalfLen*2 +1;
  87. int i;
  88. assert (dCutOff>0.0 && dCutOff<0.5);
  89. pdWindow = ComputeWindow(WINDOW_BLACK, iFilterLen, true);
  90. if (!pdWindow)
  91. {
  92. return 0;
  93. }
  94. pdCoeffs = new double[iFilterLen];
  95. if (pdCoeffs)
  96. {
  97. dArg = 2.0 * M_PI * dCutOff;
  98. pdCoeffs[iHalfLen] = (double)(dGain * 2.0 * dCutOff);
  99. for (i=1; i<=iHalfLen; i++)
  100. {
  101. dSinc = dGain * sin(dArg*i)/(M_PI*i) * pdWindow[iHalfLen- i];
  102. pdCoeffs[iHalfLen+i] = (double)dSinc;
  103. pdCoeffs[iHalfLen-i] = (double)dSinc;
  104. }
  105. }
  106. delete[] pdWindow;
  107. return pdCoeffs;
  108. }
  109. /*****************************************************************************
  110. * FindResampleFactors *
  111. *---------------------*
  112. * Description:
  113. *
  114. ******************************************************************* PACOG ***/
  115. void FindResampleFactors (int iInSampFreq, int iOutSampFreq, int* piUpFactor, int* piDownFactor)
  116. {
  117. static int aiPrimes[] = {2,3,5,7,11,13,17,19,23,29,31,37};
  118. static int iNumPrimes = sizeof (aiPrimes) / sizeof(aiPrimes[0]);
  119. int iDiv = 1;
  120. int i;
  121. assert (piUpFactor);
  122. assert (piDownFactor);
  123. while (iDiv)
  124. {
  125. iDiv = 0;
  126. for (i=0; i<iNumPrimes;i++)
  127. {
  128. if ( (iInSampFreq % aiPrimes[i]) == 0 && (iOutSampFreq % aiPrimes[i]) == 0 )
  129. {
  130. iInSampFreq/=aiPrimes[i];
  131. iOutSampFreq/=aiPrimes[i];
  132. iDiv = 1;
  133. break;
  134. }
  135. }
  136. }
  137. *piUpFactor = iOutSampFreq;
  138. *piDownFactor = iInSampFreq;
  139. }