2011-01-26 12 views
5

Utilizzo il framework Accelerate per eseguire una trasformazione Fast Fourier (FFT) e sto cercando di trovare un modo per creare un buffer da utilizzare con una lunghezza di 1024. Ho accesso al picco e al picco medio di un segnale su cui voglio fare la FFT.Come si imposta un buffer quando si esegue un FFT utilizzando il framework Accelerate?

Qualcuno può aiutarmi o darmi qualche suggerimento per farlo?

+2

In una delle sessioni WWDC2010 su Accelerate.Framework hanno parlato di questo. Potrei sbagliarmi ma * probabilmente * c'è un esempio a riguardo. Ad ogni modo, dovresti dare un'occhiata al riferimento Accelerate.Framework, ci sono funzioni molto utili per fare ciò che vuoi;) – nacho4d

+0

Puoi dare un'occhiata alle risposte a [questa domanda StackOverflow] (http://stackoverflow.com/questions/ 3398753/using-the-apple-fft-and-accelerate-framework "questa domanda di overflow dello stack"). Un buon numero di buoni esempi sono forniti dall'utilizzo del framework Accelerate di Apple per generare un FFT di audio. – rcw3

risposta

12

Apple ha alcuni esempi su come impostare FFT nel loro vDSP Programming Guide. Dovresti anche dare un'occhiata all'applicazione di esempio vDSP Examples. Mentre per il Mac, questo codice dovrebbe essere tradotto direttamente su iOS.

Recentemente ho bisogno di fare una semplice FFT di una forma d'onda di ingresso 64 intero, per cui ho usato il codice seguente:

static FFTSetupD fft_weights; 
static DSPDoubleSplitComplex input; 
static double *magnitudes; 

+ (void)initialize 
{ 
    /* Setup weights (twiddle factors) */ 
    fft_weights = vDSP_create_fftsetupD(6, kFFTRadix2); 

    /* Allocate memory to store split-complex input and output data */ 
    input.realp = (double *)malloc(64 * sizeof(double)); 
    input.imagp = (double *)malloc(64 * sizeof(double)); 
    magnitudes = (double *)malloc(64 * sizeof(double)); 
} 

- (CGFloat)performAcceleratedFastFourierTransformAndReturnMaximumAmplitudeForArray:(NSUInteger *)waveformArray; 
{ 
    for (NSUInteger currentInputSampleIndex = 0; currentInputSampleIndex < 64; currentInputSampleIndex++) 
    { 
     input.realp[currentInputSampleIndex] = (double)waveformArray[currentInputSampleIndex]; 
     input.imagp[currentInputSampleIndex] = 0.0f; 
    } 

    /* 1D in-place complex FFT */ 
    vDSP_fft_zipD(fft_weights, &input, 1, 6, FFT_FORWARD); 

    input.realp[0] = 0.0; 
    input.imagp[0] = 0.0; 

    // Get magnitudes 
    vDSP_zvmagsD(&input, 1, magnitudes, 1, 64); 

    // Extract the maximum value and its index 
    double fftMax = 0.0; 
    vDSP_maxmgvD(magnitudes, 1, &fftMax, 64); 

    return sqrt(fftMax); 
} 

Come si può vedere, ho usato solo i valori reali in questo FFT per impostare su i buffer di input, eseguita la FFT, e quindi leggere le grandezze.

+0

thx, che ha aiutato molto. – Kiwi

+1

Grazie - questo è un esempio molto più semplice di altri che ho visto (dove eseguono per lo più una FFT inversa subito dopo). Molto utile come ho potuto vedere quali sono i bit minimi di cui avevo bisogno per il mio problema! –

+1

Metti solo indici di ampiezza d'onda a valori reali. Dovrebbe essere zero? Non è chiaro per me. Perché non stai usando la funzione CTOZ? thx –

Problemi correlati