我应该从getFft看到什么样的输出? [英] What kind of output should I see from getFft?

查看:137
本文介绍了我应该从getFft看到什么样的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我正在开发一个Android音频可视化应用程序。问题是,我得到形式的方法getFft()没有jive与谷歌说,它应该产生。我跟踪源代码一路回到C ++,但我不熟悉C ++或FFT才能真正了解发生了什么。

Alright, so I am working on creating an Android audio visualization app. The problem is, what I get form the method getFft() doesn't jive with what google says it should produce. I traced the source code all the way back to C++, but I am not familiar enough with C++ or FFT to actually understand what is happening.

我会尝试包括一切需要此处:

I will try and include everything needed here:

(Java)Visualizer.getFft(byte [] fft)

 /**
 * Returns a frequency capture of currently playing audio content. The capture is a 8-bit
 * magnitude FFT. Note that the size of the FFT is half of the specified capture size but both
 * sides of the spectrum are returned yielding in a number of bytes equal to the capture size.
 * {@see #getCaptureSize()}.
 * <p>This method must be called when the Visualizer is enabled.
 * @param fft array of bytes where the FFT should be returned
 * @return {@link #SUCCESS} in case of success,
 * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
 * in case of failure.
 * @throws IllegalStateException
 */
public int getFft(byte[] fft)
throws IllegalStateException {
    synchronized (mStateLock) {
        if (mState != STATE_ENABLED) {
            throw(new IllegalStateException("getFft() called in wrong state: "+mState));
        }
        return native_getFft(fft);
    }
}

(C ++)Visualizer.getFft(uint8_t * fft)

status_t Visualizer::getFft(uint8_t *fft)
{
if (fft == NULL) {
    return BAD_VALUE;
}
if (mCaptureSize == 0) {
    return NO_INIT;
}

status_t status = NO_ERROR;
if (mEnabled) {
    uint8_t buf[mCaptureSize];
    status = getWaveForm(buf);
    if (status == NO_ERROR) {
        status = doFft(fft, buf);
    }
} else {
    memset(fft, 0, mCaptureSize);
}
return status;
}

(C ++)Visualizer.doFft(uint8_t * fft,uint8_t * waveform)

status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform)
{
int32_t workspace[mCaptureSize >> 1];
int32_t nonzero = 0;

for (uint32_t i = 0; i < mCaptureSize; i += 2) {
    workspace[i >> 1] = (waveform[i] ^ 0x80) << 23;
    workspace[i >> 1] |= (waveform[i + 1] ^ 0x80) << 7;
    nonzero |= workspace[i >> 1];
}

if (nonzero) {
    fixed_fft_real(mCaptureSize >> 1, workspace);
}

for (uint32_t i = 0; i < mCaptureSize; i += 2) {
    fft[i] = workspace[i >> 1] >> 23;
    fft[i + 1] = workspace[i >> 1] >> 7;
}

return NO_ERROR;
}

(C ++)fixedfft.fixed_fft_real(int n,int32_t * v)



(C++) fixedfft.fixed_fft_real(int n, int32_t *v)

void fixed_fft_real(int n, int32_t *v)
{
int scale = LOG_FFT_SIZE, m = n >> 1, i;

fixed_fft(n, v);
for (i = 1; i <= n; i <<= 1, --scale);
v[0] = mult(~v[0], 0x80008000);
v[m] = half(v[m]);

for (i = 1; i < n >> 1; ++i) {
    int32_t x = half(v[i]);
    int32_t z = half(v[n - i]);
    int32_t y = z - (x ^ 0xFFFF);
    x = half(x + (z ^ 0xFFFF));
    y = mult(y, twiddle[i << scale]);
    v[i] = x - y;
    v[n - i] = (x + y) ^ 0xFFFF;
}
}

(C ++)fixedfft.fixed_fft(int n,int32_t * v)

void fixed_fft(int n, int32_t *v)
{
int scale = LOG_FFT_SIZE, i, p, r;

for (r = 0, i = 1; i < n; ++i) {
    for (p = n; !(p & r); p >>= 1, r ^= p);
    if (i < r) {
        int32_t t = v[i];
        v[i] = v[r];
        v[r] = t;
    }
}

for (p = 1; p < n; p <<= 1) {
    --scale;

    for (i = 0; i < n; i += p << 1) {
        int32_t x = half(v[i]);
        int32_t y = half(v[i + p]);
        v[i] = x + y;
        v[i + p] = x - y;
    }

    for (r = 1; r < p; ++r) {
        int32_t w = MAX_FFT_SIZE / 4 - (r << scale);
        i = w >> 31;
        w = twiddle[(w ^ i) - i] ^ (i << 16);
        for (i = r; i < n; i += p << 1) {
            int32_t x = half(v[i]);
            int32_t y = mult(w, v[i + p]);
            v[i] = x - y;
            v[i + p] = x + y;
        }
    }
}
}

你通过所有这一切,你是真棒!所以我的问题是,当我调用java方法getFft()我结束了负值,如果返回的数组意味着表示大小不应该存在。所以我的问题是,我需要做什么,使数组表示幅度?

If you made it through all that, you are awesome! So my issue, is when I call the java method getFft() I end up with negative values, which shouldn't exist if the returned array is meant to represent magnitude. So my question is, what do I need to do to make the array represent magnitude?

编辑它似乎我的数据可能实际上是傅立叶系数。我在网上窥探,发现。小程序开始函数FFT显示系数的图形表示,并且它是当我绘制来自getFft()的数据时将发生什么的间谍图像。所以新的问题:这是我的数据是什么?如果是,我该如何从系数到它的光谱分析?

It appears my data may actually be the Fourier coefficients. I was poking around the web and found this. The applet "Start Function FFT" displays a graphed representation of coefficients and it is a spitting image of what happens when I graph the data from getFft(). So new question: Is this what my data is? and if so, how do I go from the coefficients to a spectral analysis of it?

推荐答案

只是产生幅度;它也产生相位(每个样本的输出是复数)。如果你想要幅度,那么你需要为每个输出样本显式计算它,如 re * re + im * im ,其中 re im 分别是每个复数的实部和虚部。

An FFT doesn't just produce magnitude; it produces phase as well (the output for each sample is a complex number). If you want magnitude, then you need to explicitly calculate it for each output sample, as re*re + im*im, where re and im are the real and imaginary components of each complex number, respectively.


不幸的是,我不能在你的代码中看到你正在使用复数的任何地方,所以可能需要一些重写。

UPDATE

猜猜(在看代码之后),我会说实际组件是偶数索引,奇数组件是奇数索引。所以要获得量值,你需要做如下:

If I had to guess (after glancing at the code), I'd say that real components were at even indices, and odd components were at odd indices. So to get magnitudes, you'd need to do something like:

uint32_t mag[N/2];
for (int i = 0; i < N/2; i++)
{
    mag[i] = fft[2*i]*fft[2*i] + fft[2*i+1]*fft[2*i+1];
}

这篇关于我应该从getFft看到什么样的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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