Настройте структуру ускорителя для fft на iPhone

Я установил функцию для настройки ускорителя после того, как прочитал:

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

iPhone FFT с Accelerate framework vDSP

и документы Apple.

я сделал это :

void fftSetup()
{

    COMPLEX_SPLIT   A;
    FFTSetup        setupReal;
    uint32_t        log2n;
    uint32_t        n, nOver2;
    int32_t         stride;
    uint32_t        i;
    float          *originalReal, *obtainedReal;
    float           scale;
    uint32_t L = 1024;
    float *mag = new float[L/2];


     log2n = 10 ;
     n = 1 << log2n;
     stride = 1;
     nOver2 = n / 2;

    printf("1D real FFT of length log2 ( %d ) = %d\n\n", n, log2n);

    for (i = 0; i < n; i++)
        originalReal[i] = (float) (i + 1);


    vDSP_ctoz((COMPLEX *) originalReal,2,&A,1,nOver2);

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

    setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);

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




    //get magnitude;
    for(i = 1; i < L/2; i++){
        mag[i] = sqrtf(A.realp[i]*A.realp[i] + A.imagp[i] * A.imagp[i]);
    }





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


}

вопросы:

  1. мое приложение всегда вылетает без ошибок (ПЛОХОЙ ДОСТУП) в одной из этих двух строк:

originalReal[i] = (с плавающей запятой) (i + 1); // или

vDSP_ctoz((COMPLEX *) originalReal,2,&A,1,nOver2);

Я думаю, я не установил хорошее значение для log2n? (10, чтобы получить окно 1024?)

  • как я могу получить реальную величину бункеров? мой настоящий фф? то же самое я написал здесь?

  • где я могу ввести МОЙ буферный массив данных (где именно в моем коде? вместо originalReal?)

большое спасибо.


person Curnelious    schedule 02.01.2013    source источник
comment
возможный дубликат Использование ускорителя для БПФ в аудиобуфере   -  person Paul R    schedule 02.01.2013


Ответы (1)


Мне действительно удается заставить его работать, когда я вставляю в него синусоидальную волну определенной f.

Это код:

   COMPLEX_SPLIT   A;
    FFTSetup        setupReal;
    uint32_t        log2n;
    uint32_t        n, nOver2;
    int32_t         stride;
    uint32_t        i;
    float          *originalReal, *obtainedReal;
    float           scale;
    uint32_t L = 1024;
    float *mag = new float[L/2];


     log2n = 10 ;
     n = 1 << log2n;
     stride = 1;
     nOver2 = n / 2;

    //printf("1D real FFT of length log2 ( %d ) = %d\n\n", n, log2n);

    A.realp = (float *) malloc(nOver2 * sizeof(float));
    A.imagp = (float *) malloc(nOver2 * sizeof(float));
    originalReal = (float *) malloc(n * sizeof(float));
    obtainedReal = (float *) malloc(n * sizeof(float));

     for (i = 0; i < n; i++)
         originalReal[i] = cos(2*3.141592*11000*i/44100);//(float) (i + 1);


    vDSP_ctoz((COMPLEX *) originalReal,2,&A,1,nOver2);



    setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);

    vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);
    //vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_INVERSE);

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


    //get magnitude;
    for(i = 1; i < L/2; i++)
    {
        mag[i] = sqrtf(A.realp[i]*A.realp[i] + A.imagp[i] * A.imagp[i]);
           NSLog(@"%d:%f",i,mag[i]);
    }

На самом деле это не 44 Гц между бинами, как написал парень в посте выше! но 43! 22050/512=43 . это критично! потому что в более высоких ячейках, таких как ячейка [300], вы получите совершенно другой результат для 44 и 43! (дрейф 300 Гц). так что позаботьтесь об этом.

person Curnelious    schedule 02.01.2013