[英]KissFFT forward / inverse is outputting noise, why?
我正在嘗試在Java應用程序中本機使用KissFFT,但是輸入信號的正向/反向沒有返回應有的狀態:信號振幅幾乎不存在。 如果刪除比例因子(除以2N),則結果是諧波噪聲。 任何人都可以發現該錯誤嗎?
這是前向呼叫(從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);
}
根據受保護成員的請求,這是一個更完整的示例(無論如何在本機端)。 我最終稍微修改了libgdx代碼(使用v.0.9.4)。 我還使用浮點而不是固定值進行編譯,因為后者在反轉時會引入量化噪聲。 這段代碼應該都適用(因為kiss_fft_scalar取決於編譯器標志適應short還是float),但是還沒有進行過固定測試,因為我發現它對fft-> ifft系列沒有用。
我很好奇您是否成功,請告訴我!
(請注意,libgdx之后的此代碼受Apache 2.0許可!)
#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自述文件中:
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
哎呦! 找到了問題。 我應該一直在對短數組進行逆變換:
kiss_fftri( fft->inverseConfig, fft->spectrum, shortSamples );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.