Cooley-Tukey FFT算法和Portaudio

时间:2018-08-07 17:12:07

标签: c signal-processing fft portaudio

我实现了上述算法(https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm)。 这是完整的工作代码。 我在非交错立体声回调中从麦克风接收流输入。 然后我用输入样本填充缓冲区,并将该缓冲区处理为fft和ifft 功能。 最后,我使用指针将处理后的缓冲区发送到输出。 我使用Asio4all V2。 我真的不明白问题出在哪里,因为它确实可以正常工作,但是我无法超越N = 16或输出听起来断断续续。

非常感谢。

回调+主:

#include <stdio.h>
#include <stdlib.h>

#include "portaudio.h"
#include "FFT.h"

#define SAMPLE_RATE   (44100)
#define FRAMES_PER_BUFFER  (64)
#define NUM_SECONDS   (10)

typedef struct
{
}
paTestData;

static int patestCallback(  void *INbuffers[2], void *OUTbuffers[2],
                            unsigned long framesPerBuffer,
                            const PaStreamCallbackTimeInfo* timeInfo,
                            PaStreamCallbackFlags statusFlags,
                            void *userData )
{
    paTestData *data = (paTestData*)userData;

    float *inL  = (float *) INbuffers [0];
    float *inR  = (float *) INbuffers [1];
    float *outL = (float *) OUTbuffers[0];
    float *outR = (float *) OUTbuffers[1];

    unsigned long i;

    (void) timeInfo; 
    (void) statusFlags;

    for( i=0; i<framesPerBuffer; i++ )
    {
        for(int i=0; i<N; i++)
        {
            Y[i] = *inL + 0*I;
        }
        *inL++;

        fft(Y, N);
        ifft(Y, N);

        for(int i=0; i<N; i++)
        {
            p_out=&Y[i];
        }

        *outL++ = *p_out++;
        *outR++ = *p_out++;
    }

    return paContinue;
}



int main()
{
    PaStreamParameters inputParameters;
    PaStreamParameters outputParameters;
    PaStream *stream;
    paTestData data;

    Pa_Initialize();

    inputParameters.device = Pa_GetDefaultInputDevice();
    inputParameters.channelCount = 2;
    inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
    inputParameters.suggestedLatency = 0;
    inputParameters.hostApiSpecificStreamInfo = NULL;

    outputParameters.device = Pa_GetDefaultOutputDevice();
    outputParameters.channelCount = 2;
    outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
    outputParameters.suggestedLatency = 0;
    outputParameters.hostApiSpecificStreamInfo = NULL;

    Pa_OpenStream( &stream,
                   &inputParameters,
                   &outputParameters,
                   SAMPLE_RATE,
                   FRAMES_PER_BUFFER,
                   paClipOff,
                   patestCallback,
                   &data );

    Pa_StartStream( stream );

    Pa_Sleep( NUM_SECONDS * 1000);

    Pa_StopStream( stream );

    Pa_CloseStream( stream );
}

标题:

#ifndef FFT_H_INCLUDED
#define FFT_H_INCLUDED



#include <stdio.h>
#include <math.h>
#include <complex.h>

#define N (16)

complex Y[N];
complex *p_out;



void separate (complex *a, int n)
{
    complex b[N/2];

    for(int i=0; i<n/2; i++) // copy all odd elements to b
        b[i] = a[i*2+1];

    for(int i=0; i<n/2; i++) // copy all even elements to lower-half of a[]
        a[i] = a[i*2];

    for(int i=0; i<n/2; i++) // copy all odd (from heap) to upper-half of a[]
        a[i+n/2] = b[i];
}



complex fft(complex *X, int m)   // forward fft
{
    if(m < 2) {
        // bottom of recursion.
        // Do nothing here, because already X[0] = x[0]
    } else {

    separate(X, m);        // all evens to lower half, all odds to upper half

    fft(X, m/2);           // recurse even items
    fft(X+m/2, m/2);       // recurse odd  items

    for(int k=0; k<m/2; k++)    // combine results of two half recursions
    {
        complex e = X[k    ];   // even
        complex o = X[k+m/2];   // odd

        complex w = cexp( 0 + (-2.*M_PI*k/m)*I ); // w is the twiddle-factor

        X[k    ] = e + w * o;
        X[k+m/2] = e - w * o;
    }
    }
}



float ifft(complex *X, int m)   // inverse fft
{
    for (int i=0; i<m; i++)   
    {
        X[i]=conj(X[i]);        // conjugate the complex array  
    }

    fft(X, m);                  // forward fft                

    for (int i=0; i<m; i++)   
    {
        X[i]=conj(X[i]);        // conjugate the complex array again
    }

    for (int i=0; i<m; i++)   
    {
        X[i] /= m;              // scale the numbers
    }
}



#endif // FFT_H_INCLUDED

0 个答案:

没有答案