了解onWaveFormDataCapture字节数组格式

时间:2018-09-02 09:52:43

标签: android signal-processing mp3 visualizer

我正在分析Android上的音频信号。第一次尝试与MIC并成功。现在,我尝试对来自Visualizer.OnDataCaptureListener的{​​{3}} onWaveFormDataCapture方法的MP3数据应用FFT,该方法链接到MediaPlayer。有一个称为byte[] waveform的字节数组,当对该数据进行FFT运算时,会发生频谱泄漏或重叠。

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

我试图通过以下for循环中的代码将数据转换为-1..1范围;

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

然后我将raw复制到fft缓冲区中;

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

然后我调用fft函数;

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

最后,我将它们转换为以dB为单位的幅度,然后在屏幕上绘制频率

        // 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]
        }

当我播放20Hz至20kHz的扫描信号时,我看不到MIC上看到的内容。它不会画一条步行线,而会画远或近的几条对称线。可视化器另一端以某种方式存在较弱的对称信号。 使用32768而不是128进行除法的相同代码在带有AudioRecord的MIC输入上效果很好。

我在哪里做错了? (是的,我知道有直接的fft输出)

1 个答案:

答案 0 :(得分:2)

输入音频为8位无符号单声道。 raw[i] = (double) waveform[i]行引起了无意的无符号转换,并且由于raw被偏置到大约128 DC电平,一个小的正弦波最终变成了一个高振幅修正方波,当信号越过127 / -128边界时。这会引起一堆有趣的谐波(导致您正在谈论的“对称线来来去去”)。

解决方案

更改为(double) (waveform[i] & 0xFF),以使转换后的值位于0..255范围内,而不是-128..127。