0

サウンド カードにトーンを生成しようとしています (周波数: 1950 hz、持続時間: 40 ms、レベル: -30 db、右チャンネル (ステレオ)、蒸気 1)。最終的には、これらのトーンを 2 つ再生したいと考えています (1 つはチャンネル 1 に、もう 1 つはチャンネル 2 に行きます)。

どんな助けや指示も大歓迎です。

ありがとう、DW


こんにちはビョルン、私はこれを試しましたが、周波数として期待しているものを取得していません (さらに、音がきれいではないようです)。何が問題なのですか?助けていただければ幸いです。

#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 * 望ましい周波数 * 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 に答える