了解 onWaveFormDataCapture 字节数组格式
Understanding onWaveFormDataCapture byte array format
我正在分析 Android 上的音频信号。首先尝试使用 MIC 并成功。现在我正在尝试对来自 Visualizer.OnDataCaptureListener
的 * 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 输出)
输入音频为 8 位无符号单声道。 raw[i] = (double) waveform[i]
行导致无意的无符号到有符号转换,并且由于 raw
偏置到大约 128 DC 电平,小正弦波最终变成高振幅修正方波,当信号穿过 127/-128 边界时。这导致了一堆有趣的谐波(这导致了你正在谈论的 "symmetric lines coming and going")。
解决方案
更改为 (double) (waveform[i] & 0xFF)
以便转换后的值位于 0..255 范围内,而不是 -128..127.
我正在分析 Android 上的音频信号。首先尝试使用 MIC 并成功。现在我正在尝试对来自 Visualizer.OnDataCaptureListener
的 * 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 输出)
输入音频为 8 位无符号单声道。 raw[i] = (double) waveform[i]
行导致无意的无符号到有符号转换,并且由于 raw
偏置到大约 128 DC 电平,小正弦波最终变成高振幅修正方波,当信号穿过 127/-128 边界时。这导致了一堆有趣的谐波(这导致了你正在谈论的 "symmetric lines coming and going")。
解决方案
更改为 (double) (waveform[i] & 0xFF)
以便转换后的值位于 0..255 范围内,而不是 -128..127.