我需要在我的应用中反复播放单个声音,例如使用XAudio2进行枪击。
这是我为此目的编写的代码的一部分:
public sealed class X2SoundPlayer : IDisposable
{
private readonly WaveStream _stream;
private readonly AudioBuffer _buffer;
private readonly SourceVoice _voice;
public X2SoundPlayer(XAudio2 device, string pcmFile)
{
var fileStream = File.OpenRead(pcmFile);
_stream = new WaveStream(fileStream);
fileStream.Close();
_buffer = new AudioBuffer
{
AudioData = _stream,
AudioBytes = (int) _stream.Length,
Flags = BufferFlags.EndOfStream
};
_voice = new SourceVoice(device, _stream.Format);
}
public void Play()
{
_voice.SubmitSourceBuffer(_buffer);
_voice.Start();
}
public void Dispose()
{
_stream.Close();
_stream.Dispose();
_buffer.Dispose();
_voice.Dispose();
}
}
上面的代码实际上是基于SlimDX示例。
现在它做的是,当我反复调用Play()时,声音会像:
声音 - >声音 - >声
所以它只是填充缓冲区并播放它。
但是,我需要能够播放当前正在播放的 相同的声音,所以这两个或更多声音应该同时混合和播放。
这里有什么我错过了,或者我目前的解决方案是不可能的(也许SubmixVoices可以提供帮助)?
我正在尝试找到与文档相关的内容,但我没有成功,并且我可以参考的在线示例不多。
感谢。
答案 0 :(得分:3)
虽然为此目的使用XACT是更好的选择,因为它支持声音提示(正是我需要的),但我确实设法让它以这种方式工作。
我已经更改了代码,因此它总是会从流中创建新的SourceVoice对象并进行播放。
// ------ code piece
/// <summary>
/// Gets the available voice.
/// </summary>
/// <returns>New SourceVoice object is always returned. </returns>
private SourceVoice GetAvailableVoice()
{
return new SourceVoice(_player.GetDevice(), _stream.Format);
}
/// <summary>
/// Plays this sound asynchronously.
/// </summary>
public void Play()
{
// get the next available voice
var voice = GetAvailableVoice();
if (voice != null)
{
// submit new buffer and start playing.
voice.FlushSourceBuffers();
voice.SubmitSourceBuffer(_buffer);
voice.Start();
}
}