windows.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. dsp/windows.h
  3. Copyright 2004-11 Tim Goetze <tim@quitte.de>
  4. http://quitte.de/dsp/
  5. select few common windowing algorithms.
  6. */
  7. /*
  8. This program is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU General Public License
  10. as published by the Free Software Foundation; either version 2
  11. of the License, or (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. 02111-1307, USA or point your web browser to http://www.gnu.org.
  20. */
  21. #ifndef _DSP_WINDOWS_H_
  22. #define _DSP_WINDOWS_H_
  23. namespace DSP {
  24. /* prototypes for window value application ... */
  25. typedef void (*window_sample_func_t) (sample_t &, sample_t);
  26. /* ... which go as template parameters for the window calculation below */
  27. inline void
  28. store_sample (sample_t & d, sample_t s)
  29. {
  30. d = s;
  31. }
  32. inline void
  33. apply_window (sample_t &d, sample_t s)
  34. {
  35. d *= s;
  36. }
  37. template <window_sample_func_t F>
  38. void
  39. hanning (sample_t * s, int n)
  40. {
  41. /* could speed up by using DSP::Sine but we rarely use this window */
  42. for (int i = 0; i < n; ++i)
  43. {
  44. register double f = (double) i / n - 1;
  45. F (s[i], .5 - .5 * cos (2 * M_PI * f));
  46. }
  47. }
  48. template <window_sample_func_t F>
  49. void
  50. blackman (sample_t * s, int n)
  51. {
  52. register float w = n;
  53. for (int i = 0; i < n; ++i)
  54. {
  55. register float f = (float) i;
  56. register double b = .42f -
  57. .5f * cos (2.f * f * M_PI / w) +
  58. .08 * cos (4.f * f * M_PI / w);
  59. F (s[i], b);
  60. }
  61. }
  62. template <window_sample_func_t F>
  63. void
  64. blackman_harris (sample_t * s, int n)
  65. {
  66. register double w1 = 2.f * M_PI / (n - 1);
  67. register double w2 = 2.f * w1;
  68. register double w3 = 3.f * w1;
  69. for (int i = 0; i < n; ++i)
  70. {
  71. register double f = (double) i;
  72. register double bh = .35875f -
  73. .48829f * cos (w1 * f) +
  74. .14128f * cos (w2 * f) -
  75. .01168f * cos (w3 * f);
  76. bh *= .761f;
  77. F (s[i], bh);
  78. }
  79. }
  80. /* helper for the kaiser window, courtesy of R. Dobson, courtesy of csound */
  81. inline double
  82. besseli (double x)
  83. {
  84. double ax, ans;
  85. double y;
  86. if ((ax = fabs (x)) < 3.75)
  87. {
  88. y = x / 3.75;
  89. y *= y;
  90. ans = (1.0 + y * (3.5156229 +
  91. y * (3.0899424 +
  92. y * (1.2067492 +
  93. y * (0.2659732 +
  94. y * (0.360768e-1 +
  95. y * 0.45813e-2))))));
  96. }
  97. else
  98. {
  99. y = 3.75 / ax;
  100. ans = ((exp (ax) / sqrt (ax))
  101. * (0.39894228 +
  102. y * (0.1328592e-1 +
  103. y * (0.225319e-2 +
  104. y * (-0.157565e-2 +
  105. y * (0.916281e-2 +
  106. y * (-0.2057706e-1 +
  107. y * (0.2635537e-1 +
  108. y * (-0.1647633e-1 +
  109. y * 0.392377e-2)))))))));
  110. }
  111. return ans;
  112. }
  113. template <window_sample_func_t F>
  114. void
  115. kaiser (sample_t * s, int n, double beta)
  116. {
  117. double bb = besseli (beta);
  118. int si = 0;
  119. for (double i = -n / 2 + .1; si < n; ++si, ++i)
  120. {
  121. double k = besseli ((beta * sqrt (1 - pow ((2 * i / (n - 1)), 2)))) / bb;
  122. /* can you spell hack */
  123. if (!isfinite (k) || isnan(k))
  124. k = 0;
  125. F (s[si], k);
  126. }
  127. /* asymmetrical hack: sort out first value!
  128. win[0] = win[len-1];
  129. */
  130. }
  131. }; /* namespace DSP */
  132. #endif /* _DSP_WINDOWS_H_ */