2014-11-06 4 views
0

Новичок здесь (OSX 10.9.5, Xcode 6)FFT образцов из Portaudio потока

У меня есть поток Portaudio, который выдает шум. Теперь я хотел бы получить эти случайные значения, сгенерированные в обратном вызове, и запустить их через fftw-план. Насколько мне известно, fftw необходимо выполнить в основном. Итак, как я могу показать числа от обратного вызова к основному? У меня такое чувство, что это имеет какое-то отношение к указателям, но это очень необразованное предположение ...

У меня возникли трудности с присоединением к двум различным библиотекам. Маленькая помощь будет очень признательна, спасибо!

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include "portaudio.h" 
#include "fftw3.h" 



#define NUM_SECONDS (1) 
#define SAMPLE_RATE (44100) 

typedef struct 
{ 
    float left_phase; 
    float right_phase; 
} 
paTestData; 

static int patestCallback(const void *inputBuffer, void *outputBuffer, 
          unsigned long framesPerBuffer, 
          const PaStreamCallbackTimeInfo* timeInfo, 
          PaStreamCallbackFlags statusFlags, 
          void *userData) 
{ 
    /* Cast data passed through stream to our structure. */ 
    paTestData *data = (paTestData*)userData; 
    float *out = (float*)outputBuffer; 
    unsigned int i; 
    (void) inputBuffer; /* Prevent unused variable warning. */ 

    for(i=0; i<framesPerBuffer; i++) 
    { 
     *out++ = data->left_phase; /* left */ 
     *out++ = data->right_phase; /* right */ 

     /* Generate random value that ranges between -1.0 and 1.0. */ 
     data->left_phase = (((float)rand()/(float)(RAND_MAX)) * 2) - 1 ; 

     data->right_phase = (((float)rand()/(float)(RAND_MAX)) * 2) - 1 ; 


     printf("%f, %f\n", data->left_phase, data->right_phase); 
    } 
    return 0; 
} 

/*******************************************************************/ 
static paTestData data; 
int main(void); 
int main(void) 
{ 


    PaStream *stream; 
    PaError err; 


    printf("PortAudio Test: output noise.\n"); 
    /* Initialize our data for use by callback. */ 
    data.left_phase = data.right_phase = 0.0; 
    /* Initialize library before making any other calls. */ 
    err = Pa_Initialize(); 
    if(err != paNoError) goto error; 

    /* Open an audio I/O stream. */ 
    err = Pa_OpenDefaultStream(&stream, 
           0,   /* no input channels */ 
           2,   /* stereo output */ 
           paFloat32, /* 32 bit floating point output */ 
           SAMPLE_RATE, 
           512,  /* frames per buffer */ 
           patestCallback, 
           &data); 
    if(err != paNoError) goto error; 


    err = Pa_StartStream(stream); 
    if(err != paNoError) goto error; 



    /* Sleep for several seconds. */ 
    Pa_Sleep(NUM_SECONDS*1000); 


    err = Pa_StopStream(stream); 
    if(err != paNoError) goto error; 
    err = Pa_CloseStream(stream); 
    if(err != paNoError) goto error; 
    Pa_Terminate(); 
    printf("Test finished.\n"); 
    return err; 
error: 
    Pa_Terminate(); 
    fprintf(stderr, "An error occured while using the portaudio stream\n"); 
    fprintf(stderr, "Error number: %d\n", err); 
    fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); 
    return err; 
} 

ответ

0

Вы можете попробовать запустить поток в режиме «блокировки записи» вместо использования обратного вызова. Чтобы использовать этот режим, вы передаете NULL для параметра streamCallbackPa_OpenDefaultStream, а затем вы непрерывно вызываете Pa_WriteStream в цикле. При необходимости звонок будет блокироваться. Что-то вроде этого псевдокода:

Pa_OpenStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, 512, NULL, NULL); 
Pa_StartStream(stream); 
float interleavedSamples[2*512]; 
for (int i = 0 ; i < SAMPLE_RATE/512 ; i++) // approx 1 second 
{ 
    GenerateNoise(&interleavedSamples, 2, 512, &data); 
    RunFft(interleavedSamples, ...); 
    PaWriteStream(stream, interleavedSamples, 512); 
} 
+0

Это помогло, спасибо! – biduramk