gpt4 book ai didi

c# - 使用 SlimDX 和 DirectSound (C#) 播放声音

转载 作者:行者123 更新时间:2023-11-30 12:17:22 25 4
gpt4 key购买 nike

(抱歉,如果这是重复的......我发布了但没有看到它确实进入论坛的证据)

我一直在努力让 SlimDX DirectSound 正常工作。这是我的代码。它从 wav 文件填充辅助缓冲区,然后在线程循环中交替填充缓冲区的下半部分或上半部分。

它很好地播放了缓冲区的第一次加载。 AutoResetEvents 在它们应该触发的时候触发,然后填充缓冲区的下半部分和上半部分(使用调试语句验证)。但是在第一次加载缓冲区后播放不会继续。因此,缓冲区的重新填充以某种方式无法正常工作。

想法?

(我正在使用 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();
}
}

最佳答案

您还没有将其设置为在播放缓冲区上循环播放。将您的代码更改为:

sBuffer1.Play(0, PlayFlags.Looping); 

关于c# - 使用 SlimDX 和 DirectSound (C#) 播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3877362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com