protected virtual bool InitializeForWriting(Stream underlyingStream, WaveFormat2 wfIn, WaveFormat2 wfOut, bool fAppend) { if (fAppend) { long position = underlyingStream.Position; underlyingStream.Seek(0, SeekOrigin.Begin); LoadHeader(); _ckData.BeginWrite(); _ckData.Seek(position - _ckData.DataStart, SeekOrigin.Begin); } else { _baseStream.Position = 0; _mmc = new RiffChunk(underlyingStream); (_mmc as RiffChunk).BeginWrite(); _ckFmt = new FmtChunk(underlyingStream, wfOut); _mmc.AppendChunk(_ckFmt); _ckFmt.BeginWrite(); _ckFmt.Write(_ckFmt.WaveFormat.GetBytes()); _fmt = wfOut; _ckData = new DataChunk(underlyingStream); _mmc.AppendChunk(_ckData); _ckData.BeginWrite(); } return(true); }
internal static AcmFormatInfo FromFormatTagDetails(ACMFORMATTAGDETAILS details, IntPtr hDriver, int driverId) { if (driverId == 0) { AcmNativeMethods.acmDriverID(hDriver, out driverId, 0); } AcmFormatInfo info = new AcmFormatInfo(); info.DriverId = driverId; //info.Format = new WaveFormat2( info.FormatName = details.szFormatTag; info.FormatTag = (FormatTag)details.dwFormatTag; for (int i = 0; i < details.cStandardFormats; i++) { ACMFORMATDETAILS fd = new ACMFORMATDETAILS(); fd.cbStruct = Marshal.SizeOf(fd); fd.cbwfx = details.cbFormatSize; WaveFormat2 fmt = new WaveFormat2(new byte[fd.cbwfx]); fmt.FormatTag = (FormatTag)details.dwFormatTag; fmt.Size = (short)(fd.cbwfx == 16 ? 0 : fd.cbwfx - 18); fmt.Extra = new byte[fmt.Size]; fd.pwfx = Marshal.AllocHGlobal(fd.cbwfx); Marshal.Copy(fmt.GetBytes(), 0, fd.pwfx, fd.cbwfx); fd.dwFormatIndex = i; fd.dwFormatTag = (int)info.FormatTag; /*MMResult mmr = */ int mmr = AcmNativeMethods.acmFormatDetails(hDriver, ref fd, AcmFormatDetailsFlags.INDEX); byte[] fmtData = new byte[fd.cbwfx]; Marshal.Copy(fd.pwfx, fmtData, 0, fd.cbwfx); info.Format = new WaveFormat2(fmtData); Marshal.FreeHGlobal(fd.pwfx); } return(info); }
protected void SetFormat(WaveFormat2 fmt) { _fmt = fmt; if (_ckFmt == null) { _baseStream.Position = _ckData.Start + 12; _ckFmt = new FmtChunk(_baseStream, fmt); } }
public override void LoadFromStream(Stream st) { byte[] data = new byte[4]; m_posStart = st.Position - 4; st.Read(data, 0, 4); m_nSize = BitConverter.ToInt32(data, 0); m_fmt = WaveFormat2.FromStream(st); st.Position = Start + 8 + m_nSize; }
/// <summary> /// Set the volume for the default waveOut device (device ID = 0) /// </summary> /// <param name="Volume"></param> public void SetVolume(int Volume) { WaveFormat2 format = new WaveFormat2(); IntPtr hWaveOut = IntPtr.Zero; NativeMethods.waveOutOpen(out hWaveOut, 0, format.GetBytes(), IntPtr.Zero, 0, 0); NativeMethods.waveOutSetVolume(hWaveOut, Volume); NativeMethods.waveOutClose(hWaveOut); }
public override bool Equals(object obj) { if (obj is WaveFormat2) { WaveFormat2 fmt = obj as WaveFormat2; return(fmt.FormatTag == FormatTag && fmt.Channels == Channels && fmt.SamplesPerSec == SamplesPerSec && fmt.BitsPerSample == BitsPerSample); } return(base.Equals(obj)); }
public static ACMStream OpenWrite(Stream underlyingStream, WaveFormat2 fmtIn, WaveFormat2 fmtOut) { ACMStream stm = new ACMStream(); stm._accessMode = FileAccess.Write; stm._baseStream = underlyingStream; stm.InitializeForWriting(underlyingStream, fmtIn, fmtOut, false); stm.WriteHeader(); return(stm); }
public void CopyFrom(WaveFormat2 wf) { this.AvgBytesPerSec = wf.AvgBytesPerSec; this.BitsPerSample = wf.BitsPerSample; this.BlockAlign = wf.BlockAlign; this.Channels = wf.Channels; this.Extra = wf.Extra.Clone() as byte[]; this.FormatTag = wf.FormatTag; this.SamplesPerSec = wf.SamplesPerSec; this.Size = wf.Size; }
/// <summary> /// Get the current volume setting for the default waveOut device (device ID = 0) /// </summary> /// <returns></returns> public int GetVolume() { WaveFormat2 format = new WaveFormat2(); IntPtr hWaveOut = IntPtr.Zero; int volume = 0; NativeMethods.waveOutOpen(out hWaveOut, 0, format.GetBytes(), IntPtr.Zero, 0, 0); NativeMethods.waveOutGetVolume(hWaveOut, ref volume); NativeMethods.waveOutClose(hWaveOut); return(volume); }
public static WaveFormat2 GetPCMWaveFormat(int SamplesPerSecond, short Channels, short BitPerSample) { WaveFormat2 fmt = new WaveFormat2(); fmt.Extra = new byte[0]; fmt.BitsPerSample = BitPerSample; fmt.Channels = Channels; fmt.FormatTag = FormatTag.PCM; fmt.SamplesPerSec = SamplesPerSecond; fmt.BlockAlign = (short)(Channels * BitPerSample / 8); fmt.AvgBytesPerSec = SamplesPerSecond * Channels * BitPerSample / 8; return(fmt); }
public static ACMStream Append(Stream underlyingStream, WaveFormat2 fmt) { ACMStream stm = new ACMStream(); stm._accessMode = FileAccess.Write; stm._baseStream = underlyingStream; stm._baseStream.Position = 0; WaveFormat2 fmtOut = WaveFormat2.FromStream(underlyingStream); stm._baseStream.Position = stm._baseStream.Length; stm.InitializeForWriting(underlyingStream, fmt ?? fmtOut, fmtOut, true); stm.WriteHeader(); return(stm); }
protected virtual void LoadHeader() { _mmc = MMChunk.FromStream(_baseStream); _ckFmt = _mmc.FindChunk(FourCC.Fmt) as FmtChunk; if (_ckFmt != null) { _fmt = _ckFmt.WaveFormat; } _ckData = _mmc.FindChunk(FourCC.Data) as DataChunk; if (_ckData != null) { _posData = _ckData.DataStart; } _baseStream.Seek(_posData, SeekOrigin.Begin); }
/// <summary> /// Default constructor /// </summary> public static WaveFormat2 FromStream(Stream stm) { byte[] data = new byte[18]; stm.Read(data, 0, data.Length); WaveFormat2 fmt = new WaveFormat2(); fmt.FormatTag = (FormatTag)BitConverter.ToInt16(data, 0); fmt.Channels = BitConverter.ToInt16(data, 2); fmt.SamplesPerSec = BitConverter.ToInt32(data, 4); fmt.AvgBytesPerSec = BitConverter.ToInt32(data, 8); fmt.BlockAlign = BitConverter.ToInt16(data, 12); fmt.BitsPerSample = BitConverter.ToInt16(data, 14); fmt.Size = BitConverter.ToInt16(data, 16); fmt.Extra = new byte[fmt.Size]; stm.Read(fmt.Extra, 0, fmt.Size); return(fmt); }
public static WaveFormat2 GetSupportedFormat(FormatTag tag, int SamplesPerSecond, short Channels, short BitsPerSample) { MatchType bestMatchType = 0; WaveFormat2 bestMatch = null; foreach (AcmDriverInfo driverInfo in ACMSupport.SupportedDrivers) { foreach (AcmFormatInfo fmtInfo in driverInfo.Formats) { MatchType matchType = 0; if (fmtInfo.FormatTag != tag) { continue; } if (fmtInfo.Format.BitsPerSample == BitsPerSample) { matchType |= MatchType.Bits; } if (fmtInfo.Format.Channels == Channels) { matchType |= MatchType.Channels; } if (fmtInfo.Format.SamplesPerSec == SamplesPerSecond) { matchType |= MatchType.SamplesPerSecond; } if ((int)matchType > (int)bestMatchType) { bestMatch = fmtInfo.Format; bestMatchType = matchType; } } } return(bestMatch); }
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); }
protected override bool InitializeForWriting(Stream underlyingStream, WaveFormat2 wfIn, WaveFormat2 wfOut, bool fAppend) { base.InitializeForWriting(underlyingStream, wfIn, wfOut, fAppend); MMResult mmr; int driverId = 0; foreach (AcmDriverInfo drvInfo in ACMSupport.SupportedDrivers) { foreach (AcmFormatInfo fmtInfo in drvInfo.Formats) { if (fmtInfo.Format == wfOut) { driverId = fmtInfo.DriverId; break; } } } foreach (AcmDriverInfo drvInfo in ACMSupport.SupportedDrivers) { foreach (AcmFormatInfo fmtInfo in drvInfo.Formats) { if (fmtInfo.DriverId == driverId && fmtInfo.Format.FormatTag == wfIn.FormatTag) { wfIn.CopyFrom(fmtInfo.Format); break; } } } byte[] fmtIn = wfIn.GetBytes(); byte[] fmtOut = wfOut.GetBytes(); IntPtr hDrv = IntPtr.Zero; if (driverId != 0) { AcmNativeMethods.acmDriverOpen(out hDrv, driverId, 0); } mmr = AcmNativeMethods.acmStreamOpen(out hStreamComp, hDrv, fmtIn, fmtOut, IntPtr.Zero, 0, 0, AcmStreamOpenFlags.CALLBACK_NULL | AcmStreamOpenFlags.NONREALTIME); hdr1 = new ACMSTREAMHEADER(); hdr1.cbStruct = Marshal.SizeOf(hdr1); hdr2 = new ACMSTREAMHEADER(); hdr2.cbStruct = Marshal.SizeOf(hdr2); int cbIn = (wfIn.AvgBytesPerSec * DefaultBufferSizeInSeconds / wfIn.BlockAlign + 1) * wfIn.BlockAlign; inBuffer1 = new byte[cbIn]; inBuffer2 = new byte[cbIn]; int cbOut = wfOut.BlockAlign * wfOut.AvgBytesPerSec * DefaultBufferSizeInSeconds; mmr = AcmNativeMethods.acmStreamSize(hStreamComp, cbIn, out cbOut, AcmStreamSizeFlags.DESTINATION); 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; firstBlock = true; mmr = AcmNativeMethods.acmStreamPrepareHeader(hStreamComp, ref hdr1, 0); mmr = AcmNativeMethods.acmStreamPrepareHeader(hStreamComp, ref hdr2, 0); return(true); }
private static new ACMStream OpenWrite(Stream underlyingStream, WaveFormat2 fmt) { return(null); }
public static WaveFormat2 GetPCMWaveFormat(SoundFormats SoundFormat) { WaveFormat2 fmt = new WaveFormat2(); #region long format switch() switch (SoundFormat) { case SoundFormats.Mono16bit11kHz: fmt.Channels = 1; fmt.SamplesPerSec = 11025; fmt.BitsPerSample = 16; break; case SoundFormats.Mono16bit22kHz: fmt.Channels = 1; fmt.SamplesPerSec = 22050; fmt.BitsPerSample = 16; break; case SoundFormats.Mono16bit44kHz: fmt.Channels = 1; fmt.SamplesPerSec = 44100; fmt.BitsPerSample = 16; break; case SoundFormats.Mono8bit11kHz: fmt.Channels = 1; fmt.SamplesPerSec = 11025; fmt.BitsPerSample = 8; break; case SoundFormats.Mono8bit22kHz: fmt.Channels = 1; fmt.SamplesPerSec = 22050; fmt.BitsPerSample = 8; break; case SoundFormats.Mono8bit44kHz: fmt.Channels = 1; fmt.SamplesPerSec = 44100; fmt.BitsPerSample = 8; break; case SoundFormats.Stereo16bit11kHz: fmt.Channels = 2; fmt.SamplesPerSec = 11025; fmt.BitsPerSample = 16; break; case SoundFormats.Stereo16bit22kHz: fmt.Channels = 2; fmt.SamplesPerSec = 22050; fmt.BitsPerSample = 16; break; case SoundFormats.Stereo16bit44kHz: fmt.Channels = 2; fmt.SamplesPerSec = 44100; fmt.BitsPerSample = 16; break; case SoundFormats.Stereo8bit11kHz: fmt.Channels = 2; fmt.SamplesPerSec = 11025; fmt.BitsPerSample = 8; break; case SoundFormats.Stereo8bit22kHz: fmt.Channels = 2; fmt.SamplesPerSec = 22050; fmt.BitsPerSample = 8; break; case SoundFormats.Stereo8bit44kHz: fmt.Channels = 2; fmt.SamplesPerSec = 44100; fmt.BitsPerSample = 8; break; } #endregion long format switch() return(GetPCMWaveFormat(fmt.SamplesPerSec, fmt.Channels, fmt.BitsPerSample)); }
public FmtChunk(Stream st, WaveFormat2 fmt) : base(new FourCC('f', 'm', 't', ' '), st) { m_fmt = fmt; }
/// <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); }
public void RecordFor(Stream st, short Seconds, SoundFormats SoundFormat) { RecordFor(st, Seconds, WaveFormat2.GetPCMWaveFormat(SoundFormat)); }
/// <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); } }
public WAVEFORMAT_MIDI() { WAVEFORMATEX = new WaveFormat2(); WAVEFORMATEX.Extra = new byte[10]; }