アプリ版:「スタンプのみでお礼する」機能のリリースについて

waveIn、waveOutでの音声録音・再生プログラミングを作成しています。
内容は、マルチバッファリング機能で音声の取り込みを行い、同時にファイルへの書き込みと、スピーカーへの出力をするのですが、当然waveInで取り込み後にwaveOutするので、元の音声とずれて音がスピーカーへ出力されます。
WAVEFORMATEX構造体のメンバには秒単位での設定値であるため、最小1秒のずれが計算上でます。実際のズレは1秒も無いですが、かなり気になります。
同様の機能のフリーソフトでは、若干のズレはあってもこのプログラムほどではありません。どのようにすれば、このズレを少なく出来るのでしょうか。
どなたか、ご教示願いたくお願いします。

A 回答 (2件)

> (wf.nAvgBytesPerSec=wf.nSamplesPerSec * wf.nBlockAlign / 10;)



それはやったらダメです。
これは「ファイルフォーマット」を指定するものですので、入出力のバッファサイズ(処理時間単位)とは関係なく、常に

1秒あたりのバイト数=1秒あたりのサンプル数×1サンプルあたりのバイト数

でなければなりません。必ず
wf.nAvgBytesPerSec=wf.nSamplesPerSec * wf.nBlockAlign;
にする必要があります。

その上で、PrepareFormat 時の WAVEHDR で指定する dwBufferLengthを、バッファしたい秒数にあわせて、nAvgBytesPerSecの1/10のサイズにしたりする、
といったことになります。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。
dwBufferLength = wf.nAvgBytesPerSec / 10;
ですかね。これで出力したwavファイルも再生できました。
ご教示感謝いたします。

お礼日時:2010/06/05 13:27

> WAVEFORMATEX構造体のメンバには秒単位での設定値



そんなことはありません。
WAVEFORMATEX の各パラメータは「1秒あたりのデータ量」という「スペック」を指定するものであり、
実際にwaveIn/waveOutするデータ量は1秒単位である必然性はありません。

waveInPrepareHeader/waveOutPrepareHeader 時の WAVEHDR 構造体内の dwBufferLength で、
入出力するデータ量を指定していますが、これは WAVEFORMATEX のnBlockAlignの倍数であればいくらでも構いません。

たとえば、44.1kHz 16bit ステレオなら、nSamplesPerSecは44100、nBlockAlign は 4 になりますが、
176400(=44100*4)バイトのバッファを用意・指定すれば、1秒単位の入出力になりますが、
17640バイトを指定すれば0.1秒単位に、1764バイトのバッファなら0.01秒単位になります。


サイズを小さくすると、それだけタイムラグは小さくなりますが、
その代わりに、入出力処理を行う回数が増えて負荷が重くなりますし、あまりに短すぎると
処理が間に合わずに音飛びしたりする可能性もあります。どの位のサイズがちょうど良いかはプログラム次第です。
(複数のバッファをPrepareHeader しておけば、「たまたまギリギリ間に合わなかった」場合の音飛びは防ぐことができますが、その場合でも平均的にはバッファのPrepareが十分間に合っている必要があり、
「根本的に処理が追いつかない」場合の音飛びには対処できません。そういう場合は、バッファサイズを大きくするしかないです)
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
>実際にwaveIn/waveOutするデータ量は1秒単位である必然性はありません。
そうでしたか。試しに1/10で録音再生したところ、同時再生でのズレは気にならないぐらいになりました。
(wf.nAvgBytesPerSec=wf.nSamplesPerSec * wf.nBlockAlign / 10;)
ただ、出力したファイルでの再生が出来なくなってしまったので、こちらは少し汗をかいてみます。
ありがとうございました。

お礼日時:2010/06/05 13:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!