/// <summary>Get the output device name from device id</summary> /// <param name="deviceId">device id</param> /// <param name="prodName">returns device name</param> /// <returns>MMSYSERR</returns> public MMSYSERR GetOutputDeviceName(uint deviceId, ref string prodName) { WAVEOUTCAPS caps = new WAVEOUTCAPS(); MMSYSERR result = waveOutGetDevCaps(deviceId, out caps, (uint)Marshal.SizeOf(caps)); if (result != MMSYSERR.NOERROR) { return(result); } //WAVEOUTCAPS2 often does not return product name GUID, as it is not //a required field, so is most often left blank.. //The only way to get full string in vista/w7 that I have come across is //by enumerating devices with directsound, but that would mean referencing //the library, so.. deal with it prodName = new string(caps.szPname); if (prodName.Contains("(") && !(prodName.Contains(")"))) { prodName = prodName.Substring(0, prodName.IndexOf("(")); } else if (prodName.Contains(")")) { if (prodName.IndexOf(")") > 8) { prodName = prodName.Substring(0, prodName.IndexOf(")") + 1); } } return(MMSYSERR.NOERROR); }
/// <summary>Stop recording and reset</summary> /// <returns>MMSYSERR</returns> public MMSYSERR Stop() { MMSYSERR mmr = MMSYSERR.ERROR; try { _bFinished = true; if (_pWaveIn != IntPtr.Zero) { waveInReset(_pWaveIn); } if (_cThread != null) { _cThread.Abort(); } _eDoneProc = null; FreeBuffers(); if (_pWaveIn != IntPtr.Zero) { mmr = waveInClose(_pWaveIn); } else { mmr = MMSYSERR.NOERROR; } } finally { _cThread = null; _pWaveIn = IntPtr.Zero; Recording = false; } return(mmr); }
/// <summary>Stop playback, and cleanup resources</summary> /// <returns>MMSYSERR</returns> public MMSYSERR Stop() { MMSYSERR mmr = MMSYSERR.ERROR; try { _bFinished = true; if (_pWaveOut != IntPtr.Zero) { waveOutReset(_pWaveOut); } if (_cThread != null) { _cThread.Abort(); } _eFillProc = null; FreeBuffers(); if (_pWaveOut != IntPtr.Zero) { mmr = waveOutClose(_pWaveOut); } else { mmr = MMSYSERR.NOERROR; } } finally { _cThread = null; _pWaveOut = IntPtr.Zero; this.Playing = false; } return(mmr); }
private MMSYSERR SetVolume(IntPtr hmixer, MIXERCONTROL mxc, uint volume) { IntPtr hmem = IntPtr.Zero; MMSYSERR err = MMSYSERR.NOERROR; MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS(); MIXERCONTROLDETAILS_UNSIGNED vol = new MIXERCONTROLDETAILS_UNSIGNED(); try { mxcd.hwndOwner = IntPtr.Zero; mxcd.dwControlID = mxc.dwControlID; mxcd.cbStruct = (uint)Marshal.SizeOf(mxcd); mxcd.cbDetails = (uint)Marshal.SizeOf(vol); mxcd.cChannels = 1; vol.value = volume; hmem = malloc(Marshal.SizeOf(vol)); mxcd.paDetails = hmem; Marshal.StructureToPtr(vol, mxcd.paDetails, true); err = mixerSetControlDetails(hmixer, ref mxcd, 0x0); if (hmem != IntPtr.Zero) { free(hmem, Marshal.SizeOf(vol)); } return(err); } catch { return(err); } }
private void ClearBuffers() { foreach (InItem item in _queueOut) { WaveHeader waveHeader = item._waveHeader; MMSYSERR mMSYSERR = SafeNativeMethods.waveOutUnprepareHeader(_hwo, waveHeader.WAVEHDR.AddrOfPinnedObject(), waveHeader.SizeHDR); } }
internal AudioException(MMSYSERR errorCode) : base(string.Format(CultureInfo.InvariantCulture, "{0} - Error Code: 0x{1:x}", new object[2] { SR.Get(SRID.AudioDeviceError), (int)errorCode })) { }
internal override void Resume() { lock (_noWriteOutLock) { if (!_aborted && _fPaused && _deviceOpen) { MMSYSERR mMSYSERR = SafeNativeMethods.waveOutRestart(_hwo); } } _fPaused = false; }
internal static MMSYSERR GetDeviceName(int deviceId, [MarshalAs(UnmanagedType.LPWStr)] out string prodName) { prodName = string.Empty; SafeNativeMethods.WAVEOUTCAPS caps = default(SafeNativeMethods.WAVEOUTCAPS); MMSYSERR mMSYSERR = SafeNativeMethods.waveOutGetDevCaps((IntPtr)deviceId, ref caps, Marshal.SizeOf((object)caps)); if (mMSYSERR != 0) { return(mMSYSERR); } prodName = caps.szPname; return(MMSYSERR.NOERROR); }
internal override void Pause() { lock (_noWriteOutLock) { if (!_aborted && !_fPaused) { if (_deviceOpen) { MMSYSERR mMSYSERR = SafeNativeMethods.waveOutPause(_hwo); } _fPaused = true; } } }
/// <summary> /// Play a wave file. /// </summary> internal override void Play(byte[] buffer) { if (!_deviceOpen) { System.Diagnostics.Debug.Assert(false); } else { int bufferSize = buffer.Length; _bytesWritten += bufferSize; System.Diagnostics.Debug.Assert(bufferSize % _blockAlign == 0); WaveHeader waveHeader = new(buffer); GCHandle waveHdr = waveHeader.WAVEHDR; MMSYSERR result = SafeNativeMethods.waveOutPrepareHeader(_hwo, waveHdr.AddrOfPinnedObject(), waveHeader.SizeHDR); if (result != MMSYSERR.NOERROR) { throw new AudioException(result); } lock (_noWriteOutLock) { if (!_aborted) { lock (_queueIn) { InItem item = new(waveHeader); _queueIn.Add(item); // Something in the queue cannot exit anymore _evt.Reset(); } // Start playback of the first buffer result = SafeNativeMethods.waveOutWrite(_hwo, waveHdr.AddrOfPinnedObject(), waveHeader.SizeHDR); if (result != MMSYSERR.NOERROR) { lock (_queueIn) { _queueIn.RemoveAt(_queueIn.Count - 1); throw new AudioException(result); } } } } } }
/// <summary> /// Get the name of the specified playback device. /// </summary> /// <param name="deviceId">ID of the device</param> /// <param name="prodName">Destination string assigned the name</param> /// <returns>MMSYSERR.NOERROR if successful</returns> internal static MMSYSERR GetDeviceName(int deviceId, [MarshalAs(UnmanagedType.LPWStr)] out string prodName) { prodName = string.Empty; SafeNativeMethods.WAVEOUTCAPS caps = new(); MMSYSERR result = SafeNativeMethods.waveOutGetDevCaps((IntPtr)deviceId, ref caps, Marshal.SizeOf <SafeNativeMethods.WAVEOUTCAPS>()); if (result != MMSYSERR.NOERROR) { return(result); } prodName = caps.szPname; return(MMSYSERR.NOERROR); }
/// <summary>Set the volume level</summary> /// <param name="left">left channel</param> /// <param name="right">right channel</param> /// <returns>MMSYSERR</returns> public MMSYSERR SetVolume(uint left, uint right) { uint vol = (left & 0x00ff) | (right << 8); MMSYSERR err = MMSYSERR.NOERROR; err = waveOutSetVolume(_pWaveOut, vol); // probably poor ol' vista if (err != MMSYSERR.NOERROR) { Mixer mx = new Mixer(); mx.OpenMixer(); err = mx.SetVolume(vol); mx.CloseMixer(); } return(err); }
/// <summary>Get the current volume levels</summary> /// <param name="left">returns left channel</param> /// <param name="right">returns right channel</param> /// <returns>MMSYSERR</returns> public MMSYSERR GetVolume(ref uint left, ref uint right) { uint vol = 0; MMSYSERR err = waveOutGetVolume(_pWaveOut, out vol); if (err != MMSYSERR.NOERROR) { return(err); } left = (vol & 0x00ff); right = (vol >> 8); return(err); }
/// <summary> /// Start playing the audio /// </summary> /// <param name="cnsStart"></param> public void Start(long cnsStart) { // // Ensure that a reader object has been instantiated. // if (IsDisposed()) { throw new COMException("Instance has been Disposed", E_Unexpected); } m_OldTime = -1; // // Configure the wave output device. // if (IntPtr.Zero != m_hWaveOut) { int woe = waveOut.Reset(m_hWaveOut); waveOut.ThrowExceptionForError(woe); } else { int mmr = waveOut.Open(out m_hWaveOut, m_DeviceIndex, m_pWfx, IntPtr.Zero, IntPtr.Zero, WaveOpenFlags.Null); waveOut.ThrowExceptionForError(mmr); // If a form was provided if (m_fForm != null) { // Ensure volume change events get sent MIXER_OBJECTF flags = MIXER_OBJECTF.CallBack_Window | MIXER_OBJECTF.WaveOut; MMSYSERR rc = Mixer.Open(out m_hMixer, m_DeviceIndex, m_fForm.Handle, IntPtr.Zero, flags); // Not checking for error. If something goes wrong, rather than fail the call, we // just won't update the volume bar } for (int x = 0; x < MAXBUFFERS; x++) { m_InsBuf[x] = new INSBuf(m_hWaveOut, m_MaxSampleSize); } } m_pReader.Start(cnsStart, 0, 1.0f, IntPtr.Zero); }
internal override void End() { if (!_deviceOpen) { throw new InvalidOperationException(); } lock (_noWriteOutLock) { _deviceOpen = false; CheckForAbort(); if (_queueIn.Count != 0) { SafeNativeMethods.waveOutReset(_hwo); } MMSYSERR mMSYSERR = SafeNativeMethods.waveOutClose(_hwo); } }
/// <summary> /// Resume the playback of a paused sound. /// </summary> internal override void Resume() { lock (_noWriteOutLock) { if (!_aborted && _fPaused) { if (_deviceOpen) { MMSYSERR result = SafeNativeMethods.waveOutRestart(_hwo); if (result != MMSYSERR.NOERROR) { System.Diagnostics.Debug.Assert(false); } } } } _fPaused = false; }
/// <summary> /// Pause the playback of a sound. /// </summary> internal override void Pause() { lock (_noWriteOutLock) { if (!_aborted && !_fPaused) { if (_deviceOpen) { MMSYSERR result = SafeNativeMethods.waveOutPause(_hwo); if (result != MMSYSERR.NOERROR) { System.Diagnostics.Debug.Assert(false, ((int)result).ToString(System.Globalization.CultureInfo.InvariantCulture)); } } _fPaused = true; } } }
/// <summary>Begin recording</summary> /// <returns>MMSYSERR</returns> public MMSYSERR Record() { MMSYSERR mmr = waveInOpen(out _pWaveIn, Device, ref _tWaveFormat, _cBufferProc, 0, CALLBACK_FUNCTION); if (mmr == MMSYSERR.NOERROR) { AllocateBuffers(BufferSize, BufferCount); for (uint i = 0; i < BufferCount; i++) { SelectNextBuffer(); _cCurrentBuffer.Record(); } waveInStart(_pWaveIn); _cThread = new Thread(new ThreadStart(ThreadProc)); _cThread.Start(); Recording = true; } return(mmr); }
private MMSYSERR GetVolumeInfo(IntPtr hmixer, int ctrlType, ref MIXERCONTROL mxc) { MMSYSERR err = MMSYSERR.NOERROR; try { IntPtr hmem = IntPtr.Zero; MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS(); mxlc.cbStruct = (uint)Marshal.SizeOf(mxlc); MIXERLINE mxl = new MIXERLINE(); mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwComponentType = (uint)MIXERLINE_COMPONENTTYPE.DST_SPEAKERS; err = mixerGetLineInfo(hmixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE); if (err == MMSYSERR.NOERROR) { mxlc.dwLineID = (uint)mxl.dwLineID; mxlc.dwControlID = (uint)ctrlType; mxlc.cControls = 1; mxlc.cbmxctrl = (uint)Marshal.SizeOf(mxc); hmem = malloc(Marshal.SizeOf(mxlc)); mxlc.pamxctrl = hmem; mxc.cbStruct = (uint)Marshal.SizeOf(mxc); err = mixerGetLineControls(hmixer, ref mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (err == MMSYSERR.NOERROR) { mxc = (MIXERCONTROL)Marshal.PtrToStructure(mxlc.pamxctrl, typeof(MIXERCONTROL)); if (hmem != IntPtr.Zero) { free(hmem, Marshal.SizeOf(mxc)); } return(err); } if (hmem != IntPtr.Zero) { free(hmem, Marshal.SizeOf(mxc)); } } return(err); } catch { return(err); } }
/// <summary>Start playback - must call CopyStream() first</summary> /// <param name="file">file name</param> /// <returns>MMSYSERR</returns> public MMSYSERR Play(string file) { if (this.Playing) { Stop(); } _btZero = _tWaveFormat.wBitsPerSample == 8 ? (byte)128 : (byte)0; MMSYSERR err = waveOutOpen(out _pWaveOut, this.Device, ref _tWaveFormat, _BufferProc, 0, CALLBACK_FUNCTION); // if success if (err == MMSYSERR.NOERROR) { this.Playing = true; // create buffers and launch thread AllocateBuffers(this.BufferSize, this.BufferCount); _cThread = new Thread(new ThreadStart(ThreadProc)); _cThread.Start(); } return(err); }
/// <summary> /// Begin recording. /// </summary> /// <returns>MMSYSERR.</returns> public MMSYSERR Record() { MMSYSERR mmr = waveInOpen(out _pWaveIn, _device, ref _waveFormat, _cBufferProc, 0, CALLBACK_FUNCTION_FLAG); // system function if (mmr == MMSYSERR.NOERROR) { _AllocateBuffers(BUFFER_SIZE, BUFFERS_COUNT); for (uint i = 0; i < BUFFERS_COUNT; i++) { _SelectNextBuffer(); _currentBuffer.Record(); } waveInStart(_pWaveIn); // system function _thread = new Thread(new ThreadStart(_ThreadProc)); _thread.Start(); } return(mmr); }
/// <summary> /// Get the input device name from device id. /// </summary> /// <param name="deviceId">Device id.</param> /// <param name="prodName">Returns device name.</param> /// <returns>MMSYSERR.</returns> private static MMSYSERR _GetInputDeviceName(uint deviceId, ref string prodName) { var caps = new WaveInCaps(); MMSYSERR result = waveInGetDevCaps(deviceId, out caps, (uint)Marshal.SizeOf(caps)); // system function if (result != MMSYSERR.NOERROR) { return(result); } prodName = new string(caps.szPname); if (prodName.Contains("(") && !(prodName.Contains(")"))) { prodName = prodName.Substring(0, prodName.IndexOf("(")); } else if (prodName.Contains(")")) { if (prodName.IndexOf(")") > 8) { prodName = prodName.Substring(0, prodName.IndexOf(")") + 1); } } return(MMSYSERR.NOERROR); }
/// <summary>Get the input device name from device id</summary> /// <param name="deviceId">device id</param> /// <param name="prodName">returns device name</param> /// <returns>MMSYSERR</returns> public MMSYSERR GetInputDeviceName(uint deviceId, ref string prodName) { WAVEINCAPS caps = new WAVEINCAPS(); MMSYSERR result = waveInGetDevCaps(deviceId, out caps, (uint)Marshal.SizeOf(caps)); if (result != MMSYSERR.NOERROR) { return(result); } prodName = new string(caps.szPname); if (prodName.Contains("(") && !(prodName.Contains(")"))) { prodName = prodName.Substring(0, prodName.IndexOf("(")); } else if (prodName.Contains(")")) { if (prodName.IndexOf(")") > 8) { prodName = prodName.Substring(0, prodName.IndexOf(")") + 1); } } return(MMSYSERR.NOERROR); }
/// <summary>Open the mixer</summary> /// <returns>error</returns> public MMSYSERR OpenMixer() { MMSYSERR err = MMSYSERR.NOERROR; err = mixerOpen(ref _hMixer, 0, IntPtr.Zero, IntPtr.Zero, 0); if (err == MMSYSERR.NOERROR) { _tVolume = new MIXERCONTROL(); _tVolume.cbStruct = (uint)Marshal.SizeOf(_tVolume); err = GetVolumeInfo(_hMixer, MIXERCONTROL_CONTROLTYPE_VOLUME, ref _tVolume); if (err == MMSYSERR.NOERROR) { _iVolNorm = (int)_tVolume.fdwControl; return(err); } } if (err != MMSYSERR.NOERROR && _hMixer != IntPtr.Zero) { CloseMixer(); } return(err); }
/// <summary>Stop recording and reset.</summary> /// <returns>MMSYSERR.</returns> public MMSYSERR Stop() { MMSYSERR mmr = MMSYSERR.ERROR; try { _isFinished = true; if (_pWaveIn != IntPtr.Zero) { waveInReset(_pWaveIn); // system function } if (_thread != null) { _thread.Abort(); } _eDoneProc = null; _FreeBuffers(); if (_pWaveIn != IntPtr.Zero) { mmr = waveInClose(_pWaveIn); // system function } else { mmr = MMSYSERR.NOERROR; } } finally { _thread = null; _pWaveIn = IntPtr.Zero; } return(mmr); }
internal override void Play(byte[] buffer) { if (_deviceOpen) { int num = buffer.Length; _bytesWritten += num; WaveHeader waveHeader = new WaveHeader(buffer); GCHandle wAVEHDR = waveHeader.WAVEHDR; MMSYSERR mMSYSERR = SafeNativeMethods.waveOutPrepareHeader(_hwo, wAVEHDR.AddrOfPinnedObject(), waveHeader.SizeHDR); if (mMSYSERR != 0) { throw new AudioException(mMSYSERR); } lock (_noWriteOutLock) { if (!_aborted) { lock (_queueIn) { InItem item = new InItem(waveHeader); _queueIn.Add(item); _evt.Reset(); } mMSYSERR = SafeNativeMethods.waveOutWrite(_hwo, wAVEHDR.AddrOfPinnedObject(), waveHeader.SizeHDR); if (mMSYSERR != 0) { lock (_queueIn) { _queueIn.RemoveAt(_queueIn.Count - 1); throw new AudioException(mMSYSERR); } } } } } }
public static string Errorstring(MMSYSERR iError) { string sRet; switch (iError) { case MMSYSERR.NoError: sRet = "The specified command was carried out."; break; case MMSYSERR.Error: sRet = "Undefined external error."; break; case MMSYSERR.BadDeviceID: sRet = "A device ID has been used that is out of range for your system."; break; case MMSYSERR.NotEnabled: sRet = "The driver was not enabled."; break; case MMSYSERR.Allocated: sRet = "The specified device is already in use. Wait until it is free, and then try again."; break; case MMSYSERR.InvalHandle: sRet = "The specified device handle is invalid."; break; case MMSYSERR.NoDriver: sRet = "There is no driver installed on your system."; break; case MMSYSERR.NoMem: sRet = "There is not enough memory available for this task. Quit one or more applications to increase avai"; break; case MMSYSERR.NotSupported: sRet = "This function is not supported. Use the Capabilities function to determine which functions and mes"; break; case MMSYSERR.BadErrNum: sRet = "An error number was specified that is not defined in the system."; break; case MMSYSERR.InvalFlag: sRet = "An invalid flag was passed to a system function."; break; case MMSYSERR.InvalParam: sRet = "An invalid parameter was passed to a system function."; break; case MMSYSERR.HandleBusy: sRet = "Handle being used simultaneously on another thread (eg callback)."; break; case MMSYSERR.InvalidAlias: sRet = "Specified alias not found in WIN.INI."; break; case MMSYSERR.BadDB: sRet = "The registry database is corrupt."; break; case MMSYSERR.KeyNotFound: sRet = "The specified registry key was not found."; break; case MMSYSERR.ReadError: sRet = "The registry could not be opened or could not be read."; break; case MMSYSERR.WriteError: sRet = "The registry could not be written to."; break; case MMSYSERR.DeleteError: sRet = "The specified registry key could not be deleted."; break; case MMSYSERR.ValNotFound: sRet = "The specified registry key value could not be found."; break; case MMSYSERR.NoDriverCB: sRet = "The driver did not generate a valid OPEN callback."; break; case MMSYSERR.MoreData: sRet = "More data to be returned"; break; case MMSYSERR.InvalLine: sRet = "The line reference is invalid."; break; case MMSYSERR.InvalControl: sRet = "The control reference is invalid."; break; case MMSYSERR.InvalValue: sRet = "The value is invalid."; break; default: sRet = "Unknown error code"; break; } return sRet; }
internal AudioException(MMSYSERR errorCode) : base(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0} - Error Code: 0x{1:x}", SR.Get(SRID.AudioDeviceError), (int)errorCode)) { }
public static void ThrowExceptionForError(MMSYSERR i) { if (i != MMSYSERR.NoError) { throw new Exception(Errorstring(i)); } }