c语言编写程序:对输入的.bin格式的音频文件进行傅里叶变换,并出图演示
时间: 2023-06-25 09:03:35 浏览: 153
C语言编写傅立叶变换程序
4星 · 用户满意度95%
要对音频文件进行傅里叶变换,需要先读取文件中的数据,然后对数据进行傅里叶变换,最后将变换结果以图表形式展示出来。下面是一个简单的C语言程序,可以对输入的.bin格式的音频文件进行傅里叶变换,并用GNU Plot绘制变换结果的图表。
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265358979323846
/* 傅里叶变换 */
void fourier_transform(double* x, double* y, int n) {
if (n <= 1) return;
double* xe = (double*)malloc(n / 2 * sizeof(double));
double* xo = (double*)malloc(n / 2 * sizeof(double));
for (int i = 0; i < n / 2; i++) {
xe[i] = x[2 * i];
xo[i] = x[2 * i + 1];
}
fourier_transform(xe, y, n / 2);
fourier_transform(xo, y, n / 2);
for (int i = 0; i < n; i++) {
double re, im;
if (i < n / 2) {
re = xe[i];
im = y[i];
} else {
re = xo[i - n / 2];
im = y[i - n / 2];
}
double angle = -2 * PI * i / n;
double cosA = cos(angle);
double sinA = sin(angle);
x[i] = xe[i % (n / 2)] + re * cosA - im * sinA;
y[i] = y[i % (n / 2)] + re * sinA + im * cosA;
}
free(xe);
free(xo);
}
/* 读取音频文件 */
int read_audio_file(const char* file_name, short** data, int* num_samples) {
FILE* fp = fopen(file_name, "rb");
if (fp == NULL) {
fprintf(stderr, "Failed to open %s\n", file_name);
return -1;
}
fseek(fp, 0L, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
*num_samples = file_size / sizeof(short);
*data = (short*)malloc(*num_samples * sizeof(short));
fread(*data, sizeof(short), *num_samples, fp);
fclose(fp);
return 0;
}
/* 绘制图表 */
void plot(double* x, double* y, int n) {
FILE* fp = popen("gnuplot -persist", "w");
fprintf(fp, "set terminal png\n");
fprintf(fp, "set output 'fft.png'\n");
fprintf(fp, "plot '-' with lines\n");
for (int i = 0; i < n; i++) {
fprintf(fp, "%lf %lf\n", (double)i / n, sqrt(x[i] * x[i] + y[i] * y[i]));
}
fprintf(fp, "e\n");
fflush(fp);
pclose(fp);
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s audio_file.bin\n", argv[0]);
return -1;
}
short* data;
int num_samples;
if (read_audio_file(argv[1], &data, &num_samples) != 0) {
return -1;
}
int n = pow(2, ceil(log2(num_samples))); // 确保样本数为2的幂次方
double* x = (double*)malloc(n * sizeof(double));
double* y = (double*)calloc(n, sizeof(double));
for (int i = 0; i < num_samples; i++) {
x[i] = (double)data[i];
}
fourier_transform(x, y, n); // 傅里叶变换
plot(x, y, n); // 绘制图表
free(data);
free(x);
free(y);
return 0;
}
```
编译和运行程序:
```bash
$ gcc -o fft fft.c -lm
$ ./fft audio_file.bin
```
程序将读取名为`audio_file.bin`的音频文件,并对其进行傅里叶变换。变换结果将以图表形式展示出来,并保存为`fft.png`文件。你可以使用任何图片查看器打开这个文件,以查看图表的内容。
阅读全文