2012-03-04 25 views
2

waveOutWrite()を使用してスムーズなオーディオ再生を実現しようとすると問題が発生します。私のデータには、各adpcmブロックをデコードした後、waveOutWrite()を使って再生した後に、カメラから取得した多くのadpcmdataブロックが含まれています。最初のブロックは正常に再生されますが(少なくとも私が聞くことができます)、これらのブロックの間にギャップが存在する次のブロックで再生するときに問題があります。私はwaveOutWrite()を使用した後にsleep()を呼び出そうとしましたが、okではありません。この場合、どのようにスムーズになるのですか?オーディオを再生する方法に問題はありますか?waveOutWrite()を使用してオーディオ再生をスムーズにする方法

for (i = 0, i < MaxBlockData, i++) 


     BYTE * pcmBuff = new BYTE[length*8]; 
     memset(pcmBuff, 0, length*8); 
     G726 g726; 

     int pcmDataSize = 0; 
     g726.SetRate(g726.Rate32kBits); 
     g726.SetLaw(g726.PCM16); 
     pcmDataSize = g726.Decode(pcmBuff, adpcmData[i], 0, length*8); /decode adcmData PCM 16 

     if(pcmDataSize > 0) 
     { 
      int sampleRate = 8000; 
      CHAR* waveIn = new CHAR[pcmDataSize]; 

      HWAVEIN hWaveIn; 
      WAVEHDR WaveInHdr; 
      MMRESULT result; 
      HWAVEOUT hWaveOut; 

      WAVEFORMATEX pFormat; 
      pFormat.wFormatTag = WAVE_FORMAT_PCM; 
      pFormat.nChannels = 1; 
      pFormat.nSamplesPerSec = sampleRate; 
      pFormat.nAvgBytesPerSec = 2 * sampleRate; 
      pFormat.nBlockAlign = 2; 
      pFormat.wBitsPerSample = 16; 
      pFormat.cbSize = 0; 

      result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT); 

      if(result != MMSYSERR_NOERROR) 
      { 
       char fault[256]; 
       waveInGetErrorTextA(result, fault, 256); 
       MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION); 
       return; 
      } 

      WaveInHdr.lpData = (LPSTR)waveIn; 
      WaveInHdr.dwBufferLength = pcmDataSize; 
      WaveInHdr.dwBytesRecorded = 0; 
      WaveInHdr.dwUser = 0; 
      WaveInHdr.dwFlags = 0; 
      WaveInHdr.dwLoops = 0; 

      waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); 
      memcpy(WaveInHdr.lpData, pcmBuff, pcmDataSize); 

      if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT)) 
      { 
       MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION); 
      } 

      waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); 
      Sleep((pcmDataSize/sampleRate) * 1000); //Sleep for as long as there was recorded 

      waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR)); 
      waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); 
      waveInClose(hWaveIn); 
      waveOutClose(hWaveOut); 


      WaveInHdr.lpData = NULL; 
      delete []waveIn; 
     } 
    } 

私の質問を読んでくれてありがとう。

+0

私は既に同様の質問に回答していますので、これをコメントとして追加します。オーディオブロック間の遅延を取り除くには、[ダブルバッファリング](http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=4422&lngWId=3)を実装する必要があります。 WaveOutXXX関数のチュートリアルとの素晴らしいリンクがあります。ここに[元の回答](http://stackoverflow.com/questions/10833479/winapi-audio-output/10833690#10833690)へのリンクがあります。 –

答えて

1

私はこのように動作しません。
最初のサンプルを再生する場合、次のサンプルの時間はスリープできず、代わりにダブルまたはマルチバッファリングとコールバックメカニズムを使用する必要があります。
全体的なプロトコルは以下の通りである:
1))カメラまたは任意
2から最初のブロックを取得するカメラまたは任意
3から第二のブロックを取得する)任意待機することなく、第1ブロック及び第2ブロックを書き込みます。
コールバックからの信号を待つループを作成し、受信した信号が次のキャプチャされたブロックを書き込む。

0

waveOut *ファミリを使用してオーディオをスムーズに再生するには、デバイスを開き、バッファを割り当てて、バックログを再生したままデバイスにバッファを送信し続けます。コードにSleepがある場合、デバイスに新しいデータを準備して書き込むことと同時に、再生されたバッファをチェックする(WHDR_DONEフラグは、ドライバがバッファを使用していないことを示すように設定されています。バック)。

関連する問題