Данные FFT для Android-визуализатора зависят от объема - PullRequest
3 голосов
/ 13 апреля 2019

Я пишу плагин для приложения Unity, использующего класс Android Visualizer .Я использую функцию getFft () и код, предоставленный там, чтобы получить величины FFT.Возвращаемые значения зависят от объема - намного более высокие значения с более высоким объемом и намного более низкие значения с более низким объемом.

Вот мой конструктор, в котором я инициализирую визуализатор:

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

I 'm устанавливаю эквалайзер (я назвал setEnabled до того, как был создан Визуализатор, после того, как он был создан, но до того, как он был отключен, после того, как он был отключен, почти во всем).

Установлен режим масштабированиябыть нормализованным, и когда я звоню getScalingMode(), я могу подтвердить, что оно действительно установлено на SCALING_MODE_NORMALIZED.

У кого-нибудь есть какие-либо идеи относительно того, почему это так?В другом дубликате этого вопроса, без объяснений, один ответ говорит использовать setVolumeControlStream(AudioManager.STREAM_MUSIC);.Я попробовал это безрезультатно, но я не понимаю, почему это все равно будет работать.

ОП отказались от своих вопросов, которые задавали это раньше, с ответами на ожидающие ответы от респондентов и без предоставления кода, поэтомуЯ должен был открыть этот.Таким образом, я также могу добавить награду к вопросу.

Я запускаю приложение в режиме VR на случай, если это какая-то неясная ошибка с VR и Android Java и Unity, которые не очень хорошо играют вместе.

Спасибо!

Редактировать Вот код, который я использую для создания значений БПФ:

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;
}

1 Ответ

2 голосов
/ 24 апреля 2019

некоторые реализации FFT (например, FFTW) не нормируют свои результаты.Таким образом, если у вас есть массив x, преобразуйте его в пространство Фурье x ', а затем обратно вы не получите исходный результат.В случае FFTW вы должны делиться на длину массива.Это длинный выстрел, но ваша проблема звучит до боли знакомо.

...