/// <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); }
protected override void LoadHeader() { base.LoadHeader(); byte[] fmtIn = _fmt.GetBytes(); if (_fmt2 == null) { _fmt2 = WaveFormat2.GetPCMWaveFormat(_fmt.SamplesPerSec, _fmt.Channels, _fmt.BitsPerSample != 0 ? _fmt.BitsPerSample : (short)16); } byte[] fmtOut = _fmt2.GetBytes(); MMResult mmr; _fmt2 = new WaveFormat2(fmtOut); mmr = AcmNativeMethods.acmStreamOpen(out hStreamComp, IntPtr.Zero, fmtIn, fmtOut, IntPtr.Zero, 0, 0, AcmStreamOpenFlags.CALLBACK_NULL); hdr1 = new ACMSTREAMHEADER(); hdr1.cbStruct = Marshal.SizeOf(hdr1); hdr2 = new ACMSTREAMHEADER(); hdr2.cbStruct = Marshal.SizeOf(hdr2); int cbIn = (_fmt.AvgBytesPerSec * DefaultBufferSizeInSeconds / _fmt.BlockAlign + 1) * _fmt.BlockAlign; inBuffer1 = new byte[cbIn]; inBuffer2 = new byte[cbIn]; int cbOut = _fmt2.BlockAlign * _fmt2.AvgBytesPerSec * DefaultBufferSizeInSeconds; mmr = AcmNativeMethods.acmStreamSize(hStreamComp, cbIn, out cbOut, AcmStreamSizeFlags.SOURCE); outBuffer1 = new byte[cbOut]; outBuffer2 = new byte[cbOut]; hinBuffer1 = GCHandle.Alloc(inBuffer1, GCHandleType.Pinned); houtBuffer1 = GCHandle.Alloc(outBuffer1, GCHandleType.Pinned); hinBuffer2 = GCHandle.Alloc(inBuffer2, GCHandleType.Pinned); houtBuffer2 = GCHandle.Alloc(outBuffer2, GCHandleType.Pinned); hdr1.pbSrc = hinBuffer1.AddrOfPinnedObject(); hdr1.pbDst = houtBuffer1.AddrOfPinnedObject(); hdr1.cbSrcLength = cbIn; hdr1.cbDstLength = cbOut; hdr2.pbSrc = hinBuffer2.AddrOfPinnedObject(); hdr2.pbDst = houtBuffer2.AddrOfPinnedObject(); hdr2.cbSrcLength = cbIn; hdr2.cbDstLength = cbOut; ptrBuffer1 = ptrBuffer1 = 0; bufferRead = new SlidingBuffer(cbOut); firstBlock = true; bufferRead.BufferStarving = (BufferStarvingHandler) delegate(SlidingBuffer obj, int spaceAvailable) { if (hdr1.cbDstLengthUsed == ptrBuffer1) { int cb = ReadInternal(inBuffer1, 0, inBuffer1.Length); if (cb == 0) { return(0); } ptrBuffer1 = 0; AcmStreamConvertFlags flags; if (firstBlock) { flags = AcmStreamConvertFlags.START; firstBlock = false; } else if (cb == inBuffer1.Length) { flags = AcmStreamConvertFlags.BLOCKALIGN; } else { flags = AcmStreamConvertFlags.END; } hdr1.cbSrcLength = cb; MMResult res = AcmNativeMethods.acmStreamConvert(hStreamComp, ref hdr1, flags); return(cb); } int written = obj.Append(outBuffer1, ptrBuffer1, hdr1.cbDstLengthUsed - ptrBuffer1); ptrBuffer1 += written; return(written); }; mmr = AcmNativeMethods.acmStreamPrepareHeader(hStreamComp, ref hdr1, 0); mmr = AcmNativeMethods.acmStreamPrepareHeader(hStreamComp, ref hdr2, 0); }
public void RecordFor(Stream st, short Seconds, SoundFormats SoundFormat) { RecordFor(st, Seconds, WaveFormat2.GetPCMWaveFormat(SoundFormat)); }