如何在WinRT中使用SharpDX同时播放多个声音?

时间:2012-11-30 10:04:14

标签: c# windows-8 windows-runtime sharpdx xaudio2

我正在尝试制作乐器类型的应用程序。我遇到的问题是只有旧的声音完成后才能播放新的声音。我希望能够同时播放它们。

这就是我的代码的样子:

首先,MyWave类只保存音频缓冲区和其他一些信息:

class MyWave
{
    public AudioBuffer Buffer { get; set; }
    public uint[] DecodedPacketsInfo { get; set; }
    public WaveFormat WaveFormat { get; set; }
}

在SoundPlayer类中:

    private XAudio2 xaudio;
    private MasteringVoice mvoice;
    Dictionary<string, MyWave> sounds;

    // Constructor
    public SoundPlayer()
    {
        xaudio = new XAudio2();
        xaudio.StartEngine();
        mvoice = new MasteringVoice(xaudio);
        sounds = new Dictionary<string, MyWave>();
    }

    // Reads a sound and puts it in the dictionary
    public void AddWave(string key, string filepath)
    {
        MyWave wave = new MyWave();

        var nativeFileStream = new NativeFileStream(filepath, NativeFileMode.Open, NativeFileAccess.Read, NativeFileShare.Read);
        var soundStream = new SoundStream(nativeFileStream);
        var buffer = new AudioBuffer() { Stream = soundStream, AudioBytes = (int)soundStream.Length, Flags = BufferFlags.EndOfStream };

        wave.Buffer = buffer;
        wave.DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
        wave.WaveFormat = soundStream.Format;

        this.sounds.Add(key, wave);
    }

    // Plays the sound
    public void Play(string key)
    {
        if (!this.sounds.ContainsKey(key)) return;
        MyWave w = this.sounds[key];

        var sourceVoice = new SourceVoice(this.xaudio, w.WaveFormat);
        sourceVoice.SubmitSourceBuffer(w.Buffer, w.DecodedPacketsInfo);
        sourceVoice.Start();
    }
}

谷歌不是很有帮助,我找不到任何有用的东西。那么如何同时播放多个声音呢?

2 个答案:

答案 0 :(得分:2)

您必须创建(最好是池)多个SourceVoice实例并同时播放它们。

事实上,您当前的代码应该有效,不是吗?您可能希望在回放完成后将SourceEnd事件侦听器添加到SourceVoice以自行处理,并记住在调用SourceVoice的构造函数时启用回调。

答案 1 :(得分:0)

只需将 mciSendString 与 open 和 play 命令一起使用。此示例在启动时一起播放 note1.wav 和 note2.wav。

[System.Runtime.InteropServices.DllImport("winmm.dll")]
static extern Int32 mciSendString(string command,                                             
                                  StringBuilder buffer, 
                                  int bufferSize, 
                                  IntPtr hwndCallback);

        public frmGame()
        {
            InitializeComponent();
            DoubleBuffered = true;            
            mciSendString("open note1.wav type waveaudio  alias s1", null, 0, IntPtr.Zero);
            mciSendString("play s1", null, 0, IntPtr.Zero);
            mciSendString("open note2.wav type waveaudio  alias s2", null, 0, IntPtr.Zero);
            mciSendString("play s2", null, 0, IntPtr.Zero);
        }