我已经使用SharpDX.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似乎说最大输入语音数是64。
-使每个sfx从不同的wav文件播放都没有区别。
-设置原始声音和/或主声音的音量没有区别。

XAudio2 API Documentation中,我找到了这句话:'XAudio2取消了多声道声音的6声道限制,并在任何具有多声道功能的声卡上支持多声道音频。该卡不需要硬件加速。 。这是我最近发现有关此问题的内容。

我对sfx编程经验不足,其中的很多对我来说都是很新的,因此请在适当的时候随意称呼我为白痴,但请尝试以外行的方式进行解释。

请,如果您有任何想法或答案,将不胜感激!
-乔什

最佳答案

正如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(),它们都从内存运行?

无论哪种方式,这都使限制达到了以前的三倍,因此这是非常有用的-但需要做进一步的工作。

关于c# - SharpDX XAudio2:6 SourceVoice限制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53582583/

10-12 04:40