Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat kind of output should I see from getFft?
    primarykey
    data
    text
    <p>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.</p> <p>I will try and include everything needed here:</p> <p><a href="http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/media/java/android/media/audiofx/Visualizer.java" rel="nofollow"><strong>(Java) Visualizer.getFft(byte[] fft)</strong></a></p> <pre><code> /** * 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()}. * &lt;p&gt;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); } } </code></pre> <p><a href="http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/media/libmedia/Visualizer.cpp" rel="nofollow"><strong>(C++) Visualizer.getFft(uint8_t *fft)</strong></a></p> <pre><code>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; } </code></pre> <p><a href="http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/media/libmedia/Visualizer.cpp" rel="nofollow"><strong>(C++) Visualizer.doFft(uint8_t *fft, uint8_t *waveform)</strong></a></p> <pre><code>status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform) { int32_t workspace[mCaptureSize &gt;&gt; 1]; int32_t nonzero = 0; for (uint32_t i = 0; i &lt; mCaptureSize; i += 2) { workspace[i &gt;&gt; 1] = (waveform[i] ^ 0x80) &lt;&lt; 23; workspace[i &gt;&gt; 1] |= (waveform[i + 1] ^ 0x80) &lt;&lt; 7; nonzero |= workspace[i &gt;&gt; 1]; } if (nonzero) { fixed_fft_real(mCaptureSize &gt;&gt; 1, workspace); } for (uint32_t i = 0; i &lt; mCaptureSize; i += 2) { fft[i] = workspace[i &gt;&gt; 1] &gt;&gt; 23; fft[i + 1] = workspace[i &gt;&gt; 1] &gt;&gt; 7; } return NO_ERROR; } </code></pre> <p><a href="http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/media/libmedia/fixedfft.cpp" rel="nofollow"><strong>(C++) fixedfft.fixed_fft_real(int n, int32_t *v)</strong></a></p> <pre><code>void fixed_fft_real(int n, int32_t *v) { int scale = LOG_FFT_SIZE, m = n &gt;&gt; 1, i; fixed_fft(n, v); for (i = 1; i &lt;= n; i &lt;&lt;= 1, --scale); v[0] = mult(~v[0], 0x80008000); v[m] = half(v[m]); for (i = 1; i &lt; n &gt;&gt; 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 &lt;&lt; scale]); v[i] = x - y; v[n - i] = (x + y) ^ 0xFFFF; } } </code></pre> <p><a href="http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/media/libmedia/fixedfft.cpp" rel="nofollow"><strong>(C++) fixedfft.fixed_fft(int n, int32_t *v)</strong></a></p> <pre><code>void fixed_fft(int n, int32_t *v) { int scale = LOG_FFT_SIZE, i, p, r; for (r = 0, i = 1; i &lt; n; ++i) { for (p = n; !(p &amp; r); p &gt;&gt;= 1, r ^= p); if (i &lt; r) { int32_t t = v[i]; v[i] = v[r]; v[r] = t; } } for (p = 1; p &lt; n; p &lt;&lt;= 1) { --scale; for (i = 0; i &lt; n; i += p &lt;&lt; 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 &lt; p; ++r) { int32_t w = MAX_FFT_SIZE / 4 - (r &lt;&lt; scale); i = w &gt;&gt; 31; w = twiddle[(w ^ i) - i] ^ (i &lt;&lt; 16); for (i = r; i &lt; n; i += p &lt;&lt; 1) { int32_t x = half(v[i]); int32_t y = mult(w, v[i + p]); v[i] = x - y; v[i + p] = x + y; } } } } </code></pre> <p>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?</p> <p><strong>EDIT:</strong> It appears my data may actually be the Fourier coefficients. I was poking around the web and found <a href="http://www.mathcs.org/java/programs/FFT/" rel="nofollow">this</a>. 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: <em>Is this what my data is? and if so, how do I go from the coefficients to a spectral analysis of it?</em></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload