iPhone FFT с фреймворком Accelerate vDSP

У меня проблемы с реализацией БПФ с использованием vDSP. Я понимаю теорию, но ищу конкретный пример кода, пожалуйста.

У меня есть данные из файла wav, как показано ниже:

Вопрос 1. Как мне поместить аудиоданные в БПФ?

Вопрос 2. Как мне получить выходные данные из БПФ?

Вопрос 3. Конечная цель - проверить низкочастотные звуки. Как мне это сделать?

-(OSStatus)open:(CFURLRef)inputURL{
OSStatus result = -1;

result = AudioFileOpenURL (inputURL, kAudioFileReadPermission, 0, &mAudioFile);
if (result == noErr) {
    //get  format info
    UInt32 size = sizeof(mASBD);

    result = AudioFileGetProperty(mAudioFile, kAudioFilePropertyDataFormat, &size, &mASBD);

    UInt32 dataSize = sizeof packetCount;
    result = AudioFileGetProperty(mAudioFile, kAudioFilePropertyAudioDataPacketCount, &dataSize, &packetCount);
    NSLog([NSString stringWithFormat:@"File Opened, packet Count: %d", packetCount]);

    UInt32 packetsRead = packetCount;
    UInt32 numBytesRead = -1;
    if (packetCount > 0) { 
        //allocate  buffer
        audioData = (SInt16*)malloc( 2 *packetCount);
        //read the packets
        result = AudioFileReadPackets (mAudioFile, false, &numBytesRead, NULL, 0, &packetsRead,  audioData); 
        NSLog([NSString stringWithFormat:@"Read %d  bytes,  %d packets", numBytesRead, packetsRead]);
    }
}
return result;
}

Код FFT ниже:

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

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

/* Allocate memory for the input operands and check its availability,
 * use the vector version to get 16-byte alignment. */

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

if (originalReal == NULL || A.realp == NULL || A.imagp == NULL) {
printf("\nmalloc failed to allocate memory for  the real FFT"
"section of the sample.\n");
exit(0);
}

/* Generate an input signal in the real domain. */
for (i = 0; i < n; i++)

    originalReal[i] = (float) (i + 1);

/* Look at the real signal as an interleaved complex vector  by
 * casting it.  Then call the transformation function vDSP_ctoz to
 * get a split complex vector, which for a real signal, divides into
 * an even-odd configuration. */

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

/* Set up the required memory for the FFT routines and check  its
 * availability. */

setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);

if (setupReal == NULL) {

printf("\nFFT_Setup failed to allocate enough memory  for"
"the real FFT.\n");

exit(0);
}

/* Carry out a Forward and Inverse FFT transform. */
vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);
vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_INVERSE);

/* Verify correctness of the results, but first scale it by  2n. */
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);

/* The output signal is now in a split real form.  Use the  function
 * vDSP_ztoc to get a split real vector. */
vDSP_ztoc(&A, 1, (COMPLEX *) obtainedReal, 2, nOver2);

/* Check for accuracy by looking at the inverse transform  results. */
Compare(originalReal, obtainedReal, n);

Спасибо

10
задан Paul R 15 June 2011 в 14:15
поделиться