生のオーディオストリームを録音して再生する目的でWaveOutとWaveInクラスを公開するWinMMライブラリラッパーライブラリを作成しました。WinMMライブラリの問題
すべてがうまくいきますが、完成したバッファを処理する方法に関するオペレーティングシステムの仕様に従うために、バッファを準備してメモリを解放するスレッドを追加しました。また、すべての同期がダウンしているので、クラスは確実にスレッドセーフです。
しかし、WaveOutデバイスにバッファを追加してオペレーティングシステムが成功コードを返すという稀な問題があるようですが、デバイスが直後にリセットされた場合、OSはバッファを完了したものとしてマークしません。それをアプリケーションに戻します。
バッファを失っているようです。だから問題は、デバイスに送信された個々のバッファの数を追跡し、それらをクリーンアップするスレッドにClose()関数を参加させないことです。
アイデア、または既知のバグはありますか?
PS:これはVistaのクアッドコアでは起こりそうにないが、XPプロのデュアルコアで起こる。
EDIT1:完全なソースコードを公開していただき、誰かを助けることができれば、コードプレックスでライセンスを取得していただきます。
EDIT2:CodePlexのに掲示されるライブラリ:http://winmm.codeplex.com/
ここでは、問題の原因かのアイデアです:
public partial class MainView : Form
{
private WaveIn waveIn = new WaveIn(WaveIn.WaveInMapperDeviceId);
private WaveOut waveOut = new WaveOut(WaveOut.WaveOutMapperDeviceId);
public MainView()
{
InitializeComponent();
WaveFormat format = WaveFormat.Pcm44Khz16BitMono;
waveOut.Open(format);
waveIn.DataReady += new EventHandler<DataReadyEventArgs>(WaveIn_DataReady);
// Tweaking these values affects the internal buffering thread.
// Setting too small of a QueueSize with too small of a BufferSize
// will cause buffer underruns, which will sound like choppy audio.
waveIn.BufferQueueSize = 200;
waveIn.BufferSize = 64;
waveIn.Open(format);
waveIn.Start();
}
void WaveIn_DataReady(object sender, DataReadyEventArgs e)
{
if (waveOut != null)
{
lock (waveOut)
{
// We have to check for null after the lock,
// because waveOut may have been disposed
// inside another lock.
if (waveOut != null)
{
waveOut.Write(e.Data);
}
}
}
}
private void MainView_FormClosed(object sender, FormClosedEventArgs e)
{
if (waveIn != null)
{
lock (waveIn)
{
waveIn.Dispose();
waveIn = null;
}
}
if (waveOut != null)
{
lock (waveOut)
{
waveOut.Dispose();
waveOut = null;
}
}
}
}
ああ、別のオブジェクトに良いアイデア。 また、私が問題に取り組んでいた実際のアプリでは、私はexplicetly nullに設定していました。 –
少なくとも建設的なフィードバックをいただいたので、問題が解決されているかどうか分からないにもかかわらず、奨励金をお渡しします。 –