添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
仗义的冲锋衣  ·  gradle ...·  1 年前    · 
直爽的冲锋衣  ·  Python Pandas ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm analyzing audio signals on Android. First tried with MIC and succeeded. Now I'm trying to apply FFT on MP3 data comes from Visualizer.OnDataCaptureListener 's * onWaveFormDataCapture method which is linked to MediaPlayer . There is a byte array called byte[] waveform which I get spectral leakage or overlap when apply FFT on this data.

public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate)

I tried to convert the data into -1..1 range by using the code below in a for loop;

        // waveform varies in range of -128..+127
        raw[i] = (double) waveform[i];
        // change it to range -1..1
        raw[i] /= 128.0;

Then I copy the raw into fft buffer;

        fftre[i] = raw[i];
        fftim[i] = 0;

Then I call the fft function;

        fft.fft(fftre, fftim); // in: audio signal, out: fft data

As final process I convert them into magnitudes in dB then draw freqs on screen

        // Ignore the first fft data which is DC component
        for (i = 1, j = 0; i < waveform.length / 2; i++, j++)
            magnitude = (fftre[i] * fftre[i] + fftim[i] * fftim[i]);
            magnitudes[j] = 20.0 * Math.log10(Math.sqrt(magnitude) + 1e-5); // [dB]

When I play a sweep signal from 20Hz to 20kHz, I don't see what I see on MIC. It doesn't draw a single walking line, but several symmetric lines going far or coming near. Somehow there is a weaker symmetric signal on other end of the visualizer. The same code which using 32768 instead of 128 on division works very well on MIC input with AudioRecord.

Where am I doing wrong? (and yes, I know there is a direct fft output)

It would be good if you could include a screenshot of the spectrum. However, it is indeed possible that your problem is caused by a misinterpretation of the audio format. It could be ENCODING_PCM_16BIT, or perhaps even ENCODING_PCM_FLOAT. Depends how your .mp3 decoder is configured. Could even be stereo. – greeble31 Sep 2, 2018 at 15:33 @greeble31 I'm using MediaPlayer() linked with Visualizer, there are no audio format settings in MediaPlayer. Also the Visualizer has no format options. Should I use AudioTrack instead? – Phillip Sep 2, 2018 at 18:49 Scratch that. Docs say it's 8-bit unsigned mono. My bad. Could you add a dump of a few hundred consecutive samples of waveform to your question so we can have a look at the data? And, are you staying within getCaptureSize()? – greeble31 Sep 2, 2018 at 19:05 Oops I missed something else: You're doing an implicit unsigned-to-signed conversion. Replace (double) waveform[i] with (double) (waveform[i] & 0xFF) and try again. If that doesn't work, then yes, capture some data. Preferably closer to the 20KHz end. – greeble31 Sep 2, 2018 at 19:41 Briefly: For a scale of -1..1, do raw[i] = (raw[i] - 128) / 128. It's your preference; you're using logs, so you have extremely high dynamic range, and the scaling really won't matter much. For the MIC, I think you're doing it right, b/c it appears to be a signed array, biased around 0. No further ANDing is necessary. Have fun. – greeble31 Sep 2, 2018 at 20:14

The input audio is 8-bit unsigned mono. The line raw[i] = (double) waveform[i] causes an unintentional unsigned-to-signed conversion, and since raw is biased to approximately a 128 DC level, a small sine wave ends up getting changed into a high-amplitude modified square wave, as the signal crosses the 127/-128 boundary. That causes a bunch of funny harmonics (which caused the "symmetric lines coming and going" you were talking about).

Solution

Change to (double) (waveform[i] & 0xFF) so that the converted value lies in the range 0..255, instead of -128..127.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.