リアルタイム音声入出力するには?

解決


shun  2009-09-28 20:00:48  No: 70982

VC++6.0のwin32console applicationでマイク入力音声をリアルタイムに再生するプログラムを作成しようと考えています。
現在、マイク入力と出力はできるプログラムを作成しているのですが、
リアルタイム性を出す方法として、
短期間(<<1秒)でwaveInStartとwaveOutWriteを繰り返すことを考えたのですが、
waveInPrepareHeaderおよびwaveOutPrepareHeaderでバッファ期間を1秒未満にしようとすると、エラーは出ないのに録音・再生されません。
この問題の解決方法をご存じ、あるいは他の実現方法をご存じの方はアドバイス頂けないでしょうか?
宜しくお願い致します。


オショウ  2009-09-28 23:19:26  No: 70983

先に書いた件の内容で、1個の録音バッファだけだと間に合わない
ので、複数確保して、とっかえひっかえして録音が止まらないよう
にする必要があります。

要はまず無限録音(メモリと言う意味では有限ですが)ができる様
にする。

私は10秒の録音バッファを16個確保して、とっかえひっかえし
て実現しましたが、再生を行うとなれば、短い録音バッファを大量
に用意しておく必要があろうかと・・・

※  ちょっともう作った時点での記憶が・・・
    何か隠れた機能・意味があったかも・・・

録音から再生への時間遅れを考慮すると、録音バッファがフルにな
らない限りイベントは発生しないので、逆に小さい録音バッファを
大量に用意してとっかえひっかえするように考えてください。

CPU性能がそのまま影響しますので、適正な数は何とも・・・

ですが、それを作ったのは、Win95初期〜Win98時代ですので、推し
てしるべし・・・間に合うようにつくるなら、極力コードを書かな
いでシンプルで高速になるようにしないといけないでしょう。

ただ現在のCPUの性能で、そこそこ無茶しても追いつかない・・・
と言うことにはならないかと。動画でのTV会話を実現しているの
ではないので・・・

音声だけなら、どう考えてもロジックが悪い・・・
アルゴリズムの見直しと各APIの呼び出しの機能の意味を見直さ
れるのがよろしいかと・・・

以上。頑張ってください。


shun  2009-09-30 20:53:12  No: 70984

オショウさん、前回に引き続きレスありがとうございます。
風邪で寝込んでいたので返信が遅くなってしまい申し訳ありません。
私の認識では、再生と録音が同時にできない限りマルチバッファにしても
途切れが発生してしまうと考えているのですが、間違いでしょうか??
もう一つ質問なのですが、
「録音バッファがフルにならない限りイベントは起きない」のでしたら、
バッファサイズを1秒として録音途中でwaveInStop関数を使うと再生や再録音に影響するのでしょうか?
質問が多く長くなってしまってすいません。


オショウ  2009-09-30 21:27:17  No: 70985

録音用バッファを複数用意して行えば、途切れはありません。

無限録音を行えるようにできれば、その機能の検証ができるかと。
この場合、長い録音バッファを作るのではなく、例えば200ms程度
録音できるバッファ長のものを5〜10個用意して行うとか・・・

1個の長さとバッファ個数は、CPUの性能に依存しますのでテ
ストが必要です。

1個のバッファに対し録音途中にwaveInStopを行うと・・・
http://msdn.microsoft.com/ja-jp/library/cc428810.aspx
仕様では、録音された分までがバッファに返ってくるようです。

そこから次の録音開始(再開)を行うにしても、結果的に再度
まっさらの録音バッファを用意して行うことになるので、何か
問題でもあるんでしょうか?

先の録音し保存したWAVEファイルに継ぎ足す?
と言うことですか?

その辺は、WAVEファイルの仕様に従ってヘッダー部を調整すれ
ば済みますので、まずは、録音が問題なくできるようにする事
が先決で、次に録音しながらの再生を行うことでしょう。

WAVEファイルの連結は、その後ですネ!

録音しながらの再生は、その1個の録音バッファの長さ分だけ
遅延することになります。遅延時間を100〜200ms程度にできれ
ば、そう遅れを感じることはありませんが、録音完了イベント
での処理がシンプル且つ高速に行えないと、間に合わなくなる
ので、途切れることもあるでしょう。

何はともあれ、動くコードがあるので、録音バッファ長を短く
しても無限録音ができるものを作成するのが、機能確認の為に
は必要でしょう!

※  質問するよりも、APIのヘルプをよく読みましょう!
    次にテストしてみて、その結果、思惑と違うならば、何故
    そうなったのか確認して解らなければ質問しましょう!

頑張って下さい。


shun  2009-09-30 23:08:25  No: 70986

オショウさん、レスありがとうございます。

waveファイルの連結は必要ありませんが、
最初に書いたように1秒未満のバッファを作成すると警告が出て
録音も再生も動作していないようになってしまいます。

いろいろ調べているのですが、
1秒未満のバッファを作成する方法が分かりません。
for文で繰り返しているだけですが、
1秒毎なら録音・再生を繰り返すことは出来ています。

APIのヘルプなども参照しているのですが、基本的な知識が足りていないので、「バッファが処理済みとなる」の意味が分かりませんでした。
もう少し周辺知識を増やしたいと思います。
ありがとうございました。


fuku  2009-10-02 05:37:25  No: 70987

横槍失礼します。
制御は少しややこしいですがDirectSound/DirectSoundCaptureのほうが向いてるかもしれません。
DirectX所属だけあって非同期での再生/録音が可能です。
#コンソールアプリで使ってみたことはないので、機能が使えない事態になる恐れはありますが・・・

ただし再生音声が録音ストリームに流れ込むようだとハウリングしてしまいますので、
録音の設定で「PC上で再生している音を録音しない」ようにしておく必要はあります。

DirectSoundCaptureによる録音は確保したメモリ領域を循環しながら書き込みます。
次の周回で上書きされるまでに読みだすことで、
録音を停止することなく取得したオーディオデータを読み出すことができます。

DirectSoundの再生側も同様に確保したメモリ領域を循環しながら読みだすので、
DirectSoundが読み込みに来るまでに次のオーディオデータを書き込んでいれば再生できます。

両方とも、安定させるには最低50ms程度の猶予を見たほうが良かったと思いますので、
録音して即座に再生に回すとしても100ms程度は遅延することになるかと思います。

今回の場合、ある程度大きめのバッファを確保して(小さいと周回が短くなり、タイミングがシビアになるので)、
イベント通知を待つのではなく、
タイマーを使って定期的に録音バッファから読み取り可能になっているデータを再生バッファに
転送し続ければ一応、途切れることはないと思います。
また、各バッファへのアクセス時に録音/再生を停止する必要もありませんので、
バッファはそれぞれ1本で足りるでしょう。


shun  2009-10-02 20:07:16  No: 70988

fukuさん、レスありがとうございます。
現在、コンソールアプリの方で、再生と録音を同時に実行しているプログラムにできました。
1秒以上の遅延や細かな音の途切れはあるのですが、ダブルバッファを作成してもう少しこちらでがんばってみたいと思います。
遅延がどうしても削減できないと感じたら(結構そう感じているのですが),fukuさんのおっしゃるDirectSoundを用いた方法に切り替えたいと思います。


fackt  2009-10-03 01:07:23  No: 70989

DirectSounddでも50〜100ms程度の遅延が発生します。
さらに遅延を少なくしたい場合は、ASIOを使用します。
だいたい10〜20ms以下、ハイスペックなデバイスであれば数ms程度の遅延に抑えられます。
http://ja.wikipedia.org/wiki/ASIO

JUCEというオーディオ処理に特化したオープンソースのフレームワークライブラリがあります。
ASIO/DirectSound/MME に対応しているので参考になると思います。
http://www.rawmaterialsoftware.com/juce/


shun  2009-10-03 02:45:05  No: 70990

facktさん、レスありがとうございます。
初心者なのでまったく知らない単語ばかりで困惑しており、
業界標準のものを理解してプログラムを作成できる自信はありませんが、
勉強してみたいと思います。


shun  2009-10-06 01:40:08  No: 70991

皆様、ありがとうございました。
なんとかダブルバッファリングのプログラムが作成できました。
しかし、ダブルバッファ手法では最初の1秒分が二回繰り返されてしまいます。
この原因の解消方法として、
バッファのサイズを小さくしたいと思うのですが、
どのように変更すれば良いか分かりません。
現在のサイズ指定方法は以下のサイトのままにしています。

http://www.codeproject.com/KB/audio-video/VoiceRecording.aspx

たとえばバッファ量を200msにしたい場合どのようにすればよいでしょうか?
初歩的な質問かも知れませんが、
いろいろ調べたり試した結果実現できないのでどうかご教示ください。
宜しくお願い致します。


shun  2009-10-09 20:59:49  No: 70992

あまり賢い方法ではありませんが、バッファ部のパラメータを直接いじることで解決しました。
皆さん、ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加