private void ReloadLines() { MMErrors errorCode = 0; _audioLines.Clear(); MIXERLINE mxl = new MIXERLINE(); uint dwDestination; unchecked { dwDestination = (uint)-1; } mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwComponentType = _componentType; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(_hMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, WMME.Audio.GetErrorDescription(FuncName.fnMixerGetLineInfo, errorCode)); } dwDestination = mxl.dwDestination; var mixLine = new AudioLine(this, mxl); if (mixLine.CControls != 0 && !(mixLine.CControls == 1 && mixLine.Controls[0].ControlType == MIXERCONTROL_CONTROLTYPE.MUX)) { _audioLines.Add(mixLine); } int cConnections = (int)mxl.cConnections; for (int i = 0; i < cConnections; i++) { mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwDestination = dwDestination; mxl.dwSource = (uint)i; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(Handle, ref mxl, MIXER_GETLINEINFOF.SOURCE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, WMME.Audio.GetErrorDescription(FuncName.fnMixerGetLineInfo, errorCode)); } var mixLineNew = new AudioLine(this, mxl); if (mixLineNew.CControls != 0) { _audioLines.Add(mixLineNew); } } }
private unsafe void ReloadAudioLineControls() { MMErrors errorCode = 0; MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); IntPtr pmc = IntPtr.Zero; try { _audioLineControls.Clear(); if (CControls == 0) { return; } pmc = Marshal.AllocHGlobal((int)(Marshal.SizeOf(typeof(MIXERCONTROL)) * CControls)); mlc.cbStruct = (uint)sizeof(MIXERLINECONTROLS); mlc.dwLineID = Id; mlc.cControls = CControls; mlc.pamxctrl = pmc; mlc.cbmxctrl = (uint)(Marshal.SizeOf(typeof(MIXERCONTROL))); errorCode = (MMErrors)MixerNative.mixerGetLineControls(AudioDeviceInternal.Handle, ref mlc, MIXER_GETLINECONTROLSFLAG.ALL); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnMixerGetLineControls, errorCode)); } for (int i = 0; i < mlc.cControls; i++) { var mc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)(((byte *)pmc) + (Marshal.SizeOf(typeof(MIXERCONTROL)) * i)), typeof(MIXERCONTROL)); AudioLineControl lineControl; switch ((MIXERCONTROL_CONTROLTYPE)mc.dwControlType) { case MIXERCONTROL_CONTROLTYPE.MUTE: lineControl = new MuteAudioLineControl(this, mc, new Action <AudioLine>(RaiseMuteChangedEvent)); break; default: lineControl = new VolumeAudioLineControl(this, mc, new Action <AudioLine>(RaiseVolumeChangedEvent)); break; } _audioLineControls.Add(lineControl); } } finally { if (pmc != IntPtr.Zero) { Marshal.FreeHGlobal((IntPtr)pmc); } } }
private static unsafe bool getMuteStatus(IntPtr mHMixer, uint controlId) { MMErrors errorCode = 0; IntPtr pUnsigned = IntPtr.Zero; bool status = false; try { // find the microphone source line connected to this wave in destination IntPtr pmxcdSelectValue = Marshal.AllocHGlobal((int)(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN))); MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS(); mxcd.cbStruct = (uint)sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = controlId; mxcd.cChannels = 1; mxcd.hwndOwner = IntPtr.Zero; mxcd.cbDetails = (uint)sizeof(MIXERCONTROLDETAILS_BOOLEAN); mxcd.paDetails = pmxcdSelectValue; unchecked { errorCode = (MMErrors)MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, (MIXER_GETCONTROLDETAILSFLAG)(int)((uint)MIXER_OBJECTFLAG.HMIXER | (int)MIXER_GETCONTROLDETAILSFLAG.VALUE)); } if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, MicInterface.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode)); } status = *((uint *)pmxcdSelectValue) != 0U; errorCode = (MMErrors)MixerNative.mixerSetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, MicInterface.GetErrorDescription(FuncName.fnMixerSetControlDetails, errorCode)); } } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { if (pUnsigned != IntPtr.Zero) { Marshal.FreeHGlobal(pUnsigned); } } return(status); }
internal static string GetErrorDescription(FuncName funcName, MMErrors errorCode) { string errorDesc = ""; switch (funcName) { case FuncName.fnWaveOutOpen: case FuncName.fnWaveInOpen: switch (errorCode) { case MMErrors.MMSYSERR_ALLOCATED: errorDesc = "Specified resource is already allocated."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "Specified device identifier is out of range."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; case MMErrors.WAVERR_BADFORMAT: errorDesc = "Attempted to open with an unsupported waveform-audio format."; break; case MMErrors.WAVERR_SYNC: errorDesc = "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break; } break; case FuncName.fnMixerOpen: switch (errorCode) { case MMErrors.MMSYSERR_ALLOCATED: errorDesc = "The specified resource is already allocated by the maximum number of clients possible."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "The uMxId parameter specifies an invalid device identifier."; break; case MMErrors.MMSYSERR_INVALFLAG: errorDesc = "One or more flags are invalid."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "The uMxId parameter specifies an invalid handle."; break; case MMErrors.MMSYSERR_INVALPARAM: errorDesc = "One or more parameters are invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; } break; case FuncName.fnMixerGetID: case FuncName.fnMixerGetLineInfo: case FuncName.fnMixerGetLineControls: case FuncName.fnMixerGetControlDetails: case FuncName.fnMixerSetControlDetails: switch (errorCode) { case MMErrors.MIXERR_INVALCONTROL: errorDesc = "The control reference is invalid."; break; case MMErrors.MIXERR_INVALLINE: errorDesc = "The audio line reference is invalid."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "The hmxobj parameter specifies an invalid device identifier."; break; case MMErrors.MMSYSERR_INVALFLAG: errorDesc = "One or more flags are invalid."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "The hmxobj parameter specifies an invalid handle."; break; case MMErrors.MMSYSERR_INVALPARAM: errorDesc = "One or more parameters are invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; } break; case FuncName.fnMixerClose: switch (errorCode) { case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "Specified device handle is invalid."; break; } break; case FuncName.fnWaveOutClose: case FuncName.fnWaveInClose: case FuncName.fnWaveInGetDevCaps: case FuncName.fnWaveOutGetDevCaps: case FuncName.fnMixerGetDevCaps: switch (errorCode) { case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "Specified device identifier is out of range."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "Specified device handle is invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; case MMErrors.WAVERR_STILLPLAYING: errorDesc = "There are still buffers in the queue."; break; } break; case FuncName.fnCustom: switch (errorCode) { case (MMErrors)1000: errorDesc = "Device Not Found."; break; } break; } return(errorDesc); }
private void ReloadAudioDevices() { if (_reloadDevicesInProgress) { return; } MMErrors errorCode = 0; IntPtr hMixer = IntPtr.Zero; try { _reloadDevicesInProgress = true; var newAudioDevices = new List <AudioDeviceDescriptor>(); MIXERCAPS wic = new MIXERCAPS(); int iNumDevs = MixerNative.mixerGetNumDevs(); for (int i = 0; i < iNumDevs; i++) { // Get info about the next device errorCode = (MMErrors)MixerNative.mixerGetDevCaps(i, ref wic, Marshal.SizeOf(wic)); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, GetErrorDescription(FuncName.fnMixerGetDevCaps, errorCode)); } errorCode = (MMErrors)MixerNative.mixerOpen(out hMixer, i, IntPtr.Zero, IntPtr.Zero, 0); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, GetErrorDescription(FuncName.fnMixerOpen, errorCode)); } MIXERLINE mxl = new MIXERLINE(); mxl.cbStruct = (uint)Marshal.SizeOf(mxl); var deviceDescriptor = new AudioDeviceDescriptor() { DeviceId = i, Name = wic.szPname }; foreach (var mixerlineComponenttype in AudioDevice.RecordingLineTypes) { mxl.dwComponentType = mixerlineComponenttype; if (MixerNative.mixerGetLineInfo(hMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE) == 0) { deviceDescriptor.RecordingSupport = true; deviceDescriptor.RecordingComponentType = mixerlineComponenttype; break; } } foreach (var mixerlineComponenttype in AudioDevice.PlaybackLineTypes) { mxl.dwComponentType = mixerlineComponenttype; if (MixerNative.mixerGetLineInfo(hMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE) == 0) { deviceDescriptor.PlaybackSupport = true; deviceDescriptor.PlaybackComponentType = mixerlineComponenttype; break; } } if (deviceDescriptor.PlaybackSupport || deviceDescriptor.RecordingSupport) { if (deviceDescriptor.PlaybackSupport && deviceDescriptor.RecordingSupport) { var playbackDeviceDescriptor = new AudioDeviceDescriptor() { DeviceId = deviceDescriptor.DeviceId, Name = deviceDescriptor.Name, PlaybackSupport = true, RecordingSupport = false, PlaybackComponentType = deviceDescriptor.PlaybackComponentType }; var recordingDeviceDescriptor = new AudioDeviceDescriptor() { DeviceId = deviceDescriptor.DeviceId, Name = deviceDescriptor.Name, PlaybackSupport = false, RecordingSupport = true, RecordingComponentType = deviceDescriptor.RecordingComponentType }; newAudioDevices.Add(playbackDeviceDescriptor); newAudioDevices.Add(recordingDeviceDescriptor); } else { newAudioDevices.Add(deviceDescriptor); } } } if (newAudioDevices.Count > 0 || (_audioDevices.Count > 0 && iNumDevs == 0)) { UpdateAudioDevicesLists(newAudioDevices); } } finally { if (hMixer != IntPtr.Zero) { MixerNative.mixerClose(hMixer); } _reloadDevicesInProgress = false; } }
private AudioDevice GetDefaultDevice(MixerType mixerType) { MMErrors errorCode = 0; IntPtr hWave = IntPtr.Zero; IntPtr hMixer = IntPtr.Zero; try { WAVEFORMATEX waveFormat = WAVEFORMATEX.Empty; waveFormat.formatTag = WaveFormatTag.PCM; waveFormat.nChannels = 1; waveFormat.nSamplesPerSec = 8000; waveFormat.wBitsPerSample = 8; waveFormat.nBlockAlign = (short)(waveFormat.nChannels * (waveFormat.wBitsPerSample / 8)); waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; // Get default mixer HWND if (mixerType == MixerType.Recording) { errorCode = (MMErrors)WaveNative.waveInOpen(out hWave, WaveNative.WAVE_MAPPER, ref waveFormat, CallbackForm.Handle, IntPtr.Zero, (int)CallBackFlag.CALLBACK_WINDOW); } else if (mixerType == MixerType.Playback) { errorCode = (MMErrors)WaveNative.waveOutOpen(out hWave, WaveNative.WAVE_MAPPER, ref waveFormat, CallbackForm.Handle, IntPtr.Zero, (int)CallBackFlag.CALLBACK_WINDOW); } if (errorCode != MMErrors.MMSYSERR_NOERROR) { // TODO: Log error!!! //throw new MixerException(errorCode, Audio.GetErrorDescription(FuncName.fnWaveInOpen, errorCode)); return(null); } if (mixerType == MixerType.Recording) { errorCode = (MMErrors)MixerNative.mixerOpen(out hMixer, hWave, IntPtr.Zero, IntPtr.Zero, ((uint)MIXER_OBJECTFLAG.HWAVEIN)); } else if (mixerType == MixerType.Playback) { errorCode = (MMErrors)MixerNative.mixerOpen(out hMixer, hWave, IntPtr.Zero, IntPtr.Zero, ((uint)MIXER_OBJECTFLAG.HWAVEOUT)); } if (errorCode != MMErrors.MMSYSERR_NOERROR) { // TODO: Log error!!! //throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerOpen, errorCode)); return(null); } int deviceId = -1; errorCode = (MMErrors)MixerNative.mixerGetID(hMixer, ref deviceId, MIXER_OBJECTFLAG.MIXER); if (errorCode != MMErrors.MMSYSERR_NOERROR) { // TODO: Log error!!! //throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetID, errorCode)); return(null); } MIXERCAPS wic = new MIXERCAPS(); errorCode = (MMErrors)MixerNative.mixerGetDevCaps(deviceId, ref wic, Marshal.SizeOf(wic)); if (errorCode != MMErrors.MMSYSERR_NOERROR) { // TODO: Log error!!! //throw new MixerException(errorCode, GetErrorDescription(FuncName.fnMixerGetDevCaps, errorCode)); return(null); } return(GetAudioDeviceByName(wic.szPname, mixerType == MixerType.Playback)); } finally { if (hMixer != IntPtr.Zero) { MixerNative.mixerClose(hMixer); } if (hWave != IntPtr.Zero && mixerType == MixerType.Playback) { WaveNative.waveOutClose(hWave); } if (hWave != IntPtr.Zero && mixerType == MixerType.Recording) { WaveNative.waveInClose(hWave); } } }
private void ReloadLines() { MMErrors errorCode = 0; mLines.Clear(); mUserLines.Clear(); MIXERLINE mxl = new MIXERLINE(); MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); MIXERCONTROL mc = new MIXERCONTROL(); uint dwDestination; unchecked { dwDestination = (uint)-1; } mxl.cbStruct = (uint)Marshal.SizeOf(mxl); if (mMixerType == MixerType.Recording) { mxl.dwComponentType = MIXERLINE_COMPONENTTYPE.DST_WAVEIN; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetLineInfo, errorCode)); } } else if (mMixerType == MixerType.Playback) { mxl.dwComponentType = MIXERLINE_COMPONENTTYPE.DST_SPEAKERS; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { mxl.dwComponentType = MIXERLINE_COMPONENTTYPE.DST_UNDEFINED; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetLineInfo, errorCode)); } } } dwDestination = mxl.dwDestination; MixerLine mixLine = new MixerLine(); if (mMixerType == MixerType.Recording) { mixLine.Direction = MixerType.Recording; } else if (mMixerType == MixerType.Playback) { mixLine.Direction = MixerType.Playback; } mixLine.Mixer = this; mixLine.Channels = mxl.cChannels; mixLine.CControls = mxl.cControls; mixLine.Connections = mxl.cConnections; mixLine.Flag = mxl.fdwLine; mixLine.Destination = dwDestination; mixLine.Name = mxl.szName; mixLine.Id = mxl.dwLineID; mixLine.ComponentType = mxl.dwComponentType; mixLine.Source = mxl.dwSource; mixLine.HMixer = mHMixer; if (mixLine.CControls != 0 && !(mixLine.CControls == 1 && mixLine.Controls[0].Type == MIXERCONTROL_CONTROLTYPE.MUX)) { mUserLines.Add(mixLine); } mLines.Add(mixLine); int cConnections = (int)mxl.cConnections; for (int i = 0; i < cConnections; i++) { mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwDestination = dwDestination; mxl.dwSource = (uint)i; errorCode = (MMErrors)MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.SOURCE); if (errorCode != MMErrors.MMSYSERR_NOERROR) { throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetLineInfo, errorCode)); } MixerLine mixLineNew = new MixerLine(); if (mMixerType == MixerType.Recording) { mixLineNew.Direction = MixerType.Recording; } else if (mMixerType == MixerType.Playback) { mixLineNew.Direction = MixerType.Playback; } mixLineNew.Mixer = this; mixLineNew.Channels = mxl.cChannels; mixLineNew.CControls = mxl.cControls; mixLineNew.Connections = mxl.cConnections; mixLineNew.Flag = mxl.fdwLine; mixLineNew.Destination = dwDestination; mixLineNew.Name = mxl.szName; mixLineNew.Id = mxl.dwLineID; mixLineNew.ComponentType = mxl.dwComponentType; mixLineNew.Source = mxl.dwSource; mixLineNew.HMixer = mHMixer; if (mixLineNew.CControls != 0) { mUserLines.Add(mixLineNew); } mLines.Add(mixLineNew); } }
public MixerException(MMErrors errorCode, string errorMessage) : base(errorMessage) { mErrorCode = errorCode; }
public static unsafe void MuteOrUnMuteAllMics(bool mute) { IntPtr mHMixer = IntPtr.Zero; try { uint dwDestination; unchecked { dwDestination = (uint)-1; } int iNumDevs = MixerNative.mixerGetNumDevs(); for (int i = 0; i < iNumDevs; i++) { MixerNative.mixerOpen(out mHMixer, i, IntPtr.Zero /*mCallbackWindow.Handle*/, IntPtr.Zero, MixerNative.CALLBACK_WINDOW); // Get the line info for the wave in destination line MIXERLINE mxl = new MIXERLINE(); // find the microphone source line connected to this wave in destination IntPtr pmc = IntPtr.Zero; MMErrors errorCode = 0; mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwComponentType = MIXERLINE_COMPONENTTYPE.DST_SPEAKERS; if (MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.COMPONENTTYPE) == 0) { dwDestination = mxl.dwDestination; int cConnections = (int)mxl.cConnections; for (uint j = 0; j < cConnections; j++) { mxl.cbStruct = (uint)Marshal.SizeOf(mxl); mxl.dwDestination = dwDestination; mxl.dwSource = (uint)j; mxl.dwComponentType = MIXERLINE_COMPONENTTYPE.SRC_MICROPHONE; if (MixerNative.mixerGetLineInfo(mHMixer, ref mxl, MIXER_GETLINEINFOF.SOURCE) == 0) { if (mxl.dwComponentType == MIXERLINE_COMPONENTTYPE.SRC_MICROPHONE) { //it is a microphone pmc = Marshal.AllocHGlobal((int)(Marshal.SizeOf(typeof(MIXERCONTROL)) * mxl.cControls)); MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); mlc.cbStruct = (uint)sizeof(MIXERLINECONTROLS); mlc.dwLineID = mxl.dwLineID; mlc.cControls = mxl.cControls; mlc.pamxctrl = pmc; mlc.cbmxctrl = (uint)(Marshal.SizeOf(typeof(MIXERCONTROL))); mlc.dwControlType = MIXERCONTROL_CONTROLTYPE.MUTE; errorCode = (MMErrors)MixerNative.mixerGetLineControls(mHMixer, ref mlc, MIXER_GETLINECONTROLSFLAG.ALL); for (int k = 0; k < mlc.cControls; k++) { MIXERCONTROL mc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)(((byte *)pmc) + (Marshal.SizeOf(typeof(MIXERCONTROL)) * k)), typeof(MIXERCONTROL)); if (mc.dwControlType == (uint)MIXERCONTROL_CONTROLTYPE.MUTE) { MicInterface.muteOrUnMuteMixerControl(mute, mHMixer, mc.dwControlID); } } } } } } } } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { if (mHMixer != IntPtr.Zero) { MixerNative.mixerClose(mHMixer); } } }
internal static string GetErrorDescription(FuncName funcName, MMErrors errorCode) { string errorDesc = ""; switch(funcName) { case FuncName.fnWaveOutOpen: case FuncName.fnWaveInOpen: switch(errorCode) { case MMErrors.MMSYSERR_ALLOCATED: errorDesc = "Specified resource is already allocated."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "Specified device identifier is out of range."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; case MMErrors.WAVERR_BADFORMAT: errorDesc = "Attempted to open with an unsupported waveform-audio format."; break; case MMErrors.WAVERR_SYNC: errorDesc = "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break; } break; case FuncName.fnMixerOpen: switch(errorCode) { case MMErrors.MMSYSERR_ALLOCATED: errorDesc = "The specified resource is already allocated by the maximum number of clients possible."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "The uMxId parameter specifies an invalid device identifier."; break; case MMErrors.MMSYSERR_INVALFLAG: errorDesc = "One or more flags are invalid."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "The uMxId parameter specifies an invalid handle."; break; case MMErrors.MMSYSERR_INVALPARAM: errorDesc = "One or more parameters are invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; } break; case FuncName.fnMixerGetID: case FuncName.fnMixerGetLineInfo: case FuncName.fnMixerGetLineControls: case FuncName.fnMixerGetControlDetails: case FuncName.fnMixerSetControlDetails: switch(errorCode) { case MMErrors.MIXERR_INVALCONTROL: errorDesc = "The control reference is invalid."; break; case MMErrors.MIXERR_INVALLINE: errorDesc = "The audio line reference is invalid."; break; case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "The hmxobj parameter specifies an invalid device identifier."; break; case MMErrors.MMSYSERR_INVALFLAG: errorDesc = "One or more flags are invalid."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "The hmxobj parameter specifies an invalid handle."; break; case MMErrors.MMSYSERR_INVALPARAM: errorDesc = "One or more parameters are invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; } break; case FuncName.fnMixerClose: switch(errorCode) { case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "Specified device handle is invalid."; break; } break; case FuncName.fnWaveOutClose: case FuncName.fnWaveInClose: case FuncName.fnWaveInGetDevCaps: case FuncName.fnWaveOutGetDevCaps: case FuncName.fnMixerGetDevCaps: switch(errorCode) { case MMErrors.MMSYSERR_BADDEVICEID: errorDesc = "Specified device identifier is out of range."; break; case MMErrors.MMSYSERR_INVALHANDLE: errorDesc = "Specified device handle is invalid."; break; case MMErrors.MMSYSERR_NODRIVER: errorDesc = "No device driver is present."; break; case MMErrors.MMSYSERR_NOMEM: errorDesc = "Unable to allocate or lock memory."; break; case MMErrors.WAVERR_STILLPLAYING: errorDesc = "There are still buffers in the queue."; break; } break; case FuncName.fnCustom: switch(errorCode) { case (MMErrors) 1000: errorDesc = "Device Not Found."; break; } break; } return errorDesc; }