首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KissFFT正向/反向输出噪声,为什么?

KissFFT正向/反向输出噪声,为什么?
EN

Stack Overflow用户
提问于 2012-06-09 09:02:59
回答 2查看 1.8K关注 0票数 0

我正尝试在java应用程序中原生使用KissFFT,但是输入信号的正向/反向并没有正常返回:信号幅度几乎不存在。如果我去掉比例因子(除以2N),结果就是谐波噪声。有人能发现这个bug吗?

这是前向调用(从GDX复制,所以应该没问题!):

代码语言:javascript
复制
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);

}

这里是相反的(由我写的,可能有一个错误;) ):

代码语言:javascript
复制
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);

}
EN

回答 2

Stack Overflow用户

发布于 2012-06-29 23:32:33

对于每个受保护成员的请求,这里是一个更完整的示例(无论如何,在本机端)。我最终稍微修改了libgdx代码(使用v.0.9.4)。我还使用浮点数而不是固定数进行编译,因为后者在反转时会引入量化噪声。这段代码应该适用于任何一种(因为kiss_fft_scalar根据编译器标志适应短整型或浮点型),但没有使用fixed重新测试,因为我发现它对fft->ifft系列没有用处。

我很好奇,如果你成功了,一定要让我知道!

(请注意,在libgdx之后,此代码受Apache2.0许可!)

代码语言:javascript
复制
#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);

}
票数 2
EN

Stack Overflow用户

发布于 2012-06-11 06:24:17

哇哦!找到了问题所在。我应该直接对短数组进行逆变换:

代码语言:javascript
复制
kiss_fftri( fft->inverseConfig, fft->spectrum, shortSamples );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10957604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档