Пример #1
0
        /// <summary>
        /// Plays specified audio data bytes. If player is currently playing, data will be queued for playing.
        /// </summary>
        /// <param name="audioData">Audio data. Data boundary must n * BlockSize.</param>
        /// <param name="offset">Offset in the buffer.</param>
        /// <param name="count">Number of bytes to play form the specified offset.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>audioData</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when <b>audioData</b> is with invalid length.</exception>
        public void Play(byte[] audioData,int offset,int count)
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException("WaveOut");
            }
            if(audioData == null){
                throw new ArgumentNullException("audioData");
            }
            if((count % m_BlockSize) != 0){
                throw new ArgumentException("Audio data is not n * BlockSize.");
            }

            //--- Queue specified audio block for play. --------------------------------------------------------
            byte[]   data       = new byte[count];
            Array.Copy(audioData,offset,data,0,count);
            GCHandle dataHandle = GCHandle.Alloc(data,GCHandleType.Pinned);
            //            m_BytesBuffered += data.Length;

            WAVEHDR wavHeader = new WAVEHDR();
            wavHeader.lpData          = dataHandle.AddrOfPinnedObject();
            wavHeader.dwBufferLength  = (uint)data.Length;
            wavHeader.dwBytesRecorded = 0;
            wavHeader.dwUser          = IntPtr.Zero;
            wavHeader.dwFlags         = 0;
            wavHeader.dwLoops         = 0;
            wavHeader.lpNext          = IntPtr.Zero;
            wavHeader.reserved        = 0;
            GCHandle headerHandle = GCHandle.Alloc(wavHeader,GCHandleType.Pinned);
            int result = 0;
            result = WavMethods.waveOutPrepareHeader(m_pWavDevHandle,headerHandle.AddrOfPinnedObject(),Marshal.SizeOf(wavHeader));
            if(result == MMSYSERR.NOERROR){
                PlayItem item = new PlayItem(ref headerHandle,ref dataHandle,data.Length);
                m_pPlayItems.Add(item);

                // We ran out of minimum buffer, we must pause playing while min buffer filled.
                if(m_BytesBuffered < 1000){
                    if(!m_IsPaused){
                        WavMethods.waveOutPause(m_pWavDevHandle);
                        m_IsPaused = true;
                    }
                    //File.AppendAllText("aaaa.txt","Begin buffer\r\n");
                }
                // Buffering completed,we may resume playing.
                else if(m_IsPaused && m_BytesBuffered > m_MinBuffer){
                    WavMethods.waveOutRestart(m_pWavDevHandle);
                    m_IsPaused = false;
                    //File.AppendAllText("aaaa.txt","end buffer: " + m_BytesBuffered + "\r\n");
                }
                /*
                // TODO: If we ran out of minimum buffer, we must pause playing while min buffer filled.
                if(m_BytesBuffered < m_MinBuffer){
                    if(!m_IsPaused){
                        WavMethods.waveOutPause(m_pWavDevHandle);
                        m_IsPaused = true;
                    }
                }
                else if(m_IsPaused){
                    WavMethods.waveOutRestart(m_pWavDevHandle);
                }*/

                m_BytesBuffered += data.Length;

                result = WavMethods.waveOutWrite(m_pWavDevHandle,headerHandle.AddrOfPinnedObject(),Marshal.SizeOf(wavHeader));
            }
            else{
                dataHandle.Free();
                headerHandle.Free();
            }
            //--------------------------------------------------------------------------------------------------
        }
Пример #2
0
        /// <summary>
        /// Fills recording buffers.
        /// </summary>
        private void EnsureBuffers()
        {
            // We keep 3 x buffer.
            lock(m_pBuffers){
                while(m_pBuffers.Count < 3){
                    byte[]   data       = new byte[m_BufferSize];
                    GCHandle dataHandle = GCHandle.Alloc(data,GCHandleType.Pinned);

                    WAVEHDR wavHeader = new WAVEHDR();
                    wavHeader.lpData          = dataHandle.AddrOfPinnedObject();
                    wavHeader.dwBufferLength  = (uint)data.Length;
                    wavHeader.dwBytesRecorded = 0;
                    wavHeader.dwUser          = IntPtr.Zero;
                    wavHeader.dwFlags         = 0;
                    wavHeader.dwLoops         = 0;
                    wavHeader.lpNext          = IntPtr.Zero;
                    wavHeader.reserved        = 0;
                    GCHandle headerHandle = GCHandle.Alloc(wavHeader,GCHandleType.Pinned);
                    int result = 0;        
                    result = WavMethods.waveInPrepareHeader(m_pWavDevHandle,headerHandle.AddrOfPinnedObject(),Marshal.SizeOf(wavHeader));
                    if(result == MMSYSERR.NOERROR){
                        m_pBuffers.Add(new BufferItem(ref headerHandle,ref dataHandle,m_BufferSize));

                        result = WavMethods.waveInAddBuffer(m_pWavDevHandle,headerHandle.AddrOfPinnedObject(),Marshal.SizeOf(wavHeader));
                        if(result != MMSYSERR.NOERROR){
                            throw new Exception("Error adding wave in buffer, error: " + result + ".");
                        }
                    }
                }
            }
        }