iOS FFT Draw спектра

прочитал эти вопросы:

Использование Apple FFT и Accelerate Framework

Как настроить буфер при выполнении FFT с использованием инфраструктуры ускорения?

iOS FFT Accerelate.framework рисует спектр во время воспроизведения

Все они описывают, как настроить fft с помощью ускорителя. С их помощью мне удалось настроить FFT и получить базовый анализатор спектра. Прямо сейчас ям отображает все значения, которые я получил от БПФ. Тем не менее, я хочу показать только 10-15, или переменное число баров, воссоздающих определенные частоты. Так же, как измеритель уровня iTunes или WinAmp. 1. Нужно ли усреднять значения величин из диапазона частот? Или они просто показывают вам величину для определенной полосы частот? 2. Кроме того, мне нужно преобразовать мои значения величины в дБ? 3. Как мне сопоставить мои данные с определенным диапазоном. Я сопоставляю с максимальным диапазоном дБ для моих звуков bitdepth? Получение максимального значения для корзины приведет к скачку максимальных значений сопоставления.

Мой RenderCallback:

static OSStatus PlaybackCallback(void *inRefCon,
                                 AudioUnitRenderActionFlags *ioActionFlags,
                                 const AudioTimeStamp *inTimeStamp,
                                 UInt32 inBusNumber,
                                 UInt32 inNumberFrames,
                                 AudioBufferList *ioData)
{
    UInt32 maxSamples = kAudioBufferNumFrames;

    UInt32 log2n = log2f(maxSamples); //bins
    UInt32 n = 1 < log2n;

    UInt32 stride = 1;
    UInt32 nOver2 = n/2;

    COMPLEX_SPLIT   A;
    float          *originalReal, *obtainedReal, *frequencyArray, *window, *in_real;

    in_real = (float *) malloc(maxSamples * sizeof(float));

    A.realp = (float *) malloc(nOver2 * sizeof(float));
    A.imagp = (float *) malloc(nOver2 * sizeof(float));
    memset(A.imagp, 0, nOver2 * sizeof(float));

    obtainedReal = (float *) malloc(n * sizeof(float));
    originalReal = (float *) malloc(n * sizeof(float));
    frequencyArray = (float *) malloc(n * sizeof(float));

    //-- window

    UInt32 windowSize = maxSamples;
    window = (float *) malloc(windowSize * sizeof(float));

    memset(window, 0, windowSize * sizeof(float));
    //    vDSP_hann_window(window, windowSize, vDSP_HANN_DENORM);

    vDSP_blkman_window(window, windowSize, 0);

    vDSP_vmul(ioBuffer, 1, window, 1, in_real, 1, maxSamples);

    //-- window

    vDSP_ctoz((COMPLEX*)in_real, 2, &A, 1, maxSamples/2);

    vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);
    vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_INVERSE);

    float scale = (float) 1.0 / (2 * n);

    vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, nOver2);
    vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, nOver2);

    vDSP_ztoc(&A, 1, (COMPLEX *) obtainedReal, 2, nOver2);
    vDSP_zvmags(&A, 1, obtainedReal, 1, nOver2);

    Float32 one = 1;
    vDSP_vdbcon(obtainedReal, 1, &one, obtainedReal, 1, nOver2, 0);

    for (int i = 0; i < nOver2; i++) {
        frequencyArray[i] = obtainedReal[i];
    }


    // Extract the maximum value
    double fftMax = 0.0;
    vDSP_maxmgvD((double *)obtainedReal, 1, &fftMax, nOver2);

    float max = sqrt(fftMax);
}

Ответы на вопрос(1)

Ваш ответ на вопрос