Beispiel #1
0
        private static void PlayWithoutStreaming(IWaveSource waveSource)
        {
            using (var xaudio2 = XAudio2.CreateXAudio2())
            using (var masteringVoice = xaudio2.CreateMasteringVoice()) //ALWAYS create at least one masteringVoice.
            using (var sourceVoice = xaudio2.CreateSourceVoice(waveSource.WaveFormat))
            {
                var buffer = waveSource.ToByteArray();
                using (var sourceBuffer = new XAudio2Buffer(buffer.Length))
                {
                    using (var stream = sourceBuffer.GetStream())
                    {
                        stream.Write(buffer, 0, buffer.Length);
                    }

                    sourceVoice.SubmitSourceBuffer(sourceBuffer);
                }

                sourceVoice.Start();

                Console.WriteLine("Press any key to exit.");
                Console.ReadKey();

                sourceVoice.Stop();
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="StreamingSourceVoice" /> class.
        /// </summary>
        /// <param name="ptr">Pointer to a <see cref="XAudio2SourceVoice" /> object.</param>
        /// <param name="voiceCallback">
        ///     <see cref="VoiceCallback" /> instance which receives notifications from the
        ///     <see cref="XAudio2SourceVoice" /> which got passed as a pointer (see the <paramref name="ptr" /> argument).
        /// </param>
        /// <param name="waveSource"><see cref="IWaveSource" /> which provides the audio data to stream.</param>
        /// <param name="bufferSize">
        ///     Buffersize of the internal used buffers in milliseconds. Values in the range from 70ms to
        ///     200ms are recommended.
        /// </param>
        /// <remarks>It is recommended to use the <see cref="Create" /> method instead of the this constructor.</remarks>
        public StreamingSourceVoice(IntPtr ptr, VoiceCallback voiceCallback, IWaveSource waveSource, int bufferSize)
        {
            BasePtr = ptr;
            _voiceCallback = voiceCallback;
            _waveSource = waveSource;

            var maxBufferBytes = (int) waveSource.WaveFormat.MillisecondsToBytes(bufferSize);
            _buffer = new byte[maxBufferBytes];

            for (int i = 0; i < _buffers.Length; i++)
            {
                var buffer = new XAudio2Buffer(maxBufferBytes);
                _buffers[i] = buffer;
            }

            InitializeForStreaming();
        }
Beispiel #3
0
        internal StreamingSourceVoice(XAudio2 xaudio2, IWaveSource waveSource, VoiceCallback voiceCallback, int bufferSize)
            : base(CreateSourceVoice(xaudio2, waveSource, voiceCallback), xaudio2.Version)
        {
            _voiceCallback = voiceCallback;
            _waveSource = waveSource;

            var maxBufferBytes = (int)waveSource.WaveFormat.MillisecondsToBytes(bufferSize);
            _buffer = new byte[maxBufferBytes];

            for (int i = 0; i < _buffers.Length; i++)
            {
                var buffer = new XAudio2Buffer(maxBufferBytes);
                _buffers[i] = buffer;
            }

            InitializeForStreaming();
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="StreamingSourceVoice" /> class.
        /// </summary>
        /// <param name="ptr">Pointer to a <see cref="XAudio2SourceVoice" /> object.</param>
        /// <param name="voiceCallback">
        ///     <see cref="VoiceCallback" /> instance which receives notifications from the
        ///     <see cref="XAudio2SourceVoice" /> which got passed as a pointer (see the <paramref name="ptr" /> argument).
        /// </param>
        /// <param name="waveSource"><see cref="IWaveSource" /> which provides the audio data to stream.</param>
        /// <param name="bufferSize">
        ///     Buffersize of the internal used buffers in milliseconds. Values in the range from 70ms to
        ///     200ms are recommended.
        /// </param>
        /// <remarks>It is recommended to use the <see cref="Create(XAudio2,IWaveSource,int)" /> method instead of the this constructor.</remarks>
        internal StreamingSourceVoice(IntPtr ptr, VoiceCallback voiceCallback, IWaveSource waveSource, int bufferSize)
        {
            BasePtr        = ptr;
            _voiceCallback = voiceCallback;
            _waveSource    = waveSource;

            var maxBufferBytes = (int)waveSource.WaveFormat.MillisecondsToBytes(bufferSize);

            _buffer = new byte[maxBufferBytes];

            for (int i = 0; i < _buffers.Length; i++)
            {
                var buffer = new XAudio2Buffer(maxBufferBytes);
                _buffers[i] = buffer;
            }

            InitializeForStreaming();
        }
        internal StreamingSourceVoice(XAudio2 xaudio2, IWaveSource waveSource, VoiceCallback voiceCallback, int bufferSize)
            : base(CreateSourceVoice(xaudio2, waveSource, voiceCallback), xaudio2.Version)
        {
            _voiceCallback = voiceCallback;
            _waveSource    = waveSource;

            var maxBufferBytes = (int)waveSource.WaveFormat.MillisecondsToBytes(bufferSize);

            _buffer = new byte[maxBufferBytes];

            for (int i = 0; i < _buffers.Length; i++)
            {
                var buffer = new XAudio2Buffer(maxBufferBytes);
                _buffers[i] = buffer;
            }

            InitializeForStreaming();
        }
        /// <summary>
        ///     Notifies the <see cref="StreamingSourceVoice" /> class that new data got requested. If there are any buffers which
        ///     are currently not queued and the underlying <see cref="IWaveSource" /> holds any more data, this data refills the
        ///     internal used buffers and provides audio data to play.
        /// </summary>
        public virtual void Refill()
        {
            lock (_lockObj) //make sure that nothing gets disposed while anything is still in use.
            {
                if (_disposed)
                {
                    _waitHandle.Close();
                    return;
                }

                int buffersQueued = GetState(GetVoiceStateFlags.NoSamplesPlayed).BuffersQueued;
                if (buffersQueued >= MaxBufferCount)
                {
                    return;
                }

                int read = _waveSource.Read(_buffer, 0, _buffer.Length);
                if (read == 0)
                {
                    return;
                }

                XAudio2Buffer nbuffer = _buffers[_currentBufferIndex];
                nbuffer.AudioBytes = read;
                //bug: could be critical since some wave sources don't provide length and position
                nbuffer.Flags = _waveSource.Position >= _waveSource.Length
                    ? XAudio2BufferFlags.EndOfStream
                    : XAudio2BufferFlags.None;
                using (var stream = nbuffer.GetStream())
                {
                    stream.Write(_buffer, 0, read);
                }

                Debug.WriteLine(String.Format("Submit: {0};{1}", nbuffer.Flags, nbuffer.AudioBytes));
                SubmitSourceBuffer(nbuffer);

                _currentBufferIndex++;
                _currentBufferIndex %= MaxBufferCount;
            }
        }
Beispiel #7
0
        public void CanSubmitSourceBuffer()
        {
            const int lengthInSeconds = 2;

            using (var masteringVoice = _xaudio2.CreateMasteringVoice())
            using (var sourceVoice = _xaudio2.CreateSourceVoice(_source.WaveFormat))
            {
                byte[] rawBuffer = new byte[_source.WaveFormat.BytesPerSecond * lengthInSeconds];
                int read = _source.Read(rawBuffer, 0, rawBuffer.Length);

                var buffer = new XAudio2Buffer(read);
                using (var stream = buffer.GetStream())
                {
                    stream.Write(rawBuffer, 0, read);
                }

                sourceVoice.SubmitSourceBuffer(buffer);
                sourceVoice.Start();

                Thread.Sleep(lengthInSeconds * 1000 + 500);
            }
        }
Beispiel #8
0
        public void CanRegisterSourceVoiceCallback()
        {
            const int lengthInSeconds = 2;
            bool b0 = false, b1 = false;

            var callback = new VoiceCallback();

            using (var masteringVoice = _xaudio2.CreateMasteringVoice())
            using (var sourceVoice = _xaudio2.CreateSourceVoice(_source.WaveFormat, VoiceFlags.None, CSCore.XAudio2.XAudio2.DefaultFrequencyRatio, callback, null, null))
            {
                callback.BufferStart += (s,e) => b0 = true;
                callback.BufferEnd += (s,e) => b1 = true;

                byte[] rawBuffer = new byte[_source.WaveFormat.BytesPerSecond * lengthInSeconds];
                int read = _source.Read(rawBuffer, 0, rawBuffer.Length);

                var buffer = new XAudio2Buffer(read);
                using (var stream = buffer.GetStream())
                {
                    stream.Write(rawBuffer, 0, read);
                }

                sourceVoice.SubmitSourceBuffer(buffer);
                sourceVoice.Start();

                Thread.Sleep(lengthInSeconds * 1000 + 2000);

                Assert.IsTrue(b0, "No BufferStart.");
                Assert.IsTrue(b1, "No BufferEnd.");
            }
        }
Beispiel #9
0
        public void CanRegisterEngineCallback()
        {
            const int lengthInSeconds = 2;
            bool b0 = false, b1 = false;

            XAudio2EngineCallback engineCallback = new XAudio2EngineCallback();
            engineCallback.ProcessingPassStart += (s, e) =>
                b0 = true;
            engineCallback.ProcessingPassEnd += (s, e) =>
                b1 = true;

            _xaudio2.RegisterForCallbacks(engineCallback);

            using (var masteringVoice = _xaudio2.CreateMasteringVoice())
            using (var sourceVoice = _xaudio2.CreateSourceVoice(_source.WaveFormat))
            {
                byte[] rawBuffer = new byte[_source.WaveFormat.BytesPerSecond * lengthInSeconds];
                int read = _source.Read(rawBuffer, 0, rawBuffer.Length);

                var buffer = new XAudio2Buffer(read);
                using (var stream = buffer.GetStream())
                {
                    stream.Write(rawBuffer, 0, read);
                }

                sourceVoice.SubmitSourceBuffer(buffer);
                sourceVoice.Start();

                Thread.Sleep((lengthInSeconds * 1000 + 500) / 2);

                Assert.IsTrue(b0 || b1);

                Console.WriteLine("Unregistered");
                _xaudio2.UnregisterForCallbacks(engineCallback);
                b0 = b1 = false;

                Thread.Sleep((lengthInSeconds * 1000 + 500) / 4);

                Assert.IsFalse(b0 && b1);

                Console.WriteLine("Register");
                _xaudio2.RegisterForCallbacks(engineCallback);

                Thread.Sleep((lengthInSeconds * 1000 + 500) / 4);

                Assert.IsTrue(b0 || b1);
            }

            _xaudio2.UnregisterForCallbacks(engineCallback);
        }
Beispiel #10
0
 /// <summary>
 ///     Adds a new audio buffer to the voice queue.
 /// </summary>
 /// <param name="buffer"><see cref="XAudio2Buffer" /> structure to queue.</param>
 /// <remarks>
 ///     See
 ///     http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.ixaudio2sourcevoice.ixaudio2sourcevoice.submitsourcebuffer(v=vs.85).aspx.
 /// </remarks>
 public unsafe void SubmitSourceBuffer(XAudio2Buffer buffer)
 {
     XAudio2Exception.Try(SubmitSourceBufferNative(new IntPtr(&buffer), IntPtr.Zero), N, "SubmitSourceBuffer");
 }
 /// <summary>
 ///     Adds a new audio buffer to the voice queue.
 /// </summary>
 /// <param name="buffer"><see cref="XAudio2Buffer" /> structure to queue.</param>
 /// <remarks>
 ///     See
 ///     http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.ixaudio2sourcevoice.ixaudio2sourcevoice.submitsourcebuffer(v=vs.85).aspx.
 /// </remarks>
 public unsafe void SubmitSourceBuffer(XAudio2Buffer buffer)
 {
     XAudio2Exception.Try(SubmitSourceBufferNative(new IntPtr(&buffer), IntPtr.Zero), N, "SubmitSourceBuffer");
 }