2012-11-30 49 views
1

我正在嘗試製作一種樂器類型的應用程序。我遇到的問題是,只有在舊的聲音完成後才能播放新的聲音。我希望能夠同時播放它們。如何在WinRT中使用SharpDX同時播放多個聲音?

這是我的代碼看起來像:

首先,它只是擁有一個音頻緩衝區和其他一些信息的MYWAVE類:

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

在聲音播放類:

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(); 
    } 
} 

谷歌不是很有幫助,我找不到任何有用的東西。那麼我怎麼能同時播放多個聲音呢?

+0

這個問題是如何解決的?你能幫我用代碼嗎?請 – 2015-07-31 15:37:17

回答

2

您必須創建(並優選共享)多個SourceVoice實例並同時播放它們。

事實上,你現在的代碼應該可以工作,不是嗎?在播放完成後,您可能需要將一個StreamEnd事件監聽器添加到SourceVoice中以自行處理,並且記得在調用SourceVoice的構造函數時啓用回調。

+0

是的,這就是我所做的。但是,我在某個地方閱讀過,在使用它之後我不應該銷燬SourceVoice,而是重複使用它,這就是我所做的。爲了播放聲音,我檢查了'State.BuffersQueued'屬性等於0的聲音,該聲音不播放任何內容。如果我沒有發現任何空的聲音,我選擇其中一個,停止播放,並播放新的聲音。 – Tibi

+0

對不起,很久沒有。如果你正在處理這個問題,「不銷燬」SourceVoice僅僅意味着你應該在可能的時候重新使用該聲音,但是一個SourceVoice仍然只能在給定的時間播放單個聲音。我的建議是爲您的SourceVoice實例創建一個對象池,並且在停止/完成播放時使用StreamEnd事件將語音返回到池,並將考慮到併發性的StreamEnd從單獨的線程調用。 –