fir_proc.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * This program is free software; you can redistribute it and modify it
  3. * under the terms of the GNU General Public License as published by the
  4. * Free Software Foundation; either version 2 of the license or (at your
  5. * option) any later version.
  6. *
  7. * Authors: Markus Fick <[email protected]> fir-resampler, technical information
  8. * Chris Moeller <[email protected]> Table/struct file generator
  9. *
  10. */
  11. #include <math.h>
  12. #include <stdio.h>
  13. /*
  14. ------------------------------------------------------------------------------------------------
  15. fir interpolation doc,
  16. (derived from "an engineer's guide to fir digital filters", n.j. loy)
  17. calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
  18. c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
  19. then apply selected window to coefficients
  20. c[-N..N] *= w(0..N)
  21. with n in 2*N and w(n) being a window function (see loy)
  22. then calculate gain and scale filter coefs to have unity gain.
  23. ------------------------------------------------------------------------------------------------
  24. */
  25. // quantizer scale of window coefs
  26. #define WFIR_QUANTBITS 14
  27. #define WFIR_QUANTSCALE (1L<<WFIR_QUANTBITS)
  28. #define WFIR_8SHIFT (WFIR_QUANTBITS-8)
  29. #define WFIR_16BITSHIFT (WFIR_QUANTBITS)
  30. // log2(number)-1 of precalculated taps range is [4..12]
  31. #define WFIR_FRACBITS 10
  32. #define WFIR_LUTLEN ((1L<<(WFIR_FRACBITS+1))+1)
  33. // number of samples in window
  34. #define WFIR_LOG2WIDTH 3
  35. #define WFIR_WIDTH (1L<<WFIR_LOG2WIDTH)
  36. #define WFIR_SMPSPERWING ((WFIR_WIDTH-1)>>1)
  37. // cutoff (1.0 == pi/2)
  38. #define WFIR_CUTOFF 0.90f
  39. #define WFIR_CUTOFFBITS 9
  40. #define WFIR_CUTOFFLEN ((1L<<(WFIR_CUTOFFBITS))+1)
  41. // wfir type
  42. #define WFIR_HANN 0
  43. #define WFIR_HAMMING 1
  44. #define WFIR_BLACKMANEXACT 2
  45. #define WFIR_BLACKMAN3T61 3
  46. #define WFIR_BLACKMAN3T67 4
  47. #define WFIR_BLACKMAN4T92 5
  48. #define WFIR_BLACKMAN4T74 6
  49. #define WFIR_KAISER4T 7
  50. #define WFIR_TYPE WFIR_BLACKMANEXACT
  51. // wfir help
  52. #ifndef M_zPI
  53. #define M_zPI 3.1415926535897932384626433832795
  54. #endif
  55. #define M_zEPS 1e-8
  56. #define M_zBESSELEPS 1e-21
  57. class CzWINDOWEDFIR
  58. { public:
  59. CzWINDOWEDFIR( );
  60. ~CzWINDOWEDFIR( );
  61. float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
  62. { double _LWidthM1 = _PWidth-1;
  63. double _LWidthM1Half = 0.5*_LWidthM1;
  64. double _LPosU = ((double)_PCnr - _POfs);
  65. double _LPos = _LPosU-_LWidthM1Half;
  66. double _LPIdl = 2.0*M_zPI/_LWidthM1;
  67. double _LWc,_LSi;
  68. if( fabs(_LPos)<M_zEPS )
  69. { _LWc = 1.0;
  70. _LSi = _PCut;
  71. }
  72. else
  73. { switch( _PType )
  74. { case WFIR_HANN:
  75. _LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
  76. break;
  77. case WFIR_HAMMING:
  78. _LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
  79. break;
  80. case WFIR_BLACKMANEXACT:
  81. _LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
  82. break;
  83. case WFIR_BLACKMAN3T61:
  84. _LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
  85. break;
  86. case WFIR_BLACKMAN3T67:
  87. _LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
  88. break;
  89. case WFIR_BLACKMAN4T92:
  90. _LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
  91. break;
  92. case WFIR_BLACKMAN4T74:
  93. _LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
  94. break;
  95. case WFIR_KAISER4T:
  96. _LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
  97. break;
  98. default:
  99. _LWc = 1.0;
  100. break;
  101. }
  102. _LPos *= M_zPI;
  103. _LSi = sin(_PCut*_LPos)/_LPos;
  104. }
  105. return (float)(_LWc*_LSi);
  106. }
  107. static signed short lut[WFIR_LUTLEN*WFIR_WIDTH];
  108. };
  109. signed short CzWINDOWEDFIR::lut[WFIR_LUTLEN*WFIR_WIDTH];
  110. CzWINDOWEDFIR::CzWINDOWEDFIR()
  111. { int _LPcl;
  112. float _LPcllen = (float)(1L<<WFIR_FRACBITS); // number of precalculated lines for 0..1 (-1..0)
  113. float _LNorm = 1.0f / (float)(2.0f * _LPcllen);
  114. float _LCut = WFIR_CUTOFF;
  115. float _LScale = (float)WFIR_QUANTSCALE;
  116. float _LGain,_LCoefs[WFIR_WIDTH];
  117. for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
  118. {
  119. float _LOfs = ((float)_LPcl-_LPcllen)*_LNorm;
  120. int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
  121. for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
  122. { _LGain += (_LCoefs[_LCc] = coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
  123. }
  124. _LGain = 1.0f/_LGain;
  125. for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
  126. { float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
  127. lut[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
  128. }
  129. }
  130. }
  131. CzWINDOWEDFIR::~CzWINDOWEDFIR()
  132. { // nothing todo
  133. }
  134. CzWINDOWEDFIR sfir;
  135. // extern "C" signed short *fir_lut = &CzWINDOWEDFIR::lut[0];
  136. #define lut(a) CzWINDOWEDFIR::lut[a]
  137. int main()
  138. {
  139. FILE *f;
  140. int i;
  141. f = fopen("fir_table.h","w");
  142. fprintf(f,"static __int64 fir_lut[%d] = {\n",WFIR_LUTLEN * 2);
  143. for (i=0;i<(WFIR_LUTLEN*WFIR_WIDTH);i+=WFIR_WIDTH)
  144. {
  145. fprintf(f,"\t0x%.4hx%.4hx%.4hx%.4hx, 0x%.4hx%.4hx%.4hx%.4hx%s",
  146. lut(i+3), lut(i+2), lut(i+1), lut(i),
  147. lut(i+7), lut(i+6), lut(i+5), lut(i+4),
  148. (i<((WFIR_LUTLEN-1)*WFIR_WIDTH)) ? ",\n" : "\n};\n");
  149. }
  150. fclose(f);
  151. return(0);
  152. }