簡體   English   中英

SharpDX XAudio2:6 SourceVoice限制

[英]SharpDX XAudio2: 6 SourceVoice limit

我一直在玩SharpSharp.XAudio2幾天了,盡管事情在很大程度上是積極的(在這里和那里,奇怪的軟件怪癖),但以下問題卻使我完全陷入困境:

我正在使用VS2015在C#.NET中工作。
我正在嘗試同時播放多種聲音。

為此,我做了:
-Test.cs:包含主要方法
-cSoundEngine.cs:包含XAudio2,MasteringVoice和聲音管理方法。
-VoiceChannel.cs:保存SourceVoice,以及將來的所有sfx /相關數據。

cSoundEngine:

    List<VoiceChannel> sourceVoices;
    XAudio2 engine;
    MasteringVoice master;

public cSoundEngine()
    {
        engine = new XAudio2();
        master = new MasteringVoice(engine);
        sourceVoices = new List<VoiceChannel>();
    }

public VoiceChannel AddAndPlaySFX(string filepath, double vol, float pan)
    {
        /**
         * Set up and start SourceVoice
         */
        NativeFileStream fileStream = new NativeFileStream(filepath, NativeFileMode.Open, NativeFileAccess.Read);
        SoundStream soundStream = new SoundStream(fileStream);
        SourceVoice source = new SourceVoice(engine, soundStream.Format);
        AudioBuffer audioBuffer = new AudioBuffer()
        {
            Stream = soundStream.ToDataStream(),
            AudioBytes = (int)soundStream.Length,
            Flags = SharpDX.XAudio2.BufferFlags.EndOfStream
        };

        //Make voice wrapper
        VoiceChannel voice = new VoiceChannel(source);
        sourceVoices.Add(voice);

        //Volume
        source.SetVolume((float)vol);

        //Play sound
        source.SubmitSourceBuffer(audioBuffer, soundStream.DecodedPacketsInfo);
        source.Start();

        return voice;
    }

test.cs中:

            cSoundEngine engine = new cSoundEngine();
            total = 6;

            for (int i = 0; i < total; i++)
            {
                string filepath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName + @"\Assets\Planet.wav";
                VoiceChannel sfx = engine.AddAndPlaySFX(filepath, 0.1, 0);
            }
            Console.Read(); //Input anything to end play.

目前在VoiceChannel.cs中沒有值得顯示的內容-它包含“ SourceVoice源”,這是在構造函數中發送的一個參數!

一切都很好,並且運行良好,最多有5種聲音(總計= 5)。 您所聽到的只是Planet.wav的幸福無人機。 高於5的值將導致控制台凍結約5秒鍾,然后關閉(可能是調試器無法處理的C ++錯誤)。 遺憾的是,沒有錯誤消息可供我們查看或其他任何內容。
從測試:
-只要您運行的聲音不超過5個,就不會崩潰。
-更改采樣率似乎無濟於事。
-將主對象的inputChannels設置為其他數字沒有區別。
-MasteringVoice似乎說inputvoices的最大數量是64。
-使每個sfx從不同的wav文件播放都沒有區別。
-設置原始聲音和/或主音量的音量沒有區別。

XAudio2 API文檔中,我找到了這句話: 'XAudio2取消了多聲道聲音的6聲道限制,並在任何具有多聲道功能的聲卡上支持多聲道音頻。 該卡不需要硬件加速。 這是我最近發現有關此問題的內容。

我對sfx編程經驗不足,其中的很多對我來說還是很新的,因此請在適當的時候隨意稱呼我為白痴,但請嘗試以外行的方式進行解釋。

請,如果您有任何想法或答案,將不勝感激!
-Josh

正如Chuck所建議的那樣,我創建了一個數據庫來保存.wav數據,並且我只引用了每個緩沖區的單個數據存儲。 這樣可以將聲音限制提高到20級-但這並不能解決整個問題,可能是因為我沒有正確實現這一點。 執行:

class SoundDataBank
{
    /**
     * Holds a single byte array for each sound
     */

    Dictionary<eSFX, Byte[]> bank;
    string curdir => Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

    public SoundDataBank()
    {
        bank = new Dictionary<eSFX, byte[]>();
        bank.Add(eSFX.planet, NativeFile.ReadAllBytes(curdir + @"\Assets\Planet.wav"));
        bank.Add(eSFX.base1, NativeFile.ReadAllBytes(curdir + @"\Assets\Base.wav"));
    }

    public Byte[] GetSoundData(eSFX sfx)
    {
        byte[] output = bank[sfx];
        return output;
    }

}

在SoundEngine中,我們創建一個SoundBank對象(在SoundEngine構造函數中初始化):

    SoundDataBank soundBank;

    public VoiceChannel AddAndPlaySFXFromStore(eSFX sfx, double vol)
    {
        /**
         * sourcevoice will be automatically added to MasteringVoice and engine in the constructor.
         */
        byte[] buffer = soundBank.GetSoundData(sfx);
        MemoryStream memoryStream = new MemoryStream(buffer);
        SoundStream soundStream = new SoundStream(memoryStream);
        SourceVoice source = new SourceVoice(engine, soundStream.Format);
        AudioBuffer audioBuffer = new AudioBuffer()
        {
            Stream = soundStream.ToDataStream(),
            AudioBytes = (int)soundStream.Length,
            Flags = SharpDX.XAudio2.BufferFlags.EndOfStream
        };


        //Make voice wrapper
        VoiceChannel voice = new VoiceChannel(source, engine, MakeOutputMatrix());

        //Volume
        source.SetVolume((float)vol);

        //Play sound
        source.SubmitSourceBuffer(audioBuffer, soundStream.DecodedPacketsInfo);
        source.Start();

        sourceVoices.Add(voice);

        return voice;
    }

現在,執行此實現后,我可以播放多達20種聲音效果-但不是因為我們正在從音庫中播放。 實際上,即使運行聲音效果的舊方法,現在也可以達到20個sfx實例。

由於我們已經在SoundBank的構造函數中完成了NativeFile.ReadAllBytes(curdir + @“ \\ Assets \\ Base.wav”),因此最多可以改進20個。

我懷疑NativeFile正在保存已加載文件數據的存儲,因此無論您運行原始的SoundEngine.AddAndPlaySFX()還是SoundEngine.AddAndPlaySFXFromStore(),它們都從內存運行?

無論哪種方式,這都使限制達到了以前的四倍,因此這非常有用,但需要做進一步的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM