import com.jniwrapper.*; import com.jniwrapper.win32.Handle; public class MixerHelper { static final int MMSYSERR_NOERROR = 0; static final int MAXPNAMELEN = 32; static final int MIXER_LONG_NAME_CHARS = 64; static final int MIXER_SHORT_NAME_CHARS = 16; static final int MIXER_GETLINEINFOF_COMPONENTTYPE = 0x3; static final int MIXER_GETCONTROLDETAILSF_VALUE = 0x0; static final int MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x2; static final int MIXER_SETCONTROLDETAILSF_VALUE = 0x0; static final int MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x1000; static final int MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x0; static final int MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4); static final int MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3); static final int MIXERLINE_COMPONENTTYPE_SRC_LINE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2); static final int MIXERLINE_COMPONENTTYPE_DST_WAVEIN = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 7); static final int MIXERCONTROL_CT_CLASS_FADER = 0x50000000; static final int MIXERCONTROL_CT_UNITS_UNSIGNED = 0x30000; static final int MIXERCONTROL_CONTROLTYPE_FADER = (MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED); static final int MIXERCONTROL_CONTROLTYPE_VOLUME = (MIXERCONTROL_CONTROLTYPE_FADER + 1); static final Library WINMM = new Library("winmm"); static final Function mixerClose = WINMM.getFunction("mixerClose"); static final Function mixerOpen = WINMM.getFunction("mixerOpen"); static final Function mixerGetControlDetails = WINMM.getFunction("mixerGetControlDetailsA"); static final Function mixerGetLineControls = WINMM.getFunction("mixerGetLineControlsA"); static final Function mixerGetLineInfo = WINMM.getFunction("mixerGetLineInfoA"); static final Function mixerSetControlDetails = WINMM.getFunction("mixerSetControlDetails"); /** * Wrapper for <code>MIXERCAPS</code> structure. */ static class MixerCaps extends Structure { UInt16 wMid = new UInt16(); UInt16 wPid = new UInt16(); UInt16 vDriverVersion = new UInt16(); AnsiString szPname = new AnsiString(MAXPNAMELEN); UInt32 fdwSupport = new UInt32(); UInt32 cDestinations = new UInt32(); public MixerCaps() { init(new Parameter[]{wMid, wPid, vDriverVersion, szPname, fdwSupport, cDestinations}); } } /** * Wrapper for <code>MIXERCONTROL</code> structure. */ static class MixerControl extends Structure { UInt32 cbStruct = new UInt32(); UInt32 dwControlID = new UInt32(); UInt32 dwControlType = new UInt32(); UInt32 fdwControl = new UInt32(); UInt32 cMultipleItems = new UInt32(); AnsiString szShortName = new AnsiString(MIXER_SHORT_NAME_CHARS); AnsiString szName = new AnsiString(MIXER_LONG_NAME_CHARS); ULongInt lMinimum = new ULongInt(); ULongInt lMaximum = new ULongInt(); PrimitiveArray reserved = new PrimitiveArray(UInt32.class, 10); public MixerControl() { init(new Parameter[]{cbStruct, dwControlID, dwControlType, fdwControl, cMultipleItems, szShortName, szName, lMinimum, lMaximum, reserved}); } } /** * Wrapper for <code>MIXERCONTROLDETAILS</code> structure. */ static class MixerControlDetails extends Structure { UInt32 cbStruct = new UInt32(); UInt32 dwControlID = new UInt32(); UInt32 cChannels = new UInt32(); UInt32 item = new UInt32(); UInt32 cbDetails = new UInt32(); Pointer.Void paDetails = new Pointer.Void(); public MixerControlDetails() { init(new Parameter[]{cbStruct, dwControlID, cChannels, item, cbDetails, paDetails}); } } /** * Wrapper for <code>MIXERCONTROLDETAILS_UNSIGNED</code> structure. */ static class MixerControlDetails_Unsigned extends Structure { UInt32 dwValue = new UInt32(); public MixerControlDetails_Unsigned() { init(new Parameter[]{dwValue}); } } /** * Wrapper for <code>MIXERLINE</code> structure. */ static class MixerLine extends Structure { UInt32 cbStruct = new UInt32(); UInt32 dwDestination = new UInt32(); UInt32 dwSource = new UInt32(); UInt32 dwLineID = new UInt32(); UInt32 fdwLine = new UInt32(); UInt32 dwUser = new UInt32(); UInt32 dwComponentType = new UInt32(); UInt32 cChannels = new UInt32(); UInt32 cConnections = new UInt32(); UInt32 cControls = new UInt32(); AnsiString szShortName = new AnsiString(MIXER_SHORT_NAME_CHARS); AnsiString szName = new AnsiString(MIXER_LONG_NAME_CHARS); UInt32 dwType = new UInt32(); UInt32 dwDeviceID = new UInt32(); UInt16 wMid = new UInt16(); UInt16 wPid = new UInt16(); UInt vDriverVersion = new UInt(); AnsiString szPname = new AnsiString(MAXPNAMELEN); public MixerLine() { init(new Parameter[]{cbStruct, dwDestination, dwSource, dwLineID, fdwLine, dwUser, dwComponentType, cChannels, cConnections, cControls, szShortName, szName, dwType, dwDeviceID, wMid, wPid, vDriverVersion, szPname}); } } /** * Wrapper for <code>MIXERLINECONTROLS</code> structure. */ static class MixerLineControls extends Structure { UInt32 cbStruct = new UInt32(); UInt32 dwLineID = new UInt32(); UInt32 dwControl = new UInt32(); UInt32 cControls = new UInt32(); UInt32 cbmxctrl = new UInt32(); Pointer pamxctrl = new Pointer(MixerControl.class); public MixerLineControls() { init(new Parameter[]{cbStruct, dwLineID, dwControl, cControls, cbmxctrl, pamxctrl}); } } static class MIXERCONTROLDETAILS_BOOLEAN extends Structure { LongInt fValue; public MIXERCONTROLDETAILS_BOOLEAN() { init(new Parameter[] {fValue}); } } /** * This function attempts to obtain a mixer control * * @return true if successful. */ private static boolean getVolumeControl(Handle hmixer, int componentType, int ctrlType, /*out*/ MixerControl mxc, /*out*/ Int vCurrentVol) { MixerLineControls mxlc = new MixerLineControls(); MixerLine mxl = new MixerLine(); MixerControlDetails pmxcd = new MixerControlDetails(); MixerControlDetails_Unsigned du = new MixerControlDetails_Unsigned(); boolean retValue; vCurrentVol.setValue(-1); mxl.cbStruct.setValue(mxl.getLength()); mxl.dwComponentType.setValue(componentType); UInt rc = new UInt(); mixerGetLineInfo.invoke(rc, hmixer, new Pointer(mxl), new UInt32(MIXER_GETLINEINFOF_COMPONENTTYPE)); if (MMSYSERR_NOERROR == rc.getValue()) { int sizeofMIXERCONTROL = 152; PrimitiveArray buffer = new PrimitiveArray(UInt8.class, sizeofMIXERCONTROL); mxlc.pamxctrl.setReferencedObject(buffer); mxlc.cbStruct.setValue(mxlc.getLength()); mxlc.dwLineID.setValue(mxl.dwLineID.getValue()); mxlc.dwControl.setValue(ctrlType); mxlc.cControls.setValue(1); mxlc.cbmxctrl.setValue(sizeofMIXERCONTROL); // Allocate a buffer for the control mxc.cbStruct.setValue(sizeofMIXERCONTROL); // Get the control mixerGetLineControls.invoke(rc, hmixer, new Pointer(mxlc), new UInt32(MIXER_GETLINECONTROLSF_ONEBYTYPE)); if (MMSYSERR_NOERROR == rc.getValue()) { retValue = true; // Copy the control into the destination structure Pointer mxcPtr = new Pointer(mxc); mxlc.pamxctrl.castTo(mxcPtr); } else { return false; } int sizeofMIXERCONTROLDETAILS = new MixerControlDetails().getLength(); int sizeofMIXERCONTROLDETAILS_UNSIGNED = new MixerControlDetails_Unsigned().getLength(); pmxcd.cbStruct.setValue(sizeofMIXERCONTROLDETAILS); pmxcd.dwControlID.setValue(mxc.dwControlID.getValue()); PrimitiveArray detailsBuffer = new PrimitiveArray(UInt8.class, sizeofMIXERCONTROLDETAILS_UNSIGNED); Pointer detailsBufferPtr = new Pointer(detailsBuffer); detailsBufferPtr.castTo(pmxcd.paDetails); pmxcd.cChannels.setValue(1); pmxcd.item.setValue(0); pmxcd.cbDetails.setValue(sizeofMIXERCONTROLDETAILS_UNSIGNED); mixerGetControlDetails.invoke(rc, hmixer, new Pointer(pmxcd), new UInt32(MIXER_GETCONTROLDETAILSF_VALUE)); Pointer duPtr = new Pointer(du); pmxcd.paDetails.castTo(duPtr); vCurrentVol.setValue(du.dwValue.getValue()); return retValue; } return false; } /** * This function sets the value for a volume control. * * @return true if successful */ private static boolean setVolumeControl(Handle hmixer, MixerControl mxc, int volume) { boolean retValue; Int rc = new Int(); MixerControlDetails mxcd = new MixerControlDetails(); MixerControlDetails_Unsigned vol = new MixerControlDetails_Unsigned(); mxcd.item.setValue(0); mxcd.dwControlID.setValue(mxc.dwControlID.getValue()); mxcd.cbStruct.setValue(mxcd.getLength()); mxcd.cbDetails.setValue(vol.getLength()); // Allocate a buffer for the control value buffer mxcd.cChannels.setValue(1); vol.dwValue.setValue(volume); // Copy the data into the control value buffer mxcd.paDetails.setValue(new MixerControlDetails_Unsigned().getLength()); Pointer volPtr = new Pointer(vol); volPtr.castTo(mxcd.paDetails); // Set the control value mixerSetControlDetails.invoke(rc, hmixer, new Pointer(mxcd), new Int(MIXER_SETCONTROLDETAILSF_VALUE)); if (MMSYSERR_NOERROR == rc.getValue()) { retValue = true; } else { retValue = false; } return retValue; } /** * Returns current master volume. * * @return current master volume */ public static int getMasterVolume() { Handle mixer = new Handle(); MixerControl volCtrl = new MixerControl(); Int currentVol = new Int(); int type = MIXERCONTROL_CONTROLTYPE_VOLUME; mixerOpen.invoke(null, new Parameter[] { new Pointer(mixer), new UInt(0), new Pointer.Void(), new Pointer.Void(), new UInt32() }); getVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol); mixerClose.invoke(null, mixer); return (int) currentVol.getValue(); } /** * Sets master volume * * @param vVolume */ public static void setMasterVolume(int vVolume) { Handle mixer = new Handle(); MixerControl volCtrl = new MixerControl(); Int currentVol = new Int(); int type = MIXERCONTROL_CONTROLTYPE_VOLUME; mixerOpen.invoke(null, new Parameter[]{ new Pointer(mixer), new UInt(0), new Pointer.Void(), new Pointer.Void(), new UInt32() }); getVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol); if (vVolume > volCtrl.lMaximum.getValue()) { vVolume = (int) volCtrl.lMaximum.getValue(); } if (vVolume < volCtrl.lMinimum.getValue()) { vVolume = (int) volCtrl.lMinimum.getValue(); } setVolumeControl(mixer, volCtrl, vVolume); getVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol); if (vVolume != currentVol.getValue()) { throw new RuntimeException("Cannot Set Volume"); } mixerClose.invoke(null, mixer); } public static int getMicrophoneVolume() { Handle mixer = new Handle(); MixerControl volCtrl = new MixerControl(); Int currentVol = new Int(); mixerOpen.invoke(null, new Parameter[] { new Pointer(mixer), new UInt(0), new Pointer.Void(), new Pointer.Void(), new UInt32() }); getVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_WAVEIN, MIXERCONTROL_CONTROLTYPE_FADER, volCtrl, currentVol); mixerClose.invoke(null, mixer); return (int) currentVol.getValue(); } public static void main(String[] args) { // int value = getMasterVolume(); // System.out.println("Master Volume = " + value + " or " + (value * 100 / 65535) + "%"); // setMasterVolume(0); int value = getMicrophoneVolume(); System.out.println("Microphone Volume = " + value + " or " + (value * 100 / 65535) + "%"); } } |
Samples > WinPack Samples >