3

この 11 秒の 44kHz .wav サンプル ファイルをテスト入力としてKissFFT ライブラリを使用しようとしています。

ただし、ウィンドウ サイズ 512 でファイルを処理すると、出力値が 1 つしか得られません。奇妙なことに、44kHz で 11 秒の .wav ファイルは、512 のウィンドウ サイズで出力として 1 つの値を与えるべきではありません。

私が間違っていることを誰かが知っていますか?

これは私のコードです:

#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;
}

この投稿の手順に従いました:

Visual Studio 2010 での "エラー LNK2019: 未解決の外部シンボル" エラー

そして、私はまだこれらのエラーを受け取ります:

ここに画像の説明を入力

4

1 に答える 1

4

この問題は KissFFT が原因ではなく、次の行で ASCII モードで開かれたバイナリウェーブ ファイルを読み込もうとしていることが原因です。

in = fopen(music_file, "r");

後でデータを読み取ろうとするとfread、最終的に無効な文字にヒットします。特定のサンプル ファイルでは、読み取られた 215番目の文字はSubstitute Character (hex value 0x1A)であり、C ランタイム ライブラリによってファイル マーカーの終わりとして解釈されます。それに応じて、freadそれ以上のデータの入力を停止し、最終的に 0 を返します (2 回目の反復でWIN512 に設定し、少し後WINに 16 に設定します)。

この問題を回避するには、ファイルをバイナリで開く必要があります。

in = fopen(music_file, "rb");

これにより、バイナリ データがそのまま入力バッファーに読み込まれますが、wave ファイル ヘッダーはデコードされないことに注意してください。Wave ファイルを適切に読み取ってデコードし、意味のあるデータを取得するには、オーディオ ライブラリ ( libsndfileなど) の使用を検討する必要があります。独自の wave ファイル リーダーを展開する必要がある場合は、仕様を読むか、トピックに関する多くのチュートリアルの 1 つをチェックしてください。

于 2016-03-02T02:08:11.063 に答える