seeyou_jpg 2023-06-01 10:37 采纳率: 38.5%
浏览 29
已结题

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

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

  • 写回答

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`
    

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

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月6日
  • 创建了问题 6月1日

悬赏问题

  • ¥15 高通uboot 打印ubi init err 22
  • ¥20 PDF元数据中的XMP媒体管理属性
  • ¥15 R语言中lasso回归报错
  • ¥15 网站突然不能访问了,上午还好好的
  • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
  • ¥15 semrush,SEO,内嵌网站,api
  • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
  • ¥15 振荡电路,ADS仿真
  • ¥15 关于#c语言#的问题,请各位专家解答!
  • ¥15 这个如何解决详细步骤