使用portaudio为声卡提供多音频音调

时间:2012-09-27 01:48:06

标签: audio portaudio

我正在尝试为声卡生成音调(频率:1950赫兹,持续时间:40毫秒,水平:-30分贝,右声道(立体声),在蒸汽1上)。最后,我想播放其中两种音调(一种进入通道1,另一种进入通道2)。

非常感谢任何帮助或指示。

谢谢, DW


嗨Bjorn,我试过这个,但我没有得到我期待的频率(加上似乎声音不干净)。有什么想法有什么不对吗? 我非常感谢任何帮助。

#define SAMPLE_RATE   (44100)
#define TABLE_SIZE   (200)
float FREQUENCY = 422;

...
for(int i=0; i<TABLE_SIZE; i++ )
{
    data.sine[i] = (float) sin( (double)i * ((2.0 * M_PI)/(double)SAMPLE_RATE) * FREQUENCY );
}

data.left_phase = 0;
data.right_phase = 0;
...

... in callback function ...
for(unsigned long i = 0; i < framesPerBuffer; i++ )
{   

  // fill output buffer with sin wave
  *out++ = data->amp * data->sine[data->left_phase];  // left     
  *out++ = data->amp * data->sine[data->right_phase]; // right                  

  data->left_phase += 1;    

  if( data->left_phase >= TABLE_SIZE ) 
    data->left_phase -= TABLE_SIZE;           

  data->right_phase += 1; 

  if( data->right_phase >= TABLE_SIZE ) 
    data->right_phase -= TABLE_SIZE;
} 

1 个答案:

答案 0 :(得分:1)

PortAudio有用于生成音调的示例代码,您只需要计算出频率。例如,见答案:

[portaudio]Transmit and Detect frequency - Windows

更新

不是试图存储正弦数据表,而是使用以下公式计算回调中的正弦值:

幅度[n] = sin(n * desiredFreq * 2 * pi / samplerate)

所以(未经测试)你的代码看起来像这样:

typedef struct
{
    long n;
} MyData;

float FREQUENCY = 422;

static int MyCallback(  
                    const void *inputBuffer, 
                    void *outputBuffer,
                    unsigned long framesPerBuffer,
                    const PaStreamCallbackTimeInfo* timeInfo,
                    PaStreamCallbackFlags statusFlags,
                    void *userData 
                  )
{   
    MyData *data = (MyData*)userData;
    float *out = (float*)outputBuffer;    

    (void) timeInfo; /* Prevent unused variable warnings. */
    (void) statusFlags;
    (void) inputBuffer;     

    for(unsigned long i = 0; i < framesPerBuffer; i++ )
    {               
        // fill output buffer with sin wave
        float v = sin( data->n * FREQUENCY * 2 * PI / (float) SAMPLERATE )
        *out++ = v; // left         
        *out++ = v; // right
    }   

    return paContinue;
}

这段代码并非没有问题:例如。最终n将“环绕”并且我不确定当输入变大时罪是否仍然准确和有效。不过这是一个很好的起点,如果你只需要在现代硬件上产生几秒钟的音调,这就是你真正需要的。如果您需要更高级的东西,请先使用它,然后您可以担心使用LUT使其更高效和更强大。