2012-06-09 3 views
0

자바 응용 프로그램에서 KissFFT를 기본적으로 사용하려고하지만 입력 신호의 정방향/역방향 신호가 반환되지 않습니다. 신호 진폭은 거의 존재하지 않습니다. 스케일링 팩터를 2N으로 나눈 값을 제거하면 고조파 노이즈가 발생합니다. 누구든지 버그를 발견 할 수 있습니까? 여기 KissFFT 정방향/역방향 출력에서 ​​잡음이 출력되는 이유는 무엇입니까?

는 앞으로 호출입니다 (! GDX에서 복사, 그래서 확인을해야) :

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); 

} 

그리고 여기에 역입니다 (내가 쓴, 아마 오류가 있습니다;)) :

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); 

} 

답변

1

my answer 비슷한 질문을 참조하십시오.

또는 kissfft의 README 파일에서

:

 
     Q: Why don't I get the output I expect? 
     A: The two most common causes of this are 
       1) scaling : is there a constant multiplier between what you got and what you want? 
       2) mixed build environment -- all code must be compiled with same preprocessor 
       definitions for FIXED_POINT and kiss_fft_scalar 

+0

감사합니다 마크, 문제를 해결 (!이 코드는, libgdx 다음, 아파치 2.0 라이센스하에 있습니다)하지만 스케일링 팁도 도움이되었다! – cmbryan

0

으악! 문제를 찾았습니다. 나는 역 바로 짧은 배열로 변환하고있다한다 : protectedmember의 요청에 따라

kiss_fftri(fft->inverseConfig, fft->spectrum, shortSamples); 
2

, 여기 (어쨌든, 네이티브 측에) 더 완벽한 예입니다. libgdx 코드를 약간 수정했다 (v.0.9.4 사용). 고정 된 것보다는 부동 소수점을 사용하여 컴파일했습니다. 후자는 반전 할 때 양자화 노이즈를 도입했기 때문입니다. 이 코드 (kiss_fft_scalar가 컴파일러 플래그에 따라 short 또는 float에 적응하기 때문에)에서 작동해야하지만 fft-> ifft 시리즈에서는 유용하지 않음을 알았 기 때문에 fixed로 다시 테스트하지 않았습니다.

내가 성공했는지 알고 싶다면 알려주세요.

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

} 
+0

이것은 정말로 도움이되지만, 왜이 줄은 :'samples [i] = samples [i]/(float) fft-> numSamples;'? – neevek

관련 문제