示例#1
0
        public static WaveOutDeviceInfo[] GetWaveOutDevices()
        {
            // enumerate WaveOut devices
            int device_count = WaveNative.waveOutGetNumDevs();

            WaveOutDeviceInfo[]    result = new WaveOutDeviceInfo[device_count + 1];
            WaveNative.WAVEOUTCAPS caps   = new WaveNative.WAVEOUTCAPS();

            result[0] = new WaveOutDeviceInfo();

            for (int i = 0; i < device_count; i++)
            {
                WaveNative.waveOutGetDevCaps((IntPtr)i, ref caps, (uint)Marshal.SizeOf(caps));
                result[i + 1]             = new WaveOutDeviceInfo();
                result[i + 1].DisplayName = caps.szPname;
            }

            // expand names
            GCHandle result_handle = GCHandle.Alloc(result);

            WaveNative.DirectSoundEnumerate(new WaveNative.DSEnumCallback(EnumCallback), (IntPtr)result_handle);
            result_handle.Free();

            if (string.IsNullOrEmpty(result[0].DisplayName))
            {
                result[0].DisplayName = "(default)";
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Starts wave out device
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            WaveNative.MMRESULT error;

            // create thread event
            m_thread_event = new AutoResetEvent(false);

            m_wave_out_format = new WaveNative.WaveFormat(SampleRate, 16, ChannelCount);

            // open wave device
            error = WaveNative.waveOutOpen(out m_wave_out_device_handle, m_device_id, m_wave_out_format, m_buffer_proc, 0, (uint)WaveNative.WaveInOutOpenFlags.CALLBACK_FUNCTION);
            if (error == WaveNative.MMRESULT.MMSYSERR_NOERROR)
            {
                // start thread
                m_thread_running  = true;
                m_thread          = new Thread(new ThreadStart(ThreadProc));
                m_thread.Priority = ThreadPriority.AboveNormal;
                m_thread.Start();
            }
            else
            {
                m_thread_event.Dispose();
                m_thread_event    = null;
                m_wave_out_format = null;
                m_thread          = null;
                m_thread_running  = false;
            }

            return(error == WaveNative.MMRESULT.MMSYSERR_NOERROR);
        }
示例#3
0
            /// <summary>
            /// Dispose of non managed resources
            /// </summary>
            public void Dispose()
            {
                if (Parent != null)
                {
                    // release header
                    WaveNative.Try(WaveNative.waveOutUnprepareHeader(Parent.Handle, m_header_handle.AddrOfPinnedObject(), Marshal.SizeOf(Header)));

                    Parent = null;
                }

                if (m_header_handle.IsAllocated)
                {
                    m_header_handle.Free();
                }

                if (m_data_handle.IsAllocated)
                {
                    m_data_handle.Free();
                }

                if (m_this.IsAllocated)
                {
                    m_this.Free();
                }

                Data = null;
            }
示例#4
0
            /// <summary>
            /// Enqueues buffer for playback
            /// </summary>
            public void Enqueue()
            {
                Free = false;

                // write header
                WaveNative.Try(WaveNative.waveOutWrite(Parent.Handle, m_header_handle.AddrOfPinnedObject(), Marshal.SizeOf(Header)));
            }
示例#5
0
        /// <summary>
        /// Waveout thread procedure
        /// </summary>
        private void ThreadProc()
        {
            WaveOutBuffer buffer;

            // create buffers
            m_wave_out_buffers = new WaveOutBuffer[BufferCount];
            for (int i = 0; i < BufferCount; i++)
            {
                m_wave_out_buffers[i] = new WaveOutBuffer(this, i);
                m_wave_out_buffers[i].ClearBuffer();
            }

            // queue buffers
            for (int i = 0; i < BufferCount; i++)
            {
                m_wave_out_buffers[i].Enqueue();
            }

            // thread loop
            while (m_thread_running)
            {
                // wait for wave event
                m_thread_event.WaitOne();

                // find finished buffers and dequeue, fill and enqueue them
                for (int i = 0; i < BufferCount && m_thread_running; i++)
                {
                    buffer = m_wave_out_buffers[i];
                    if (buffer.Free)
                    {
                        buffer.Dequeue();

                        OnSampleRequest?.Invoke(buffer.Data);

                        buffer.Enqueue();
                    }
                }
            }

            // stop wave out
            WaveNative.waveOutReset(m_wave_out_device_handle);

            // release buffers
            for (int i = 0; i < BufferCount; i++)
            {
                m_wave_out_buffers[i].Dispose();
            }

            // close wave out
            WaveNative.waveOutClose(m_wave_out_device_handle);

            m_wave_out_buffers = null;

            m_wave_out_device_handle = IntPtr.Zero;
            m_thread = null;
            m_thread_event.Dispose();
            m_thread_event = null;
        }
示例#6
0
        public void Enqueue()
        {
            Free = false;

            // write header
            //Debug.WriteLine("E: " + BufferIndex.ToString());

            WaveNative.Try(WaveNative.waveOutWrite(Parent.Handle, m_header_handle.AddrOfPinnedObject(), Marshal.SizeOf(Header)));
        }
示例#7
0
            /// <summary>
            /// Waveout buffer default constructor
            /// </summary>
            /// <param name="in_parent">Parent Waveout class</param>
            /// <param name="in_buffer_index">NUmber of the wave buffer</param>
            public WaveOutBuffer(WaveOut in_parent, int in_buffer_index)
            {
                Parent = in_parent;

                BufferIndex = in_buffer_index;
                Free        = true;
                Header      = new WaveNative.WaveHdr();
                Data        = new short[in_parent.BufferLength * in_parent.ChannelCount];

                m_this          = GCHandle.Alloc(this);
                m_header_handle = GCHandle.Alloc(Header, GCHandleType.Pinned);
                m_data_handle   = GCHandle.Alloc(Data, GCHandleType.Pinned);

                Header.lpData         = m_data_handle.AddrOfPinnedObject();
                Header.dwBufferLength = sizeof(short) * Data.Length;
                Header.dwUser         = (IntPtr)m_this;

                // prepare header
                WaveNative.Try(WaveNative.waveOutPrepareHeader(Parent.Handle, m_header_handle.AddrOfPinnedObject(), Marshal.SizeOf(Header)));
            }