KissFFT前进/逆输出噪音,为什么呢? [英] KissFFT forward / inverse is outputting noise, why?

查看:318
本文介绍了KissFFT前进/逆输出噪音,为什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个Java应用程序本身使用KissFFT,但输入信号的正向/反向没有返回,因为它应该:信号幅度几乎是不存在的。如果删除了缩放因子(由2N分割),则结果为谐波噪声。任何人都可以发现的bug?

下面是转接呼叫(GDX从复制,所以应该OK了!):

  JNIEXPORT无效JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv的* ENV,JCLASS clazz所jlong​​手柄,jshortArray obj_samples,jfloatArray obj_spectrum){
    短*样品=(短*)env-> GetPrimitiveArrayCritical(obj_samples,0);
    浮动*谱=(浮点*)env-> GetPrimitiveArrayCritical(obj_spectrum,0);        KissFFT * FFT =(KissFFT *)处理;
        kiss_fftr(fft-> forwardConfig,(kiss_fft_scalar *)样品,fft->谱);        INT LEN = fft-> NUMSAMPLES / 2 + 1;
        的for(int i = 0; I< LEN,我++)
        {
            浮重=规模(fft->谱[I] .R)* fft-> NUMSAMPLES;
            浮IM =规模(fft->谱[I] .7)* fft-> NUMSAMPLES;            如果(I 0)
                谱[I] = sqrtf(重*重新+ IM * IM);
            其他
                谱[I] = sqrtf(重*重新+ IM * IM);
        }    env-> ReleasePrimitiveArrayCritical(obj_samples,样品,0);
    env-> ReleasePrimitiveArrayCritical(obj_spectrum,频谱,0);}

这是逆(我写的,可能有一个错误;)):

  JNIEXPORT无效JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_inverse(JNIEnv的* ENV,JCLASS clazz所jlong​​手柄,jshortArray obj_samples){
    短* shortSamples =(短*)env-> GetPrimitiveArrayCritical(obj_samples,0);// @行:108        KissFFT * FFT =(KissFFT *)处理;
        kiss_fft_cpx出[fft-> NUMSAMPLES]。        kiss_fftri(fft-> inverseConfig,fft->谱,(kiss_fft_scalar *)出);        的for(int i = 0; I< fft-> NUMSAMPLES;我++){
            shortSamples [I] =(出[I] .R)/(fft-> NUMSAMPLES * 2);
        }    env-> ReleasePrimitiveArrayCritical(obj_samples,shortSamples,0);}


解决方案

每protectedmember的要求,这里是一个更完整的例子(在本机端,反正)。我结束了小幅修改libgdx code(使用v.0.9.4)。当反演我也编译了浮点,而不是固定的,因为后者引入的量化噪声。这code的的对或者(因为kiss_fft_scalar适应短期或浮动取决于编译器的标志),但没有固定重新测试,因为我发现它不是一个fft-有益的工作> IFFT系列。

我很想知道,如果你成功了,你让我知道!

(请注意,这code,以下libgdx,是根据Apache 2.0许可!)

 的#include< com.badlogic.gdx.audio.analysis.KissFFT.h>#包括LT&; kissfft / kiss_fftr.h>
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&math.h中GT;结构KissFFT
{
    kiss_fftr_cfg forwardConfig;
    kiss_fftr_cfg inverseConfig;
    kiss_fft_cpx *谱;
    INT NUMSAMPLES;
    INT spectrumSize;
};JNIEXPORT jlong​​ JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_create(JNIEnv的* ENV,JCLASS clazz所jint NUMSAMPLES){    KissFFT * FFT =新KissFFT();
    fft-> forwardConfig = kiss_fftr_alloc(NUMSAMPLES,0,NULL,NULL);
    fft-> inverseConfig = kiss_fftr_alloc(NUMSAMPLES,1,NULL,NULL);
    fft->谱=(kiss_fft_cpx *)malloc的(的sizeof(kiss_fft_cpx)* NUMSAMPLES);
    fft-> NUMSAMPLES = NUM​​SAMPLES;
    fft-> spectrumSize = NUM​​SAMPLES / 2 + 1;
    回报(jlong​​)FFT;
}JNIEXPORT无效JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_destroy(JNIEnv的* ENV,JCLASS clazz所jlong​​手柄){    KissFFT * FFT =(KissFFT *)处理;
    免费(fft-> forwardConfig);
    免费(fft-> inverseConfig);
    免费(fft->谱);
    免费(FFT);
}JNIEXPORT无效JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv的* ENV,JCLASS clazz所jlong​​手柄,jfloatArray obj_samples,jfloatArray obj_mags){    kiss_fft_scalar *样品=(kiss_fft_scalar *)env-> GetPrimitiveArrayCritical(obj_samples,0);
    浮动*弹匣=(浮点*)env-> GetPrimitiveArrayCritical(obj_mags,0);    KissFFT * FFT =(KissFFT *)处理;    kiss_fftr(fft-> forwardConfig,样品,fft->谱);    的for(int i = 0; I< fft-> spectrumSize;我++){
        弹匣[I] = hypotf(fft->谱[I] .R,fft->谱[I] .7);
    }    env-> ReleasePrimitiveArrayCritical(obj_samples,样品,0);
    env-> ReleasePrimitiveArrayCritical(obj_mags,弹匣,0);
}JNIEXPORT无效JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_inverse(JNIEnv的* ENV,JCLASS clazz所jlong​​手柄,jfloatArray obj_samples){
    kiss_fft_scalar *样品=(kiss_fft_scalar *)env-> GetPrimitiveArrayCritical(obj_samples,0);    KissFFT * FFT =(KissFFT *)处理;    kiss_fftri(fft-> inverseConfig,fft->光谱样本);    的for(int i = 0; I< fft-> NUMSAMPLES;我++){
        样本[I] =样本[I] /(浮点)fft-> NUMSAMPLES;
    }    env-> ReleasePrimitiveArrayCritical(obj_samples,样品,0);}

I'm trying to use KissFFT natively in a java app, but the forward/inverse of an input signal isn't returning as it should: the signal amplitude is almost non-existent. If I remove the scaling factor (dividing by 2N), the result is harmonic noise. Can anyone spot the bug?

Here is the forward call (copied from GDX, so should be ok!):

JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv* env, jclass clazz, jlong handle, jshortArray obj_samples, jfloatArray obj_spectrum) {
    short* samples = (short*)env->GetPrimitiveArrayCritical(obj_samples, 0);
    float* spectrum = (float*)env->GetPrimitiveArrayCritical(obj_spectrum, 0);

        KissFFT* fft = (KissFFT*)handle;
        kiss_fftr( fft->forwardConfig, (kiss_fft_scalar*)samples, fft->spectrum );

        int len = fft->numSamples / 2 + 1;
        for( int i = 0; i < len; i++ )
        {
            float re = scale(fft->spectrum[i].r) * fft->numSamples;
            float im = scale(fft->spectrum[i].i) * fft->numSamples;

            if( i > 0 )
                spectrum[i] = sqrtf(re*re + im*im);
            else
                spectrum[i] = sqrtf(re*re + im*im);
        }

    env->ReleasePrimitiveArrayCritical(obj_samples, samples, 0);
    env->ReleasePrimitiveArrayCritical(obj_spectrum, spectrum, 0);

}

And here is the inverse (written by me, probably has an error ;) ):

JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_inverse(JNIEnv* env, jclass clazz, jlong handle, jshortArray obj_samples) {
    short* shortSamples = (short*)env->GetPrimitiveArrayCritical(obj_samples, 0);

//@line:108

        KissFFT* fft = (KissFFT*)handle;
        kiss_fft_cpx out[fft->numSamples];

        kiss_fftri( fft->inverseConfig, fft->spectrum, (kiss_fft_scalar*)out );

        for (int i=0; i < fft->numSamples; i++) {
            shortSamples[i] = (out[i].r) / (fft->numSamples*2);
        }

    env->ReleasePrimitiveArrayCritical(obj_samples, shortSamples, 0);

}

解决方案

Per protectedmember's request, here is a more complete example (on the native side, anyway). I ended up modifying the libgdx code slightly (using v.0.9.4). I also compiled with floating-point rather than fixed, as the latter introduced quantization noise when inversing. This code should work for either (because kiss_fft_scalar adapts to short or float depending on the compiler flag), but have not re-tested with fixed, since I found it's not useful for a fft->ifft series.

I am curious to know if you are successful, do let me know!

(Please note that this code, following libgdx, is under Apache 2.0 license!)

#include <com.badlogic.gdx.audio.analysis.KissFFT.h>

#include <kissfft/kiss_fftr.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

struct KissFFT
{
    kiss_fftr_cfg forwardConfig;
    kiss_fftr_cfg inverseConfig;
    kiss_fft_cpx* spectrum;
    int numSamples;
    int spectrumSize;
};

JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_create(JNIEnv* env, jclass clazz, jint numSamples) {

    KissFFT* fft = new KissFFT();
    fft->forwardConfig = kiss_fftr_alloc(numSamples,0,NULL,NULL);
    fft->inverseConfig = kiss_fftr_alloc(numSamples,1,NULL,NULL);
    fft->spectrum = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * numSamples);
    fft->numSamples = numSamples;
    fft->spectrumSize = numSamples/2+1;
    return (jlong)fft;
}

JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_destroy(JNIEnv* env, jclass clazz, jlong handle) {

    KissFFT* fft = (KissFFT*)handle;
    free(fft->forwardConfig);
    free(fft->inverseConfig);
    free(fft->spectrum);
    free(fft);  
}

JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_spectrum(JNIEnv* env, jclass clazz, jlong handle, jfloatArray obj_samples, jfloatArray obj_mags) {

    kiss_fft_scalar* samples = (kiss_fft_scalar*)env->GetPrimitiveArrayCritical(obj_samples, 0);
    float* mags = (float*)env->GetPrimitiveArrayCritical(obj_mags, 0);

    KissFFT* fft = (KissFFT*) handle;

    kiss_fftr(fft->forwardConfig, samples, fft->spectrum);

    for(int i=0;i<fft->spectrumSize;i++) {
        mags[i] = hypotf(fft->spectrum[i].r,fft->spectrum[i].i);
    }

    env->ReleasePrimitiveArrayCritical(obj_samples, samples, 0);
    env->ReleasePrimitiveArrayCritical(obj_mags, mags, 0);
}

JNIEXPORT void JNICALL Java_com_badlogic_gdx_audio_analysis_KissFFT_inverse(JNIEnv* env, jclass clazz, jlong handle, jfloatArray obj_samples) {
    kiss_fft_scalar* samples = (kiss_fft_scalar*)env->GetPrimitiveArrayCritical(obj_samples, 0);

    KissFFT* fft = (KissFFT*)handle;

    kiss_fftri( fft->inverseConfig, fft->spectrum, samples );

    for(int i=0;i<fft->numSamples;i++) {
        samples[i] = samples[i] / (float)fft->numSamples;
    }

    env->ReleasePrimitiveArrayCritical(obj_samples, samples, 0);

}

这篇关于KissFFT前进/逆输出噪音,为什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆