Android Visualizer FFT 数据取决于体积

Posted

技术标签:

【中文标题】Android Visualizer FFT 数据取决于体积【英文标题】:Android Visualizer FFT Data is Dependent on Volume 【发布时间】:2019-09-03 18:30:57 【问题描述】:

我正在为使用 android Visualizer 类的 Unity 应用程序编写插件。我正在使用getFft() function 和那里提供的代码来获取 FFT 幅度。返回的值取决于音量 - 音量越大,值越高,音量越低。

这是我初始化 Visualizer 的构造函数:

private PluginClass() 
    errors = new int[2];
    int size = Visualizer.getCaptureSizeRange()[1];

    // Equalizer
    Equalizer mEqualizer = new Equalizer(0, 0);

    // Visualizer
    this.visualizer = new Visualizer(0);
    this.visualizer.setEnabled(false);
    mEqualizer.setEnabled(true);
    this.visualizer.setCaptureSize(size);
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
       this.visualizer.setScalingMode(SCALING_MODE_NORMALIZED);
       this.visualizer.setMeasurementMode(MEASUREMENT_MODE_PEAK_RMS);
    
    this.visualizer.setEnabled(true);

    this.waveFormData = new byte[size];
    this.fftData = new byte[size];

我正在设置均衡器(我在 Visualizer 创建之前、创建之后但在它被禁用之前、在它被禁用之后,几乎全部都调用过 setEnabled)。

缩放模式设置为标准化,当我调用getScalingMode()时可以确认确实设置为SCALING_MODE_NORMALIZED

有人知道为什么会这样吗?在这个问题的另一个副本中,没有解释,一个答案说使用setVolumeControlStream(AudioManager.STREAM_MUSIC);。我试过这个没有用,但我不明白为什么它会起作用。

OP 已经放弃了他们之前提出过这个问题的问题,回答者提出了待解决的问题,并且没有提供代码,所以我不得不打开这个问题。这样,我还可以为问题添加赏金。

我在 VR 模式下运行应用程序,以防这是 ​​VR 和 Android Java 和 Unity 不能很好地配合使用的一些模糊错误。

谢谢!

编辑这是我用来实际生成 FFT 幅度的代码:

public float[] getFftMagnitudes() 
    this.errors[0] = this.visualizer.getFft(this.fftData);
    int n = this.fftData.length;
    float[] magnitudes = new float[n / 2 + 1];
    magnitudes[0] = (float)Math.abs(this.fftData[0]);      // DC
    magnitudes[n / 2] = (float)Math.abs(this.fftData[1]);  // Nyquist
    for (int k = 1; k < n / 2; k++) 
        int i = k * 2;
        magnitudes[k] = (float)Math.hypot(this.fftData[i], this.fftData[i + 1]);
    
    return magnitudes;

【问题讨论】:

只是检查一下:size 是否与您运行的所有代码相同? @Ichneumwn 是的,虽然我尝试过使用不同的 2 次幂但无济于事 再看一遍,真正的问题可能是getFft() 如何将其结果拟合为 8 位整数。它必须进行一些与数据相关的缩放(不同于之前讨论的 1/N,也不同于音频音量归一化)......我可以想象它会做一些类似缩放 127/max(浮点 FFT 的大小)的事情) .猜猜工作对你没有帮助:( 【参考方案1】:

一些 FFT 实现(例如 FFTW)不规范其结果。因此,如果您有一个数组 x,请将其转换为傅立叶空间 x',然后返回您不会得到原始结果。在 FFTW 的情况下,您必须除以数组的长度。这是一个很长的镜头,但你的问题听起来非常熟悉。

【讨论】:

这就是我问size的原因 - 如果相同,那么FFT的标准化(或缺乏标准化)无关紧要 另外:您是否检查过标准化缩放模式是否也适用于 FFT 函数。归一化可能是针对其他数量的。 根据文档,它使音量正常化。这就是 OP 似乎在问的问题:尽管音量正常化,但他得到了不同的结果。 FFT 的标准化不会成为问题,除非音频序列的size(长度)恰好随音量变化。 傅里叶变换的输入是否有可能没有被归一化,但是如果你向类请求音频输入,它会传递归一化的音频信号? @MPIchael 您是说将 FFT 幅度数组中的每个值除以数组的长度吗?编辑:刚刚尝试过,它似乎不起作用:(

以上是关于Android Visualizer FFT 数据取决于体积的主要内容,如果未能解决你的问题,请参考以下文章

初始化 Visualizer 时的 Android 错误代码 -3

Android 音频可视化 Visualizer

wav 的 Audio Visualizer 看起来不对

如何在android中录制音频时做Visualizer

android.media.audiofx.Visualizer 每隔一段时间就会抛出异常

致命信号 11 android Visualizer