3

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() を繰り返し呼び出すと、サウンドは次のように再生されます。

音→音→音

したがって、バッファを埋めて再生するだけです。

ただし、現在のサウンドの再生中に同じサウンドを再生できるようにする必要があるため、効果的には、これら 2 つ以上を同時にミックスして再生する必要があります。

ここで見逃したものはありますか、または現在のソリューションでは不可能です (おそらく SubmixVoices が役立つ可能性があります)。

ドキュメントで関連するものを見つけようとしていますが、成功していません。参照できるオンラインの例はあまりありません。

ありがとう。

4

1 に答える 1

3

XACTはサウンドキュー(まさに私が必要としていたもの)をサポートしているため、この目的で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();
            }
        }
于 2011-12-29T16:29:29.303 に答える