Ejemplo n.º 1
0
        /// <summary>
        /// Record sound data for specified number of seconds using given wave format
        /// The stream will be a properly formatted RIFF file
        /// </summary>
        /// <param name="st">Stream into which recorded samples are written</param>
        /// <param name="Seconds">Seconds of data to record</param>
        /// <param name="format">Sound format to record in.</param>
        public RiffStream RecordFor(Stream st, short Seconds, WaveFormat2 format)
        {
            // only allow 1 recording session at a time
            if (recording)
            {
                throw new InvalidOperationException("Already recording");
            }

            m_hWaveIn = IntPtr.Zero;

            // set our global flag
            recording = true;

            if (m_qBuffers == null)
            {
                m_qBuffers = new Queue <WaveHeader>(MaxBuffers);
            }
            if (m_HandleMap == null)
            {
                m_HandleMap = new System.Collections.Hashtable(MaxBuffers);
            }

            m_recformat = new WaveFormat2();
#if !NDOC
            // create the callback message window
            m_recmw = new SoundMessageWindow();
            m_recmw.WaveDoneMessage  += new WaveDoneHandler(m_recmw_WaveDoneMessage);
            m_recmw.WaveCloseMessage += new WaveCloseHandler(mw_WaveCloseMessage);
            m_recmw.WaveOpenMessage  += new WaveOpenHandler(mw_WaveOpenMessage);
#endif
            bool append = st.Length >= 42;
            if (format.FormatTag == FormatTag.PCM)
            {
                m_recformat = format;
                if (append)
                {
                    m_streamRecord = RiffStream.Append(st);
                }
                else
                {
                    m_streamRecord = RiffStream.OpenWrite(st, m_recformat);
                }
            }
            else
            {
                m_recformat = WaveFormat2.GetPCMWaveFormat(SoundFormats.Mono8bit11kHz);
                if (append)
                {
                    m_streamRecord = ACMStream.Append(st, m_recformat);
                }
                else
                {
                    m_streamRecord = ACMStream.OpenWrite(st, m_recformat, format);
                }
            }
#if !NDOC
            // check for support of selected format
            CheckWaveError(NativeMethods.waveInOpen(out m_hWaveIn, WAVE_MAPPER, m_recformat.GetBytes(), IntPtr.Zero, 0, WAVE_FORMAT_QUERY));

            // open wave device
            CheckWaveError(NativeMethods.waveInOpen(out m_hWaveIn, (uint)m_deviceID, m_recformat.GetBytes(), m_recmw.Hwnd, 0, CALLBACK_WINDOW));

            m_recBufferSize = (int)(Math.Min((int)Seconds, BufferLen) * m_recformat.AvgBytesPerSec);

            for (int i = 0; i < 2; i++)
            {
                WaveHeader hdr = GetNewRecordBuffer(m_recBufferSize);

                // send the buffer to the device
                CheckWaveError(NativeMethods.waveInAddBuffer(m_hWaveIn, hdr.Pointer, hdr.HeaderLength));
            }

            // begin recording
            CheckWaveError(NativeMethods.waveInStart(m_hWaveIn));
            recordingFinished = false;
            m_recTimer        = new Timer(new TimerCallback(RecTimerCallback), this, Seconds * 1000, Timeout.Infinite);
#endif
            return(m_streamRecord);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Plays waveform contained in the given stream. Stream is exepcted to contain full riff header
        /// </summary>
        /// <param name="playStream">Stream with the waveform</param>
        public void Play(Stream playStream)
        {
            Monitor.Enter(m_syncRoot);
            try
            {
                if (m_playing)
                {
                    return;
                }

                if (playStream == null)
                {
                    throw new Exception("No valid WAV file has been opened");
                }

#if !NDOC
                if (m_qBuffers == null)
                {
                    m_qBuffers = new Queue <WaveHeader>(MaxBuffers);
                }
                if (m_HandleMap == null)
                {
                    m_HandleMap = new System.Collections.Hashtable(MaxBuffers);
                }

                // create a window to catch waveOutxxx messages
                SoundMessageWindow mw = new SoundMessageWindow();

                // wire in events
                mw.WaveOpenMessage  += new WaveOpenHandler(mw_WaveOpenMessage);
                mw.WaveCloseMessage += new WaveCloseHandler(mw_WaveCloseMessage);
                mw.WaveDoneMessage  += new WaveDoneHandler(mw_WaveDoneMessage);

                // add it to the global array
                m_mwArray.Add(mw);
                int i = m_mwArray.Count - 1;
                if (playStream is ACMStream)
                {
                    m_streamArray.Add(playStream as ACMStream);
                }
                else if (playStream is RiffStream)
                {
                    m_streamArray.Add(playStream as RiffStream);
                }
                else
                {
                    m_streamArray.Add(ACMStream.OpenRead(playStream));
                }
                m_format = (m_streamArray[m_streamArray.Count - 1] as RiffStream).Format;

                // open the waveOut device and register the callback
                CheckWaveError(NativeMethods.waveOutOpen(out m_hWaveOut, m_deviceID, m_format.GetBytes(), m_mwArray[i].Hwnd, 0, CALLBACK_WINDOW));

                // see if we need to adjust playback rate
                if ((PlaybackRate < 0.9f) || (PlaybackRate > 1.1f))
                {
                    SetPlaybackRate(PlaybackRate);
                }

                RefillPlayBuffers();

                while (m_qBuffers.Count > 0)
                {
                    Monitor.Enter(m_qBuffers);
                    WaveHeader hdr = m_qBuffers.Dequeue();
                    Monitor.Exit(m_qBuffers);

                    // play the file
                    ThreadPool.QueueUserWorkItem(BufferWriteThreadProc, hdr);

                    m_playing = true;

                    if (m_qBuffers.Count <= 1)
                    {
                        RefillPlayBuffers();
                    }
                }
#endif
            }
            finally
            {
                Monitor.Exit(m_syncRoot);
            }
        }