Ejemplo n.º 1
0
        /// <summary>
        /// Initializes the audio renderer.
        /// Call the Play Method to start reading samples
        /// </summary>
        private void Initialize()
        {
            Destroy();

            if (SoundTouch.IsAvailable)
            {
                AudioProcessor = new SoundTouch
                {
                    Channels   = (uint)WaveFormat.Channels,
                    SampleRate = (uint)WaveFormat.SampleRate
                };
            }

            AudioDevice = new WavePlayer(this)
            {
                DesiredLatency  = 200,
                NumberOfBuffers = 2,
            };

            SyncThesholdMilliseconds = 0.05 * DesiredLatency.TotalMilliseconds; // ~5% sync threshold for audio samples
            BytesPerSample           = WaveFormat.BitsPerSample / 8;
            SampleBlockSize          = BytesPerSample * WaveFormat.Channels;

            var bufferLength = WaveFormat.ConvertLatencyToByteSize(AudioDevice.DesiredLatency) * MediaElement.Blocks[MediaType.Audio].Capacity / 2;

            AudioBuffer = new CircularBuffer(bufferLength);
            AudioDevice.Init(this);
            AudioDevice.Play();
        }
Ejemplo n.º 2
0
        private bool Synchronize(byte[] targetBuffer, int targetBufferOffset, int requestedBytes)
        {
            var audioLatency = Latency;

            if (audioLatency.TotalMilliseconds > SyncThesholdMilliseconds / 2d)
            {
                // a positive audio latency means we are rendering audio behind (after) the clock (skip some samples)
                // and therefore we need to advance the buffer before we read from it.
                MediaElement.Container?.Logger?.Log(MediaLogMessageType.Warning,
                                                    $"SYNC AUDIO: LATENCY: {audioLatency.Format()} | SKIP (samples being rendered too late)");

                // skip some samples from the buffer.
                var audioLatencyBytes = WaveFormat.ConvertLatencyToByteSize((int)Math.Ceiling(audioLatency.TotalMilliseconds));
                AudioBuffer.Skip(Math.Min(audioLatencyBytes, AudioBuffer.ReadableCount));
            }
            else if (audioLatency.TotalMilliseconds < -2d * SyncThesholdMilliseconds)
            {
                // a negative audio latency means we are rendering audio ahead (before) the clock
                // and therefore we need to render some silence until the clock catches up
                MediaElement.Container?.Logger?.Log(MediaLogMessageType.Warning,
                                                    $"SYNC AUDIO: LATENCY: {audioLatency.Format()} | WAIT (samples being rendered too early)");

                // render silence for the wait time and return
                Array.Clear(targetBuffer, targetBufferOffset, requestedBytes);

                return(false);
            }

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes the audio renderer.
        /// Call the Play Method to start reading samples
        /// </summary>
        private void Initialize()
        {
            Destroy();

            if (SoundTouch.IsAvailable)
            {
                AudioProcessor = new SoundTouch
                {
                    Channels   = Convert.ToUInt32(WaveFormat.Channels),
                    SampleRate = Convert.ToUInt32(WaveFormat.SampleRate)
                };
            }

            AudioDevice = new WavePlayer(this)
            {
                DesiredLatency  = 200,
                NumberOfBuffers = 2,
            };

            SampleBlockSize = Constants.Audio.BytesPerSample * Constants.Audio.ChannelCount;
            var bufferLength = WaveFormat.ConvertLatencyToByteSize(AudioDevice.DesiredLatency) * MediaCore.Blocks[MediaType.Audio].Capacity / 2;

            AudioBuffer = new CircularBuffer(bufferLength);
            AudioDevice.Init(this);
            AudioDevice.Play();
        }
        private void InitialiseDirectSound(IntPtr windowHandle, int sampleRate)
        {
            var waveFormat = new WaveFormat(sampleRate, 16, 2);

            _directSound = new DirectSound();
            _directSound.SetCooperativeLevel(windowHandle, CooperativeLevel.Priority);

            var primaryBufferDescription = new SoundBufferDescription()
            {
                Flags          = BufferFlags.PrimaryBuffer,
                AlgorithmFor3D = Guid.Empty,
            };

            _primarySoundBuffer = new PrimarySoundBuffer(_directSound, primaryBufferDescription)
            {
                Format = waveFormat
            };

            _soundBufferLength = waveFormat.ConvertLatencyToByteSize(500);

            var secondaryBufferDescription = new SoundBufferDescription()
            {
                Format         = waveFormat,
                Flags          = BufferFlags.GetCurrentPosition2 | BufferFlags.GlobalFocus,
                BufferBytes    = _soundBufferLength,
                AlgorithmFor3D = Guid.Empty,
            };

            _soundBuffer = new SecondarySoundBuffer(_directSound, secondaryBufferDescription);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes the audio renderer.
        /// Call the Play Method to start reading samples
        /// </summary>
        private void Initialize()
        {
            Destroy();

            if (SoundTouch.IsAvailable)
            {
                AudioProcessor = new SoundTouch
                {
                    Channels   = (uint)WaveFormat.Channels,
                    SampleRate = (uint)WaveFormat.SampleRate
                };
            }

            AudioDevice = new WavePlayer(this)
            {
                DesiredLatency  = 200,
                NumberOfBuffers = 2,
            };

            BytesPerSample  = WaveFormat.BitsPerSample / 8;
            SampleBlockSize = BytesPerSample * WaveFormat.Channels;

            var bufferLength = WaveFormat.ConvertLatencyToByteSize(AudioDevice.DesiredLatency) * MediaCore.Blocks[MediaType.Audio].Capacity / 2;

            AudioBuffer = new CircularBuffer(bufferLength);
            AudioDevice.Init(this);
            AudioDevice.Play();
        }
Ejemplo n.º 6
0
        static void Main(string[] args)
        {
            DirectSound directSound = new DirectSound();

            var form = new Form();
            form.Text = "SharpDX - DirectSound Demo";

            // Set Cooperative Level to PRIORITY (priority level can call the SetFormat and Compact methods)
            //
            directSound.SetCooperativeLevel(form.Handle, CooperativeLevel.Priority);

            // Create PrimarySoundBuffer
            var primaryBufferDesc = new SoundBufferDescription();
            primaryBufferDesc.Flags = BufferFlags.PrimaryBuffer;
            primaryBufferDesc.AlgorithmFor3D = Guid.Empty;

            var primarySoundBuffer = new PrimarySoundBuffer(directSound, primaryBufferDesc);

            // Play the PrimarySound Buffer
            primarySoundBuffer.Play(0, PlayFlags.Looping);

            // Default WaveFormat Stereo 44100 16 bit
            WaveFormat waveFormat = new WaveFormat();

            // Create SecondarySoundBuffer
            var secondaryBufferDesc = new SoundBufferDescription();
            secondaryBufferDesc.BufferBytes = waveFormat.ConvertLatencyToByteSize(60000);
            secondaryBufferDesc.Format = waveFormat;
            secondaryBufferDesc.Flags = BufferFlags.GetCurrentPosition2 | BufferFlags.ControlPositionNotify | BufferFlags.GlobalFocus |
                                        BufferFlags.ControlVolume | BufferFlags.StickyFocus;
            secondaryBufferDesc.AlgorithmFor3D = Guid.Empty;
            var secondarySoundBuffer = new SecondarySoundBuffer(directSound, secondaryBufferDesc);

            // Get Capabilties from secondary sound buffer
            var capabilities = secondarySoundBuffer.Capabilities;

            // Lock the buffer
            DataStream dataPart2;
            var dataPart1 =secondarySoundBuffer.Lock(0, capabilities.BufferBytes,  LockFlags.EntireBuffer, out dataPart2);

            // Fill the buffer with some sound
            int numberOfSamples = capabilities.BufferBytes/waveFormat.BlockAlign;
            for (int i = 0; i < numberOfSamples; i++)
            {
                double vibrato = Math.Cos(2 * Math.PI * 10.0 * i /waveFormat.SampleRate);
                short value = (short) (Math.Cos(2*Math.PI*(220.0 + 4.0 * vibrato)*i/waveFormat.SampleRate)*16384); // Not too loud
                dataPart1.Write(value);
                dataPart1.Write(value);
            }

            // Unlock the buffer
            secondarySoundBuffer.Unlock(dataPart1, dataPart2);

            // Play the song
            secondarySoundBuffer.Play(0, PlayFlags.Looping);
           
            Application.Run(form);
        }
Ejemplo n.º 7
0
        static void Main(string[] args)
        {
            Console.WriteLine("1 - Direct sound");
            Console.WriteLine("2 - Windows media player");
            Console.WriteLine("Twój wybór:");
            string wartosc = Console.ReadLine();

            if (wartosc == "1")
            {
                Console.Write("Podaj nazwe pliku z pulpitu: ");
                string      nazwa_pliku = Console.ReadLine();
                var         path        = "C:\\Users\\lab\\Desktop\\" + nazwa_pliku;
                DirectSound directSound = new DirectSound();

                var primaryBufferDesc = new SoundBufferDescription();
                primaryBufferDesc.Flags = BufferFlags.PrimaryBuffer;

                var primarySoundBuffer = new PrimarySoundBuffer(directSound, primaryBufferDesc);

                primarySoundBuffer.Play(0, PlayFlags.Looping);

                WaveFormat waveFormat = new WaveFormat();

                var secondaryBufferDesc = new SoundBufferDescription();
                secondaryBufferDesc.BufferBytes = waveFormat.ConvertLatencyToByteSize(60000);
                secondaryBufferDesc.Format      = waveFormat;
                secondaryBufferDesc.Flags       = BufferFlags.GetCurrentPosition2 | BufferFlags.ControlPositionNotify | BufferFlags.GlobalFocus |
                                                  BufferFlags.ControlVolume | BufferFlags.StickyFocus;
                secondaryBufferDesc.AlgorithmFor3D = Guid.Empty;
                var secondarySoundBuffer = new SecondarySoundBuffer(directSound, secondaryBufferDesc);
                var capabilities         = secondarySoundBuffer.Capabilities;

                //Stream stream = File.Open(path, FileMode.Open);
                //byte[] arrayTest = ReadFully(stream);
                byte[]     array = File.ReadAllBytes(path);
                DataStream dataPart2;
                var        dataPart1 = secondarySoundBuffer.Lock(0, capabilities.BufferBytes, LockFlags.EntireBuffer, out dataPart2);
                dataPart1.Read(array, 0, array.Length);
                int numberOfSamples = capabilities.BufferBytes / waveFormat.BlockAlign;
                for (int i = 0; i < numberOfSamples; i++)
                {
                    double vibrato = Math.Cos(2 * Math.PI * 10.0 * i / waveFormat.SampleRate);
                    short  value   = (short)(Math.Cos(2 * Math.PI * (220.0 + 4.0 * vibrato) * i / waveFormat.SampleRate) * 16384); // Not too loud
                    dataPart1.Write(value);
                }
                secondarySoundBuffer.Unlock(dataPart1, dataPart2);
                secondarySoundBuffer.Play(0, PlayFlags.None);
            }
            else
            {
                Console.Write("Podaj nazwe pliku z pulpitu: ");
                string nazwa_pliku = Console.ReadLine();
                player     = new WindowsMediaPlayer();
                player.URL = "C:\\Users\\lab\\Desktop\\" + nazwa_pliku;
                player.controls.play();
            }
        }
Ejemplo n.º 8
0
        public Sound(IntPtr handle)
        {
            test[1] = test[0] + 2;
            test[2] = test[1] + 2;
            test[3] = test[2] + 1;
            test[4] = test[3] + 2;
            test[5] = test[4] + 2;
            test[6] = test[5] + 2;


            DirectSound directSound = new DirectSound();

            // Set Cooperative Level to PRIORITY (priority level can call the SetFormat and Compact methods)
            //
            directSound.SetCooperativeLevel(handle, CooperativeLevel.Priority);

            // Create PrimarySoundBuffer
            var primaryBufferDesc = new SoundBufferDescription();

            primaryBufferDesc.Flags          = BufferFlags.PrimaryBuffer;
            primaryBufferDesc.AlgorithmFor3D = Guid.Empty;

            var primarySoundBuffer = new PrimarySoundBuffer(directSound, primaryBufferDesc);

            // Play the PrimarySound Buffer
            primarySoundBuffer.Play(0, PlayFlags.Looping);

            // Default WaveFormat Stereo 44100 16 bit
            waveFormat = new WaveFormat();

            // Create SecondarySoundBuffer
            var secondaryBufferDesc = new SoundBufferDescription();

            secondaryBufferDesc.BufferBytes = waveFormat.ConvertLatencyToByteSize(10000);
            secondaryBufferDesc.Format      = waveFormat;
            secondaryBufferDesc.Flags       = BufferFlags.GetCurrentPosition2 | BufferFlags.ControlPositionNotify | BufferFlags.GlobalFocus |
                                              BufferFlags.ControlVolume | BufferFlags.StickyFocus;
            secondaryBufferDesc.AlgorithmFor3D = Guid.Empty;
            secondarySoundBuffer = new SecondarySoundBuffer(directSound, secondaryBufferDesc);

            // Get Capabilties from secondary sound buffer
            capabilities = secondarySoundBuffer.Capabilities;
            sounds       = new short[capabilities.BufferBytes / waveFormat.BlockAlign];

            // Play the song
            secondarySoundBuffer.Play(0, PlayFlags.Looping);

            for (int i = 0; i < sounds.Length; i++)
            {
                sounds[i] = 0;
            }
        }
Ejemplo n.º 9
0
        public SourceVoiceEx(SourceVoice sourceVoice, Guid id, WaveFormat waveFormat, int operationId)
        {
            SourceVoice = sourceVoice;
            Id          = id;

            WaveFormat  = waveFormat;
            _bufferSize = WaveFormat.ConvertLatencyToByteSize(8);

            OperationId = operationId;

            PreviousWorkItem = new PlayWorkItem {
                Pan = Double.MinValue, Pitch = Double.MinValue, Volume = Double.MinValue
            };
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes the audio renderer.
        /// Call the Play Method to start reading samples
        /// </summary>
        private void Initialize()
        {
            Destroy();

            AudioDevice = new WavePlayer()
            {
                DesiredLatency  = 200,
                NumberOfBuffers = 2,
            };

            var bufferLength = WaveFormat.ConvertLatencyToByteSize(AudioDevice.DesiredLatency) * MediaElement.Blocks[MediaType.Audio].Capacity / 2;

            AudioBuffer = new CircularBuffer(bufferLength);
            AudioDevice.Init(this);
        }
Ejemplo n.º 11
0
        public PlayForm()
        {
            InitializeComponent();

            // Initalize XAudio2
            xaudio2        = new XAudio2(XAudio2Flags.None, ProcessorSpecifier.DefaultProcessor);
            masteringVoice = new MasteringVoice(xaudio2);

            var waveFormat = new WaveFormat(44100, 32, 2);

            sourceVoice = new SourceVoice(xaudio2, waveFormat);

            int        bufferSize = waveFormat.ConvertLatencyToByteSize(60000);
            DataStream dataStream = new DataStream(bufferSize, true, true);

            // Prepare the initial sound to modulate
            int numberOfSamples = bufferSize / waveFormat.BlockAlign;

            for (int i = 0; i < numberOfSamples; i++)
            {
                float value = (float)(Math.Cos(2 * Math.PI * 220.0 * i / waveFormat.SampleRate) * 0.5);
                dataStream.Write(value);
                dataStream.Write(value);
            }
            dataStream.Position = 0;

            audioBuffer = new AudioBuffer
            {
                Stream     = dataStream,
                Flags      = BufferFlags.EndOfStream,
                AudioBytes = bufferSize,
                LoopBegin  = 0,
                LoopLength = numberOfSamples,
                LoopCount  = AudioBuffer.LoopInfinite
            };

            // Set the effect on the source
            ModulatorEffect     = new ModulatorEffect();
            modulatorDescriptor = new EffectDescriptor(ModulatorEffect);
            reverb           = new Reverb();
            effectDescriptor = new EffectDescriptor(reverb);
            //sourceVoice.SetEffectChain(modulatorDescriptor, effectDescriptor);
            sourceVoice.SetEffectChain(modulatorDescriptor);
            //sourceVoice.EnableEffect(0);

            this.Closed += new EventHandler(PlayForm_Closed);
        }
Ejemplo n.º 12
0
        public AudioCapture()
        {
            try
            {
                directSoundCapture = new DirectSoundCapture();
            }
            catch
            {
                throw new AudioCaptureException("Could not open recording device");
            }
            //var directSoundCaps = directSoundCapture.Capabilities;

            // Default 44.1kHz 16-bit stereo PCM
            waveFormat = new WaveFormat();

            // Set the buffer size.
            // Note that the buffer position will roll over to 0 when the buffer fills up,
            // so set the notification position's offset to one less than the buffer size.
            bufferSize      = waveFormat.ConvertLatencyToByteSize(latency);
            numberOfSamples = bufferSize / waveFormat.BlockAlign;

            // Create audio capture buffer
            captureBufferDesc             = new CaptureBufferDescription();
            captureBufferDesc.Format      = waveFormat;
            captureBufferDesc.BufferBytes = bufferSize;
            captureBuffer = new CaptureBuffer(directSoundCapture, captureBufferDesc);

            // Wait events allow the thread to wait asynchronously for the buffer to fill
            var evt = new AutoResetEvent(false);

            fullEvent = new WaitHandle[] { evt };

            // Notify the thread when the buffer is full
            var nf = new NotificationPosition();

            nf.Offset     = bufferSize - 1;
            nf.WaitHandle = fullEvent[0];
            var nfs = new NotificationPosition[] { nf };

            captureBuffer.SetNotificationPositions(nfs);

            // Start the processing thread
            thread = new Thread(new ThreadStart(Process));
            thread.IsBackground = true; // Allow application to exit
            thread.Start();
        }
Ejemplo n.º 13
0
        /// <summary>
        /// SharpDX XAudio2 sample. Plays a generated sound with some reverb.
        /// </summary>
        static void Main(string[] args)
        {
            var xaudio2        = new XAudio2();
            var masteringVoice = new MasteringVoice(xaudio2);

            var waveFormat  = new WaveFormat(44100, 32, 2);
            var sourceVoice = new SourceVoice(xaudio2, waveFormat);

            int bufferSize = waveFormat.ConvertLatencyToByteSize(60000);
            var dataStream = new DataStream(bufferSize, true, true);

            int numberOfSamples = bufferSize / waveFormat.BlockAlign;

            for (int i = 0; i < numberOfSamples; i++)
            {
                // cos(2 * PI * (220 + 4 * cos(2 * PI * 10 * t)) * t) * 0.5
                double vibrato = Math.Cos(2 * Math.PI * 10.0 * i / waveFormat.SampleRate);
                float  value   = (float)(Math.Cos(2 * Math.PI * (220.0 + 4.0 * vibrato) * i / waveFormat.SampleRate) * 0.5);
                dataStream.Write(value);
                dataStream.Write(value);
            }
            dataStream.Position = 0;

            var audioBuffer = new AudioBuffer {
                Stream = dataStream, Flags = BufferFlags.EndOfStream, AudioBytes = bufferSize
            };

            var reverb           = new Reverb(xaudio2);
            var effectDescriptor = new EffectDescriptor(reverb);

            sourceVoice.SetEffectChain(effectDescriptor);
            sourceVoice.EnableEffect(0);

            sourceVoice.SubmitSourceBuffer(audioBuffer, null);

            sourceVoice.Start();

            Console.WriteLine("Play sound");
            for (int i = 0; i < 60; i++)
            {
                Console.Write(".");
                Console.Out.Flush();
                Thread.Sleep(1000);
            }
        }
Ejemplo n.º 14
0
        public SineGenerator()
        {
            _xaudio2        = new XAudio2();
            _masteringVoice = new MasteringVoice(_xaudio2);

            _waveFormat = new WaveFormat(44100, 32, 2);

            _sourceVoice = new SourceVoice(_xaudio2, _waveFormat);

            _bufferSize = _waveFormat.ConvertLatencyToByteSize(7);
            _dataStream = new DataStream(_bufferSize, true, true);

            _sourceVoice.BufferEnd += sourceVoice_BufferEnd;
            _sourceVoice.Start();

            _isConvolutionOn = false;
            _horizontalAngle = 0;
            _elevation       = 0;

            _bufferEndEvent = new AutoResetEvent(false);

            _valueRate = 20;
            _valueAmp  = 0.5f;

            _nextBuffer = 0;

            _playEvent = new ManualResetEventSlim();
            _log       = new List <string>();


            // Pre-allocate buffers
            _audioBuffersRing = new AudioBuffer[3];
            _memBuffers       = new DataPointer[_audioBuffersRing.Length];
            for (int i = 0; i < _audioBuffersRing.Length; i++)
            {
                _audioBuffersRing[i]   = new AudioBuffer();
                _memBuffers[i].Size    = _bufferSize;
                _memBuffers[i].Pointer = Utilities.AllocateMemory(_memBuffers[i].Size);
            }

            _playSoundTask = Task.Factory.StartNew(PlaySoundAsync, TaskCreationOptions.LongRunning);
        }
Ejemplo n.º 15
0
        public BeatDetector(WaveFormat waveFormat, int historyLength, int bufferSize)
        {
            //this.bufferSize = bufferSize;
            this.historyLength = historyLength;

            // Number of history buffers needed to be equivalent to historyLength (milliseconds)
            historySize = waveFormat.ConvertLatencyToByteSize(historyLength) / bufferSize;
            beatsSize   = historySize;

            history      = new float[historySize];
            historyIndex = 0;

            beats     = new float[beatsSize];
            beatIndex = 0;

            fft = new FastFourierTransform(beatsSize, 1);

            InstantaneousEnergy = 0.0f;
            AverageEnergy       = 0.0f;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AudioPlayer" /> class.
        /// </summary>
        /// <param name="xaudio2">The xaudio2 engine.</param>
        /// <param name="audioStream">The input audio stream.</param>
        public AudioPlayer(XAudio2 xaudio2, Stream audioStream)
        {
            _xaudio2 = xaudio2;
            var audioDecoder = new AudioDecoder(audioStream);

            audioStream.Seek(0, SeekOrigin.Begin);
            _indDataStream = ConverStreamToIeeeFloat(new SoundStream(audioStream).ToDataStream());

            _waveFormat = new WaveFormat(audioDecoder.WaveFormat.SampleRate, 32, audioDecoder.WaveFormat.Channels);
            audioDecoder.Dispose();
            _sourceVoice = new SourceVoice(xaudio2, _waveFormat);

            _bufferSize      = _waveFormat.ConvertLatencyToByteSize(7);
            _isConvolutionOn = false;
            _horizontalAngle = 0f;
            _elevation       = 0f;

            _sourceVoice.BufferEnd += sourceVoice_BufferEnd;
            _sourceVoice.Start();

            _bufferEndEvent = new AutoResetEvent(false);
            _playEvent      = new ManualResetEvent(false);

            _convolution = new Convolution();

            // Pre-allocate buffers
            _audioBuffersRing = new AudioBuffer[3];
            _memBuffers       = new DataPointer[_audioBuffersRing.Length];
            for (int i = 0; i < _audioBuffersRing.Length; i++)
            {
                _audioBuffersRing[i]   = new AudioBuffer();
                _memBuffers[i].Size    = 32 * 1024; // default size 32Kb
                _memBuffers[i].Pointer = Utilities.AllocateMemory(_memBuffers[i].Size);
            }

            // Initialize to stopped
            State = PlayerState.Stopped;

            // Starts the playing thread
            _playingTask = Task.Factory.StartNew(PlayAsync, TaskCreationOptions.LongRunning);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Initializes the audio renderer.
        /// Call the Play Method to start reading samples
        /// </summary>
        private void Initialize()
        {
            Destroy();

            if (SoundTouch.IsAvailable)
            {
                AudioProcessor = new SoundTouch
                {
                    Channels   = Convert.ToUInt32(WaveFormat.Channels),
                    SampleRate = Convert.ToUInt32(WaveFormat.SampleRate)
                };
            }

            AudioDevice = MediaElement.RendererOptions.UseLegacyAudioOut ?
                          new LegacyAudioPlayer(this, MediaElement.RendererOptions.LegacyAudioDevice?.DeviceId ?? -1) as IWavePlayer :
                          new DirectSoundPlayer(this, MediaElement.RendererOptions.DirectSoundDevice?.DeviceId ?? DirectSoundPlayer.DefaultPlaybackDeviceId);

            SampleBlockSize = Constants.Audio.BytesPerSample * Constants.Audio.ChannelCount;
            var bufferLength = WaveFormat.ConvertLatencyToByteSize(AudioDevice.DesiredLatency) * MediaCore.Blocks[MediaType.Audio].Capacity / 2;

            AudioBuffer = new CircularBuffer(bufferLength);
            AudioDevice.Start();
        }
Ejemplo n.º 18
0
        public void Generate()
        {
            var xaudio2        = new XAudio2();
            var masteringVoice = new MasteringVoice(xaudio2);

            var waveFormat  = new WaveFormat(44100, 32, 2);
            var sourceVoice = new SourceVoice(xaudio2, waveFormat);

            int bufferSize = waveFormat.ConvertLatencyToByteSize(60000);
            var dataStream = new DataStream(bufferSize, true, true);

            int numberOfSamples = bufferSize / waveFormat.BlockAlign;

            for (int i = 0; i < numberOfSamples; i++)
            {
                float value = (float)(Math.Cos(2 * Math.PI * (220.0 + 4.0) * i / waveFormat.SampleRate) * 0.5);
                dataStream.Write(value);
                dataStream.Write(value);
            }
            dataStream.Position = 0;

            var audioBuffer = new AudioBuffer {
                Stream = dataStream, Flags = BufferFlags.EndOfStream, AudioBytes = bufferSize
            };

            sourceVoice.SubmitSourceBuffer(audioBuffer, null);

            sourceVoice.Start();

            Console.WriteLine("Play sound");
            for (int i = 0; i < 60; i++)
            {
                Console.Write(".");
                Console.Out.Flush();
                Thread.Sleep(1000);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// SharpDX X3DAudio sample. Plays a generated sound rotating around the listener.
        /// </summary>
        static void Main(string[] args)
        {
            var xaudio2 = new XAudio2();

            using (var masteringVoice = new MasteringVoice(xaudio2))
            {
                // Instantiate X3DAudio
                var x3dAudio = new X3DAudio(Speakers.Stereo);

                var emitter = new Emitter
                {
                    ChannelCount        = 1,
                    CurveDistanceScaler = float.MinValue,
                    OrientFront         = new Vector3(0, 0, 1),
                    OrientTop           = new Vector3(0, 1, 0),
                    Position            = new Vector3(0, 0, 0),
                    Velocity            = new Vector3(0, 0, 0)
                };

                var listener = new Listener
                {
                    OrientFront = new Vector3(0, 0, 1),
                    OrientTop   = new Vector3(0, 1, 0),
                    Position    = new Vector3(0, 0, 0),
                    Velocity    = new Vector3(0, 0, 0)
                };

                var waveFormat  = new WaveFormat(44100, 32, 1);
                var sourceVoice = new SourceVoice(xaudio2, waveFormat);

                int bufferSize = waveFormat.ConvertLatencyToByteSize(60000);
                var dataStream = new DataStream(bufferSize, true, true);

                int numberOfSamples = bufferSize / waveFormat.BlockAlign;
                for (int i = 0; i < numberOfSamples; i++)
                {
                    float value = (float)(Math.Cos(2 * Math.PI * 220.0 * i / waveFormat.SampleRate) * 0.5);
                    dataStream.Write(value);
                }
                dataStream.Position = 0;

                var audioBuffer = new AudioBuffer
                {
                    Stream = dataStream, Flags = BufferFlags.EndOfStream, AudioBytes = bufferSize
                };

                //var reverb = new Reverb();
                //var effectDescriptor = new EffectDescriptor(reverb);
                //sourceVoice.SetEffectChain(effectDescriptor);
                //sourceVoice.EnableEffect(0);

                sourceVoice.SubmitSourceBuffer(audioBuffer, null);

                sourceVoice.Start();

                Console.WriteLine("Play a sound rotating around the listener");
                for (int i = 0; i < 1200; i++)
                {
                    // Rotates the emitter
                    var rotateEmitter      = Matrix.RotationY(i / 5.0f);
                    var newPosition        = Vector3.Transform(new Vector3(0, 0, 1000), rotateEmitter);
                    var newPositionVector3 = new Vector3(newPosition.X, newPosition.Y, newPosition.Z);
                    emitter.Velocity = (newPositionVector3 - emitter.Position) / 0.05f;
                    emitter.Position = newPositionVector3;

                    // Calculate X3DAudio settings
                    var dspSettings = x3dAudio.Calculate(listener, emitter, CalculateFlags.Matrix | CalculateFlags.Doppler, 1, 2);

                    // Modify XAudio2 source voice settings
                    sourceVoice.SetOutputMatrix(1, 2, dspSettings.MatrixCoefficients);
                    sourceVoice.SetFrequencyRatio(dspSettings.DopplerFactor);

                    // Wait for 50ms
                    Thread.Sleep(50);
                }
            }
        }
Ejemplo n.º 20
0
        static void Main()
        {
            var initError = EVRInitError.None;

            system = OpenVR.Init(ref initError);

            if (initError != EVRInitError.None)
            {
                return;
            }

            compositor = OpenVR.Compositor;

            compositor.CompositorBringToFront();
            compositor.FadeGrid(5.0f, false);

            count = OpenVR.k_unMaxTrackedDeviceCount;

            currentPoses = new TrackedDevicePose_t[count];
            nextPoses    = new TrackedDevicePose_t[count];

            controllers                    = new List <uint>();
            controllerModels               = new RenderModel_t[count];
            controllerTextures             = new RenderModel_TextureMap_t[count];
            controllerTextureViews         = new ShaderResourceView[count];
            controllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
            controllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
            controllerVertexBufferBindings = new VertexBufferBinding[count];
            controllerEmitters             = new Emitter[count];
            controllerVoices               = new SourceVoice[count];

            for (uint device = 0; device < count; device++)
            {
                var deviceClass = system.GetTrackedDeviceClass(device);

                switch (deviceClass)
                {
                case ETrackedDeviceClass.HMD:
                    headset = device;
                    break;

                case ETrackedDeviceClass.Controller:
                    controllers.Add(device);
                    break;
                }
            }

            uint width  = 0;
            uint height = 0;

            system.GetRecommendedRenderTargetSize(ref width, ref height);

            headsetSize = new Size((int)width, (int)height);
            windowSize  = new Size(960, 540);

            var leftEyeProjection  = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
            var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

            var leftEyeView  = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left));
            var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right));

            foreach (var controller in controllers)
            {
                var modelName     = new StringBuilder(255, 255);
                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                {
                    var modelName2 = modelName.ToString();

                    while (true)
                    {
                        var pointer    = IntPtr.Zero;
                        var modelError = EVRRenderModelError.None;

                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                        if (modelError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (modelError == EVRRenderModelError.None)
                        {
                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                            controllerModels[controller] = renderModel;
                            break;
                        }
                    }

                    while (true)
                    {
                        var pointer      = IntPtr.Zero;
                        var textureError = EVRRenderModelError.None;

                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                        if (textureError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (textureError == EVRRenderModelError.None)
                        {
                            var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                            controllerTextures[controller] = texture;
                            break;
                        }
                    }
                }
            }

            int adapterIndex = 0;

            system.GetDXGIOutputInfo(ref adapterIndex);

            using (var form = new Form())
                using (var factory = new Factory4())
                {
                    form.ClientSize = windowSize;

                    var adapter = factory.GetAdapter(adapterIndex);

                    var swapChainDescription = new SwapChainDescription
                    {
                        BufferCount     = 1,
                        Flags           = SwapChainFlags.None,
                        IsWindowed      = true,
                        ModeDescription = new ModeDescription
                        {
                            Format      = Format.B8G8R8A8_UNorm,
                            Width       = form.ClientSize.Width,
                            Height      = form.ClientSize.Height,
                            RefreshRate = new Rational(60, 1)
                        },
                        OutputHandle      = form.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect        = SwapEffect.Discard,
                        Usage             = Usage.RenderTargetOutput
                    };

                    SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain);

                    factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None);

                    context = device.ImmediateContext;

                    using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                        backBufferView = new RenderTargetView(device, backBuffer);

                    var depthBufferDescription = new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = form.ClientSize.Width,
                        Height            = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default,
                        BindFlags         = BindFlags.DepthStencil,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        OptionFlags       = ResourceOptionFlags.None
                    };

                    using (var depthBuffer = new Texture2D(device, depthBufferDescription))
                        depthStencilView = new DepthStencilView(device, depthBuffer);

                    // Create Eye Textures
                    var eyeTextureDescription = new Texture2DDescription
                    {
                        ArraySize         = 1,
                        BindFlags         = BindFlags.RenderTarget,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.B8G8R8A8_UNorm,
                        Width             = headsetSize.Width,
                        Height            = headsetSize.Height,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.None,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default
                    };

                    var leftEyeTexture  = new Texture2D(device, eyeTextureDescription);
                    var rightEyeTexture = new Texture2D(device, eyeTextureDescription);

                    var leftEyeTextureView  = new RenderTargetView(device, leftEyeTexture);
                    var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture);

                    // Create Eye Depth Buffer
                    eyeTextureDescription.BindFlags = BindFlags.DepthStencil;
                    eyeTextureDescription.Format    = Format.D32_Float;

                    var eyeDepth     = new Texture2D(device, eyeTextureDescription);
                    var eyeDepthView = new DepthStencilView(device, eyeDepth);

                    Shapes.Cube.Load(device);
                    Shapes.Sphere.Load(device);
                    Shaders.Load(device);

                    // Load Controller Models
                    foreach (var controller in controllers)
                    {
                        var model = controllerModels[controller];

                        controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.VertexBuffer,
                            SizeInBytes = (int)model.unVertexCount * 32
                        });

                        controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                        controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.IndexBuffer,
                            SizeInBytes = (int)model.unTriangleCount * 3 * 2
                        });

                        var texture = controllerTextures[controller];

                        using (var texture2d = new Texture2D(device, new Texture2DDescription
                        {
                            ArraySize = 1,
                            BindFlags = BindFlags.ShaderResource,
                            Format = Format.R8G8B8A8_UNorm,
                            Width = texture.unWidth,
                            Height = texture.unHeight,
                            MipLevels = 1,
                            SampleDescription = new SampleDescription(1, 0)
                        }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4)))
                            controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);
                    }

                    var controllerVertexShaderByteCode = SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "VS", "vs_5_0");
                    controllerVertexShader = new VertexShader(device, controllerVertexShaderByteCode);
                    controllerPixelShader  = new PixelShader(device, SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "PS", "ps_5_0"));

                    var controllerLayout = new InputLayout(device, SharpDX.D3DCompiler.ShaderSignature.GetInputSignature(controllerVertexShaderByteCode), new InputElement[]
                    {
                        new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                        new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                        new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0)
                    });

                    worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.None;

                    rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();

                    blendStateDescription.RenderTarget[0].BlendOperation   = BlendOperation.Add;
                    blendStateDescription.RenderTarget[0].SourceBlend      = BlendOption.SourceAlpha;
                    blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;

                    blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

                    blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    samplerState = new SamplerState(device, samplerStateDescription);

                    startTime  = DateTime.Now;
                    frame      = 0;
                    windowSize = form.ClientSize;

                    backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1);

                    var vrEvent   = new VREvent_t();
                    var eventSize = (uint)Utilities.SizeOf <VREvent_t>();

                    head = Matrix.Identity;

                    // Initialize Audio
                    audio = new XAudio2();
                    var voice = new MasteringVoice(audio);
                    audio3d = new X3DAudio(Speakers.Stereo);

                    foreach (var controller in controllers)
                    {
                        controllerEmitters[controller] = new Emitter
                        {
                            ChannelCount        = 1,
                            CurveDistanceScaler = 0.15f,
                            OrientFront         = Vector3.ForwardLH,
                            OrientTop           = Vector3.Up,
                            Position            = new Vector3(0, 0, 1000),
                            //Velocity = Vector3.Zero
                        };
                    }

                    listener = new Listener
                    {
                        OrientFront = Vector3.ForwardLH,
                        OrientTop   = Vector3.Up,
                        Position    = new Vector3(0, 0, 1000)
                    };

                    var audioFormat = new WaveFormat(44100, 32, 1);
                    //var audioSource = new SourceVoice(audio, audioFormat);
                    var audioBufferSize = audioFormat.ConvertLatencyToByteSize(1000);
                    var audioStream     = new DataStream(audioBufferSize, true, true);
                    var audioSamples    = audioBufferSize / audioFormat.BlockAlign;

                    var random = new Random();

                    for (var sample = 0; sample < audioSamples; sample++)
                    {
                        audioStream.Write((float)random.NextFloat(-1, 1));
                    }

                    audioStream.Position = 0;

                    var audioBuffer = new AudioBuffer
                    {
                        Stream     = audioStream,
                        AudioBytes = audioBufferSize,
                        LoopCount  = 255
                    };

                    var audioSettings = new DspSettings(1, 2);

                    foreach (var controller in controllers)
                    {
                        var audioSource = new SourceVoice(audio, audioFormat);

                        audioSource.SubmitSourceBuffer(audioBuffer, null);

                        audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                        audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);

                        audioSource.Start();

                        controllerVoices[controller] = audioSource;
                    }

                    RenderLoop.Run(form, () =>
                    {
                        while (system.PollNextEvent(ref vrEvent, eventSize))
                        {
                            switch ((EVREventType)vrEvent.eventType)
                            {
                            case EVREventType.VREvent_TrackedDeviceActivated:
                                var controller = vrEvent.trackedDeviceIndex;

                                controllers.Add(controller);

                                var modelName     = new StringBuilder(255, 255);
                                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                                {
                                    var modelName2 = modelName.ToString();

                                    while (true)
                                    {
                                        var pointer    = IntPtr.Zero;
                                        var modelError = EVRRenderModelError.None;

                                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                                        if (modelError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (modelError == EVRRenderModelError.None)
                                        {
                                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                                            controllerModels[controller] = renderModel;

                                            // Load Controller Model
                                            var model = controllerModels[controller];

                                            controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.VertexBuffer,
                                                SizeInBytes = (int)model.unVertexCount * 32
                                            });

                                            controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                                            controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.IndexBuffer,
                                                SizeInBytes = (int)model.unTriangleCount * 3 * 2
                                            });

                                            break;
                                        }
                                    }

                                    while (true)
                                    {
                                        var pointer      = IntPtr.Zero;
                                        var textureError = EVRRenderModelError.None;

                                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                                        if (textureError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (textureError == EVRRenderModelError.None)
                                        {
                                            var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                                            controllerTextures[controller] = textureMap;

                                            using (var texture2d = new Texture2D(device, new Texture2DDescription
                                            {
                                                ArraySize = 1,
                                                BindFlags = BindFlags.ShaderResource,
                                                Format = Format.R8G8B8A8_UNorm,
                                                Width = textureMap.unWidth,
                                                Height = textureMap.unHeight,
                                                MipLevels = 1,
                                                SampleDescription = new SampleDescription(1, 0)
                                            }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4)))
                                                controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);

                                            break;
                                        }
                                    }

                                    controllerEmitters[controller] = new Emitter
                                    {
                                        ChannelCount        = 1,
                                        CurveDistanceScaler = 0.15f,
                                        OrientFront         = Vector3.ForwardLH,
                                        OrientTop           = Vector3.Up,
                                        Position            = new Vector3(0, 0, 1000),
                                        //Velocity = Vector3.Zero
                                    };

                                    var audioSource = new SourceVoice(audio, audioFormat);

                                    audioSource.SubmitSourceBuffer(audioBuffer, null);

                                    audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                                    audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);

                                    audioSource.Start();

                                    controllerVoices[controller] = audioSource;
                                }
                                break;

                            case EVREventType.VREvent_TrackedDeviceDeactivated:
                                controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex);
                                break;

                            default:
                                System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType);
                                break;
                            }
                        }

                        if (form.ClientSize != windowSize)
                        {
                            Utilities.Dispose(ref backBufferView);

                            if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0)
                            {
                                swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None);

                                using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                                    backBufferView = new RenderTargetView(device, backBuffer);
                            }

                            windowSize = form.ClientSize;
                        }

                        // Update Device Tracking
                        compositor.WaitGetPoses(currentPoses, nextPoses);

                        if (currentPoses[headset].bPoseIsValid)
                        {
                            Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head);

                            // Update Audio Listener
                            listener.Position    = head.TranslationVector * new Vector3(1, 1, -1);
                            listener.OrientFront = head.Forward * new Vector3(1, 1, -1);
                            listener.OrientTop   = head.Up * new Vector3(1, 1, -1);
                        }

                        foreach (var controller in controllers)
                        {
                            var controllerMatrix = Matrix.Identity;

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix);

                            var position = controllerMatrix.TranslationVector * new Vector3(1, 1, -1);

                            controllerEmitters[controller].Position = position;

                            audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                            controllerVoices[controller].SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);
                        }

                        // Render Left Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(leftEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        var ratio = (float)headsetSize.Width / (float)headsetSize.Height;

                        var projection = leftEyeProjection;
                        var view       = Matrix.Invert(leftEyeView * head);
                        var world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        var texture = new Texture_t
                        {
                            eType       = ETextureType.DirectX,
                            eColorSpace = EColorSpace.Gamma,
                            handle      = leftEyeTextureView.Resource.NativePointer
                        };

                        var bounds = new VRTextureBounds_t
                        {
                            uMin = 0.0f,
                            uMax = 1.0f,
                            vMin = 0.0f,
                            vMax = 1.0f,
                        };

                        var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Right Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(rightEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        projection = rightEyeProjection;
                        view       = Matrix.Invert(rightEyeView * head);
                        world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        texture.handle = rightEyeTextureView.Resource.NativePointer;

                        submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Window
                        context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height);

                        context.OutputMerger.SetTargets(depthStencilView, backBufferView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(backBufferView, backgroundColor);
                        context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height;

                        projection = Matrix.PerspectiveFovRH(3.14F / 3.0F, ratio, 0.01f, 1000);
                        view       = Matrix.Invert(head);
                        world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Show Backbuffer
                        swapChain.Present(0, PresentFlags.None);
                    });

                    audio.Dispose();
                }
        }
Ejemplo n.º 21
0
        private bool Synchronize(byte[] targetBuffer, int targetBufferOffset, int requestedBytes, double speedRatio)
        {
            /*
             * Wikipedia says:
             * For television applications, audio should lead video by no more than 15 milliseconds and audio should
             * lag video by no more than 45 milliseconds. For film, acceptable lip sync is considered to be no more
             * than 22 milliseconds in either direction.
             *
             * The Media and Acoustics Perception Lab says:
             * The results of the experiment determined that the average audio leading threshold for a/v sync
             * detection was 185.19 ms, with a standard deviation of 42.32 ms
             *
             * The ATSC says:
             * At first glance it seems loose: +90 ms to -185 ms as a Window of Acceptability
             * - Undetectable from -100 ms to +25 ms
             * - Detectable at -125 ms & +45 ms
             * - Becomes unacceptable at -185 ms & +90 ms
             *
             * NOTE: (- Sound delayed, + Sound advanced)
             */

            var audioLatencyMs    = Latency.TotalMilliseconds;
            var isBeyondThreshold = false;
            var readableCount     = AudioBuffer.ReadableCount;
            var rewindableCount   = AudioBuffer.RewindableCount;

            if (audioLatencyMs > SyncThresholdLagging)
            {
                isBeyondThreshold = true;

                // a positive audio latency means we are rendering audio behind (after) the clock (skip some samples)
                // and therefore we need to advance the buffer before we read from it.
                if (speedRatio == 1.0)
                {
                    MediaCore.Log(MediaLogMessageType.Warning,
                                  $"SYNC AUDIO: LATENCY: {Latency.Format()} | SKIP (samples being rendered too late)");
                }

                // skip some samples from the buffer.
                var audioLatencyBytes = WaveFormat.ConvertLatencyToByteSize(Convert.ToInt32(Math.Ceiling(audioLatencyMs)));
                AudioBuffer.Skip(Math.Min(audioLatencyBytes, readableCount));
            }
            else if (audioLatencyMs < SyncThresholdLeading)
            {
                isBeyondThreshold = true;

                // Compute the latency in bytes
                var audioLatencyBytes = WaveFormat.ConvertLatencyToByteSize(Convert.ToInt32(Math.Ceiling(Math.Abs(audioLatencyMs))));

                // audioLatencyBytes = requestedBytes; // uncomment this line to enable rewinding.
                if (audioLatencyBytes > requestedBytes && audioLatencyBytes < rewindableCount)
                {
                    // This means we have the audio pointer a little too ahead of time and we need to
                    // rewind it the requested amount of bytes.
                    AudioBuffer.Rewind(Math.Min(audioLatencyBytes, rewindableCount));
                }
                else
                {
                    // a negative audio latency means we are rendering audio ahead (before) the clock
                    // and therefore we need to render some silence until the clock catches up
                    if (speedRatio == 1.0)
                    {
                        MediaCore.Log(MediaLogMessageType.Warning,
                                      $"SYNC AUDIO: LATENCY: {Latency.Format()} | WAIT (samples being rendered too early)");
                    }

                    // render silence for the wait time and return
                    Array.Clear(targetBuffer, targetBufferOffset, requestedBytes);
                    return(false);
                }
            }

            // Perform minor adjustments until the delay is less than 10ms in either direction
            if (MediaCore.State.HasVideo &&
                speedRatio == 1.0 &&
                isBeyondThreshold == false &&
                Math.Abs(audioLatencyMs) > SyncThresholdPerfect)
            {
                var stepDurationMillis = Convert.ToInt32(Math.Min(SyncThresholdMaxStep, Math.Abs(audioLatencyMs)));
                var stepDurationBytes  = WaveFormat.ConvertLatencyToByteSize(stepDurationMillis);

                if (audioLatencyMs > SyncThresholdPerfect)
                {
                    AudioBuffer.Skip(Math.Min(stepDurationBytes, readableCount));
                }
                else if (audioLatencyMs < -SyncThresholdPerfect)
                {
                    AudioBuffer.Rewind(Math.Min(stepDurationBytes, rewindableCount));
                }
            }

            return(true);
        }
Ejemplo n.º 22
0
        private bool Synchronize(byte[] targetBuffer, int targetBufferOffset, int requestedBytes, double speedRatio)
        {
            #region Documentation

            /*
             * Wikipedia says:
             * For television applications, audio should lead video by no more than 15 milliseconds and audio should
             * lag video by no more than 45 milliseconds. For film, acceptable lip sync is considered to be no more
             * than 22 milliseconds in either direction.
             *
             * The Media and Acoustics Perception Lab says:
             * The results of the experiment determined that the average audio leading threshold for a/v sync
             * detection was 185.19 ms, with a standard deviation of 42.32 ms
             *
             * The ATSC says:
             * At first glance it seems loose: +90 ms to -185 ms as a Window of Acceptability
             * - Undetectable from -100 ms to +25 ms
             * - Detectable at -125 ms & +45 ms
             * - Becomes unacceptable at -185 ms & +90 ms
             *
             * NOTE: (- Sound delayed, + Sound advanced)
             */

            #endregion

            #region Private State

            var audioLatencyMs    = Latency.TotalMilliseconds;
            var isBeyondThreshold = false;
            var readableCount     = AudioBuffer.ReadableCount;
            var rewindableCount   = AudioBuffer.RewindableCount;

            #endregion

            #region Sync Give-up Conditions

            if (MediaElement.RendererOptions.AudioDisableSync)
            {
                return(true);
            }

            // Determine if we should continue to perform syncs.
            // Some live, non-seekable streams will send out-of-sync audio packets
            // and after trying too many times we simply give up.
            // The Sync conditions are reset in the Update method.
            if ((MediaCore?.State?.IsSeekable ?? true) == false && PlaySyncGaveUp.Value == false)
            {
                // 1. Determine if a sync is required
                if (audioLatencyMs > SyncThresholdLagging ||
                    audioLatencyMs < SyncThresholdLeading ||
                    Math.Abs(audioLatencyMs) > SyncThresholdPerfect)
                {
                    PlaySyncCount++;
                }

                // 2. Compute the variables to determine give-up conditions
                var playbackElapsedSeconds = PlaySyncStartTime.HasValue == false ?
                                             0 : DateTime.UtcNow.Subtract(PlaySyncStartTime.Value).TotalSeconds;
                var syncsPerSecond = PlaySyncCount / playbackElapsedSeconds;

                // 3. Determine if we need to give up
                if (playbackElapsedSeconds >= 3 && syncsPerSecond >= 3)
                {
                    MediaCore.Log(MediaLogMessageType.Warning,
                                  $"SYNC AUDIO: GIVE UP | SECS: {playbackElapsedSeconds:0.00}; SYN: {PlaySyncCount}; RATE: {syncsPerSecond:0.00} SYN/s; LAT: {audioLatencyMs} ms.");
                    PlaySyncGaveUp.Value = true;
                }
            }

            // Detect if we have given up
            if (PlaySyncGaveUp.Value == true)
            {
                return(true);
            }

            #endregion

            #region Large Latency Handling

            if (audioLatencyMs > SyncThresholdLagging)
            {
                isBeyondThreshold = true;

                // a positive audio latency means we are rendering audio behind (after) the clock (skip some samples)
                // and therefore we need to advance the buffer before we read from it.
                if (speedRatio == 1.0)
                {
                    MediaCore.Log(MediaLogMessageType.Warning,
                                  $"SYNC AUDIO: LATENCY: {audioLatencyMs} ms. | SKIP (samples being rendered too late)");
                }

                // skip some samples from the buffer.
                var audioLatencyBytes = WaveFormat.ConvertLatencyToByteSize(Convert.ToInt32(Math.Ceiling(audioLatencyMs)));
                AudioBuffer.Skip(Math.Min(audioLatencyBytes, readableCount));
            }
            else if (audioLatencyMs < SyncThresholdLeading)
            {
                isBeyondThreshold = true;

                // Compute the latency in bytes
                var audioLatencyBytes = WaveFormat.ConvertLatencyToByteSize(Convert.ToInt32(Math.Ceiling(Math.Abs(audioLatencyMs))));

                // audioLatencyBytes = requestedBytes; // uncomment this line to enable rewinding.
                if (audioLatencyBytes > requestedBytes && audioLatencyBytes < rewindableCount)
                {
                    // This means we have the audio pointer a little too ahead of time and we need to
                    // rewind it the requested amount of bytes.
                    AudioBuffer.Rewind(Math.Min(audioLatencyBytes, rewindableCount));
                }
                else
                {
                    // a negative audio latency means we are rendering audio ahead (before) the clock
                    // and therefore we need to render some silence until the clock catches up
                    if (speedRatio == 1.0)
                    {
                        MediaCore.Log(MediaLogMessageType.Warning,
                                      $"SYNC AUDIO: LATENCY: {audioLatencyMs} ms. | WAIT (samples being rendered too early)");
                    }

                    // render silence for the wait time and return
                    Array.Clear(targetBuffer, targetBufferOffset, requestedBytes);
                    return(false);
                }
            }

            #endregion

            #region Small Latency Handling

            // Perform minor adjustments until the delay is less than 10ms in either direction
            if (MediaCore.State.HasVideo &&
                speedRatio == 1.0 &&
                isBeyondThreshold == false &&
                Math.Abs(audioLatencyMs) > SyncThresholdPerfect)
            {
                var stepDurationMillis = Convert.ToInt32(Math.Min(SyncThresholdMaxStep, Math.Abs(audioLatencyMs)));
                var stepDurationBytes  = WaveFormat.ConvertLatencyToByteSize(stepDurationMillis);

                if (audioLatencyMs > SyncThresholdPerfect)
                {
                    AudioBuffer.Skip(Math.Min(stepDurationBytes, readableCount));
                }
                else if (audioLatencyMs < -SyncThresholdPerfect)
                {
                    AudioBuffer.Rewind(Math.Min(stepDurationBytes, rewindableCount));
                }
            }

            #endregion

            return(true);
        }
Ejemplo n.º 23
0
        static void Main()
        {
            const int samples = 512;
            const int latency = 24;

            var devices = DirectSoundCapture.GetDevices();

            //var capture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid);
            var capture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid);

            var audioFormat = new WaveFormat();

            var audioBuffer = new CaptureBuffer(capture, new CaptureBufferDescription
            {
                BufferBytes = audioFormat.ConvertLatencyToByteSize(latency),
                Format      = audioFormat
            });

            audioBuffer.Start(true);

            using (var form = new Form())
                using (var factory = new Factory4())
                {
                    form.Text          = "AudioDX";
                    form.ClientSize    = new System.Drawing.Size(1024, 768);
                    form.StartPosition = FormStartPosition.CenterScreen;

                    Device11  device;
                    SwapChain swapChain;

                    Device11.CreateWithSwapChain(
                        DriverType.Hardware,
                        DeviceCreationFlags.None,
                        new SwapChainDescription
                    {
                        IsWindowed        = true,
                        BufferCount       = 1,
                        OutputHandle      = form.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        ModeDescription   = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.B8G8R8A8_UNorm),
                        Usage             = Usage.RenderTargetOutput,
                        SwapEffect        = SwapEffect.Discard
                    },
                        out device,
                        out swapChain);

                    var context = device.ImmediateContext;

                    var backBuffer = swapChain.GetBackBuffer <Texture2D>(0);

                    var backBufferView = new RenderTargetView(device, backBuffer);

                    backBuffer.Dispose();

                    var depthBuffer = new Texture2D(device, new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = form.ClientSize.Width,
                        Height            = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        BindFlags         = BindFlags.DepthStencil
                    });

                    var depthBufferView = new DepthStencilView(device, depthBuffer);

                    depthBuffer.Dispose();

                    Shapes.Sphere.Load(device);
                    Shapes.Cube.Load(device);
                    Shapes.Billboard.Load(device);
                    Shaders.Normal.Load(device);
                    Shaders.Color.Load(device);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    //rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.Back;
                    var rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();
                    //blendStateDescription.RenderTarget[0] = new RenderTargetBlendDescription(true, BlendOption.SourceAlpha, BlendOption.InverseSourceAlpha, BlendOperation.Add, BlendOption.SourceAlpha, BlendOption.DestinationAlpha, BlendOperation.Add, ColorWriteMaskFlags.All);

                    var blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    var depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    var samplerState = new SamplerState(device, samplerStateDescription);

                    var startTime = DateTime.Now;
                    var frame     = 0;
                    var size      = form.ClientSize;

                    var audioData  = new byte[audioFormat.ConvertLatencyToByteSize(latency)];
                    var audioIndex = 0;

                    var leftWaveForm  = new float[samples * 8];
                    var rightWaveForm = new float[samples * 8];

                    for (var sample = 0; sample < samples; sample++)
                    {
                        leftWaveForm[(sample * 8) + 0]  = -1.0f + ((float)sample / (samples - 1) * 2.0f);
                        rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / (samples - 1) * 2.0f);
                    }

                    var waveFormBufferDescription = new BufferDescription
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        SizeInBytes    = leftWaveForm.Length * sizeof(float),
                        CpuAccessFlags = CpuAccessFlags.Write,
                        Usage          = ResourceUsage.Dynamic
                    };

                    //var leftWaveFormVertexBuffer = Buffer11.Create(device, leftWaveForm, waveFormBufferDescription);
                    //var rightWaveFormVertexBuffer = Buffer11.Create(device, rightWaveForm, waveFormBufferDescription);

                    //var leftWaveFormVertexBufferBinding = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0);
                    //var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0);

                    var leftFrequencies  = new float[samples];
                    var rightFrequencies = new float[samples];

                    //var rotation = 0.0f;

                    RenderLoop.Run(form, () =>
                    {
                        if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition)
                        {
                            audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None);

                            //for (var sample = 0; sample < samples; sample++)
                            //{
                            //	leftWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue;
                            //	rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue;
                            //}

                            //DataStream stream;

                            //context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            //stream.WriteRange(leftWaveForm);

                            //context.UnmapSubresource(leftWaveFormVertexBuffer, 0);

                            //stream.Dispose();

                            //context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            //stream.WriteRange(rightWaveForm);

                            //context.UnmapSubresource(rightWaveFormVertexBuffer, 0);

                            //stream.Dispose();

                            for (var sample = 0; sample < samples; sample++)
                            {
                                leftFrequencies[sample]  = 0.0f;
                                rightFrequencies[sample] = 0.0f;

                                for (var sample2 = 0; sample2 < samples; sample2++)
                                {
                                    var theta = -2.0f * MathUtil.Pi * (float)sample2 * (float)sample / (samples << 1);
                                    var value = (float)Math.Cos(theta);

                                    leftFrequencies[sample]  += value * (-BitConverter.ToInt16(audioData, sample2 * 4) / (float)short.MinValue);
                                    rightFrequencies[sample] += value * (-BitConverter.ToInt16(audioData, (sample2 * 4) + 2) / (float)short.MinValue);
                                }
                            }

                            //for (var sample = 0; sample < samples; sample++)
                            //{
                            //	leftWaveForm[(sample * 8) + 1] = Math.Abs(leftFrequencies[sample]);
                            //	rightWaveForm[(sample * 8) + 1] = Math.Abs(rightFrequencies[sample]);

                            //var angle = ((float)sample / (float)samples) * MathUtil.TwoPi;
                            //var sin = (float)Math.Sin(angle);
                            //var cos = (float)Math.Cos(angle);

                            //leftWaveForm[(sample * 8) + 0] = (Math.Abs(leftFrequencies[sample]) + 10.0f) * sin * -0.01f;
                            //leftWaveForm[(sample * 8) + 1] = (Math.Abs(leftFrequencies[sample]) + 10.0f) * cos * -0.01f;
                            //rightWaveForm[(sample * 8) + 0] = (Math.Abs(rightFrequencies[sample]) + 10.0f) * sin * 0.01f;
                            //rightWaveForm[(sample * 8) + 1] = (Math.Abs(rightFrequencies[sample]) + 10.0f) * cos * -0.01f;
                            //}

                            //context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            //stream.WriteRange(leftWaveForm);

                            //context.UnmapSubresource(leftWaveFormVertexBuffer, 0);

                            //stream.Dispose();

                            //context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            //stream.WriteRange(rightWaveForm);

                            //context.UnmapSubresource(rightWaveFormVertexBuffer, 0);

                            //stream.Dispose();
                        }

                        if (form.ClientSize != size)
                        {
                            Utilities.Dispose(ref backBufferView);
                            Utilities.Dispose(ref depthBufferView);

                            if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0)
                            {
                                swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None);

                                backBuffer = swapChain.GetBackBuffer <Texture2D>(0);

                                backBufferView = new RenderTargetView(device, backBuffer);
                                backBuffer.Dispose();

                                depthBuffer = new Texture2D(device, new Texture2DDescription
                                {
                                    Format            = Format.D16_UNorm,
                                    ArraySize         = 1,
                                    MipLevels         = 1,
                                    Width             = form.ClientSize.Width,
                                    Height            = form.ClientSize.Height,
                                    SampleDescription = new SampleDescription(1, 0),
                                    BindFlags         = BindFlags.DepthStencil
                                });

                                depthBufferView = new DepthStencilView(device, depthBuffer);
                                depthBuffer.Dispose();
                            }

                            size = form.ClientSize;
                        }

                        var ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height;

                        var projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000);
                        var view       = Matrix.LookAtRH(new Vector3(0, 2, 50), Vector3.Zero, Vector3.UnitY);
                        //var world = Matrix.Scaling(1.0f + Math.Abs(((leftWaveForm[audioIndex + 1]) * 0.01f))) * Matrix.RotationY(Environment.TickCount / 2000.0f);
                        //var world = Matrix.RotationY(rotation);
                        //var world = Matrix.Scaling(1.0f + ((audioData[audioIndex] + audioData[audioIndex + 1] << 8) * 0.00001f)) * Matrix.RotationY(Environment.TickCount / 1000.0f);

                        //audioIndex += 8;

                        //if (audioIndex >= leftWaveForm.Length)
                        //	audioIndex = 0;

                        //rotation += 0.01f;

                        //var worldViewProjection = world * view * projection;
                        //var diffuse = new Vector4(1, 0, 0, 0.5f);

                        //Shaders.Color.WorldViewProjection(context, ref worldViewProjection);
                        //Shaders.Color.Emissive(context, ref diffuse);

                        context.Rasterizer.SetViewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);
                        context.OutputMerger.SetTargets(depthBufferView, backBufferView);

                        context.ClearRenderTargetView(backBufferView, new RawColor4(0, 0, 0, 1));
                        context.ClearDepthStencilView(depthBufferView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        //Shaders.Color.Apply(context);
                        //Shapes.Sphere.Begin(context);
                        //Shapes.Cube.Begin(context);
                        //Shapes.Billboard.Begin(context);

                        context.Rasterizer.State = rasterizerState;
                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);
                        context.PixelShader.SetSampler(0, samplerState);
                        context.PixelShader.SetShaderResource(0, null);

                        //Shapes.Sphere.Draw(context);
                        //Shapes.Cube.Draw(context);
                        //Shapes.Billboard.Draw(context);

                        // Draw Waveforms
                        //diffuse = new Vector4(0, 0, 1, 0.5f);

                        //Shaders.Color.Apply(context);

                        //worldViewProjection = Matrix.Scaling(1, 0.1f, 1) * Matrix.Translation(0, 0.1f, 0);
                        //worldViewProjection = Matrix.Scaling(1, 1, 1) * Matrix.Translation(-0.5f, 0, 0);

                        //Shaders.Color.WorldViewProjection(context, ref worldViewProjection);
                        //Shaders.Color.Emissive(context, ref diffuse);

                        //context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        //context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        //context.Draw(samples, 0);

                        //worldViewProjection = Matrix.Scaling(1, 0.1f, 1) * Matrix.Translation(0, -0.1f, 0);

                        //Shaders.Color.WorldViewProjection(context, ref worldViewProjection);

                        //context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        //context.Draw(samples, 0);

                        // Draw Frequencies
                        Shapes.Billboard.Begin(context);
                        Shaders.Color.Apply(context);

                        var emissive = new Vector4(0.2f, 0.2f, 0.8f, 1);

                        Shaders.Color.Emissive(context, ref emissive);

                        for (var sample = 0; sample < samples; sample++)
                        {
                            var volume = 1 + (int)(Math.Abs(leftFrequencies[sample]) * 10.0f);

                            for (var pixel = 0; pixel < volume; pixel++)
                            {
                                //var worldViewProjection = Matrix.Scaling(0.5f) * Matrix.Translation(-256.0f + sample, Math.Abs(leftFrequencies[sample]) * 10.0f, 0) * view * projection;
                                var worldViewProjection = Matrix.Scaling(0.5f) * Matrix.Translation(-50.0f + sample, pixel, 0) * view * projection;

                                Shaders.Color.WorldViewProjection(context, ref worldViewProjection);

                                emissive = new Vector4(pixel * 0.06f, 0.0f, 0.8f - (pixel * 0.02f), 1);
                                Shaders.Color.Emissive(context, ref emissive);
                                Shapes.Billboard.Draw(context);
                            }
                        }

                        swapChain.Present(1, PresentFlags.None);

                        frame++;
                    });

                    MessageBox.Show((frame / DateTime.Now.Subtract(startTime).TotalSeconds).ToString() + " FPS");
                }
        }
Ejemplo n.º 24
0
        static void Main()
        {
            var initError = EVRInitError.None;

            system = OpenVR.Init(ref initError);

            if (initError != EVRInitError.None)
            {
                return;
            }

            compositor = OpenVR.Compositor;

            compositor.CompositorBringToFront();
            compositor.FadeGrid(5.0f, false);

            count = OpenVR.k_unMaxTrackedDeviceCount;

            currentPoses = new TrackedDevicePose_t[count];
            nextPoses    = new TrackedDevicePose_t[count];

            controllers                    = new List <uint>();
            controllerModels               = new RenderModel_t[count];
            controllerTextures             = new RenderModel_TextureMap_t[count];
            controllerTextureViews         = new ShaderResourceView[count];
            controllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
            controllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
            controllerVertexBufferBindings = new VertexBufferBinding[count];

            for (uint device = 0; device < count; device++)
            {
                var deviceClass = system.GetTrackedDeviceClass(device);

                switch (deviceClass)
                {
                case ETrackedDeviceClass.HMD:
                    headset = device;
                    break;

                case ETrackedDeviceClass.Controller:
                    controllers.Add(device);
                    break;
                }
            }

            uint width  = 0;
            uint height = 0;

            system.GetRecommendedRenderTargetSize(ref width, ref height);

            headsetSize = new Size((int)width, (int)height);
            windowSize  = new Size(960, 540);

            var leftEyeProjection  = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
            var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

            var leftEyeView  = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left));
            var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right));

            foreach (var controller in controllers)
            {
                var modelName     = new StringBuilder(255, 255);
                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                {
                    var modelName2 = modelName.ToString();

                    while (true)
                    {
                        var pointer    = IntPtr.Zero;
                        var modelError = EVRRenderModelError.None;

                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                        if (modelError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (modelError == EVRRenderModelError.None)
                        {
                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                            controllerModels[controller] = renderModel;
                            break;
                        }
                    }

                    while (true)
                    {
                        var pointer      = IntPtr.Zero;
                        var textureError = EVRRenderModelError.None;

                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                        if (textureError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (textureError == EVRRenderModelError.None)
                        {
                            var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                            controllerTextures[controller] = texture;
                            break;
                        }
                    }
                }
            }

            int adapterIndex = 0;

            system.GetDXGIOutputInfo(ref adapterIndex);

            using (var form = new Form())
                using (var factory = new Factory4())
                {
                    form.ClientSize = windowSize;

                    var adapter = factory.GetAdapter(adapterIndex);

                    var swapChainDescription = new SwapChainDescription
                    {
                        BufferCount     = 1,
                        Flags           = SwapChainFlags.None,
                        IsWindowed      = true,
                        ModeDescription = new ModeDescription
                        {
                            Format      = Format.B8G8R8A8_UNorm,
                            Width       = form.ClientSize.Width,
                            Height      = form.ClientSize.Height,
                            RefreshRate = new Rational(60, 1)
                        },
                        OutputHandle      = form.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect        = SwapEffect.Discard,
                        Usage             = Usage.RenderTargetOutput
                    };

                    SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain);

                    factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None);

                    context = device.ImmediateContext;

                    using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                        backBufferView = new RenderTargetView(device, backBuffer);

                    var depthBufferDescription = new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = form.ClientSize.Width,
                        Height            = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default,
                        BindFlags         = BindFlags.DepthStencil,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        OptionFlags       = ResourceOptionFlags.None
                    };

                    using (var depthBuffer = new Texture2D(device, depthBufferDescription))
                        depthStencilView = new DepthStencilView(device, depthBuffer);

                    // Create Eye Textures
                    var eyeTextureDescription = new Texture2DDescription
                    {
                        ArraySize         = 1,
                        BindFlags         = BindFlags.RenderTarget,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.B8G8R8A8_UNorm,
                        Width             = headsetSize.Width,
                        Height            = headsetSize.Height,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.None,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default
                    };

                    var leftEyeTexture  = new Texture2D(device, eyeTextureDescription);
                    var rightEyeTexture = new Texture2D(device, eyeTextureDescription);

                    var leftEyeTextureView  = new RenderTargetView(device, leftEyeTexture);
                    var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture);

                    // Create Eye Depth Buffer
                    eyeTextureDescription.BindFlags = BindFlags.DepthStencil;
                    eyeTextureDescription.Format    = Format.D32_Float;

                    var eyeDepth     = new Texture2D(device, eyeTextureDescription);
                    var eyeDepthView = new DepthStencilView(device, eyeDepth);

                    Shapes.Cube.Load(device);
                    Shapes.Sphere.Load(device);
                    Shaders.Position.Load(device);
                    Shaders.Normal.Load(device);
                    Shaders.NormalTexture.Load(device);

                    // Load Controller Models
                    foreach (var controller in controllers)
                    {
                        var model = controllerModels[controller];

                        controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.VertexBuffer,
                            SizeInBytes = (int)model.unVertexCount * 32
                        });

                        controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                        controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.IndexBuffer,
                            SizeInBytes = (int)model.unTriangleCount * 3 * 2
                        });

                        var texture = controllerTextures[controller];

                        using (var texture2d = new Texture2D(device, new Texture2DDescription
                        {
                            ArraySize = 1,
                            BindFlags = BindFlags.ShaderResource,
                            Format = Format.R8G8B8A8_UNorm,
                            Width = texture.unWidth,
                            Height = texture.unHeight,
                            MipLevels = 1,
                            SampleDescription = new SampleDescription(1, 0)
                        }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4)))
                            controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);
                    }

                    worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.None;

                    rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();

                    blendStateDescription.RenderTarget[0].BlendOperation   = BlendOperation.Add;
                    blendStateDescription.RenderTarget[0].SourceBlend      = BlendOption.SourceAlpha;
                    blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;

                    blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

                    blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    samplerState = new SamplerState(device, samplerStateDescription);

                    startTime  = DateTime.Now;
                    frame      = 0;
                    windowSize = form.ClientSize;

                    backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1);

                    var vrEvent   = new VREvent_t();
                    var eventSize = (uint)Utilities.SizeOf <VREvent_t>();

                    head = Matrix.Identity;

                    // Initialize Audio
                    var audioSamples = 1024;

                    var audioDevices = DirectSoundCapture.GetDevices();

                    //var audioCapture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid);
                    var audioCapture = new DirectSoundCapture(audioDevices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid);

                    var audioFormat = new WaveFormat();
                    var audioLength = audioFormat.ConvertLatencyToByteSize(24);

                    var audioData     = new byte[audioLength];
                    var audioPosition = 0;

                    var leftWaveForm  = new float[1024 * 8];
                    var rightWaveForm = new float[1024 * 8];

                    for (var sample = 0; sample < 1024; sample++)
                    {
                        leftWaveForm[(sample * 8) + 0]  = -1.0f + ((float)sample / 512.0f);
                        rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f);
                    }

                    var audioBuffer = new CaptureBuffer(audioCapture, new CaptureBufferDescription
                    {
                        BufferBytes = audioLength,
                        Format      = audioFormat
                    });

                    audioBuffer.Start(true);

                    var waveFormBufferDescription = new BufferDescription
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        SizeInBytes    = leftWaveForm.Length * sizeof(float),
                        CpuAccessFlags = CpuAccessFlags.Write,
                        Usage          = ResourceUsage.Dynamic
                    };

                    var leftWaveFormVertexBuffer  = SharpDX.Direct3D11.Buffer.Create(device, leftWaveForm, waveFormBufferDescription);
                    var rightWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, rightWaveForm, waveFormBufferDescription);

                    var leftWaveFormVertexBufferBinding  = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0);
                    var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0);

                    RenderLoop.Run(form, () =>
                    {
                        if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition)
                        {
                            audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None);

                            for (var sample = 0; sample < 1024; sample++)
                            {
                                leftWaveForm[(sample * 8) + 1]  = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue;
                                rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue;
                            }

                            DataStream stream;

                            context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            stream.WriteRange(leftWaveForm);

                            context.UnmapSubresource(leftWaveFormVertexBuffer, 0);

                            stream.Dispose();

                            context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            stream.WriteRange(rightWaveForm);

                            context.UnmapSubresource(rightWaveFormVertexBuffer, 0);

                            stream.Dispose();
                        }

                        audioPosition += 8;

                        if (audioPosition >= leftWaveForm.Length)
                        {
                            audioPosition = 0;
                        }

                        while (system.PollNextEvent(ref vrEvent, eventSize))
                        {
                            switch ((EVREventType)vrEvent.eventType)
                            {
                            case EVREventType.VREvent_TrackedDeviceActivated:
                                var controller = vrEvent.trackedDeviceIndex;

                                controllers.Add(controller);

                                var modelName     = new StringBuilder(255, 255);
                                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                                {
                                    var modelName2 = modelName.ToString();

                                    while (true)
                                    {
                                        var pointer    = IntPtr.Zero;
                                        var modelError = EVRRenderModelError.None;

                                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                                        if (modelError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (modelError == EVRRenderModelError.None)
                                        {
                                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                                            controllerModels[controller] = renderModel;

                                            // Load Controller Model
                                            var model = controllerModels[controller];

                                            controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.VertexBuffer,
                                                SizeInBytes = (int)model.unVertexCount * 32
                                            });

                                            controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                                            controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.IndexBuffer,
                                                SizeInBytes = (int)model.unTriangleCount * 3 * 2
                                            });

                                            break;
                                        }
                                    }

                                    while (true)
                                    {
                                        var pointer      = IntPtr.Zero;
                                        var textureError = EVRRenderModelError.None;

                                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                                        if (textureError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (textureError == EVRRenderModelError.None)
                                        {
                                            var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                                            controllerTextures[controller] = textureMap;

                                            using (var texture2d = new Texture2D(device, new Texture2DDescription
                                            {
                                                ArraySize = 1,
                                                BindFlags = BindFlags.ShaderResource,
                                                Format = Format.R8G8B8A8_UNorm,
                                                Width = textureMap.unWidth,
                                                Height = textureMap.unHeight,
                                                MipLevels = 1,
                                                SampleDescription = new SampleDescription(1, 0)
                                            }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4)))
                                                controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);

                                            break;
                                        }
                                    }
                                }
                                break;

                            case EVREventType.VREvent_TrackedDeviceDeactivated:
                                controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex);
                                break;

                            default:
                                System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType);
                                break;
                            }
                        }

                        if (form.ClientSize != windowSize)
                        {
                            Utilities.Dispose(ref backBufferView);

                            if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0)
                            {
                                swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None);

                                using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                                    backBufferView = new RenderTargetView(device, backBuffer);
                            }

                            windowSize = form.ClientSize;
                        }

                        // Update Device Tracking
                        compositor.WaitGetPoses(currentPoses, nextPoses);

                        if (currentPoses[headset].bPoseIsValid)
                        {
                            Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head);
                        }

                        foreach (var controller in controllers)
                        {
                            var controllerMatrix = Matrix.Identity;

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix);
                        }

                        // Render Left Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(leftEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        var ratio = (float)headsetSize.Width / (float)headsetSize.Height;

                        var projection = leftEyeProjection;
                        var view       = Matrix.Invert(leftEyeView * head);
                        var world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Present Left Eye
                        var texture = new Texture_t
                        {
                            eType       = ETextureType.DirectX,
                            eColorSpace = EColorSpace.Gamma,
                            handle      = leftEyeTextureView.Resource.NativePointer
                        };

                        var bounds = new VRTextureBounds_t
                        {
                            uMin = 0.0f,
                            uMax = 1.0f,
                            vMin = 0.0f,
                            vMax = 1.0f,
                        };

                        var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Right Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(rightEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        projection = rightEyeProjection;
                        view       = Matrix.Invert(rightEyeView * head);
                        world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Present Right Eye
                        texture.handle = rightEyeTextureView.Resource.NativePointer;

                        submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Window
                        context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height);

                        context.OutputMerger.SetTargets(depthStencilView, backBufferView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(backBufferView, backgroundColor);
                        context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height;

                        projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000);
                        view       = Matrix.Invert(head);
                        world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Show Backbuffer
                        swapChain.Present(0, PresentFlags.None);
                    });
                }
        }