在波形文件上使用 KissFFT
Using KissFFT on a wave file
我正在尝试使用 KissFFT Library with this 11 second 44kHz .wav sample file 作为测试输入。
然而,当我处理 window 大小为 512 的文件时,我只得到 1 个输出值。这很奇怪,44kHz 的 11 秒 .wav 文件不应该给出 1 个值作为 windows 大小为 512 的输出。较小的 windows 像 16 会给我 5 个值,这仍然是一个计数低。
有谁知道我做错了什么吗?
这是我的代码:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#define WIN 512
int main()
{
char *music_file = "C:/MSin44W16-13.wav";
FILE *in;
char buf[WIN * 2];
int nfft = WIN, i, fx;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
in = fopen(music_file, "r");
if (!in) {
printf("unable to open file: %s\n", music_file);
perror("Error");
return 1;
}
fx = 0;
while (fread(buf, 1, WIN * 2, in))
{
for (i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
free(cfg);
scanf("%d");
return 0;
}
这是我得到的输出:
42.7577
这是更新代码版本,但我在编译时遇到错误:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#include "sndfile.h"
#define WIN 512
int main()
{
char *music_file = "C:/voice.wav";
SNDFILE *infile;
SF_INFO sfinfo;
//int readcount;
short buf[WIN * 2];
int nfft = WIN;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
if (!( infile = sf_open(music_file, SFM_READ, &sfinfo) ))
{ /* Open failed so print an error message. */
printf("Not able to open input file %s.\n", "input.wav");
/* Print the error message fron libsndfile. */
sf_perror(NULL);
return 1;
}
while ((sf_read_short(infile, buf, WIN)))//fread(buf, 1, WIN * 2, in)
{
//system("cls");
for (int i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
sf_close(infile);
free(cfg);
int temp;
scanf_s("%d", &temp);
return 0;
}
我按照这个 post 的步骤操作:
"error LNK2019: unresolved external symbol" error in Visual Studio 2010
我仍然遇到这些错误:
问题不是来自 KissFFT,而是由于您正在尝试读取以 ASCII 模式打开的 binary wave 文件这一事实:
in = fopen(music_file, "r");
当您稍后尝试使用 fread
读取数据时,您最终遇到了一个无效字符。在您的特定示例文件中,读取的第 215th 个字符是 Substitute Character (hex value 0x1A
), which is interpreted as an end of file marker by your C runtime library. Correspondingly, fread
停止填充更多数据并最终 return 0(在第二次迭代时 WIN
设置为 512,稍后将 WIN
设置为 16)。
要解决此问题,您应该以二进制方式打开文件:
in = fopen(music_file, "rb");
请注意,这将确保二进制数据按原样读入您的输入缓冲区,但不会为您解码 wave 文件头。要正确读取和解码波形文件并获取有意义的数据,您应该考虑使用音频库(例如 libsndfile to name one). If you must roll your own wave file reader you should read the specifications and/or 查看有关该主题的众多教程之一。
我正在尝试使用 KissFFT Library with this 11 second 44kHz .wav sample file 作为测试输入。
然而,当我处理 window 大小为 512 的文件时,我只得到 1 个输出值。这很奇怪,44kHz 的 11 秒 .wav 文件不应该给出 1 个值作为 windows 大小为 512 的输出。较小的 windows 像 16 会给我 5 个值,这仍然是一个计数低。
有谁知道我做错了什么吗?
这是我的代码:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#define WIN 512
int main()
{
char *music_file = "C:/MSin44W16-13.wav";
FILE *in;
char buf[WIN * 2];
int nfft = WIN, i, fx;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
in = fopen(music_file, "r");
if (!in) {
printf("unable to open file: %s\n", music_file);
perror("Error");
return 1;
}
fx = 0;
while (fread(buf, 1, WIN * 2, in))
{
for (i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
free(cfg);
scanf("%d");
return 0;
}
这是我得到的输出:
42.7577
这是更新代码版本,但我在编译时遇到错误:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#include "sndfile.h"
#define WIN 512
int main()
{
char *music_file = "C:/voice.wav";
SNDFILE *infile;
SF_INFO sfinfo;
//int readcount;
short buf[WIN * 2];
int nfft = WIN;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
if (!( infile = sf_open(music_file, SFM_READ, &sfinfo) ))
{ /* Open failed so print an error message. */
printf("Not able to open input file %s.\n", "input.wav");
/* Print the error message fron libsndfile. */
sf_perror(NULL);
return 1;
}
while ((sf_read_short(infile, buf, WIN)))//fread(buf, 1, WIN * 2, in)
{
//system("cls");
for (int i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
sf_close(infile);
free(cfg);
int temp;
scanf_s("%d", &temp);
return 0;
}
我按照这个 post 的步骤操作:
"error LNK2019: unresolved external symbol" error in Visual Studio 2010
我仍然遇到这些错误:
问题不是来自 KissFFT,而是由于您正在尝试读取以 ASCII 模式打开的 binary wave 文件这一事实:
in = fopen(music_file, "r");
当您稍后尝试使用 fread
读取数据时,您最终遇到了一个无效字符。在您的特定示例文件中,读取的第 215th 个字符是 Substitute Character (hex value 0x1A
), which is interpreted as an end of file marker by your C runtime library. Correspondingly, fread
停止填充更多数据并最终 return 0(在第二次迭代时 WIN
设置为 512,稍后将 WIN
设置为 16)。
要解决此问题,您应该以二进制方式打开文件:
in = fopen(music_file, "rb");
请注意,这将确保二进制数据按原样读入您的输入缓冲区,但不会为您解码 wave 文件头。要正确读取和解码波形文件并获取有意义的数据,您应该考虑使用音频库(例如 libsndfile to name one). If you must roll your own wave file reader you should read the specifications and/or 查看有关该主题的众多教程之一。