C实现读取音频然后对音频进行FFt后输出
时间: 2024-05-08 13:17:00 浏览: 10
以下是一个简单的C程序,可以读取一个WAV文件,对其进行FFT变换,并输出变换结果。
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265358979323846
typedef struct WAVHeader {
char chunkID[4];
int chunkSize;
char format[4];
char subchunk1ID[4];
int subchunk1Size;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bitsPerSample;
char subchunk2ID[4];
int subchunk2Size;
} WAVHeader;
void readWAVHeader(FILE* file, WAVHeader* header) {
fread(header, sizeof(WAVHeader), 1, file);
}
void printWAVHeader(WAVHeader* header) {
printf("Chunk ID: %c%c%c%c\n", header->chunkID[0], header->chunkID[1], header->chunkID[2], header->chunkID[3]);
printf("Chunk Size: %d\n", header->chunkSize);
printf("Format: %c%c%c%c\n", header->format[0], header->format[1], header->format[2], header->format[3]);
printf("Subchunk1 ID: %c%c%c%c\n", header->subchunk1ID[0], header->subchunk1ID[1], header->subchunk1ID[2], header->subchunk1ID[3]);
printf("Subchunk1 Size: %d\n", header->subchunk1Size);
printf("Audio Format: %d\n", header->audioFormat);
printf("Num Channels: %d\n", header->numChannels);
printf("Sample Rate: %d\n", header->sampleRate);
printf("Byte Rate: %d\n", header->byteRate);
printf("Block Align: %d\n", header->blockAlign);
printf("Bits Per Sample: %d\n", header->bitsPerSample);
printf("Subchunk2 ID: %c%c%c%c\n", header->subchunk2ID[0], header->subchunk2ID[1], header->subchunk2ID[2], header->subchunk2ID[3]);
printf("Subchunk2 Size: %d\n", header->subchunk2Size);
}
void readWAVData(FILE* file, short* data, int numSamples) {
fread(data, sizeof(short), numSamples, file);
}
void printWAVData(short* data, int numSamples) {
for (int i = 0; i < numSamples; i++) {
printf("%d\n", data[i]);
}
}
void fft(double* data, int n) {
if (n <= 1) return;
double* even = (double*) malloc(n/2 * sizeof(double));
double* odd = (double*) malloc(n/2 * sizeof(double));
for (int i = 0; i < n/2; i++) {
even[i] = data[2*i];
odd[i] = data[2*i+1];
}
fft(even, n/2);
fft(odd, n/2);
for (int i = 0; i < n/2; i++) {
double re = even[i];
double im = odd[i] * exp(-2 * PI * i / n);
data[i] = re + im;
data[i+n/2] = re - im;
}
free(even);
free(odd);
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s <filename>\n", argv[0]);
return 1;
}
FILE* file = fopen(argv[1], "rb");
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
WAVHeader header;
readWAVHeader(file, &header);
printWAVHeader(&header);
int numSamples = header.subchunk2Size / 2;
short* data = (short*) malloc(numSamples * sizeof(short));
readWAVData(file, data, numSamples);
fclose(file);
double* fftData = (double*) malloc(numSamples * sizeof(double));
for (int i = 0; i < numSamples; i++) {
fftData[i] = (double) data[i];
}
fft(fftData, numSamples);
for (int i = 0; i < numSamples; i++) {
printf("%f\n", fftData[i]);
}
free(data);
free(fftData);
return 0;
}
```
在上面的程序中,我们首先定义了一个`WAVHeader`结构体,用于存储WAV文件的头信息。然后定义了一些函数用于读取WAV文件的头信息和数据,以及进行FFT变换。在`main`函数中,我们首先读取WAV头信息,然后读取WAV数据,并将其转换为一个`double`类型的数组。接着,我们对这个数组进行FFT变换,最后将变换结果输出到控制台上。
注意,上面的程序中没有做任何错误处理,比如读取文件失败或者WAV文件格式不正确等情况。在实际使用中,需要做相应的错误处理。另外,在进行FFT变换时,需要注意数组长度必须是2的整数次幂,否则需要进行补零操作。