private static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS pmxcaps, int cbmxcaps);
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 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 static extern int mixerGetDevCapsA(IntPtr uMxId, ref MIXERCAPS pmxcaps, int cbmxcaps);
public static extern int mixerGetDevCaps(IntPtr uMxId, ref MIXERCAPS pmxcaps, uint cbmxcaps);
public static void RestoreState() { int index = 0; uint[] ctrl_list = { MIXERCONTROL_CONTROLTYPE_CUSTOM, MIXERCONTROL_CONTROLTYPE_BOOLEANMETER, MIXERCONTROL_CONTROLTYPE_SIGNEDMETER, MIXERCONTROL_CONTROLTYPE_PEAKMETER, MIXERCONTROL_CONTROLTYPE_BOOLEAN, MIXERCONTROL_CONTROLTYPE_ONOFF, MIXERCONTROL_CONTROLTYPE_MUTE, MIXERCONTROL_CONTROLTYPE_MONO, MIXERCONTROL_CONTROLTYPE_LOUDNESS, MIXERCONTROL_CONTROLTYPE_STEREOENH, MIXERCONTROL_CONTROLTYPE_BUTTON, MIXERCONTROL_CONTROLTYPE_DECIBELS, MIXERCONTROL_CONTROLTYPE_SIGNED, MIXERCONTROL_CONTROLTYPE_SLIDER, MIXERCONTROL_CONTROLTYPE_PAN, MIXERCONTROL_CONTROLTYPE_QSOUNDPAN, MIXERCONTROL_CONTROLTYPE_SINGLESELECT, MIXERCONTROL_CONTROLTYPE_MUX, MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT, MIXERCONTROL_CONTROLTYPE_MIXER, MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER, MIXERCONTROL_CONTROLTYPE_UNSIGNED, MIXERCONTROL_CONTROLTYPE_BASS, MIXERCONTROL_CONTROLTYPE_EQUALIZER, MIXERCONTROL_CONTROLTYPE_FADER, MIXERCONTROL_CONTROLTYPE_TREBLE, MIXERCONTROL_CONTROLTYPE_VOLUME, MIXERCONTROL_CONTROLTYPE_MICROTIME, MIXERCONTROL_CONTROLTYPE_MILLITIME, MIXERCONTROL_CONTROLTYPE_PERCENT, }; int num_mixers = mixerGetNumDevs(); int mixer = -1; int retval = -1; for(int i=0; i<num_mixers; i++) // for each mixer { mixerOpen(out mixer, i, 0, 0, 0); MIXERCAPS mc = new MIXERCAPS(); retval = mixerGetDevCaps(mixer, ref mc, Marshal.SizeOf(mc)); if(retval == MMSYSERR_NOERROR) { int num_dest = mc.cDestinations; for(int j=0; j<num_dest; j++) // for each destination line in this mixer { MIXERLINE dst_line = new MIXERLINE(); dst_line.cbStruct = Marshal.SizeOf(dst_line); dst_line.dwDestination = j; retval = mixerGetLineInfo(mixer, ref dst_line, MIXER_GETLINEINFOF_DESTINATION); if(retval == MMSYSERR_NOERROR) { for(int k=0; k<30; k++) // for each control in this destination line { MIXERLINECONTROLS dst_lc = new MIXERLINECONTROLS(); int mcSize = 152; dst_lc.pamxctrl = Marshal.AllocCoTaskMem(mcSize); dst_lc.cbStruct = Marshal.SizeOf(dst_lc); dst_lc.dwLineID = dst_line.dwLineID; dst_lc.dwControl = ctrl_list[k]; dst_lc.cControls = 1; dst_lc.cbmxctrl = mcSize; // Get the control retval = mixerGetLineControls(mixer, ref dst_lc, MIXER_GETLINECONTROLSF_ONEBYTYPE); if(retval == MMSYSERR_NOERROR) { MIXERCONTROL ctrl = new MIXERCONTROL(); ctrl.cbStruct = mcSize; // Copy the control into the destination structure ctrl = (MIXERCONTROL)Marshal.PtrToStructure(dst_lc.pamxctrl, typeof(MIXERCONTROL)); MIXERCONTROLDETAILS details = new MIXERCONTROLDETAILS(); int size = Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_SIGNED)); details.dwControlID = ctrl.dwControlID; details.cbDetails = size; details.item = ctrl.cMultipleItems; if(details.item > 0) size *= details.item; details.paDetails = Marshal.AllocCoTaskMem(size); details.cbStruct = Marshal.SizeOf(details); details.cChannels = 1; if(details.item > 0) { if(index != save.Count) { int rec_index = (int)save[index]; int[] val = new int[details.item]; for(int m=0; m<details.item; m++) { if(m == rec_index) val[m] = 1; else val[m] = 0; } Marshal.Copy(val, 0, details.paDetails, details.item); retval = mixerSetControlDetails(mixer, ref details, MIXER_GETCONTROLDETAILSF_VALUE); if(retval == MMSYSERR_NOERROR) index++; } } else { MIXERCONTROLDETAILS_UNSIGNED val = new MIXERCONTROLDETAILS_UNSIGNED(); val.dwValue = (int)save[index]; Marshal.StructureToPtr(val, details.paDetails, false); retval = mixerSetControlDetails(mixer, ref details, MIXER_GETCONTROLDETAILSF_VALUE); if(retval == MMSYSERR_NOERROR) index++; } Marshal.FreeCoTaskMem(details.paDetails); } Marshal.FreeCoTaskMem(dst_lc.pamxctrl); } int num_src = dst_line.cConnections; for(int k=0; k<num_src; k++) // for each source line connected to this destination { MIXERLINE src_line = new MIXERLINE(); src_line.cbStruct = dst_line.cbStruct; src_line.dwDestination = dst_line.dwDestination; src_line.dwSource = k; retval = mixerGetLineInfo(mixer, ref src_line, MIXER_GETLINEINFOF_SOURCE); if(retval == MMSYSERR_NOERROR) { for(int l=0; l<30; l++) // for each control in this source line { MIXERLINECONTROLS src_lc = new MIXERLINECONTROLS(); int mcSize = 152; src_lc.pamxctrl = Marshal.AllocCoTaskMem(mcSize); src_lc.cbStruct = Marshal.SizeOf(src_lc); src_lc.dwLineID = src_line.dwLineID; src_lc.dwControl = ctrl_list[l]; src_lc.cControls = 1; src_lc.cbmxctrl = mcSize; // Get the control retval = mixerGetLineControls(mixer, ref src_lc, MIXER_GETLINECONTROLSF_ONEBYTYPE); if(retval == MMSYSERR_NOERROR) { MIXERCONTROL ctrl = new MIXERCONTROL(); ctrl.cbStruct = mcSize; // Copy the control into the destination structure ctrl = (MIXERCONTROL)Marshal.PtrToStructure(src_lc.pamxctrl, typeof(MIXERCONTROL)); MIXERCONTROLDETAILS details = new MIXERCONTROLDETAILS(); int size; if(l<20) size = Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_SIGNED)); else size = Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_UNSIGNED)); details.dwControlID = ctrl.dwControlID; details.paDetails = Marshal.AllocCoTaskMem(size); details.cbStruct = Marshal.SizeOf(details); details.cChannels = 1; details.item = ctrl.cMultipleItems; details.cbDetails = size; if(details.item > 0) { int rec_index = (int)save[index]; MIXERCONTROLDETAILS_UNSIGNED[] val = new MIXERCONTROLDETAILS_UNSIGNED[details.item]; for(int m=0; m<details.item; m++) val[m] = new MIXERCONTROLDETAILS_UNSIGNED(); val[rec_index].dwValue = 1; Marshal.StructureToPtr(val[0], details.paDetails, false); } else { MIXERCONTROLDETAILS_UNSIGNED val = new MIXERCONTROLDETAILS_UNSIGNED(); val.dwValue = (int)save[index]; Marshal.StructureToPtr(val, details.paDetails, false); } retval = mixerSetControlDetails(mixer, ref details, MIXER_GETCONTROLDETAILSF_VALUE); if(retval == MMSYSERR_NOERROR) index++; Marshal.FreeCoTaskMem(details.paDetails); } Marshal.FreeCoTaskMem(src_lc.pamxctrl); } } } } } } } mixerClose(mixer); }
public static extern int mixerGetDevCaps(int uMxId, ref MIXERCAPS pmxcaps, int cbmxcaps);
public static string GetDevName(int mixer) { MIXERCAPS mc = new MIXERCAPS(); int retval = mixerGetDevCaps(mixer, ref mc, Marshal.SizeOf(mc)); if(retval != MMSYSERR_NOERROR) return ""; return mc.szPname; }
public static string GetLineName(int mixer, uint dst_type, uint src_type) { MIXERCAPS mc = new MIXERCAPS(); int retval = mixerGetDevCaps(mixer, ref mc, Marshal.SizeOf(mc)); if(retval != MMSYSERR_NOERROR) return ""; int num_dest = mc.cDestinations; for(int j=0; j<num_dest; j++) // for each destination line { MIXERLINE dst_line = new MIXERLINE(); dst_line.cbStruct = Marshal.SizeOf(dst_line); dst_line.dwDestination = j; retval = mixerGetLineInfo(mixer, ref dst_line, MIXER_GETLINEINFOF_DESTINATION); if(retval == MMSYSERR_NOERROR && dst_line.dwComponentType == dst_type) { if(src_type == 0) return dst_line.szName; else { int num_src = dst_line.cConnections; for(int k=0; k<num_src; k++) // for all source lines connected to this destination { MIXERLINE src_line = new MIXERLINE(); src_line.cbStruct = dst_line.cbStruct; src_line.dwDestination = dst_line.dwDestination; src_line.dwSource = k; retval = mixerGetLineInfo(mixer, ref src_line, MIXER_GETLINEINFOF_SOURCE); if(retval == MMSYSERR_NOERROR && src_line.dwComponentType == src_type) return src_line.szName; } } } } return ""; }
private static bool GetControlByType(int mixer, uint dst_type, uint src_type, uint ctrl_type, out MIXERCONTROL outCtrl) { outCtrl = new MIXERCONTROL(); MIXERCAPS mc = new MIXERCAPS(); int retval = mixerGetDevCaps(mixer, ref mc, Marshal.SizeOf(mc)); if(retval != MMSYSERR_NOERROR) return false; int num_dest = mc.cDestinations; for(int j=0; j<num_dest; j++) // for each destination line { MIXERLINE dst_line = new MIXERLINE(); dst_line.cbStruct = Marshal.SizeOf(dst_line); dst_line.dwDestination = j; retval = mixerGetLineInfo(mixer, ref dst_line, MIXER_GETLINEINFOF_DESTINATION); if(retval == MMSYSERR_NOERROR && dst_line.dwComponentType == dst_type) { if(src_type == 0) { MIXERLINECONTROLS dst_lc = new MIXERLINECONTROLS(); int mcSize = 152; dst_lc.pamxctrl = Marshal.AllocCoTaskMem(mcSize); dst_lc.cbStruct = Marshal.SizeOf(dst_lc); dst_lc.dwLineID = dst_line.dwLineID; dst_lc.dwControl = ctrl_type; dst_lc.cControls = 1; dst_lc.cbmxctrl = mcSize; // Get the control retval = mixerGetLineControls(mixer, ref dst_lc, MIXER_GETLINECONTROLSF_ONEBYTYPE); if(retval == MMSYSERR_NOERROR) { MIXERCONTROL ctrl = new MIXERCONTROL(); ctrl.cbStruct = mcSize; // Copy the control into the destination structure ctrl = (MIXERCONTROL)Marshal.PtrToStructure(dst_lc.pamxctrl, typeof(MIXERCONTROL)); outCtrl = ctrl; Marshal.FreeCoTaskMem(dst_lc.pamxctrl); return true; } Marshal.FreeCoTaskMem(dst_lc.pamxctrl); return false; } else { int num_src = dst_line.cConnections; for(int k=0; k<num_src; k++) // for all source lines connected to this destination { MIXERLINE src_line = new MIXERLINE(); src_line.cbStruct = dst_line.cbStruct; src_line.dwDestination = dst_line.dwDestination; src_line.dwSource = k; retval = mixerGetLineInfo(mixer, ref src_line, MIXER_GETLINEINFOF_SOURCE); if(retval == MMSYSERR_NOERROR && src_line.dwComponentType == src_type) { MIXERLINECONTROLS src_lc = new MIXERLINECONTROLS(); int mcSize = 152; src_lc.pamxctrl = Marshal.AllocCoTaskMem(mcSize); src_lc.cbStruct = Marshal.SizeOf(src_lc); src_lc.dwLineID = src_line.dwLineID; src_lc.dwControl = ctrl_type; src_lc.cControls = 1; src_lc.cbmxctrl = mcSize; // Get the control retval = mixerGetLineControls(mixer, ref src_lc, MIXER_GETLINECONTROLSF_ONEBYTYPE); if(retval == MMSYSERR_NOERROR) { MIXERCONTROL ctrl = new MIXERCONTROL(); ctrl.cbStruct = mcSize; // Copy the control into the destination structure ctrl = (MIXERCONTROL)Marshal.PtrToStructure(src_lc.pamxctrl, typeof(MIXERCONTROL)); outCtrl = ctrl; Marshal.FreeCoTaskMem(src_lc.pamxctrl); return true; } Marshal.FreeCoTaskMem(src_lc.pamxctrl); return false; } } } } } return false; }
public static bool InitSoundCard2(int mixerID) { int mixer; int retval = -1; retval = mixerOpen(out mixer, mixerID, 0, 0, 0); if(retval != MMSYSERR_NOERROR) return false; MIXERCAPS mc = new MIXERCAPS(); retval = mixerGetDevCaps(mixer, ref mc, Marshal.SizeOf(mc)); if(retval != MMSYSERR_NOERROR) goto failed; MIXERLINE dst_line = new MIXERLINE(); dst_line.cbStruct = Marshal.SizeOf(dst_line); dst_line.dwDestination = 0; retval = mixerGetLineInfo(mixer, ref dst_line, MIXER_GETLINEINFOF_DESTINATION); if(retval != MMSYSERR_NOERROR) goto failed; for(int i=0; i<dst_line.cConnections; i++) { MIXERCONTROL ctrl = new MIXERCONTROL(); GetControlByID(mixerID, 0, i, MIXERCONTROL_CONTROLTYPE_MUTE, out ctrl); SetBool(mixerID, ctrl, true); } mixerClose(mixer); SetMainVolume(mixerID, 100); SetWaveOutVolume(mixerID, 100); SetMainMute(mixerID, false); SetWaveOutMute(mixerID, false); return true; failed: mixerClose(mixer); return false; }
public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, Int32 mixerCapsSize);
public static extern uint mixerGetDevCaps(uint uMxID, ref MIXERCAPS pmxcaps, uint cbmxcaps);
protected static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS pmxcaps, int cbmxcaps);