0

我正在尝试为声卡生成音调(频率: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;
} 
4

1 回答 1

1

PortAudio 有生成音调的示例代码,你只需要弄清楚频率。例如看这个答案:

[portaudio]传输和检测频率 - Windows

更新:

无需尝试存储正弦数据表,只需使用以下公式计算回调中的正弦值:

幅度[n] = sin(n * desiredFreq * 2 * pi / 采样率)

因此(未经测试)您的代码将如下所示:

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 将“环绕”,我不确定随着输入变大, sin 是否仍然准确和有效。尽管如此,这是一个很好的起点,如果您只需要在现代硬件上生成几秒钟的音调,这确实是您所需要的。如果您需要更高级的东西,请先使其工作,然后您可以担心使用 LUT 使其更高效和更强大。

于 2012-09-28T02:20:41.730 回答