来自 portAudio 流的样本的 FFT

Posted

技术标签:

【中文标题】来自 portAudio 流的样本的 FFT【英文标题】:FFT of samples from portAudio stream 【发布时间】:2014-11-06 10:35:08 【问题描述】:

这里是初学者,(OSX 10.9.5,Xcode 6)

我有一个会发出噪音的 portAudio 流。现在我想获取回调中生成的那些随机值并通过 fftw 计划运行它们。据我所知,fftw需要在main中执行。那么我怎样才能显示从回调到主的数字呢?我觉得它与指针有关,但这是一个非常没有根据的猜测......

我在加入两个不同的库时遇到了一些困难。非常感谢您的帮助,谢谢!

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

【问题讨论】:

【参考方案1】:

您可以尝试在“阻塞写入”模式下运行流,而不是使用回调。要使用此模式,您为Pa_OpenDefaultStreamstreamCallback 参数传递NULL,然后在循环中不断调用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);

【讨论】:

以上是关于来自 portAudio 流的样本的 FFT的主要内容,如果未能解决你的问题,请参考以下文章

iOS 如何从歌曲(ipod 库)中获取音频样本?

什么是样本格式?

使用 Matlab FFT 计算的频谱对于不同长度的样本(点数相同但 Fs 不同)给出的结果不一致?

将 FFT 应用于 1024 个样本的每个块

Numpy fft 冻结更长的样本

采样率和可变长度输入样本与固定大小的 FFT 输入有何关系?