Comment lire et lire le file audio PCM .caf

J'ai une application qui sélectionne une chanson de la bibliothèque de l'iPod, puis copy cette chanson dans le directory de l'application en tant que file '.caf'. J'ai maintenant besoin de jouer et en même time lire ce file dans Apple FFT à partir de la structure Accelerate afin que je puisse visualiser datatables comme un spectrogramme. Voici le code de la FFT:

void FFTAccelerate::doFFTReal(float samples[], float amp[], int numSamples) { int i; vDSP_Length log2n = log2f(numSamples); //Convert float array of reals samples to COMPLEX_SPLIT array A vDSP_ctoz((COMPLEX*)samples,2,&A,1,numSamples/2); //Perform FFT using fftSetup and A //Results are returned in A vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD); //Convert COMPLEX_SPLIT A result to float array to be returned amp[0] = A.realp[0]/(numSamples*2); for(i=1;i<numSamples;i++) amp[i]=sqrt(A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i])/numSamples; } //Constructor FFTAccelerate::FFTAccelerate (int numSamples) { vDSP_Length log2n = log2f(numSamples); fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2); int nOver2 = numSamples/2; A.realp = (float *) malloc(nOver2*sizeof(float)); A.imagp = (float *) malloc(nOver2*sizeof(float)); } 

Ma question est de savoir comment faire une boucle dans le file audio '.caf' pour alimenter la FFT tout en jouant la chanson? J'ai seulement besoin d'un canal. Im devinant que j'ai besoin d'get 1024 échantillons de la chanson, le traiter dans la FTT, puis aller plus loin dans le file et prendre encore 1024 échantillons. Mais je ne comprends pas comment lire un file audio pour le faire. Le file a un taux d'échantillonnage de 44100.0 hz, est en format PCM linéaire, 16 bits et je crois est également entrelacé si cela aide …

Essayez l'API ExtendedAudioFile (nécessite AudioToolbox.framework).

 #include <AudioToolbox/ExtendedAudioFile.h> NSURL *urlToCAF = ...; ExtAudioFileRef caf; OSStatus status; status = ExtAudioFileOpenURL((__bridge CFURLRef)urlToCAF, &caf); if(noErr == status) { // request float format const UInt32 NumFrames = 1024; const int ChannelsPerFrame = 1; // Mono, 2 for Stereo // request float format AudioStreamBasicDescription clientFormat; clientFormat.mChannelsPerFrame = ChannelsPerFrame; clientFormat.mSampleRate = 44100; clientFormat.mFormatID = kAudioFormatLinearPCM; clientFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved; // float int cmpSize = sizeof(float); int frameSize = cmpSize*ChannelsPerFrame; clientFormat.mBitsPerChannel = cmpSize*8; clientFormat.mBytesPerPacket = frameSize; clientFormat.mFramesPerPacket = 1; clientFormat.mBytesPerFrame = frameSize; status = ExtAudioFileSetProperty(caf, kExtAudioFileProperty_ClientDataFormat, sizeof(clientFormat), &clientFormat); if(noErr != status) { /* handle it */ } while(1) { float buf[ChannelsPerFrame*NumFrames]; AudioBuffer ab = { ChannelsPerFrame, sizeof(buf), buf }; AudioBufferList abl; abl.mNumberBuffers = 1; abl.mBuffers[0] = ab; UInt32 ioNumFrames = NumFrames; status = ExtAudioFileRead(caf, &ioNumFrames, &abl); if(noErr == status) { // process ioNumFrames here in buf if(0 == ioNumFrames) { // EOF! break; } else if(ioNumFrames < NumFrames) { // TODO: pad buf with zeroes out to NumFrames } else { float amp[NumFrames]; // scratch space doFFTReal(buf, amp, NumFrames); } } } // later status = ExtAudioFileDispose(caf); if(noErr != status) { /* hmm */ } }