base.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "kiss_fft.h"
  4. #include "kiss_fftr.h"
  5. void analyze_frequency(const float* signal, int N, float Fs) {
  6. // 分配FFT配置
  7. kiss_fft_cfg cfg = kiss_fft_alloc(N, 0, NULL, NULL);
  8. // 准备输入输出缓冲区
  9. kiss_fft_cpx* in = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * N);
  10. kiss_fft_cpx* out = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * N);
  11. // 填充输入(实数信号,虚部为0)
  12. for (int i = 0; i < N; i++) {
  13. float window = 0.5 * (1 - cos(2 * M_PI * i / (N - 1)));
  14. in[i].r = signal[i] * window;
  15. in[i].i = 0;
  16. }
  17. // 执行FFT
  18. kiss_fft(cfg, in, out);
  19. // 计算频率轴和幅度谱
  20. float df = Fs / N; // 频率分辨率
  21. printf("频率分量分析(Fs = %.1f Hz, N = %d, Δf = %.3f Hz):\n", Fs, N, df);
  22. printf("k\t频率(Hz)\t幅度\t相位(度)\n");
  23. // 通常只分析前N/2+1个点(正频率部分)
  24. for (int k = 0; k <= N/2; k++) {
  25. // 计算幅度
  26. float magnitude = sqrt(out[k].r * out[k].r + out[k].i * out[k].i);
  27. // 计算相位(弧度转角度)
  28. float phase = atan2(out[k].i, out[k].r) * 180.0 / M_PI;
  29. // 实际频率
  30. float frequency = k * df;
  31. // 归一化幅度(直流和奈奎斯特频率除外)
  32. float normalized_magnitude;
  33. if (k == 0 || k == N/2) {
  34. normalized_magnitude = magnitude / N; // 直流和奈奎斯特频率
  35. } else {
  36. normalized_magnitude = magnitude / (N/2); // 其他频率
  37. }
  38. // 只显示明显的频率分量(可选阈值)
  39. if (magnitude > 0.1 * (N/2)) { // 阈值示例
  40. printf("%d\t%.2f\t\t%.4f\t%.1f\n", k, frequency, magnitude, phase);
  41. }
  42. }
  43. // 查找幅度峰值
  44. float threshold = 0.1 * (N/2); // 阈值
  45. for (int k = 1; k < N/2; k++) { // 跳过直流
  46. float magnitude = sqrt(out[k].r * out[k].r + out[k].i * out[k].i);
  47. if (magnitude > threshold) {
  48. printf("发现频率分量: %.2f Hz (幅度: %.4f)\n", k * df, magnitude);
  49. }
  50. }
  51. // 释放资源
  52. free(cfg);
  53. free(in);
  54. free(out);
  55. }
  56. void spectrum(float *signal, int n) {
  57. kiss_fftr_cfg cfg = kiss_fftr_alloc(n, 0, NULL, NULL);
  58. kiss_fft_cpx *spectrum = malloc((n/2 + 1) * sizeof(kiss_fft_cpx));
  59. kiss_fftr(cfg, signal, spectrum);
  60. printf("幅度谱:\n");
  61. for (int i = 0; i <= n/2; i++) {
  62. float mag = sqrt(spectrum[i].r * spectrum[i].r +
  63. spectrum[i].i * spectrum[i].i);
  64. printf("%.4f\n", mag);
  65. }
  66. free(spectrum);
  67. free(cfg);
  68. }
  69. // int main() {
  70. // int n = 1024;
  71. // float Fs = 1000.0; // 采样频率 1000 Hz
  72. // float *signal = malloc(n * sizeof(float));
  73. // // 50Hz + 120Hz 信号
  74. // for (int i = 0; i < n; i++) {
  75. // float t = (float)i / Fs;
  76. // signal[i] = 0.5 * cos(2 * M_PI * 50 * t) +
  77. // 0.3 * sin(2 * M_PI * 120 * t) +
  78. // 1.3 * sin(2 * M_PI * 300 * t) +
  79. // 0.9 * sin(2 * M_PI * 40 * t);
  80. // }
  81. // spectrum(signal, n);
  82. // analyze_frequency(signal, n, Fs);
  83. // free(signal);
  84. // return 0;
  85. // }
  86. int main() {
  87. // 示例参数
  88. float Fs = 1000.0; // 采样频率 1000 Hz
  89. int N = 1024; // FFT点数
  90. // 创建测试信号:50Hz + 120Hz正弦波
  91. float signal[N];
  92. for (int i = 0; i < N; i++) {
  93. float t = (float)i / Fs;
  94. signal[i] = 0.7 * sin(2 * M_PI * 50 * t) + // 50Hz
  95. 0.3 * sin(2 * M_PI * 120 * t); // 120Hz
  96. }
  97. // 分析频率
  98. analyze_frequency(signal, N, Fs);
  99. return 0;
  100. }