2009-12-27 8 views
4

Je cherche à effectuer un FFT sur un fichier audio PCM linéaire (avec potentiellement plus d'un canal audio) sur OS X. Quelle est la meilleure façon de procéder?Fichier audio FFT dans un environnement OS X

Plusieurs sources ont indiqué que le cadre d'accélération d'Apple est ce dont j'ai besoin. Si oui, comment dois-je extraire et préparer correctement les données à virgule flottante à utiliser dans ces fonctions FFT?

Répondre

6

Voici à peu près ce que vous voulez faire. Remplissez vos propres fonctions d'entrée et de sortie.

// Stick new data into inData, a (float*) array 
    fetchFreshData(inData); 

    // (You might want to window the signal here...) 
    doSomeWindowing(inData); 

    // Convert the data into a DSPSplitComplex 
    // Pardon the C++ here. Also, you should pre-allocate this, and NOT 
    // make a fresh one each time you do an FFT. 
    mComplexData = new DSPSplitComplex; 
    float *realpart = (float *)calloc(mNumFrequencies, sizeof(float)); 
    float *imagpart = (float *)calloc(mNumFrequencies, sizeof(float)); 
    mComplexData->realp = realpart; 
    mComplexData->imagp = imagpart; 

    vDSP_ctoz((DSPComplex *)inData, 2, mComplexData, 1, mNumFrequencies); 

    // Calculate the FFT 
    // (I'm assuming here you've already called vDSP_create_fftsetup()) 
    vDSP_fft_zrip(mFFTSetup, mComplexData, 1, log2f(mNumFrequencies), FFT_FORWARD); 

    // Don't need that frequency 
    mComplexData->imagp[0] = 0.0; 

    // Scale the data 
    float scale = (float) 1.0/(2 * (float)mSignalLength); 
    vDSP_vsmul(mComplexData->realp, 1, &scale, mComplexData->realp, 1, mNumFrequencies); 
    vDSP_vsmul(mComplexData->imagp, 1, &scale, mComplexData->imagp, 1, mNumFrequencies); 

    // Convert the complex data into something usable 
    // spectrumData is also a (float*) of size mNumFrequencies 
    vDSP_zvabs(mComplexData, 1, spectrumData, 1, mNumFrequencies); 

    // All done! 
    doSomethingWithYourSpectrumData(spectrumData); 

Espérons que ça aide.

+0

ce qui est inData, pouvez-vous s'il vous plaît expliquer –

0

Il me semble que vous devriez regarder dans Core Audio ... Je ne suis pas très familier avec cela, mais il semble qu'il devrait déjà désentrelacer le canal pour vous, et cela fonctionne directement avec les données PCM. En raison de ma faible familiarité, prenez ceci avec un grain de sel, mais j'essaierais de placer la FFT dans une unité audio, en prenant un seul canal de données PCM en entrée, en stockant les résultats de la FFT quelque part et en passant l'entrée jusqu'à la sortie.

En ce qui concerne l'exécution réelle de la FFT, le principal défi semble, selon moi, être de contraindre l'entrée PCM au vecteur double * contre lequel la routine FFT veut opérer. En regardant à travers vDSP.h (une partie de la structure d'accélération), je vois des fonctions comme vDSP_vflt16D (pour convertir un vecteur d'entiers de 16 bits en un vecteur de nombres réels à double précision), ce qui semble résoudre votre problème.

Core Audio Introduction

+0

vDSP_vflt16 effectue le travail de conversion de ces entiers de 16 bits en flottants de 32 bits, mais je crains que cela ne suffise pas. J'ai besoin de convertir ces valeurs en nombres complexes à virgule flottante de 32 bits. – Anonymous

3

Lorsque vous effectuez une FFT sur les données audio, les échantillons doivent aller dans la partie réelle et la partie imaginaire devrait être nul.

La plupart des bibliothèques FFT, y compris le vDSP d'Apple, incluent une méthode appelée «FFT réelle», où l'entrée est réelle (pas de composant imaginaire) et la sortie est complexe.