(これが重複している場合はお詫びします...私は投稿しましたが、実際にフォーラムに到達したという証拠は見られませんでした)
SlimDXDirectSoundを動作させようとしています。これが私が持っているコードです。それはwavファイルから二次バッファを満たし、次にスレッドループで、バッファの下半分または上半分を交互に満たします。
バッファの最初のロードを正常に再生します。AutoResetEventsは必要なときに起動し、バッファーの下半分、次に上半分にデータが入力されます(Debugステートメントで確認されます)。ただし、バッファの最初のロード後、再生は続行されません。したがって、どういうわけか、バッファの再作成は正常に機能しません。
アイデア?
(DirectSoundを使用しているのは、使用したいオーディオデバイスのGUIDを設定する唯一の方法であるためです。他の.NET対応のアプローチを利用できます。)
private void PlaySound(Guid soundCardGuid, string audioFile) { DirectSound ds = new DirectSound(soundCardGuid); ds.SetCooperativeLevel(this.Handle, CooperativeLevel.Priority); WaveFormat format = new WaveFormat(); format.BitsPerSample = 16; format.BlockAlignment = 4; format.Channels = 2; format.FormatTag = WaveFormatTag.Pcm; format.SamplesPerSecond = 44100; format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment; SoundBufferDescription desc = new SoundBufferDescription(); desc.Format = format; desc.Flags = BufferFlags.GlobalFocus; desc.SizeInBytes = 8 * format.AverageBytesPerSecond; PrimarySoundBuffer pBuffer = new PrimarySoundBuffer(ds, desc); SoundBufferDescription desc2 = new SoundBufferDescription(); desc2.Format = format; desc2.Flags = BufferFlags.GlobalFocus | BufferFlags.ControlPositionNotify | BufferFlags.GetCurrentPosition2; desc2.SizeInBytes = 8 * format.AverageBytesPerSecond; SecondarySoundBuffer sBuffer1 = new SecondarySoundBuffer(ds, desc2); NotificationPosition[] notifications = new NotificationPosition[2]; notifications[0].Offset = desc2.SizeInBytes / 2 + 1; notifications[1].Offset = desc2.SizeInBytes - 1; ; notifications[0].Event = new AutoResetEvent(false); notifications[1].Event = new AutoResetEvent(false); sBuffer1.SetNotificationPositions(notifications); byte[] bytes1 = new byte[desc2.SizeInBytes / 2]; byte[] bytes2 = new byte[desc2.SizeInBytes]; Stream stream = File.Open(audioFile, FileMode.Open); Thread fillBuffer = new Thread(() => { int readNumber = 1; int bytesRead; bytesRead = stream.Read(bytes2, 0, desc2.SizeInBytes); sBuffer1.Write<byte>(bytes2, 0, LockFlags.None); sBuffer1.Play(0, PlayFlags.None); while (true) { if (bytesRead == 0) { break; } notifications[0].Event.WaitOne(); bytesRead = stream.Read(bytes1, 0, bytes1.Length); sBuffer1.Write<byte>(bytes1, 0, LockFlags.None); if (bytesRead == 0) { break; } notifications[1].Event.WaitOne(); bytesRead = stream.Read(bytes1, 0, bytes1.Length); sBuffer1.Write<byte>(bytes1, desc2.SizeInBytes / 2, LockFlags.None); } stream.Close(); stream.Dispose(); }); fillBuffer.Start(); } }