电脑没有网络所以找不到傅立叶的库代码实现不了,求大家帮个忙运行一下
1条回答 默认 最新
阿正很牛 2023-06-01 11:58关注以下是使用C语言实现单次傅立叶变换和快速傅立叶变换的代码,同时绘制信号图和频谱图:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <SDL2/SDL.h> #define WIDTH 800 #define HEIGHT 600 #define PI 3.14159265358979323846 typedef struct { double real; double imag; } Complex; void DFT(Complex* x, int N, Complex* X) { for (int k = 0; k < N; k++) { X[k].real = 0; X[k].imag = 0; for (int n = 0; n < N; n++) { double arg = 2 * PI * k * n / N; X[k].real += x[n].real * cos(arg) + x[n].imag * sin(arg); X[k].imag += -x[n].real * sin(arg) + x[n].imag * cos(arg); } } } void FFT(Complex* x, int N, Complex* X) { if (N == 1) { X[0] = x[0]; } else { Complex* xe = (Complex*) malloc(N / 2 * sizeof(Complex)); Complex* xo = (Complex*) malloc(N / 2 * sizeof(Complex)); Complex* Xe = (Complex*) malloc(N / 2 * sizeof(Complex)); Complex* Xo = (Complex*) malloc(N / 2 * sizeof(Complex)); for (int n = 0; n < N / 2; n++) { xe[n] = x[2 * n]; xo[n] = x[2 * n + 1]; } FFT(xe, N / 2, Xe); FFT(xo, N / 2, Xo); for (int k = 0; k < N / 2; k++) { double arg = -2 * PI * k / N; Complex W = {cos(arg), sin(arg)}; X[k].real = Xe[k].real + W.real * Xo[k].real - W.imag * Xo[k].imag; X[k].imag = Xe[k].imag + W.real * Xo[k].imag + W.imag * Xo[k].real; X[k + N / 2].real = Xe[k].real - W.real * Xo[k].real + W.imag * Xo[k].imag; X[k + N / 2].imag = Xe[k].imag - W.real * Xo[k].imag - W.imag * Xo[k].real; } free(xe); free(xo); free(Xe); free(Xo); } } void drawSignal(SDL_Renderer* renderer, Complex* x, int N, int offsetX, int offsetY) { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); for (int n = 0; n < N - 1; n++) { SDL_RenderDrawLine(renderer, offsetX + n, offsetY - x[n].real, offsetX + n + 1, offsetY - x[n + 1].real); } } void drawSpectrum(SDL_Renderer* renderer, Complex* X, int N, int offsetX, int offsetY) { SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); for (int k = 0; k < N / 2; k++) { double magnitude = sqrt(X[k].real * X[k].real + X[k].imag * X[k].imag); SDL_RenderDrawLine(renderer, offsetX + k, offsetY, offsetX + k, offsetY - magnitude); SDL_RenderDrawLine(renderer, offsetX + N - k - 1, offsetY, offsetX + N - k - 1, offsetY - magnitude); } } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("FFT", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_Event event; int quit = 0; int N = 256; Complex* x = (Complex*) malloc(N * sizeof(Complex)); Complex* X = (Complex*) malloc(N * sizeof(Complex)); srand(time(NULL)); for (int n = 0; n < N; n++) { x[n].real = rand() % 256; x[n].imag = 0; } FFT(x, N, X); while (!quit) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { quit = 1; } } SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); drawSignal(renderer, x, N, 0, HEIGHT / 2); drawSpectrum(renderer, X, N, 0, HEIGHT); SDL_RenderPresent(renderer); } free(x); free(X); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }这段代码使用SDL2库绘制信号图和频谱图,需要在编译时链接SDL2库。如果你没有安装SDL2库,可以使用以下命令安装:
sudo apt-get install libsdl2-dev编译命令:
gcc -o fft fft.c -lm `sdl2-config --cflags --libs`运行后,你应该可以看到一个窗口,里面绘制了信号图和频谱图。
解决 无用评论 打赏 举报