Как воспроизводить один и тот же звук повторно с XAudio2? - PullRequest
3 голосов
/ 15 декабря 2011

Мне нужно многократно воспроизводить один звук в моем приложении, например, выстрел, используя XAudio2.

Это часть кода, которую я написал для этой цели:

public sealed class X2SoundPlayer : IDisposable
    {
        private readonly WaveStream _stream;
        private readonly AudioBuffer _buffer;
        private readonly SourceVoice _voice;

        public X2SoundPlayer(XAudio2 device, string pcmFile)
        {
            var fileStream = File.OpenRead(pcmFile);
            _stream = new WaveStream(fileStream);
            fileStream.Close();

            _buffer = new AudioBuffer
                          {
                              AudioData = _stream,
                              AudioBytes = (int) _stream.Length,
                              Flags = BufferFlags.EndOfStream

                          };

            _voice = new SourceVoice(device, _stream.Format);
        }

        public void Play()
        {
            _voice.SubmitSourceBuffer(_buffer);
            _voice.Start();
        }

        public void Dispose()
        {
            _stream.Close();
            _stream.Dispose();
            _buffer.Dispose();
            _voice.Dispose();
        }
    }

Приведенный выше код фактически основан на сэмпле SlimDX.

То, что он делает сейчас, при повторном вызове Play (), звучит как:

sound -> sound -> sound

Таким образом, он просто заполняет буфер и воспроизводит его.

Но мне нужно иметь возможность воспроизводить тот же звук , пока текущийиграя, так эффективно эти два или более должны смешиваться и играть одновременно.

Есть ли здесь что-то, что я пропустил, или это невозможно с моим текущим решением (возможно, SubmixVoices могли бы помочь)?

Я пытаюсь найти что-то связанное в документах, но я не добился успеха, и в Интернете не так много примеров, на которые я мог бы сослаться.

Спасибо.

1 Ответ

3 голосов
/ 29 декабря 2011

Хотя для этой цели лучше использовать XACT, поскольку он поддерживает звуковые сигналы (именно то, что мне нужно), мне удалось заставить его работать таким образом.

Я изменил код, чтобы он всегда создавал новый объект SourceVoice из потока и воспроизводил его.

        // ------ code piece 

        /// <summary>
        /// Gets the available voice.
        /// </summary>
        /// <returns>New SourceVoice object is always returned. </returns>
        private SourceVoice GetAvailableVoice()
        {
            return new SourceVoice(_player.GetDevice(), _stream.Format);
        }

        /// <summary>
        /// Plays this sound asynchronously.
        /// </summary>
        public void Play()
        {
            // get the next available voice
            var voice = GetAvailableVoice();
            if (voice != null)
            {
                // submit new buffer and start playing.
                voice.FlushSourceBuffers();
                voice.SubmitSourceBuffer(_buffer);

                voice.Start();
            }
        }
...