2012-02-23 25 views
3

私はopencv(オブジェクト認識用)をportaudioと組み合わせて、ビデオ入力に基づいてサウンドを再生しています。基本的に、私の目標は、あるピッチ/周波数の正弦波音を異なる速度で演奏することです。それは動作しますが、その結果は非常に予測不可能です。音声再生が動作しない(プログラムはゆっくり実行されますが動作します)、音声再生が行われない場合もあります。これは私のプログラムが行うことです:PortAudioとOpenCVを使用してオーディオの再生が一貫しないようにするにはどうすればよいですか?

ウェブカメラのフィードを開始 - >画像の領域を選択 - >ビデオフィードに戻る - > while(フレームが存在する) - >オブジェクトの位置を追跡 - >ポートオーディオツールを初期化する - >位置に基づいてサウンドを再生する - > Portaudioツールを終了する

なぜオーディオ再生が矛盾しているのか分かりません。あなたはすべてのヒントを持っていますか?私は周りを読んできましたが、私の考えはこれが待ち時間の問題であることですが、私は本当にこの問題で経験していません。私がopencvなしでportaudioを使用すると、レイテンシの問題は発生しないので、2つを組み合わせることと関係しています。どんな助けもありがとうございます。

while (frame) 
{ 
    cvCopyImage(frame, drawImg); 

    // process 
    track(frame); 

    // get result 
    CvRect r; 
    float confidence; 
    bool valid; 
    /* getRoi tells us if the region being tracked on the screen 
    * is the same region that we chose prior to entering this while loop 
    */ 
    getRoi(&r, &confidence, &valid); 

    // show 
    cvDrawRect(drawImg, cvPoint(r.x, r.y), 
     cvPoint(r.x + r.width - 1, r.y + r.height - 1), 
     valid ? cvScalar(0, 255, 0) : cvScalar(0, 255, 255), 
     2 
    ); 
    writeLogo(drawImg,"USC-IRIS"); 
    int xpos = r.x; 
    int ypos = r.y; 



    cvShowImage("Tracking", drawImg); 
    cout << "valid " << valid << endl; 
    cout << "conf val " << confidence << endl; 
    cout << "xpos, ypos " << xpos << ", " << ypos << endl; 
      //If the region on the screen is the region we chose 
      //then we should play specific sounds 
    if(valid){ 

     sI->soundWrite(xpos, ypos); 
     float freq = sI->getFreq(); 
     int amp = sI->getAmp(); 
     float pulse = sI->getPulse(); 

     switch(amp){ 
      case 0: 
       //printf("Hear sound in both ears.\n"); 
       data.targetBalance = .5; 
       break; 
      case 1: 
       //printf("Hear sound in left ear.\n"); 
       data.targetBalance = 0; 
       break; 
      case 2: 
       //printf("Hear sound in right ear.\n"); 
       data.targetBalance = 1; 
       break; 
      default: 
       //printf("Incorrect value for amp (left/right sound indicator)"); 
       data.targetBalance = .5; 
       break; 
     } 



     err = Pa_Initialize(); //scan for available devices i.e. audio jack, headphones 
     if(err != paNoError) { 
      printf("init\n"); 
      goto error; 
     } 
     //open the sound stream for processing 
     err = Pa_OpenDefaultStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, 
      256, patestCallback, &data); //open the sound stream for processing 
     if(err != paNoError) { 
      printf("open\n"); 
      goto error; 
     } 

     //start the stream (i.e. play sound) if no errors 
     err = Pa_StartStream(stream); 
     if(err != paNoError) { 
      printf("start\n"); 
      goto error; 
     } 

     //check which ear(s) the sound should be played to 



     //hold that tone for a certain amount of time (pulse*200 millisec) 
     Pa_Sleep(pulse*200); 
     cout << "pulse: " << pulse << endl << "freq: " << freq << endl; 
     cout << "amp: " << amp << endl; 

     //stop the stream (i.e. stop playing sound) 
     err = Pa_StopStream(stream); 
     if(err != paNoError) { 
      printf("stop\n"); 
      goto error; 
     } 

     err = Pa_CloseStream(stream); 
     if(err != paNoError) { 
      printf("close\n"); 
      goto error; 
     } 

     err = Pa_Terminate(); 
     if(err != paNoError) { 
      printf("term\n"); 
      goto error; 
     } 
    } 
    int key = cvWaitKey(1); 
    // write 
    if (output_txt) 
     fprintf(output_txt, "%d %d %d %d\n", r.x, r.y, r.width, r.height); 
    if (output_avi) 
     cvWriteFrame(output_avi, drawImg); 

    // next 
    if (key == 'q'||key=='Q') 
     break; 
    frame = cvQueryFrame(capture); 
} 
+0

これを行う際のCPUの負荷は?これはちょうど負荷の問題になることができますか?あなたがフレームレートを減らすとどうなりますか? –

+0

フレームレート/ framesPerBuffの低下が助けにならなかったので、負荷ではありませんでした。私は問題を理解し、このページに投稿します。助けてくれてありがとう。 – nmante

答えて

2

一貫性のないオーディオ再生は、私の質問に表示されていない別のコードセグメントが原因だったようです。その間違ったコードは以下の通りです。私は、エラーが最初のif文と関係し、この関数の最後のforloopと考えています。変数framesToCalcが正しく計算されていなかったと思います。したがって、最初のforループはoutputBuffer/out変数にデータを配置しませんでした。次に、残りの未使用のバッファ領域をゼロにします。したがって、ゼロ化されたバッファのため音が出ません。私の解決策は、最初のelseと最後のforloopを削除することでした。さらに、i = 0からframesPerBufferまでの最初のforループを実行しました。今は完璧に動作します。

static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData){ 
paTestData *data = (paTestData*)userData; 
SAMPLE_t *out = (SAMPLE_t *)outputBuffer; 
int i; 
int framesToCalc; 
int finished = 0; 
(void) inputBuffer; 
int left_phase = data->left_phase; 
int right_phase = data->right_phase; 


if(data->framesToGo < framesPerBuffer) 
{ 
    framesToCalc = data->framesToGo; 
    data->framesToGo = 0; 
    finished = 1; 
} 
else 
{ 
    framesToCalc = framesPerBuffer; 
    data->framesToGo -= framesPerBuffer; 
} 

for(i=0; i<framesToCalc; i++) 
{ 
    if(data->currentBalance < data->targetBalance) 
    { 
     data->currentBalance += BALANCE_DELTA; 
    } 
    else if(data->currentBalance > data->targetBalance) 
    { 
     data->currentBalance -= BALANCE_DELTA; 
    } 
    left_phase += (LEFT_FREQ/SAMPLE_RATE); 
    right_phase += (RIGHT_FREQ/SAMPLE_RATE); 
    if(fabs(data->currentBalance - .5) < .001){ 
     //left_phase += (double)(LEFT_FREQ/SAMPLE_RATE); 
     if(left_phase > 1.0) left_phase -= 1.0; 

     *out++ = DOUBLE_TO_SAMPLE(AMPLITUDE * sin((left_phase * M_PI * 2.))); 

     //right_phase += (double)(RIGHT_FREQ/SAMPLE_RATE); 
     if(right_phase > 1.0) right_phase -= 1.0; 
     *out++ = DOUBLE_TO_SAMPLE(AMPLITUDE * sin((right_phase * M_PI * 2.))); 
    }else{ 
     //left_phase += (double)(LEFT_FREQ/SAMPLE_RATE); 
     if(left_phase > 1.0) left_phase -= 1.0; 

     *out++ = DOUBLE_TO_SAMPLE(AMPLITUDE * sin((left_phase * M_PI * 2.))*(1.0 - data->currentBalance)); 

     //right_phase += (double)(RIGHT_FREQ/SAMPLE_RATE); 
     if(right_phase > 1.0) right_phase -= 1.0; 
     *out++ = DOUBLE_TO_SAMPLE(AMPLITUDE * sin((right_phase * M_PI * 2.))*data->currentBalance); 
    } 

} 
    // zero remainder of final buffer 
    for(; i<(int)framesPerBuffer; i++) 
    { 
     *out++ = SAMPLE_ZERO; //left 
     *out++ = SAMPLE_ZERO; //right 
    } 
    data->left_phase = left_phase; 
    data->right_phase = right_phase; 
    return finished; 
} 
1

なぜあなたは初期化し、フレームループ内PortAudioを終了していますか?あなたのプログラムの始めに一度初期化し、最後に一度終了することをお勧めします。

+0

初期化と終了をフレームループの外側に移動しました。しかし、これは私の問題のすべてを解決しませんでした。エラーの根は私のコールバック関数と関係があります。このページの別の投稿に投稿します。助けてくれてありがとう。 – nmante

関連する問題