2011-01-26 7 views
5

Estoy usando el marco Accelerate para realizar una Transformada Rápida de Fourier (FFT), y estoy tratando de encontrar una forma de crear un buffer para usarlo con una longitud de 1024. Tengo acceso al pico y al pico promedio de una señal sobre la cual quiero hacer la FFT.¿Cómo configuro un búfer al hacer una FFT usando el marco Accelerate?

¿Alguien puede ayudarme o darme algunas pistas para hacer esto?

+2

En una de las sesiones de WWDC2010 sobre Accelerate.Framework hablaron sobre eso. Podría estar equivocado, pero * probablemente * hay una muestra sobre eso. De cualquier manera, debe consultar la referencia de Accelerate.Framework, existen funciones muy útiles para hacer lo que desea;) – nacho4d

+0

Es posible que desee consultar las respuestas a [esta pregunta de StackOverflow] (http://stackoverflow.com/questions/ 3398753/using-the-apple-fft-and-accelerate-framework "esta pregunta de desbordamiento de pila"). Se proporcionan una serie de buenos ejemplos del uso del marco Accelerate de Apple para generar una FFT de audio. – rcw3

Respuesta

12

Apple tiene algunos ejemplos de cómo configurar las FFT en su vDSP Programming Guide. También debe verificar la aplicación de ejemplo vDSP Examples. Mientras que para Mac, este código también se debe traducir directamente a iOS.

recientemente que tenía que hacer una FFT sencilla de una forma de onda de entrada 64 número entero, por lo que he utilizado el siguiente código:

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

Como se puede ver, sólo utiliza los valores reales en este FFT para establecer hasta los búferes de entrada, realizó la FFT y luego leyó las magnitudes.

+0

thx, eso ayudó mucho. – Kiwi

+1

Gracias - este es un ejemplo mucho más simple que otros que he visto (donde en su mayoría realizan una FFT inversa inmediatamente después). ¡Muy útil ya que pude ver cuáles son los bits mínimos que necesitaba para mi problema! –

+1

Pone solo los índices de amplitud de onda en valores reales. ¿Debería ser imagp cero? No está claro para mí. ¿Por qué no estás usando la función CTOZ? thx –

Cuestiones relacionadas