求ccs实现傅立叶变换的信号图和频谱图single time 和fft magnitude

电脑没有网络所以找不到傅立叶的库代码实现不了,求大家帮个忙运行一下

以下是使用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`

运行后,你应该可以看到一个窗口,里面绘制了信号图和频谱图。