Example #1
0
            /// <summary>
            /// Read in the specified buffer.
            /// </summary>
            /// <param name="bufIndex">Index of buffer to use for the read</param>
            /// <returns>MMSYSERR.NOERROR if successful</returns>
            protected Wave.MMSYSERR ReadBuffer(int bufIndex)
            {
                uint readLength = (uint)m_bufferSize;

                if (bufIndex < m_numBlocks)
                {
                    uint remainingDataLength = (uint)(m_rdr.BaseStream.Length - m_rdr.BaseStream.Position);
                    if (m_bufferSize > remainingDataLength)
                    {
                        readLength = remainingDataLength;
                    }
                }

                // Read in the next block of data
                Wave.MMSYSERR result = m_whdr[bufIndex].Read(m_rdr, readLength, m_wfmt.nBlockAlign);
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                // If the header is not prepared then prepare it
                if ((m_whdr[bufIndex].dwFlags & Wave.WAVEHDR.WHDR_PREPARED) == 0)
                {
                    return(waveOutPrepareHeader(m_hwo, m_whdr[bufIndex], (uint)Marshal.SizeOf(m_whdr[bufIndex])));
                }

                return(Wave.MMSYSERR.NOERROR);
            }
Example #2
0
        /// <summary>
        /// Get the name of the specified playback device.
        /// </summary>
        /// <param name="deviceId">ID of the device</param>
        /// <param name="prodName">Destination string assigned the name</param>
        /// <returns>MMSYSERR.NOERROR if successful</returns>
        public Wave.MMSYSERR GetDeviceName(uint deviceId, ref string prodName)
        {
            WAVEOUTCAPS caps = new WAVEOUTCAPS();

            Wave.MMSYSERR result = waveOutGetDevCaps(deviceId, caps, caps.Size);
            if (result != Wave.MMSYSERR.NOERROR)
            {
                return(result);
            }

            prodName = caps.szPname;

            return(Wave.MMSYSERR.NOERROR);
        }
Example #3
0
            /// <summary>
            /// Get the volume of this sound.
            /// </summary>
            /// <param name="volLeft">Left channel volume level</param>
            /// <param name="volRight">Right channel volume level</param>
            /// <returns>MMSYSERR.NOERROR if successful</returns>
            public Wave.MMSYSERR GetVolume(ref ushort volLeft, ref ushort volRight)
            {
                uint vol = 0;

                Wave.MMSYSERR result = waveOutGetVolume(m_hwo, ref vol);
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                volLeft  = (ushort)(vol & 0x0000ffff);
                volRight = (ushort)(vol >> 16);

                return(Wave.MMSYSERR.NOERROR);
            }
Example #4
0
            /// <summary>
            /// Create an empty buffer to append to the end of the sound.  This protects
            /// the playback because the system will sometimes continue reading after the
            /// BlockDone method is called.
            /// </summary>
            /// <param name="bufIndex">Index of buffer to be created</param>
            /// <returns>MMSYSERR.NOERROR is successful</returns>
            protected Wave.MMSYSERR CreateBuffer(int bufIndex)
            {
                Wave.MMSYSERR result = m_whdr[bufIndex].Init((uint)m_bufferSize, true);
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                if ((m_whdr[bufIndex].dwFlags & Wave.WAVEHDR.WHDR_PREPARED) == 0)
                {
                    return(waveOutPrepareHeader(m_hwo, m_whdr[bufIndex], (uint)Marshal.SizeOf(m_whdr[bufIndex])));
                }

                return(Wave.MMSYSERR.NOERROR);
            }
Example #5
0
            /// <summary>
            /// Play a wave file.
            /// </summary>
            /// <param name="curDevice">Hardware device to use for playback</param>
            /// <param name="fileName">Name of file to play</param>
            /// <param name="hwnd">Handle to a message window to use for messaging</param>
            /// <param name="bufferSize">Size of streaming buffers, a 0 value specifies
            /// that the buffer should be created big enough to fit the entire file</param>
            /// <param name="volLeft">Left channel volume level</param>
            /// <param name="volRight">Right channel volume level</param>
            /// <returns>MMSYSERR.NOERROR if successful</returns>
            public Wave.MMSYSERR Play(uint curDevice, String fileName, IntPtr hwnd, int bufferSize, ushort volLeft, ushort volRight)
            {
                if (m_playing)
                {
                    return(Wave.MMSYSERR.NOERROR);
                }

                if (!File.Exists(fileName))
                {
                    return(Wave.MMSYSERR.ERROR);
                }

                FileInfo fi = new FileInfo(fileName);

                if ((fi.Attributes & FileAttributes.ReadOnly) != 0)
                {
                    fi.Attributes -= FileAttributes.ReadOnly;
                }

                FileStream strm = new FileStream(fileName, FileMode.Open);

                if (strm == null)
                {
                    return(Wave.MMSYSERR.ERROR);
                }

                m_rdr = new BinaryReader(strm);
                if (m_rdr == null)
                {
                    return(Wave.MMSYSERR.ERROR);
                }

                m_wfmt = new Wave.WAVEFORMATEX();
                m_wfmt.SeekTo(strm);

                // Read in the WAVEFORMATEX structure and attempt to open the
                // device for playback.
                m_wfmt.Read(m_rdr);

                Wave.MMSYSERR result = waveOutOpen(ref m_hwo, curDevice, m_wfmt, hwnd, 0, Wave.CALLBACK_WINDOW);
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                m_dataLength = (uint)(m_rdr.BaseStream.Length - Wave.WAVEFORMATEX.WF_OFFSET_DATA);

                if (bufferSize == 0)
                {
                    m_bufferSize = (int)m_dataLength;
                }
                else
                {
                    m_bufferSize = bufferSize / 2;
                }

                if (m_bufferSize % m_wfmt.nBlockAlign != 0)
                {
                    m_bufferSize += m_wfmt.nBlockAlign - (m_bufferSize % m_wfmt.nBlockAlign);
                }

                // Determine the number of buffer reads required to play the entire
                // file
                m_numBlocks = (int)(m_dataLength / m_bufferSize);
                if ((m_numBlocks * m_bufferSize) < m_dataLength)
                {
                    m_numBlocks++;
                }

                m_whdr[0] = new Wave.WAVEHDR();
                m_whdr[1] = new Wave.WAVEHDR();

                // Read in the first buffer
                result = ReadBuffer(0);
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                // If the entire file fits in the buffer then close the file
                if (m_numBlocks == 1)
                {
                    m_rdr.BaseStream.Close();
                    m_rdr.Close();
                    m_rdr = null;
                }

                SetVolume(volLeft, volRight);

                // Start playback of the first buffer
                result = waveOutWrite(m_hwo, m_whdr[0], (uint)Marshal.SizeOf(m_whdr[0]));
                if (result != Wave.MMSYSERR.NOERROR)
                {
                    return(result);
                }

                m_curBlock = 0;

                // Create the second buffer.  If the audio is being streamed, this will
                // be the next audio block, otherwise it will be padding
                Thread loadThread = new Thread(new ThreadStart(LoadBuffer));

                loadThread.Start();

                m_playing = true;

                return(Wave.MMSYSERR.NOERROR);
            }