//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER
// REMAINS UNCHANGED.
//
// Email: gustavo_franco@hotmail.com
//
// Copyright (C) 2005 Franco, Gustavo
//
using System;
using System.Runtime.InteropServices;
namespace WaveLib.AudioMixer
{
[Author("Gustavo Franco")]
public class MixerControl
{
#region Variables Declaration
private string mName;
private MixerLine mLine;
private uint mControlId;
private MIXERCONTROL_CONTROLTYPE mControlType;
private MIXERCONTROL_CONTROLFLAG mControlFlag;
private uint mMultipleItems;
private uint mMinimum;
private uint mMaximum;
private uint mSteps;
private IntPtr mHMixer;
#endregion
#region Constructors
public MixerControl()
{
}
#endregion
#region Properties
#region Line
public MixerLine Line
{
get{return mLine;}
set{mLine = value;}
}
#endregion
#region Name
public string Name
{
get{return mName;}
set{mName = value;}
}
#endregion
#region Id
public uint Id
{
get{return mControlId;}
set{mControlId = value;}
}
#endregion
#region Type
public MIXERCONTROL_CONTROLTYPE Type
{
get{return mControlType;}
set{mControlType = value;}
}
#endregion
#region ControlFlag
public MIXERCONTROL_CONTROLFLAG ControlFlag
{
get{return mControlFlag;}
set{mControlFlag = value;}
}
#endregion
#region MultipleItems
public uint MultipleItems
{
get{return mMultipleItems;}
set{mMultipleItems = value;}
}
#endregion
#region Minimum
public uint Minimum
{
get{return mMinimum;}
set{mMinimum = value;}
}
#endregion
#region Maximum
public uint Maximum
{
get{return mMaximum;}
set{mMaximum = value;}
}
#endregion
#region Steps
public uint Steps
{
get{return mSteps;}
set{mSteps = value;}
}
#endregion
#region HMixer
internal unsafe IntPtr HMixer
{
get{return mHMixer;}
set{mHMixer = value;}
}
#endregion
#region Signed Value
public unsafe int ValueAsSigned
{
get
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
uint cChannels = mLine.Channels;
if ((((uint) MIXERCONTROL_CONTROLFLAG.UNIFORM) & (uint) mControlFlag) != 0)
cChannels = 1;
pUnsigned = Marshal.AllocHGlobal((int) (cChannels * sizeof(MIXERCONTROLDETAILS_SIGNED)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_SIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_SIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_SIGNED mixerControlDetail ;
if (mLine.Channel == Channel.Uniform)
mixerControlDetail = (MIXERCONTROLDETAILS_SIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_SIGNED));
else
{
if (((int) mLine.Channel) > cChannels)
return -1;
mixerControlDetail = (MIXERCONTROLDETAILS_SIGNED) Marshal.PtrToStructure((IntPtr) ((int) pUnsigned + (sizeof(MIXERCONTROLDETAILS_SIGNED) * ((int) mLine.Channel - 1))), typeof(MIXERCONTROLDETAILS_SIGNED));
}
//mLine.mVolumeMin = mxcd.cbStruct->
return (int) mixerControlDetail.value;
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
set
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
uint cChannels = mLine.Channels;
if ((((uint) MIXERCONTROL_CONTROLFLAG.UNIFORM) & (uint) mControlFlag) != 0)
cChannels = 1;
pUnsigned = Marshal.AllocHGlobal((int) (cChannels * sizeof(MIXERCONTROLDETAILS_SIGNED)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_SIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_SIGNED mixerControlDetail = (MIXERCONTROLDETAILS_SIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_SIGNED));
// Set the volume to the middle (for both channels as needed)
for(int i=0; i<cChannels; i++)
{
if (mLine.Channel == Channel.Uniform || ((int) mLine.Channel - 1) == i)
{
uint* vol = ((uint*) pUnsigned) + i;
*(vol) = (uint) value;
}
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd,MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_SIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_SIGNED mixerControlDetail = (MIXERCONTROLDETAILS_SIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_SIGNED));
// Set the volume to the middle (for both channels as needed)
for(int i=0; i<cChannels; i++)
{
if (mLine.Channel == Channel.Uniform || ((int) mLine.Channel - 1) == i)
{
uint* vol = ((uint*) pUnsigned) + i;
*(vol) = (uint) value;
}
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd,MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerSetControlDetails, errorCode));
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
}
#endregion
#region Unsigned Value
public unsafe int ValueAsUnsigned
{
get
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
uint cChannels = mLine.Channels;
if ((((uint) MIXERCONTROL_CONTROLFLAG.UNIFORM) & (uint) mControlFlag) != 0)
cChannels = 1;
pUnsigned = Marshal.AllocHGlobal((int) (cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_UNSIGNED mixerControlDetail ;
if (mLine.Channel == Channel.Uniform)
mixerControlDetail = (MIXERCONTROLDETAILS_UNSIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_UNSIGNED));
else
{
if (((int) mLine.Channel) > cChannels)
return -1;
mixerControlDetail = (MIXERCONTROLDETAILS_UNSIGNED) Marshal.PtrToStructure((IntPtr) ((int) pUnsigned + (sizeof(MIXERCONTROLDETAILS_UNSIGNED) * ((int) mLine.Channel - 1))), typeof(MIXERCONTROLDETAILS_UNSIGNED));
}
//mLine.mVolumeMin = mxcd.cbStruct->
return (int) mixerControlDetail.dwValue;
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
set
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
uint cChannels = mLine.Channels;
if ((((uint) MIXERCONTROL_CONTROLFLAG.UNIFORM) & (uint) mControlFlag) != 0)
cChannels = 1;
pUnsigned = Marshal.AllocHGlobal((int) (cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_UNSIGNED mixerControlDetail = (MIXERCONTROLDETAILS_UNSIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_UNSIGNED));
// Set the volume to the middle (for both channels as needed)
for(int i=0; i<cChannels; i++)
{
if (mLine.Channel == Channel.Uniform || ((int) mLine.Channel - 1) == i)
{
uint* vol = ((uint*) pUnsigned) + i;
*(vol) = (uint) value;
}
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd,MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
mxcd.cChannels = cChannels;
mxcd.hwndOwner = IntPtr.Zero;
mxcd.cbDetails = (uint) sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = pUnsigned;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
MIXERCONTROLDETAILS_UNSIGNED mixerControlDetail = (MIXERCONTROLDETAILS_UNSIGNED) Marshal.PtrToStructure(pUnsigned, typeof(MIXERCONTROLDETAILS_UNSIGNED));
// Set the volume to the middle (for both channels as needed)
for(int i=0; i<cChannels; i++)
{
if (mLine.Channel == Channel.Uniform || ((int) mLine.Channel - 1) == i)
{
uint* vol = ((uint*) pUnsigned) + i;
*(vol) = (uint) value;
}
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd,MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerSetControlDetails, errorCode));
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
}
#endregion
#region Boolean Value
public unsafe bool ValueAsBoolean
{
get
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
IntPtr pmxcdSelectValue = Marshal.AllocHGlobal((int) (1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
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));
}
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
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, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
uint val = *((uint*) pmxcdSelectValue);
return val == 1 ? true : false;
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
set
{
MMErrors errorCode = 0;
IntPtr pUnsigned = IntPtr.Zero;
try
{
IntPtr pmxcdSelectValue = Marshal.AllocHGlobal((int) (1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN)));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = Id;
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, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
*((uint*) pmxcdSelectValue) = value ? 1U : 0U;
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcd = new MIXERCONTROLDETAILS64();
mxcd.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcd.dwControlID = Id;
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, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
*((uint*) pmxcdSelectValue) = value ? 1U : 0U;
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcd, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerSetControlDetails, errorCode));
}
finally
{
if (pUnsigned != IntPtr.Zero)
Marshal.FreeHGlobal(pUnsigned);
}
}
}
#endregion
#region Volume
internal unsafe int Volume
{
get{return ValueAsUnsigned;}
set{ValueAsUnsigned = value;}
}
#endregion
#region Selected
internal unsafe uint Selected
{
get
{
IntPtr pmixList = IntPtr.Zero;
IntPtr pmixBool = IntPtr.Zero;
MMErrors errorCode = 0;
try
{
if (mMultipleItems == 1 && this.Line.Mixer.UserLines.Count >= 1)
return this.Line.Mixer.UserLines[0].Id;
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcdl = new MIXERCONTROLDETAILS();
pmixList = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT))));
mxcdl.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcdl.dwControlID = mControlId;
mxcdl.cChannels = 1;
mxcdl.cMultipleItems= mMultipleItems;
mxcdl.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT));
mxcdl.paDetails = pmixList;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdl, MIXER_GETCONTROLDETAILSFLAG.LISTTEXT);
}
else
{
MIXERCONTROLDETAILS64 mxcdl = new MIXERCONTROLDETAILS64();
pmixList = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT))));
mxcdl.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcdl.dwControlID = mControlId;
mxcdl.cChannels = 1;
mxcdl.cMultipleItems= mMultipleItems;
mxcdl.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT));
mxcdl.paDetails = pmixList;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdl, MIXER_GETCONTROLDETAILSFLAG.LISTTEXT);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcdb = new MIXERCONTROLDETAILS();
pmixBool = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN))));
mxcdb.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcdb.dwControlID = mControlId;
mxcdb.cChannels = 1;
mxcdb.cMultipleItems = mMultipleItems;
mxcdb.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN));
mxcdb.paDetails = pmixBool;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdb, ((uint) MIXER_OBJECTFLAG.HMIXER | (uint) MIXER_GETCONTROLDETAILSFLAG.VALUE));
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
for(uint y=0; y<mxcdb.cMultipleItems; y++)
{
IntPtr pVmixList = (IntPtr) (((byte*) pmixList) + (Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT)) * y));
MIXERCONTROLDETAILS_LISTTEXT mixList = (MIXERCONTROLDETAILS_LISTTEXT) Marshal.PtrToStructure(pVmixList, typeof(MIXERCONTROLDETAILS_LISTTEXT));
uint lineId = mixList.dwParam1;
bool selected = (*(((uint*) pmixBool) + y)) == 1 ? true : false;
if (selected == true)
return lineId;
}
}
else
{
MIXERCONTROLDETAILS64 mxcdb = new MIXERCONTROLDETAILS64();
pmixBool = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN))));
mxcdb.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcdb.dwControlID = mControlId;
mxcdb.cChannels = 1;
mxcdb.cMultipleItems = mMultipleItems;
mxcdb.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN));
mxcdb.paDetails = pmixBool;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdb, ((uint) MIXER_OBJECTFLAG.HMIXER | (uint) MIXER_GETCONTROLDETAILSFLAG.VALUE));
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
for(uint y=0; y<mxcdb.cMultipleItems; y++)
{
IntPtr pVmixList = (IntPtr) (((byte*) pmixList) + (Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT)) * y));
MIXERCONTROLDETAILS_LISTTEXT mixList = (MIXERCONTROLDETAILS_LISTTEXT) Marshal.PtrToStructure(pVmixList, typeof(MIXERCONTROLDETAILS_LISTTEXT));
uint lineId = mixList.dwParam1;
bool selected = (*(((uint*) pmixBool) + y)) == 1 ? true : false;
if (selected == true)
return lineId;
}
}
}
finally
{
if (pmixList != IntPtr.Zero)
Marshal.FreeHGlobal(pmixList);
if(pmixBool != IntPtr.Zero)
Marshal.FreeHGlobal(pmixBool);
}
return 0;
}
set
{
IntPtr pmixList = IntPtr.Zero;
IntPtr pmixBool = IntPtr.Zero;
MMErrors errorCode = 0;
try
{
uint minusOne;
unchecked{minusOne = (uint) -1;}
if ((mMultipleItems == 1 && this.Line.Mixer.UserLines.Count >= 1) || value == minusOne)
{
MixerNative.SendMessage(this.Line.Mixer.CallbackWindowHandle, MixerNative.MM_MIXM_LINE_CHANGE, (uint) mHMixer, this.Line.Mixer.UserLines[0].Id);
return;
}
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcdl = new MIXERCONTROLDETAILS();
pmixList = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT))));
mxcdl.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcdl.dwControlID = mControlId;
mxcdl.cChannels = 1;
mxcdl.cMultipleItems = mMultipleItems;
mxcdl.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT));
mxcdl.paDetails = pmixList;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdl, MIXER_GETCONTROLDETAILSFLAG.LISTTEXT);
}
else
{
MIXERCONTROLDETAILS64 mxcdl = new MIXERCONTROLDETAILS64();
pmixList = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT))));
mxcdl.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcdl.dwControlID = mControlId;
mxcdl.cChannels = 1;
mxcdl.cMultipleItems = mMultipleItems;
mxcdl.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT));
mxcdl.paDetails = pmixList;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdl, MIXER_GETCONTROLDETAILSFLAG.LISTTEXT);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
if (IntPtr.Size == 4)
{
MIXERCONTROLDETAILS mxcdb = new MIXERCONTROLDETAILS();
pmixBool = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN))));
mxcdb.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS);
mxcdb.dwControlID = mControlId;
mxcdb.cChannels = 1;
mxcdb.cMultipleItems = mMultipleItems;
mxcdb.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN));
mxcdb.paDetails = pmixBool;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdb, ((uint) MIXER_OBJECTFLAG.HMIXER | (uint) MIXER_GETCONTROLDETAILSFLAG.VALUE));
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
for(uint y=0; y<mxcdb.cMultipleItems; y++)
{
IntPtr pVmixList = (IntPtr) (((byte*) pmixList) + (Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT)) * y));
MIXERCONTROLDETAILS_LISTTEXT mixList = (MIXERCONTROLDETAILS_LISTTEXT) Marshal.PtrToStructure(pVmixList, typeof(MIXERCONTROLDETAILS_LISTTEXT));
uint lineId = mixList.dwParam1;
uint* pBoolVal = (((uint*) pmixBool) + y);
if (lineId == value)
*pBoolVal = 1;
else
*pBoolVal = 0;
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcdb, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
else
{
MIXERCONTROLDETAILS64 mxcdb = new MIXERCONTROLDETAILS64();
pmixBool = Marshal.AllocHGlobal((int) (mMultipleItems * Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN))));
mxcdb.cbStruct = (uint) sizeof(MIXERCONTROLDETAILS64);
mxcdb.dwControlID = mControlId;
mxcdb.cChannels = 1;
mxcdb.cMultipleItems = mMultipleItems;
mxcdb.cbDetails = (uint) Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_BOOLEAN));
mxcdb.paDetails = pmixBool;
errorCode = (MMErrors) MixerNative.mixerGetControlDetails(mHMixer, ref mxcdb, ((uint) MIXER_OBJECTFLAG.HMIXER | (uint) MIXER_GETCONTROLDETAILSFLAG.VALUE));
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerGetControlDetails, errorCode));
for(uint y=0; y<mxcdb.cMultipleItems; y++)
{
IntPtr pVmixList = (IntPtr) (((byte*) pmixList) + (Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_LISTTEXT)) * y));
MIXERCONTROLDETAILS_LISTTEXT mixList = (MIXERCONTROLDETAILS_LISTTEXT) Marshal.PtrToStructure(pVmixList, typeof(MIXERCONTROLDETAILS_LISTTEXT));
uint lineId = mixList.dwParam1;
uint* pBoolVal = (((uint*) pmixBool) + y);
if (lineId == value)
*pBoolVal = 1;
else
*pBoolVal = 0;
}
errorCode = (MMErrors) MixerNative.mixerSetControlDetails(mHMixer, ref mxcdb, MIXER_SETCONTROLDETAILSFLAG.VALUE);
}
if (errorCode != MMErrors.MMSYSERR_NOERROR)
throw new MixerException(errorCode, Mixers.GetErrorDescription(FuncName.fnMixerSetControlDetails, errorCode));
foreach(MixerLine line in this.Line.Mixer.Lines)
MixerNative.SendMessage(this.Line.Mixer.CallbackWindowHandle, MixerNative.MM_MIXM_LINE_CHANGE, (uint) mHMixer, line.Id);
}
finally
{
if (pmixList != IntPtr.Zero)
Marshal.FreeHGlobal(pmixList);
if(pmixBool != IntPtr.Zero)
Marshal.FreeHGlobal(pmixBool);
}
}
}
#endregion
#region Mute
internal unsafe bool Mute
{
get{return ValueAsBoolean;}
set{ValueAsBoolean = value;}
}
#endregion
#endregion
#region Overrides
public override string ToString()
{
return mName;
}
#endregion
}
}