Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2014
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.73 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. #define FLOATING float
  5. #define SAMPLE unsigned char
  6.  
  7. #define SAMPLING_RATE 8000.0 //8kHz
  8. #define TARGET_FREQUENCY 941.0 //941 Hz
  9. #define N 205 //Block size
  10.  
  11. FLOATING coeff;
  12. FLOATING Q1;
  13. FLOATING Q2;
  14. FLOATING sine;
  15. FLOATING cosine;
  16.  
  17. SAMPLE testData[N];
  18.  
  19. /* Call this routine before every "block" (size=N) of samples. */
  20. void ResetGoertzel(void)
  21. {
  22. Q2 = 0;
  23. Q1 = 0;
  24. }
  25.  
  26. /* Call this once, to precompute the constants. */
  27. void InitGoertzel(void)
  28. {
  29. int k;
  30. FLOATING floatN;
  31. FLOATING omega;
  32.  
  33. floatN = (FLOATING) N;
  34. k = (int) (0.5 + ((floatN * TARGET_FREQUENCY) / SAMPLING_RATE));
  35. omega = (2.0 * PI * k) / floatN;
  36. sine = sin(omega);
  37. cosine = cos(omega);
  38. coeff = 2.0 * cosine;
  39.  
  40. printf("For SAMPLING_RATE = %f", SAMPLING_RATE);
  41. printf(" N = %d", N);
  42. printf(" and FREQUENCY = %f,n", TARGET_FREQUENCY);
  43. printf("k = %d and coeff = %fnn", k, coeff);
  44.  
  45. ResetGoertzel();
  46. }
  47.  
  48. /* Call this routine for every sample. */
  49. void ProcessSample(SAMPLE sample)
  50. {
  51. FLOATING Q0;
  52. Q0 = coeff * Q1 - Q2 + (FLOATING) sample;
  53. Q2 = Q1;
  54. Q1 = Q0;
  55. }
  56.  
  57.  
  58. /* Basic Goertzel */
  59. /* Call this routine after every block to get the complex result. */
  60. void GetRealImag(FLOATING *realPart, FLOATING *imagPart)
  61. {
  62. *realPart = (Q1 - Q2 * cosine);
  63. *imagPart = (Q2 * sine);
  64. }
  65.  
  66. /* Optimized Goertzel */
  67. /* Call this after every block to get the RELATIVE magnitude squared. */
  68. FLOATING GetMagnitudeSquared(void)
  69. {
  70. FLOATING result;
  71.  
  72. result = Q1 * Q1 + Q2 * Q2 - Q1 * Q2 * coeff;
  73. return result;
  74. }
  75.  
  76. /*** End of Goertzel-specific code, the remainder is test code. */
  77.  
  78. /* Synthesize some test data at a given frequency. */
  79. void Generate(FLOATING frequency)
  80. {
  81. int index;
  82. FLOATING step;
  83.  
  84. step = frequency * ((2.0 * PI) / SAMPLING_RATE);
  85.  
  86. /* Generate the test data */
  87. for (index = 0; index < N; index++)
  88. {
  89. testData[index] = (SAMPLE) (100.0 * sin(index * step) + 100.0);
  90. }
  91. }
  92.  
  93. /* Demo 1 */
  94. void GenerateAndTest(FLOATING frequency)
  95. {
  96. int index;
  97.  
  98. FLOATING magnitudeSquared;
  99. FLOATING magnitude;
  100. FLOATING real;
  101. FLOATING imag;
  102.  
  103. printf("For test frequency %f:n", frequency);
  104. Generate(frequency);
  105.  
  106. /* Process the samples */
  107. for (index = 0; index < N; index++)
  108. {
  109. ProcessSample(testData[index]);
  110. }
  111.  
  112. /* Do the "basic Goertzel" processing. */
  113. GetRealImag(&real, &imag);
  114.  
  115. printf("real = %f imag = %fn", real, imag);
  116.  
  117. magnitudeSquared = real*real + imag*imag;
  118. printf("Relative magnitude squared = %fn", magnitudeSquared);
  119. magnitude = sqrt(magnitudeSquared);
  120. printf("Relative magnitude = %fn", magnitude);
  121.  
  122. /* Do the "optimized Goertzel" processing */
  123. magnitudeSquared = GetMagnitudeSquared();
  124. printf("Relative magnitude squared = %fn", magnitudeSquared);
  125. magnitude = sqrt(magnitudeSquared);
  126. printf("Relative magnitude = %fnn", magnitude);
  127.  
  128. ResetGoertzel();
  129. }
  130.  
  131. /* Demo 2 */
  132. void GenerateAndTest2(FLOATING frequency)
  133. {
  134. int index;
  135.  
  136. FLOATING magnitudeSquared;
  137. FLOATING magnitude;
  138. FLOATING real;
  139. FLOATING imag;
  140.  
  141. printf("Freq=%7.1f ", frequency);
  142. Generate(frequency);
  143.  
  144. /* Process the samples. */
  145. for (index = 0; index < N; index++)
  146. {
  147. ProcessSample(testData[index]);
  148. }
  149.  
  150. /* Do the "standard Goertzel" processing. */
  151. GetRealImag(&real, &imag);
  152.  
  153. magnitudeSquared = real*real + imag*imag;
  154. printf("rel mag^2=%16.5f ", magnitudeSquared);
  155. magnitude = sqrt(magnitudeSquared);
  156. printf("rel mag=%12.5fn", magnitude);
  157.  
  158. ResetGoertzel();
  159. }
  160.  
  161. int main(void)
  162. {
  163. FLOATING freq;
  164.  
  165. InitGoertzel();
  166.  
  167. /* Demo 1 */
  168. GenerateAndTest(TARGET_FREQUENCY - 250);
  169. GenerateAndTest(TARGET_FREQUENCY);
  170. GenerateAndTest(TARGET_FREQUENCY + 250);
  171.  
  172. /* Demo 2 */
  173. for (freq = TARGET_FREQUENCY - 300; freq <= TARGET_FREQUENCY + 300; freq += 15)
  174. {
  175. GenerateAndTest2(freq);
  176. }
  177.  
  178. return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement