同时播放三个声音c#
Posted
技术标签:
【中文标题】同时播放三个声音c#【英文标题】:Play three sounds simultaneously c# 【发布时间】:2015-08-14 13:00:02 【问题描述】:我想同时播放三个声音,但是第二个声音必须在一秒钟后播放,第三个声音必须在两秒钟后播放。我有这个代码:
private void Play()
AxWindowsMediaPlayer player1 = new AxWindowsMediaPlayer();
player1.CreateControl();
AxWindowsMediaPlayer player2 = new AxWindowsMediaPlayer();
player2.CreateControl();
AxWindowsMediaPlayer player3 = new AxWindowsMediaPlayer();
player3.CreateControl();
player1.URL = "sounds\\1.wav";
player1.Ctlcontrols.play();
System.Threading.Thread.Sleep(1000);
player2.URL = "sounds\\2.wav";
player2.Ctlcontrols.play();
System.Threading.Thread.Sleep(1000);
player3.URL = "sounds\\3.wav";
player3.Ctlcontrols.play();
为什么所有这些声音会在两秒后一次播放?
【问题讨论】:
使用 Directx 库,它是击球手并使用托管代码 我猜是因为 .play() 是一个异步方法,调用它之后,你立即调用了 Thread.Sleep(1000)。您必须创建 3 个线程并同步它们,以便第一个调用 play(),而第二个和第三个调用 Sleep(1000) 和 Sleep(2000) 【参考方案1】:我最终使用了 SharpDX(可通过 NuGet 包获得 SharpDX
和SharpDX.XAudio2
。
可以在我的一个 GitHub 项目中找到它的使用示例:2DAI 在这个screen recording 中你也可以听到各种重叠的声音。
播放声音:
var backgroundMusicSound = new AudioClip(@".\Assets\Sounds\Music\Background.wav" /*Sound path*/, 1.0 /* Volumne*/, true /*Loop Forever?*/)
backgroundMusicSound.Play();
我拼凑的课程:
public class AudioClip
private XAudio2 _xaudio = new XAudio2();
private WaveFormat _waveFormat;
private AudioBuffer _buffer;
private SoundStream _soundstream;
private SourceVoice _singleSourceVoice;
private bool _loopForever;
private bool _isPlaying = false; //Only applicable when _loopForever == false;
private bool _isFading;
private string _wavFilePath; //For debugging.
private float _initialVolumne;
public AudioClip(string wavFilePath, float initialVolumne = 1, bool loopForever = false)
_loopForever = loopForever;
_wavFilePath = wavFilePath;
_initialVolumne = initialVolumne;
var masteringsound = new MasteringVoice(_xaudio); //Yes, this is required.
var nativefilestream = new NativeFileStream(wavFilePath,
NativeFileMode.Open, NativeFileAccess.Read, NativeFileShare.Read);
_soundstream = new SoundStream(nativefilestream);
_waveFormat = _soundstream.Format;
_buffer = new AudioBuffer
Stream = _soundstream.ToDataStream(),
AudioBytes = (int)_soundstream.Length,
Flags = BufferFlags.EndOfStream
;
if (loopForever)
_buffer.LoopCount = 100;
public void Play()
lock (this)
if (_loopForever == true)
if (_isPlaying)
if (_isFading)
_isFading = false;
_singleSourceVoice.SetVolume(_initialVolumne);
return;
_singleSourceVoice = new SourceVoice(_xaudio, _waveFormat, true);
_singleSourceVoice.SubmitSourceBuffer(_buffer, _soundstream.DecodedPacketsInfo);
_singleSourceVoice.SetVolume(_initialVolumne);
_singleSourceVoice.Start();
_isPlaying = true;
return;
var sourceVoice = new SourceVoice(_xaudio, _waveFormat, true);
sourceVoice.SubmitSourceBuffer(_buffer, _soundstream.DecodedPacketsInfo);
sourceVoice.SetVolume(_initialVolumne);
sourceVoice.Start();
public void Fade()
if (_isPlaying && _isFading == false)
_isFading = true;
(new Thread(FadeThread)).Start();
private void FadeThread()
float volumne;
_singleSourceVoice.GetVolume(out volumne);
while (_isFading && volumne > 0)
volumne -= 0.25f;
volumne = volumne < 0 ? 0 : volumne;
_singleSourceVoice.SetVolume(volumne);
Thread.Sleep(100);
Stop();
public void Stop()
if (_loopForever == true)
if (_singleSourceVoice != null && _isPlaying)
_singleSourceVoice.Stop();
_isPlaying = false;
_isFading = false;
else
throw new Exception("Cannot stop overlapped audio.");
还应该注意的是,加载声音可能是一个繁重的过程,所以如果你经常这样做,那么你可能想像我一样缓存它们:
private Dictionary<string, AudioClip> _audioClips get; set; = new Dictionary<string, AudioClip>();
public AudioClip GetSoundCached(string wavFilePath, float initialVolumne, bool loopForever = false)
lock (_audioClips)
AudioClip result = null;
wavFilePath = wavFilePath.ToLower();
if (_audioClips.ContainsKey(wavFilePath))
result = _audioClips[wavFilePath];
else
result = new AudioClip(wavFilePath, initialVolumne, loopForever);
_audioClips.Add(wavFilePath, result);
return result;
【讨论】:
以上是关于同时播放三个声音c#的主要内容,如果未能解决你的问题,请参考以下文章