その2

waveIn/Out系関数の中で使うものは、

  • waveInOpen
  • waveInPrepareHeader
  • waveInAddBuffer
  • waveInStart
  • waveInUnprepareHeader
  • waveInClose

・waveInOpen関数
バイスをオープンしてそのハンドルを取得します。
コールバックを指定でき、そこでOPEN、DATAFULL、CLOSEのメッセージを受け取ります。
一部のサイトでは、OPENメッセージが発行された時に次の処理を行うのが良いと書かれています。(非同期関数ではないか、という推測)
ただ、OPENメッセージが関数の実行と同時に送られるようなので、関数から戻った時のハンドルは正しいという結論です。


・waveInPrepareHeader関数
・waveInUnprepareHeader関数
入力デバイス用のバッファを準備します。
APIがバッファ情報をチェックして構造体に書き込むようです。
Unprepare関数は使用中でないかどうかチェックしてデバイスから抹消します。
なのでwaveIn系関数とwaveOut系関数で(同じデバイス上では?)共通で使用できます。


・waveInAddBuffer関数
入力デバイス用のバッファを追加します。
追加するとどんどんバッファが数珠繋ぎにされます。
直前にPrepare関数を、コールバックでDATAFULLが飛んできた時にUnprepare関数を呼んでアプリケーションで処理します。
これの肝は、DATAFULLメッセージが飛んだ時点ではデバイスがまだ解放していない点。
(↑追記:たまに解放したりしなかったりします。デバイスとのやりとりに遅延がでるのかも。だとしたら非同期?)
一部のサイトで「WAVERR_STILLPLAYINGというエラーがでる」というのがありましたが、上記の理由によるものだと思います。
なのでリングバッファを用いる場合は、最低限3つ以上のバッファに分割しなければなりません。


・waveInClose関数
入力デバイスを解放します。
waveInAddBufferで追加したバッファを全て使用しなければ解放できません。(次からwaveInOpenできなくなります)
なのでラストは必ずバッファを使い切ってから呼び出します。

waveInStart(hIn);
Sleep(バッファ分);
waveInStop(hIn);
waveInClose(hIn);


・ショートディレイ
http://d.hatena.ne.jp/nepo_n/Delay.cpp
http://d.hatena.ne.jp/nepo_n/Delay.zip