Beispiel #1
0
        // Add more buffers to the playback queue - keep it full
        private void RefillPlayBuffers()
        {
            while (m_qBuffers.Count < MaxBuffers)
            {
                int    cb   = (int)(BufferLen * m_format.SamplesPerSec * m_format.Channels);
                byte[] data = new byte[cb];

                for (int i = 0; i < m_streamArray.Count; i++)
                {
                    if (m_streamArray[i] != null)
                    {
                        cb = ((Stream)m_streamArray[i]).Read(data, 0, cb);
                        break;
                    }
                }

                if (cb == 0)
                {
                    break;
                }

                WaveHeader hdr = new WaveHeader(data);
                Monitor.Enter(m_HandleMap.SyncRoot);
                m_HandleMap.Add(hdr.Header.ToInt32(), hdr);
                Monitor.Exit(m_HandleMap.SyncRoot);

                // prepare the header
                CheckWaveError(Wave.waveOutPrepareHeader(m_hWaveOut, hdr.Header, hdr.HeaderLength));
                Monitor.Enter(m_qBuffers.SyncRoot);
                m_qBuffers.Enqueue(hdr);
                Monitor.Exit(m_qBuffers.SyncRoot);
            }
        }
Beispiel #2
0
        private void m_recmw_WaveDoneMessage(object sender, IntPtr wParam, IntPtr lParam)
        {
#if !NDOC
            // Retrieve Waveheader object by the lpHeader pointer
            Monitor.Enter(m_HandleMap.SyncRoot);
            WaveHeader hdr = m_HandleMap[lParam.ToInt32()] as WaveHeader;
            m_HandleMap.Remove(hdr.Header.ToInt32());
            Monitor.Exit(m_HandleMap.SyncRoot);

            // unprepare the header
            CheckWaveError(Wave.waveInUnprepareHeader(m_hWaveIn, hdr.Header, hdr.HeaderLength));
            hdr.RetrieveHeader();
            m_qBuffers.Enqueue(hdr);

            if (recordingFinished)               // last chunk
            {
                DumpRecordBuffers();
                CheckWaveError(Wave.waveInClose(m_hWaveIn));
                WaveChunk wck = m_ck[0] as WaveChunk;
                if (wck != null)
                {
                    DataChunk dck = wck.FindChunk(FourCC.Data) as DataChunk;
                    if (dck != null)
                    {
                        dck.EndWrite();
                    }
                    wck.EndWrite();
                }
                m_ck.EndWrite();
                m_streamRecord.Close();
                // clean up the messageWindow
                m_recmw.Dispose();

                // reset the global flag
                recording = false;
                // set our event
                if (DoneRecording != null)
                {
                    DoneRecording();
                }

                foreach (WaveHeader whdr in m_HandleMap.Values)
                {
                    whdr.Dispose();
                }
                m_HandleMap.Clear();
            }
            else
            {
                hdr = GetNewRecordBuffer(m_recBufferSize);
                CheckWaveError(Wave.waveInAddBuffer(m_hWaveIn, hdr.Header, hdr.HeaderLength));
                DumpRecordBuffers();
            }
#endif
        }
Beispiel #3
0
        private void mw_WaveDoneMessage(object sender, IntPtr wParam, IntPtr lParam)
        {
            // free the header
            Monitor.Enter(m_HandleMap.SyncRoot);
            WaveHeader hdr = m_HandleMap[lParam.ToInt32()] as WaveHeader;

            m_HandleMap.Remove(lParam.ToInt32());
            Monitor.Exit(m_HandleMap.SyncRoot);
            CheckWaveError(Wave.waveOutUnprepareHeader(m_hWaveOut, lParam, hdr.HeaderLength));
            hdr.Dispose();

            // Check if we got here because of waveOutReset
            if (!m_playing)
            {
                // Cleanup - free buffers and headers
                Monitor.Enter(m_qBuffers.SyncRoot);
                while (m_qBuffers.Count > 0)
                {
                    hdr = m_qBuffers.Dequeue() as WaveHeader;
                    CheckWaveError(Wave.waveOutUnprepareHeader(m_hWaveOut, hdr.Header, hdr.HeaderLength));
                    m_HandleMap.Remove(hdr.Header.ToInt32());
                    hdr.Dispose();
                }
                Monitor.Exit(m_qBuffers.SyncRoot);
            }

            // Are there any pending buffers?
            if (m_qBuffers.Count == 0)
            {
                // No more buffers
                // Close the device
                CheckWaveError(Wave.waveOutClose(m_hWaveOut));
                m_playing  = false;
                m_qBuffers = null;

                // Notify clients
                if (DonePlaying != null)
                {
                    DonePlaying(this, wParam, lParam);
                }
            }
            else
            {
                //Get next buffer (already prepared)
                Monitor.Enter(m_qBuffers.SyncRoot);
                hdr = (WaveHeader)m_qBuffers.Dequeue();
                Monitor.Exit(m_qBuffers.SyncRoot);

                // play the file
                CheckWaveError(Wave.waveOutWrite(m_hWaveOut, hdr.Header, hdr.HeaderLength));

                // Add more buffers
                RefillPlayBuffers();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Creates a recording buffer
        /// </summary>
        /// <param name="dwBufferSize"></param>
        /// <returns>new buffer as WaveHeader</returns>
        private WaveHeader GetNewRecordBuffer(int dwBufferSize)
        {
            WaveHeader hdr = new WaveHeader(dwBufferSize);

            Monitor.Enter(m_HandleMap.SyncRoot);
            m_HandleMap.Add(hdr.Header.ToInt32(), hdr);
            Monitor.Exit(m_HandleMap.SyncRoot);
            // prepare the header
            CheckWaveError(Wave.waveInPrepareHeader(m_hWaveIn, hdr.Header, hdr.HeaderLength));
            return(hdr);
        }
Beispiel #5
0
        private void DumpRecordBuffers()
        {
            while (m_qBuffers.Count > 0)
            {
                Monitor.Enter(m_qBuffers.SyncRoot);
                WaveHeader hdr = (WaveHeader)m_qBuffers.Dequeue();
                Monitor.Exit(m_qBuffers.SyncRoot);


                m_streamRecord.Write(hdr.GetData(), 0, (int)hdr.waveHdr.BytesRecorded);
                hdr.Dispose();
            }
        }
Beispiel #6
0
		// Add more buffers to the playback queue - keep it full
		private void RefillPlayBuffers()
		{
			while( m_qBuffers.Count < MaxBuffers )
			{
				int cb = (int)(BufferLen * m_format.SamplesPerSec * m_format.Channels);
				byte[] data = new byte[cb];

				for(int i = 0 ; i < m_streamArray.Count ; i++)
				{
					if( m_streamArray[i] != null )
					{
						cb = ((Stream)m_streamArray[i]).Read(data, 0, cb);
						break;
					}
				}

				if ( cb == 0 )
					break;

				WaveHeader hdr = new WaveHeader(data);
				Monitor.Enter(m_HandleMap.SyncRoot);
				m_HandleMap.Add(hdr.Header.ToInt32(), hdr);
				Monitor.Exit(m_HandleMap.SyncRoot);

				// prepare the header
				CheckWaveError(Wave.waveOutPrepareHeader(m_hWaveOut, hdr.Header, hdr.HeaderLength));
				Monitor.Enter(m_qBuffers.SyncRoot);
				m_qBuffers.Enqueue(hdr);
				Monitor.Exit(m_qBuffers.SyncRoot);
			}
		}
Beispiel #7
0
		/// <summary>
		/// Creates a recording buffer
		/// </summary>
		/// <param name="dwBufferSize"></param>
		/// <returns>new buffer as WaveHeader</returns>
		private WaveHeader GetNewRecordBuffer(int dwBufferSize)
		{
			WaveHeader hdr = new WaveHeader(dwBufferSize);
			Monitor.Enter(m_HandleMap.SyncRoot);
			m_HandleMap.Add(hdr.Header.ToInt32(), hdr);
			Monitor.Exit(m_HandleMap.SyncRoot);
			// prepare the header
			CheckWaveError(Wave.waveInPrepareHeader(m_hWaveIn, hdr.Header, hdr.HeaderLength));
			return hdr;
		}
Beispiel #8
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="SoundFormat">Sound format to record in.</param>
        public void RecordFor(Stream st, short Seconds, SoundFormats SoundFormat)
        {
            m_hWaveIn = IntPtr.Zero;

            // only allow 1 recording session at a time
            if (recording)
            {
                throw new InvalidOperationException("Already recording");
            }

            // set our global flag
            recording = true;

            if (m_qBuffers == null)
            {
                m_qBuffers = new Queue(MaxBuffers);
            }
            if (m_HandleMap == null)
            {
                m_HandleMap = new Hashtable(MaxBuffers);
            }

            m_recformat = new WaveFormatEx();
#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
            // set up format
            #region long format switch()
            switch (SoundFormat)
            {
            case SoundFormats.Mono16bit11kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 11025;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Mono16bit22kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 22050;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Mono16bit44kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 44100;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Mono8bit11kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 11025;
                m_recformat.BitsPerSample = 8;
                break;

            case SoundFormats.Mono8bit22kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 22050;
                m_recformat.BitsPerSample = 8;
                break;

            case SoundFormats.Mono8bit44kHz:
                m_recformat.Channels      = 1;
                m_recformat.SamplesPerSec = 44100;
                m_recformat.BitsPerSample = 8;
                break;

            case SoundFormats.Stereo16bit11kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 11025;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Stereo16bit22kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 22050;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Stereo16bit44kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 44100;
                m_recformat.BitsPerSample = 16;
                break;

            case SoundFormats.Stereo8bit11kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 11025;
                m_recformat.BitsPerSample = 8;
                break;

            case SoundFormats.Stereo8bit22kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 22050;
                m_recformat.BitsPerSample = 8;
                break;

            case SoundFormats.Stereo8bit44kHz:
                m_recformat.Channels      = 2;
                m_recformat.SamplesPerSec = 44100;
                m_recformat.BitsPerSample = 8;
                break;
            }
            #endregion long format switch()

            m_recformat.FormatTag      = WAVE_FORMAT_PCM;
            m_recformat.AvgBytesPerSec = m_recformat.SamplesPerSec * m_recformat.Channels;
            m_recformat.BlockAlign     = (short)((m_recformat.Channels * m_recformat.BitsPerSample) / 8);
            m_recformat.Size           = 0;

            m_ck = new RiffChunk(st);
            m_ck.BeginWrite();
            WaveChunk wck = m_ck.CreateSubChunk(FourCC.Wave, st) as WaveChunk;
            wck.BeginWrite();
            FmtChunk fck = wck.CreateSubChunk(FourCC.Fmt, st) as FmtChunk;
            fck.BeginWrite();
            fck.WaveFormat = m_recformat;
            fck.Write(fck.WaveFormat.GetBytes());
            fck.EndWrite();
            DataChunk dck = wck.CreateSubChunk(FourCC.Data, st) as DataChunk;
            m_streamRecord = dck.BeginWrite();
#if !NDOC
            // check for support of selected format
            CheckWaveError(Wave.waveInOpen(out m_hWaveIn, WAVE_MAPPER, m_recformat, IntPtr.Zero, 0, WAVE_FORMAT_QUERY));

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

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

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

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

            // begin recording
            CheckWaveError(Wave.waveInStart(m_hWaveIn));
            recordingFinished = false;
            m_recTimer        = new Timer(new TimerCallback(RecTimerCallback), this, Seconds * 1000, Timeout.Infinite);
#endif
        }
Beispiel #9
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)
        {
            if (m_playing)
            {
                return;
            }


            MMChunk ck = MMChunk.FromStream(playStream);

            if (ck != null && ck.FourCC == FourCC.Riff)
            {
                if (ck[0] is WaveChunk)
                {
                    DataChunk dck = ck[0].FindChunk(FourCC.Data) as DataChunk;
                    if (dck != null)
                    {
                        playStream = dck.BeginRead();
                    }
                    FmtChunk fck = ck[0].FindChunk(FourCC.Fmt) as FmtChunk;
                    if (fck != null)
                    {
                        m_format = fck.WaveFormat;
                    }
                }
            }
            if (playStream == null)
            {
                throw new Exception("No valid WAV file has been opened");
            }

#if !NDOC
            if (m_qBuffers == null)
            {
                m_qBuffers = new Queue(MaxBuffers);
            }
            if (m_HandleMap == null)
            {
                m_HandleMap = new 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
            int i = m_mwArray.Add(mw);
            m_streamArray.Add(playStream);

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

            RefillPlayBuffers();

            Monitor.Enter(m_qBuffers.SyncRoot);
            WaveHeader hdr = m_qBuffers.Dequeue() as WaveHeader;
            Monitor.Exit(m_qBuffers.SyncRoot);

            // play the file
            int ret = Wave.waveOutWrite(m_hWaveOut, hdr.Header, hdr.HeaderLength);
            CheckWaveError(ret);

            m_playing = true;
#endif
        }