电脑没有网络所以找不到傅立叶的库代码实现不了,求大家帮个忙运行一下
以下是使用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`
运行后,你应该可以看到一个窗口,里面绘制了信号图和频谱图。