/**
 * Windows API header module
 *
 * Translated from MinGW Windows headers
 *
 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source: $(DRUNTIMESRC src/core/sys/windows/_mmsystem.d)
 */
module core.sys.windows.mmsystem;
version (Windows):
@system:

version (ANSI) {} else version = Unicode;
pragma(lib, "winmm");

/*  The #defines MAKEFOURCC, mmioFOURCC, sndAlias are used to define
 *  compile-time constants, so they are implemented as templates.
 */

private import core.sys.windows.w32api, core.sys.windows.windef, core.sys.windows.winver;

align(1):

enum MAXPNAMELEN = 32;
enum MAXERRORLENGTH = 256;
enum MAX_JOYSTICKOEMVXDNAME = 260;

enum TIME_MS      = 1;
enum TIME_SAMPLES = 2;
enum TIME_BYTES   = 4;
enum TIME_SMPTE   = 8;
enum TIME_MIDI    = 16;
enum TIME_TICKS   = 32;

template MAKEFOURCC(char c0, char c1, char c2, char c3)
{
enum DWORD MAKEFOURCC = c0 | (c1<<8) | (c2<<16) | (cast(DWORD)c3 <<24);
}

template mmioFOURCC(char c0, char c1, char c2, char c3)
{
enum DWORD mmioFOURCC = c0 | (c1<<8) | (c2<<16) | (cast(DWORD)c3 <<24);
}

enum {
    MM_JOY1MOVE            = 0x3A0,
    MM_JOY2MOVE,
    MM_JOY1ZMOVE,
    MM_JOY2ZMOVE,       // = 0x3A3
    MM_JOY1BUTTONDOWN      = 0x3B5,
    MM_JOY2BUTTONDOWN,
    MM_JOY1BUTTONUP,
    MM_JOY2BUTTONUP,
    MM_MCINOTIFY,       // = 0x3B9
    MM_WOM_OPEN            = 0x3BB,
    MM_WOM_CLOSE,
    MM_WOM_DONE,
    MM_WIM_OPEN,
    MM_WIM_CLOSE,
    MM_WIM_DATA,
    MM_MIM_OPEN,
    MM_MIM_CLOSE,
    MM_MIM_DATA,
    MM_MIM_LONGDATA,
    MM_MIM_ERROR,
    MM_MIM_LONGERROR,
    MM_MOM_OPEN,
    MM_MOM_CLOSE,
    MM_MOM_DONE,        // = 0x3C9
    MM_DRVM_OPEN           = 0x3D0,
    MM_DRVM_CLOSE,
    MM_DRVM_DATA,
    MM_DRVM_ERROR,
    MM_STREAM_OPEN,
    MM_STREAM_CLOSE,
    MM_STREAM_DONE,
    MM_STREAM_ERROR,    // = 0x3D7
    MM_MOM_POSITIONCB      = 0x3CA,
    MM_MCISIGNAL,
    MM_MIM_MOREDATA,    // = 0x3CC
    MM_MIXM_LINE_CHANGE    = 0x3D0,
    MM_MIXM_CONTROL_CHANGE = 0x3D1
}

enum MMSYSERR_BASE     =    0;
enum WAVERR_BASE       =   32;
enum MIDIERR_BASE      =   64;
enum TIMERR_BASE       =   96;
enum JOYERR_BASE       =  160;
enum MCIERR_BASE       =  256;
enum MIXERR_BASE       = 1024;
enum MCI_STRING_OFFSET =  512;
enum MCI_VD_OFFSET     = 1024;
enum MCI_CD_OFFSET     = 1088;
enum MCI_WAVE_OFFSET   = 1152;
enum MCI_SEQ_OFFSET    = 1216;

enum {
    MMSYSERR_NOERROR        = 0,
    MMSYSERR_ERROR          = MMSYSERR_BASE+1,
    MMSYSERR_BADDEVICEID,
    MMSYSERR_NOTENABLED,
    MMSYSERR_ALLOCATED,
    MMSYSERR_INVALHANDLE,
    MMSYSERR_NODRIVER,
    MMSYSERR_NOMEM,
    MMSYSERR_NOTSUPPORTED,
    MMSYSERR_BADERRNUM,
    MMSYSERR_INVALFLAG,
    MMSYSERR_INVALPARAM,
    MMSYSERR_HANDLEBUSY,
    MMSYSERR_INVALIDALIAS,
    MMSYSERR_BADDB,
    MMSYSERR_KEYNOTFOUND,
    MMSYSERR_READERROR,
    MMSYSERR_WRITEERROR,
    MMSYSERR_DELETEERROR,
    MMSYSERR_VALNOTFOUND,
    MMSYSERR_NODRIVERCB, // = MMSYSERR_BASE+20
    MMSYSERR_LASTERROR      = MMSYSERR_NODRIVERCB
}

enum {
    DRV_LOAD = 1,
    DRV_ENABLE,
    DRV_OPEN,
    DRV_CLOSE,
    DRV_DISABLE,
    DRV_FREE,
    DRV_CONFIGURE,
    DRV_QUERYCONFIGURE,
    DRV_INSTALL,
    DRV_REMOVE,
    DRV_EXITSESSION,
    DRV_POWER
}

enum DRV_RESERVED = 0x800;
enum DRV_USER = 0x4000;

enum DRVCNF_CANCEL = 0;
enum DRVCNF_OK = 1;
enum DRVCNF_RESTART = 2;
enum DRV_CANCEL = DRVCNF_CANCEL;
enum DRV_OK = DRVCNF_OK;
enum DRV_RESTART = DRVCNF_RESTART;
enum DRV_MCI_FIRST = DRV_RESERVED;
enum DRV_MCI_LAST  = DRV_RESERVED + 0xFFF;

enum CALLBACK_TYPEMASK = 0x70000;
enum CALLBACK_NULL     = 0;
enum CALLBACK_WINDOW   = 0x10000;
enum CALLBACK_TASK     = 0x20000;
enum CALLBACK_FUNCTION = 0x30000;
enum CALLBACK_THREAD   = CALLBACK_TASK;
enum CALLBACK_EVENT    = 0x50000;

enum SND_SYNC=0;
enum SND_ASYNC=1;
enum SND_NODEFAULT=2;
enum SND_MEMORY=4;
enum SND_LOOP=8;
enum SND_NOSTOP=16;
enum SND_NOWAIT=0x2000;
enum SND_ALIAS=0x10000;
enum SND_ALIAS_ID=0x110000;
enum SND_FILENAME=0x20000;
enum SND_RESOURCE=0x40004;
enum SND_PURGE=0x40;
enum SND_APPLICATION=0x80;
enum SND_ALIAS_START=0;

template sndAlias(char c0, char c1)
{
enum DWORD sndAlias = SND_ALIAS_START + c0 | (c1<<8);
}

enum SND_ALIAS_SYSTEMASTERISK    = sndAlias!('S', '*');
enum SND_ALIAS_SYSTEMQUESTION    = sndAlias!('S', '?');
enum SND_ALIAS_SYSTEMHAND        = sndAlias!('S', 'H');
enum SND_ALIAS_SYSTEMEXIT        = sndAlias!('S', 'E');
enum SND_ALIAS_SYSTEMSTART       = sndAlias!('S', 'S');
enum SND_ALIAS_SYSTEMWELCOME     = sndAlias!('S', 'W');
enum SND_ALIAS_SYSTEMEXCLAMATION = sndAlias!('S', '!');
enum SND_ALIAS_SYSTEMDEFAULT     = sndAlias!('S', 'D');

enum {
    WAVERR_BADFORMAT  = (WAVERR_BASE + 0),
    WAVERR_STILLPLAYING,
    WAVERR_UNPREPARED,
    WAVERR_SYNC,  // = WAVERR_BASE + 3;
    WAVERR_LASTERROR = WAVERR_SYNC
}

enum WOM_OPEN  = MM_WOM_OPEN;
enum WOM_CLOSE = MM_WOM_CLOSE;
enum WOM_DONE  = MM_WOM_DONE;
enum WIM_OPEN  = MM_WIM_OPEN;
enum WIM_CLOSE = MM_WIM_CLOSE;
enum WIM_DATA  = MM_WIM_DATA;

enum UINT WAVE_MAPPER= -1;  // FIXME: This doesn't make sense!
enum WAVE_FORMAT_QUERY=1;
enum WAVE_ALLOWSYNC=2;
enum WAVE_MAPPED=4;
enum WAVE_FORMAT_DIRECT=8;
enum WAVE_FORMAT_DIRECT_QUERY=(WAVE_FORMAT_QUERY|WAVE_FORMAT_DIRECT);
enum WHDR_DONE=1;
enum WHDR_PREPARED=2;
enum WHDR_BEGINLOOP=4;
enum WHDR_ENDLOOP=8;
enum WHDR_INQUEUE=16;

enum WAVECAPS_PITCH=1;
enum WAVECAPS_PLAYBACKRATE=2;
enum WAVECAPS_VOLUME=4;
enum WAVECAPS_LRVOLUME=8;
enum WAVECAPS_SYNC=16;
enum WAVECAPS_SAMPLEACCURATE=32;
enum WAVECAPS_DIRECTSOUND=64;

enum WAVE_INVALIDFORMAT=0;
enum WAVE_FORMAT_1M08=1;
enum WAVE_FORMAT_1S08=2;
enum WAVE_FORMAT_1M16=4;
enum WAVE_FORMAT_1S16=8;
enum WAVE_FORMAT_2M08=16;
enum WAVE_FORMAT_2S08=32;
enum WAVE_FORMAT_2M16=64;
enum WAVE_FORMAT_2S16=128;
enum WAVE_FORMAT_4M08=256;
enum WAVE_FORMAT_4S08=512;
enum WAVE_FORMAT_4M16=1024;
enum WAVE_FORMAT_4S16=2048;
enum WAVE_FORMAT_PCM=1;

enum {
    MIDIERR_UNPREPARED = MIDIERR_BASE,
    MIDIERR_STILLPLAYING,
    MIDIERR_NOMAP,
    MIDIERR_NOTREADY,
    MIDIERR_NODEVICE,
    MIDIERR_INVALIDSETUP,
    MIDIERR_BADOPENMODE,
    MIDIERR_DONT_CONTINUE, // = MIDIERR_BASE+7
    MIDIERR_LASTERROR = MIDIERR_DONT_CONTINUE
}

enum MIDIPATCHSIZE=128;

enum MIM_OPEN=MM_MIM_OPEN;
enum MIM_CLOSE=MM_MIM_CLOSE;
enum MIM_DATA=MM_MIM_DATA;
enum MIM_LONGDATA=MM_MIM_LONGDATA;
enum MIM_ERROR=MM_MIM_ERROR;
enum MIM_LONGERROR=MM_MIM_LONGERROR;
enum MOM_OPEN=MM_MOM_OPEN;
enum MOM_CLOSE=MM_MOM_CLOSE;
enum MOM_DONE=MM_MOM_DONE;
enum MIM_MOREDATA=MM_MIM_MOREDATA;
enum MOM_POSITIONCB=MM_MOM_POSITIONCB;

enum UINT MIDIMAPPER= -1; // FIXME: uint is nonsense for this!
enum UINT MIDI_MAPPER= -1; // FIXME: uint is nonsense for this!
enum MIDI_IO_STATUS=32;
enum MIDI_CACHE_ALL=1;
enum MIDI_CACHE_BESTFIT=2;
enum MIDI_CACHE_QUERY=3;
enum MIDI_UNCACHE=4;
enum MOD_MIDIPORT=1;
enum MOD_SYNTH=2;
enum MOD_SQSYNTH=3;
enum MOD_FMSYNTH=4;
enum MOD_MAPPER=5;
enum MIDICAPS_VOLUME=1;
enum MIDICAPS_LRVOLUME=2;
enum MIDICAPS_CACHE=4;
enum MIDICAPS_STREAM=8;
enum MHDR_DONE=1;
enum MHDR_PREPARED=2;
enum MHDR_INQUEUE=4;
enum MHDR_ISSTRM=8;
enum MEVT_F_SHORT=0;
enum MEVT_F_LONG=0x80000000;
enum MEVT_F_CALLBACK=0x40000000;

BYTE MEVT_EVENTTYPE(DWORD x) { return cast(BYTE)((x>>24) &0xFF); }
DWORD MEVT_EVENTPARM(DWORD x) { return x & 0xFFFFFF; }

enum MEVT_SHORTMSG=0;
enum MEVT_TEMPO=1;
enum MEVT_NOP=2;

enum BYTE MEVT_LONGMSG = 0x80;
enum BYTE MEVT_COMMENT = 0x82;
enum BYTE MEVT_VERSION = 0x84;

enum MIDISTRM_ERROR = -2;

enum MIDIPROP_SET = 0x80000000;
enum MIDIPROP_GET = 0x40000000;
enum MIDIPROP_TIMEDIV = 1;
enum MIDIPROP_TEMPO = 2;

enum UINT AUX_MAPPER = -1;

enum AUXCAPS_CDAUDIO=1;
enum AUXCAPS_AUXIN=2;
enum AUXCAPS_VOLUME=1;
enum AUXCAPS_LRVOLUME=2;
enum MIXER_SHORT_NAME_CHARS=16;
enum MIXER_LONG_NAME_CHARS=64;
enum MIXERR_INVALLINE=MIXERR_BASE;
enum MIXERR_INVALCONTROL=(MIXERR_BASE+1);
enum MIXERR_INVALVALUE=(MIXERR_BASE+2);
enum MIXERR_LASTERROR=(MIXERR_BASE+2);

enum MIXER_OBJECTF_HANDLE=0x80000000;
enum MIXER_OBJECTF_MIXER=0;
enum MIXER_OBJECTF_HMIXER=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIXER);
enum MIXER_OBJECTF_WAVEOUT=0x10000000;
enum MIXER_OBJECTF_HWAVEOUT=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_WAVEOUT);
enum MIXER_OBJECTF_WAVEIN=0x20000000;
enum MIXER_OBJECTF_HWAVEIN=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_WAVEIN);
enum MIXER_OBJECTF_MIDIOUT=0x30000000;
enum MIXER_OBJECTF_HMIDIOUT=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIDIOUT);
enum MIXER_OBJECTF_MIDIIN=0x40000000;
enum MIXER_OBJECTF_HMIDIIN=(MIXER_OBJECTF_HANDLE|MIXER_OBJECTF_MIDIIN);
enum MIXER_OBJECTF_AUX=0x50000000;

enum MIXERLINE_LINEF_ACTIVE=1;
enum MIXERLINE_LINEF_DISCONNECTED=0x8000;
enum MIXERLINE_LINEF_SOURCE=0x80000000;

enum MIXERLINE_COMPONENTTYPE_DST_FIRST=0;
enum MIXERLINE_COMPONENTTYPE_DST_UNDEFINED=MIXERLINE_COMPONENTTYPE_DST_FIRST;
enum MIXERLINE_COMPONENTTYPE_DST_DIGITAL=(MIXERLINE_COMPONENTTYPE_DST_FIRST+1);
enum MIXERLINE_COMPONENTTYPE_DST_LINE=(MIXERLINE_COMPONENTTYPE_DST_FIRST+2);
enum MIXERLINE_COMPONENTTYPE_DST_MONITOR=(MIXERLINE_COMPONENTTYPE_DST_FIRST+3);
enum MIXERLINE_COMPONENTTYPE_DST_SPEAKERS=(MIXERLINE_COMPONENTTYPE_DST_FIRST+4);
enum MIXERLINE_COMPONENTTYPE_DST_HEADPHONES=(MIXERLINE_COMPONENTTYPE_DST_FIRST+5);
enum MIXERLINE_COMPONENTTYPE_DST_TELEPHONE=(MIXERLINE_COMPONENTTYPE_DST_FIRST+6);
enum MIXERLINE_COMPONENTTYPE_DST_WAVEIN=(MIXERLINE_COMPONENTTYPE_DST_FIRST+7);
enum MIXERLINE_COMPONENTTYPE_DST_VOICEIN=(MIXERLINE_COMPONENTTYPE_DST_FIRST+8);
enum MIXERLINE_COMPONENTTYPE_DST_LAST=(MIXERLINE_COMPONENTTYPE_DST_FIRST+8);
enum MIXERLINE_COMPONENTTYPE_SRC_FIRST=0x1000;
enum MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED=MIXERLINE_COMPONENTTYPE_SRC_FIRST;
enum MIXERLINE_COMPONENTTYPE_SRC_DIGITAL=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+1);
enum MIXERLINE_COMPONENTTYPE_SRC_LINE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+2);
enum MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+3);
enum MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+4);
enum MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+5);
enum MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+6);
enum MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+7);
enum MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+8);
enum MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+9);
enum MIXERLINE_COMPONENTTYPE_SRC_ANALOG=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+10);
enum MIXERLINE_COMPONENTTYPE_SRC_LAST=(MIXERLINE_COMPONENTTYPE_SRC_FIRST+10);

enum {
    MIXERLINE_TARGETTYPE_UNDEFINED = 0,
    MIXERLINE_TARGETTYPE_WAVEOUT,
    MIXERLINE_TARGETTYPE_WAVEIN,
    MIXERLINE_TARGETTYPE_MIDIOUT,
    MIXERLINE_TARGETTYPE_MIDIIN,
    MIXERLINE_TARGETTYPE_AUX // =5
}

enum MIXER_GETLINEINFOF_DESTINATION=0;
enum MIXER_GETLINEINFOF_SOURCE=1;
enum MIXER_GETLINEINFOF_LINEID=2;
enum MIXER_GETLINEINFOF_COMPONENTTYPE=3;
enum MIXER_GETLINEINFOF_TARGETTYPE=4;
enum MIXER_GETLINEINFOF_QUERYMASK=15;

enum MIXERCONTROL_CONTROLF_UNIFORM=1;
enum MIXERCONTROL_CONTROLF_MULTIPLE=2;
enum MIXERCONTROL_CONTROLF_DISABLED=0x80000000;
enum MIXERCONTROL_CT_CLASS_MASK=0xF0000000;
enum MIXERCONTROL_CT_CLASS_CUSTOM=0;
enum MIXERCONTROL_CT_CLASS_METER=0x10000000;
enum MIXERCONTROL_CT_CLASS_SWITCH=0x20000000;
enum MIXERCONTROL_CT_CLASS_NUMBER=0x30000000;
enum MIXERCONTROL_CT_CLASS_SLIDER=0x40000000;
enum MIXERCONTROL_CT_CLASS_FADER=0x50000000;
enum MIXERCONTROL_CT_CLASS_TIME=0x60000000;
enum MIXERCONTROL_CT_CLASS_LIST=0x70000000;
enum MIXERCONTROL_CT_SUBCLASS_MASK=0xF000000;
enum MIXERCONTROL_CT_SC_SWITCH_BOOLEAN=0;
enum MIXERCONTROL_CT_SC_SWITCH_BUTTON=0x1000000;
enum MIXERCONTROL_CT_SC_METER_POLLED=0;
enum MIXERCONTROL_CT_SC_TIME_MICROSECS=0;
enum MIXERCONTROL_CT_SC_TIME_MILLISECS=0x1000000;
enum MIXERCONTROL_CT_SC_LIST_SINGLE=0;
enum MIXERCONTROL_CT_SC_LIST_MULTIPLE=0x1000000;
enum MIXERCONTROL_CT_UNITS_MASK=0xFF0000;
enum MIXERCONTROL_CT_UNITS_CUSTOM=0;
enum MIXERCONTROL_CT_UNITS_BOOLEAN=0x10000;
enum MIXERCONTROL_CT_UNITS_SIGNED=0x20000;
enum MIXERCONTROL_CT_UNITS_UNSIGNED=0x30000;
enum MIXERCONTROL_CT_UNITS_DECIBELS=0x40000;
enum MIXERCONTROL_CT_UNITS_PERCENT=0x50000;

enum MIXERCONTROL_CONTROLTYPE_CUSTOM=(MIXERCONTROL_CT_CLASS_CUSTOM|MIXERCONTROL_CT_UNITS_CUSTOM);
enum MIXERCONTROL_CONTROLTYPE_BOOLEANMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_BOOLEAN);
enum MIXERCONTROL_CONTROLTYPE_SIGNEDMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_SIGNED);
enum MIXERCONTROL_CONTROLTYPE_PEAKMETER=(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER+1);
enum MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER=(MIXERCONTROL_CT_CLASS_METER|MIXERCONTROL_CT_SC_METER_POLLED|MIXERCONTROL_CT_UNITS_UNSIGNED);
enum MIXERCONTROL_CONTROLTYPE_BOOLEAN=(MIXERCONTROL_CT_CLASS_SWITCH|MIXERCONTROL_CT_SC_SWITCH_BOOLEAN|MIXERCONTROL_CT_UNITS_BOOLEAN);
enum MIXERCONTROL_CONTROLTYPE_ONOFF=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+1);
enum MIXERCONTROL_CONTROLTYPE_MUTE=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+2);
enum MIXERCONTROL_CONTROLTYPE_MONO=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+3);
enum MIXERCONTROL_CONTROLTYPE_LOUDNESS=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+4);
enum MIXERCONTROL_CONTROLTYPE_STEREOENH=(MIXERCONTROL_CONTROLTYPE_BOOLEAN+5);
enum MIXERCONTROL_CONTROLTYPE_BUTTON=(MIXERCONTROL_CT_CLASS_SWITCH|MIXERCONTROL_CT_SC_SWITCH_BUTTON|MIXERCONTROL_CT_UNITS_BOOLEAN);
enum MIXERCONTROL_CONTROLTYPE_DECIBELS=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_DECIBELS);
enum MIXERCONTROL_CONTROLTYPE_SIGNED=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_SIGNED);
enum MIXERCONTROL_CONTROLTYPE_UNSIGNED=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_UNSIGNED);
enum MIXERCONTROL_CONTROLTYPE_PERCENT=(MIXERCONTROL_CT_CLASS_NUMBER|MIXERCONTROL_CT_UNITS_PERCENT);
enum MIXERCONTROL_CONTROLTYPE_SLIDER=(MIXERCONTROL_CT_CLASS_SLIDER|MIXERCONTROL_CT_UNITS_SIGNED);
enum MIXERCONTROL_CONTROLTYPE_PAN=(MIXERCONTROL_CONTROLTYPE_SLIDER+1);
enum MIXERCONTROL_CONTROLTYPE_QSOUNDPAN=(MIXERCONTROL_CONTROLTYPE_SLIDER+2);
enum MIXERCONTROL_CONTROLTYPE_FADER=(MIXERCONTROL_CT_CLASS_FADER|MIXERCONTROL_CT_UNITS_UNSIGNED);
enum MIXERCONTROL_CONTROLTYPE_VOLUME=(MIXERCONTROL_CONTROLTYPE_FADER+1);
enum MIXERCONTROL_CONTROLTYPE_BASS=(MIXERCONTROL_CONTROLTYPE_FADER+2);
enum MIXERCONTROL_CONTROLTYPE_TREBLE=(MIXERCONTROL_CONTROLTYPE_FADER+3);
enum MIXERCONTROL_CONTROLTYPE_EQUALIZER=(MIXERCONTROL_CONTROLTYPE_FADER+4);
enum MIXERCONTROL_CONTROLTYPE_SINGLESELECT=(MIXERCONTROL_CT_CLASS_LIST|MIXERCONTROL_CT_SC_LIST_SINGLE|MIXERCONTROL_CT_UNITS_BOOLEAN);
enum MIXERCONTROL_CONTROLTYPE_MUX=(MIXERCONTROL_CONTROLTYPE_SINGLESELECT+1);
enum MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT=(MIXERCONTROL_CT_CLASS_LIST|MIXERCONTROL_CT_SC_LIST_MULTIPLE|MIXERCONTROL_CT_UNITS_BOOLEAN);
enum MIXERCONTROL_CONTROLTYPE_MIXER=(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT+1);
enum MIXERCONTROL_CONTROLTYPE_MICROTIME=(MIXERCONTROL_CT_CLASS_TIME|MIXERCONTROL_CT_SC_TIME_MICROSECS|MIXERCONTROL_CT_UNITS_UNSIGNED);
enum MIXERCONTROL_CONTROLTYPE_MILLITIME=(MIXERCONTROL_CT_CLASS_TIME|MIXERCONTROL_CT_SC_TIME_MILLISECS|MIXERCONTROL_CT_UNITS_UNSIGNED);

enum MIXER_GETLINECONTROLSF_ALL=0;
enum MIXER_GETLINECONTROLSF_ONEBYID=1;
enum MIXER_GETLINECONTROLSF_ONEBYTYPE=2;
enum MIXER_GETLINECONTROLSF_QUERYMASK=15;
enum MIXER_GETCONTROLDETAILSF_VALUE=0;
enum MIXER_GETCONTROLDETAILSF_LISTTEXT=1;
enum MIXER_GETCONTROLDETAILSF_QUERYMASK=15;
enum MIXER_SETCONTROLDETAILSF_VALUE=0;
enum MIXER_SETCONTROLDETAILSF_CUSTOM=1;
enum MIXER_SETCONTROLDETAILSF_QUERYMASK=15;

enum TIMERR_NOERROR=0;
enum TIMERR_NOCANDO=(TIMERR_BASE+1);
enum TIMERR_STRUCT=(TIMERR_BASE+33);
enum TIME_ONESHOT=0;
enum TIME_PERIODIC=1;
enum TIME_CALLBACK_FUNCTION=0;
enum TIME_CALLBACK_EVENT_SET=16;
enum TIME_CALLBACK_EVENT_PULSE=32;

static if (_WIN32_WINNT >= 0x501) {

enum TIME_KILL_SYNCHRONOUS=0x0100;

}

enum JOYERR_NOERROR = 0;
enum JOYERR_PARMS=(JOYERR_BASE+5);
enum JOYERR_NOCANDO=(JOYERR_BASE+6);
enum JOYERR_UNPLUGGED=(JOYERR_BASE+7);

enum JOY_BUTTON1=1;
enum JOY_BUTTON2=2;
enum JOY_BUTTON3=4;
enum JOY_BUTTON4=8;
enum JOY_BUTTON1CHG=256;
enum JOY_BUTTON2CHG=512;
enum JOY_BUTTON3CHG=1024;
enum JOY_BUTTON4CHG=2048;
enum JOY_BUTTON5=257;
enum JOY_BUTTON6=513;
enum JOY_BUTTON7=1025;
enum JOY_BUTTON8=2049;
enum JOY_BUTTON9=256;
enum JOY_BUTTON10=512;
enum JOY_BUTTON11=1024;
enum JOY_BUTTON12=2048;
enum JOY_BUTTON13=4096;
enum JOY_BUTTON14=8192;
enum JOY_BUTTON15=16384;
enum JOY_BUTTON16=32768;
enum JOY_BUTTON17=65536;
enum JOY_BUTTON18=0x20000;
enum JOY_BUTTON19=0x40000;
enum JOY_BUTTON20=0x80000;
enum JOY_BUTTON21=0x100000;
enum JOY_BUTTON22=0x200000;
enum JOY_BUTTON23=0x400000;
enum JOY_BUTTON24=0x800000;
enum JOY_BUTTON25=0x1000000;
enum JOY_BUTTON26=0x2000000;
enum JOY_BUTTON27=0x4000000;
enum JOY_BUTTON28=0x8000000;
enum JOY_BUTTON29=0x10000000;
enum JOY_BUTTON30=0x20000000;
enum JOY_BUTTON31=0x40000000;
enum JOY_BUTTON32=0x80000000;

enum  : DWORD {
    JOY_POVCENTERED = -1,
    JOY_POVFORWARD  = 0,
    JOY_POVBACKWARD = 18000,
    JOY_POVLEFT     = 27000,
    JOY_POVRIGHT    = 9000
}

enum DWORD
    JOY_RETURNX        = 0x00000001,
    JOY_RETURNY        = 0x00000002,
    JOY_RETURNZ        = 0x00000004,
    JOY_RETURNR        = 0x00000008,
    JOY_RETURNU        = 0x00000010,
    JOY_RETURNV        = 0x00000020,
    JOY_RETURNPOV      = 0x00000040,
    JOY_RETURNBUTTONS  = 0x00000080,
    JOY_RETURNRAWDATA  = 0x00000100,
    JOY_RETURNPOVCTS   = 0x00000200,
    JOY_RETURNCENTERED = 0x00000400,
    JOY_USEDEADZONE    = 0x00000800,
    JOY_RETURNALL      = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR
                         | JOY_RETURNU | JOY_RETURNV | JOY_RETURNPOV
                         | JOY_RETURNBUTTONS,
    JOY_CAL_READALWAYS = 0x00010000,
    JOY_CAL_READXYONLY = 0x00020000,
    JOY_CAL_READ3      = 0x00040000,
    JOY_CAL_READ4      = 0x00080000,
    JOY_CAL_READXONLY  = 0x00100000,
    JOY_CAL_READYONLY  = 0x00200000,
    JOY_CAL_READ5      = 0x00400000,
    JOY_CAL_READ6      = 0x00800000,
    JOY_CAL_READZONLY  = 0x01000000,
    JOY_CAL_READRONLY  = 0x02000000,
    JOY_CAL_READUONLY  = 0x04000000,
    JOY_CAL_READVONLY  = 0x08000000;

enum JOYSTICKID1=0;
enum JOYSTICKID2=1;

enum JOYCAPS_HASZ=1;
enum JOYCAPS_HASR=2;
enum JOYCAPS_HASU=4;
enum JOYCAPS_HASV=8;
enum JOYCAPS_HASPOV=16;
enum JOYCAPS_POV4DIR=32;
enum JOYCAPS_POVCTS=64;

enum MMIOERR_BASE=256;
enum MMIOERR_FILENOTFOUND=(MMIOERR_BASE+1);
enum MMIOERR_OUTOFMEMORY=(MMIOERR_BASE+2);
enum MMIOERR_CANNOTOPEN=(MMIOERR_BASE+3);
enum MMIOERR_CANNOTCLOSE=(MMIOERR_BASE+4);
enum MMIOERR_CANNOTREAD=(MMIOERR_BASE+5);
enum MMIOERR_CANNOTWRITE=(MMIOERR_BASE+6);
enum MMIOERR_CANNOTSEEK=(MMIOERR_BASE+7);
enum MMIOERR_CANNOTEXPAND=(MMIOERR_BASE+8);
enum MMIOERR_CHUNKNOTFOUND=(MMIOERR_BASE+9);
enum MMIOERR_UNBUFFERED=(MMIOERR_BASE+10);
enum MMIOERR_PATHNOTFOUND=(MMIOERR_BASE+11);
enum MMIOERR_ACCESSDENIED=(MMIOERR_BASE+12);
enum MMIOERR_SHARINGVIOLATION=(MMIOERR_BASE+13);
enum MMIOERR_NETWORKERROR=(MMIOERR_BASE+14);
enum MMIOERR_TOOMANYOPENFILES=(MMIOERR_BASE+15);
enum MMIOERR_INVALIDFILE=(MMIOERR_BASE+16);

enum CFSEPCHAR='+';

enum MMIO_RWMODE=3;
enum MMIO_SHAREMODE=0x70;
enum MMIO_CREATE=0x1000;
enum MMIO_PARSE=256;
enum MMIO_DELETE=512;
enum MMIO_EXIST=0x4000;
enum MMIO_ALLOCBUF=0x10000;
enum MMIO_GETTEMP=0x20000;
enum MMIO_DIRTY=0x10000000;
enum MMIO_READ=0;
enum MMIO_WRITE=1;
enum MMIO_READWRITE=2;
enum MMIO_COMPAT=0;
enum MMIO_EXCLUSIVE=16;
enum MMIO_DENYWRITE=32;
enum MMIO_DENYREAD=0x30;
enum MMIO_DENYNONE=64;
enum MMIO_FHOPEN=16;
enum MMIO_EMPTYBUF=16;
enum MMIO_TOUPPER=16;
enum MMIO_INSTALLPROC=0x10000;
enum MMIO_GLOBALPROC=0x10000000;
enum MMIO_REMOVEPROC=0x20000;
enum MMIO_UNICODEPROC=0x1000000;
enum MMIO_FINDPROC=0x40000;
enum MMIO_FINDCHUNK=16;
enum MMIO_FINDRIFF=32;
enum MMIO_FINDLIST=64;
enum MMIO_CREATERIFF=32;
enum MMIO_CREATELIST=64;
enum MMIOM_READ=MMIO_READ;
enum MMIOM_WRITE=MMIO_WRITE;
enum MMIOM_SEEK=2;
enum MMIOM_OPEN=3;
enum MMIOM_CLOSE=4;
enum MMIOM_WRITEFLUSH=5;
enum MMIOM_RENAME=6;
enum MMIOM_USER=0x8000;

enum FOURCC_RIFF = mmioFOURCC!('R', 'I', 'F', 'F');
enum FOURCC_LIST = mmioFOURCC!('L', 'I', 'S', 'T');
enum FOURCC_DOS  = mmioFOURCC!('D', 'O', 'S', ' ');
enum FOURCC_MEM  = mmioFOURCC!('M', 'E', 'M', ' ');

enum MMIO_DEFAULTBUFFER=8192;

enum {
    MCIERR_INVALID_DEVICE_ID = MCIERR_BASE + 1,
    MCIERR_UNRECOGNIZED_KEYWORD = MCIERR_BASE + 3,
    MCIERR_UNRECOGNIZED_COMMAND = MCIERR_BASE + 5,
    MCIERR_HARDWARE,
    MCIERR_INVALID_DEVICE_NAME,
    MCIERR_OUT_OF_MEMORY,
    MCIERR_DEVICE_OPEN,
    MCIERR_CANNOT_LOAD_DRIVER,
    MCIERR_MISSING_COMMAND_STRING,
    MCIERR_PARAM_OVERFLOW,
    MCIERR_MISSING_STRING_ARGUMENT,
    MCIERR_BAD_INTEGER,
    MCIERR_PARSER_INTERNAL,
    MCIERR_DRIVER_INTERNAL,
    MCIERR_MISSING_PARAMETER,
    MCIERR_UNSUPPORTED_FUNCTION,
    MCIERR_FILE_NOT_FOUND,
    MCIERR_DEVICE_NOT_READY,
    MCIERR_INTERNAL,
    MCIERR_DRIVER,
    MCIERR_CANNOT_USE_ALL,
    MCIERR_MULTIPLE,
    MCIERR_EXTENSION_NOT_FOUND,
    MCIERR_OUTOFRANGE, // = MCIERR_BASE+26
    MCIERR_FLAGS_NOT_COMPATIBLE = MCIERR_BASE + 28,
    MCIERR_FILE_NOT_SAVED = MCIERR_BASE + 30,
    MCIERR_DEVICE_TYPE_REQUIRED,
    MCIERR_DEVICE_LOCKED,
    MCIERR_DUPLICATE_ALIAS,
    MCIERR_BAD_CONSTANT,
    MCIERR_MUST_USE_SHAREABLE,
    MCIERR_MISSING_DEVICE_NAME,
    MCIERR_BAD_TIME_FORMAT,
    MCIERR_NO_CLOSING_QUOTE,
    MCIERR_DUPLICATE_FLAGS,
    MCIERR_INVALID_FILE,
    MCIERR_NULL_PARAMETER_BLOCK,
    MCIERR_UNNAMED_RESOURCE,
    MCIERR_NEW_REQUIRES_ALIAS,
    MCIERR_NOTIFY_ON_AUTO_OPEN,
    MCIERR_NO_ELEMENT_ALLOWED,
    MCIERR_NONAPPLICABLE_FUNCTION,
    MCIERR_ILLEGAL_FOR_AUTO_OPEN,
    MCIERR_FILENAME_REQUIRED,
    MCIERR_EXTRA_CHARACTERS,
    MCIERR_DEVICE_NOT_INSTALLED,
    MCIERR_GET_CD,
    MCIERR_SET_CD,
    MCIERR_SET_DRIVE,
    MCIERR_DEVICE_LENGTH,
    MCIERR_DEVICE_ORD_LENGTH,
    MCIERR_NO_INTEGER, // = MCIERR_BASE + 56
    MCIERR_WAVE_OUTPUTSINUSE = MCIERR_BASE + 64,
    MCIERR_WAVE_SETOUTPUTINUSE,
    MCIERR_WAVE_INPUTSINUSE,
    MCIERR_WAVE_SETINPUTINUSE,
    MCIERR_WAVE_OUTPUTUNSPECIFIED,
    MCIERR_WAVE_INPUTUNSPECIFIED,
    MCIERR_WAVE_OUTPUTSUNSUITABLE,
    MCIERR_WAVE_SETOUTPUTUNSUITABLE,
    MCIERR_WAVE_INPUTSUNSUITABLE,
    MCIERR_WAVE_SETINPUTUNSUITABLE, // = MCIERR_BASE + 73
    MCIERR_SEQ_DIV_INCOMPATIBLE = MCIERR_BASE + 80,
    MCIERR_SEQ_PORT_INUSE,
    MCIERR_SEQ_PORT_NONEXISTENT,
    MCIERR_SEQ_PORT_MAPNODEVICE,
    MCIERR_SEQ_PORT_MISCERROR,
    MCIERR_SEQ_TIMER,
    MCIERR_SEQ_PORTUNSPECIFIED,
    MCIERR_SEQ_NOMIDIPRESENT, // = MCIERR_BASE + 87
    MCIERR_NO_WINDOW = MCIERR_BASE + 90,
    MCIERR_CREATEWINDOW,
    MCIERR_FILE_READ,
    MCIERR_FILE_WRITE,
    MCIERR_NO_IDENTITY // = MCIERR_BASE + 94
}
enum MCIERR_CUSTOM_DRIVER_BASE = MCIERR_BASE + 256;

enum MCI_FIRST=DRV_MCI_FIRST;
enum MCI_OPEN=0x803;
enum MCI_CLOSE=0x804;
enum MCI_ESCAPE=0x805;
enum MCI_PLAY=0x806;
enum MCI_SEEK=0x807;
enum MCI_STOP=0x808;
enum MCI_PAUSE=0x809;
enum MCI_INFO=0x80A;
enum MCI_GETDEVCAPS=0x80B;
enum MCI_SPIN=0x80C;
enum MCI_SET=0x80D;
enum MCI_STEP=0x80E;
enum MCI_RECORD=0x80F;
enum MCI_SYSINFO=0x810;
enum MCI_BREAK=0x811;
enum MCI_SAVE=0x813;
enum MCI_STATUS=0x814;
enum MCI_CUE=0x830;
enum MCI_REALIZE=0x840;
enum MCI_WINDOW=0x841;
enum MCI_PUT=0x842;
enum MCI_WHERE=0x843;
enum MCI_FREEZE=0x844;
enum MCI_UNFREEZE=0x845;
enum MCI_LOAD=0x850;
enum MCI_CUT=0x851;
enum MCI_COPY=0x852;
enum MCI_PASTE=0x853;
enum MCI_UPDATE=0x854;
enum MCI_RESUME=0x855;
enum MCI_DELETE=0x856;
enum MCI_USER_MESSAGES=(DRV_MCI_FIRST+0x400);
enum MCI_LAST=0xFFF;

enum MCIDEVICEID MCI_ALL_DEVICE_ID = -1;

enum MCI_DEVTYPE_VCR=513;
enum MCI_DEVTYPE_VIDEODISC=514;
enum MCI_DEVTYPE_OVERLAY=515;
enum MCI_DEVTYPE_CD_AUDIO=516;
enum MCI_DEVTYPE_DAT=517;
enum MCI_DEVTYPE_SCANNER=518;
enum MCI_DEVTYPE_ANIMATION=519;
enum MCI_DEVTYPE_DIGITAL_VIDEO=520;
enum MCI_DEVTYPE_OTHER=521;
enum MCI_DEVTYPE_WAVEFORM_AUDIO=522;
enum MCI_DEVTYPE_SEQUENCER=523;
enum MCI_DEVTYPE_FIRST=MCI_DEVTYPE_VCR;
enum MCI_DEVTYPE_LAST=MCI_DEVTYPE_SEQUENCER;
enum MCI_DEVTYPE_FIRST_USER=0x1000;
enum MCI_MODE_NOT_READY=(MCI_STRING_OFFSET+12);
enum MCI_MODE_STOP=(MCI_STRING_OFFSET+13);
enum MCI_MODE_PLAY=(MCI_STRING_OFFSET+14);
enum MCI_MODE_RECORD=(MCI_STRING_OFFSET+15);
enum MCI_MODE_SEEK=(MCI_STRING_OFFSET+16);
enum MCI_MODE_PAUSE=(MCI_STRING_OFFSET+17);
enum MCI_MODE_OPEN=(MCI_STRING_OFFSET+18);
enum MCI_FORMAT_MILLISECONDS=0;
enum MCI_FORMAT_HMS=1;
enum MCI_FORMAT_MSF=2;
enum MCI_FORMAT_FRAMES=3;
enum MCI_FORMAT_SMPTE_24=4;
enum MCI_FORMAT_SMPTE_25=5;
enum MCI_FORMAT_SMPTE_30=6;
enum MCI_FORMAT_SMPTE_30DROP=7;
enum MCI_FORMAT_BYTES=8;
enum MCI_FORMAT_SAMPLES=9;
enum MCI_FORMAT_TMSF=10;




// Macros
BYTE MCI_HMS_HOUR(DWORD t) { return cast(BYTE)(t); }
BYTE MCI_HMS_MINUTE(DWORD t) { return cast(BYTE)(t>>>8); }
BYTE MCI_HMS_SECOND(DWORD t) { return cast(BYTE)( t>>>16); }
DWORD MCI_MAKE_HMS(BYTE h, BYTE m, BYTE s) { return h |(m<<8)|(cast(DWORD)(s)<<16); }
DWORD MCI_MAKE_MSF(BYTE m, BYTE s, BYTE f) { return m |(s<<8)|(cast(DWORD)(f)<<16); }
DWORD MCI_MAKE_TMSF(BYTE t, BYTE m, BYTE s, BYTE f) {
 return t |(m<<8)|(s<<16)|(cast(DWORD)(f)<< 24); }

BYTE MCI_MSF_MINUTE(DWORD t) { return cast(BYTE)(t); }
BYTE MCI_MSF_SECOND(DWORD t) { return cast(BYTE)(t >>> 8); }
BYTE MCI_MSF_FRAME(DWORD t)  {  return cast(BYTE)(t >>> 16); }

BYTE MCI_TMSF_TRACK(DWORD t)  { return cast(BYTE)(t); }
BYTE MCI_TMSF_MINUTE(DWORD t) { return cast(BYTE)(t>>8); }
BYTE MCI_TMSF_SECOND(DWORD t) { return cast(BYTE)(t>>16); }
BYTE MCI_TMSF_FRAME(DWORD t)  { return cast(BYTE)(t>>24); }


enum MCI_NOTIFY_SUCCESSFUL=1;
enum MCI_NOTIFY_SUPERSEDED=2;
enum MCI_NOTIFY_ABORTED=4;
enum MCI_NOTIFY_FAILURE=8;
enum MCI_NOTIFY=1;
enum MCI_WAIT=2;
enum MCI_FROM=4;
enum MCI_TO=8;
enum MCI_TRACK=16;
enum MCI_OPEN_SHAREABLE=256;
enum MCI_OPEN_ELEMENT=512;
enum MCI_OPEN_ALIAS=1024;
enum MCI_OPEN_ELEMENT_ID=2048;
enum MCI_OPEN_TYPE_ID=0x1000;
enum MCI_OPEN_TYPE=0x2000;
enum MCI_SEEK_TO_START=256;
enum MCI_SEEK_TO_END=512;
enum MCI_STATUS_ITEM=256;
enum MCI_STATUS_START=512;
enum MCI_STATUS_LENGTH=1;
enum MCI_STATUS_POSITION=2;
enum MCI_STATUS_NUMBER_OF_TRACKS=3;
enum MCI_STATUS_MODE=4;
enum MCI_STATUS_MEDIA_PRESENT=5;
enum MCI_STATUS_TIME_FORMAT=6;
enum MCI_STATUS_READY=7;
enum MCI_STATUS_CURRENT_TRACK=8;
enum MCI_INFO_PRODUCT=256;
enum MCI_INFO_FILE=512;
enum MCI_INFO_MEDIA_UPC=1024;
enum MCI_INFO_MEDIA_IDENTITY=2048;
enum MCI_INFO_NAME=0x1000;
enum MCI_INFO_COPYRIGHT=0x2000;

enum MCI_GETDEVCAPS_ITEM=256;
enum MCI_GETDEVCAPS_CAN_RECORD=1;
enum MCI_GETDEVCAPS_HAS_AUDIO=2;
enum MCI_GETDEVCAPS_HAS_VIDEO=3;
enum MCI_GETDEVCAPS_DEVICE_TYPE=4;
enum MCI_GETDEVCAPS_USES_FILES=5;
enum MCI_GETDEVCAPS_COMPOUND_DEVICE=6;
enum MCI_GETDEVCAPS_CAN_EJECT=7;
enum MCI_GETDEVCAPS_CAN_PLAY=8;
enum MCI_GETDEVCAPS_CAN_SAVE=9;

enum MCI_SYSINFO_QUANTITY=256;
enum MCI_SYSINFO_OPEN=512;
enum MCI_SYSINFO_NAME=1024;
enum MCI_SYSINFO_INSTALLNAME=2048;
enum MCI_SET_DOOR_OPEN=256;
enum MCI_SET_DOOR_CLOSED=512;
enum MCI_SET_TIME_FORMAT=1024;
enum MCI_SET_AUDIO=2048;
enum MCI_SET_VIDEO=0x1000;
enum MCI_SET_ON=0x2000;
enum MCI_SET_OFF=0x4000;

enum MCI_SET_AUDIO_ALL=0;
enum MCI_SET_AUDIO_LEFT=1;
enum MCI_SET_AUDIO_RIGHT=2;

enum MCI_BREAK_KEY=256;
enum MCI_BREAK_HWND=512;
enum MCI_BREAK_OFF=1024;

enum MCI_RECORD_INSERT=256;
enum MCI_RECORD_OVERWRITE=512;
enum MCI_SAVE_FILE=256;
enum MCI_LOAD_FILE=256;

enum MCI_VD_MODE_PARK=(MCI_VD_OFFSET+1);
enum MCI_VD_MEDIA_CLV=(MCI_VD_OFFSET+2);
enum MCI_VD_MEDIA_CAV=(MCI_VD_OFFSET+3);
enum MCI_VD_MEDIA_OTHER=(MCI_VD_OFFSET+4);

enum MCI_VD_FORMAT_TRACK=0x4001;
enum MCI_VD_PLAY_REVERSE=0x10000;
enum MCI_VD_PLAY_FAST=0x20000;
enum MCI_VD_PLAY_SPEED=0x40000;
enum MCI_VD_PLAY_SCAN=0x80000;
enum MCI_VD_PLAY_SLOW=0x100000;
enum MCI_VD_SEEK_REVERSE=0x10000;
enum MCI_VD_STATUS_SPEED=0x4002;
enum MCI_VD_STATUS_FORWARD=0x4003;
enum MCI_VD_STATUS_MEDIA_TYPE=0x4004;
enum MCI_VD_STATUS_SIDE=0x4005;
enum MCI_VD_STATUS_DISC_SIZE=0x4006;
enum MCI_VD_GETDEVCAPS_CLV=0x10000;
enum MCI_VD_GETDEVCAPS_CAV=0x20000;
enum MCI_VD_SPIN_UP=0x10000;
enum MCI_VD_SPIN_DOWN=0x20000;
enum MCI_VD_GETDEVCAPS_CAN_REVERSE=0x4002;
enum MCI_VD_GETDEVCAPS_FAST_RATE=0x4003;
enum MCI_VD_GETDEVCAPS_SLOW_RATE=0x4004;
enum MCI_VD_GETDEVCAPS_NORMAL_RATE=0x4005;
enum MCI_VD_STEP_FRAMES=0x10000;
enum MCI_VD_STEP_REVERSE=0x20000;
enum MCI_VD_ESCAPE_STRING=256;

enum MCI_CDA_STATUS_TYPE_TRACK=0x4001;
enum MCI_CDA_TRACK_AUDIO=MCI_CD_OFFSET;
enum MCI_CDA_TRACK_OTHER=(MCI_CD_OFFSET+1);

enum MCI_WAVE_PCM=MCI_WAVE_OFFSET;
enum MCI_WAVE_MAPPER=(MCI_WAVE_OFFSET+1);
enum MCI_WAVE_OPEN_BUFFER=0x10000;
enum MCI_WAVE_SET_FORMATTAG=0x10000;
enum MCI_WAVE_SET_CHANNELS=0x20000;
enum MCI_WAVE_SET_SAMPLESPERSEC=0x40000;
enum MCI_WAVE_SET_AVGBYTESPERSEC=0x80000;
enum MCI_WAVE_SET_BLOCKALIGN=0x100000;
enum MCI_WAVE_SET_BITSPERSAMPLE=0x200000;
enum MCI_WAVE_INPUT=0x400000;
enum MCI_WAVE_OUTPUT=0x800000;
enum MCI_WAVE_STATUS_FORMATTAG=0x4001;
enum MCI_WAVE_STATUS_CHANNELS=0x4002;
enum MCI_WAVE_STATUS_SAMPLESPERSEC=0x4003;
enum MCI_WAVE_STATUS_AVGBYTESPERSEC=0x4004;
enum MCI_WAVE_STATUS_BLOCKALIGN=0x4005;
enum MCI_WAVE_STATUS_BITSPERSAMPLE=0x4006;
enum MCI_WAVE_STATUS_LEVEL=0x4007;
enum MCI_WAVE_SET_ANYINPUT=0x4000000;
enum MCI_WAVE_SET_ANYOUTPUT=0x8000000;
enum MCI_WAVE_GETDEVCAPS_INPUTS=0x4001;
enum MCI_WAVE_GETDEVCAPS_OUTPUTS=0x4002;

enum MCI_SEQ_DIV_PPQN=MCI_SEQ_OFFSET;
enum MCI_SEQ_DIV_SMPTE_24=(MCI_SEQ_OFFSET+1);
enum MCI_SEQ_DIV_SMPTE_25=(MCI_SEQ_OFFSET+2);
enum MCI_SEQ_DIV_SMPTE_30DROP=(MCI_SEQ_OFFSET+3);
enum MCI_SEQ_DIV_SMPTE_30=(MCI_SEQ_OFFSET+4);
enum MCI_SEQ_FORMAT_SONGPTR=0x4001;
enum MCI_SEQ_FILE=0x4002;
enum MCI_SEQ_MIDI=0x4003;
enum MCI_SEQ_SMPTE=0x4004;
enum MCI_SEQ_NONE=65533;
enum MCI_SEQ_MAPPER=65535;

enum MCI_SEQ_STATUS_TEMPO=0x4002;
enum MCI_SEQ_STATUS_PORT=0x4003;
enum MCI_SEQ_STATUS_SLAVE=0x4007;
enum MCI_SEQ_STATUS_MASTER=0x4008;
enum MCI_SEQ_STATUS_OFFSET=0x4009;
enum MCI_SEQ_STATUS_DIVTYPE=0x400A;
enum MCI_SEQ_STATUS_NAME=0x400B;
enum MCI_SEQ_STATUS_COPYRIGHT=0x400C;

enum MCI_SEQ_SET_TEMPO=0x10000;
enum MCI_SEQ_SET_PORT=0x20000;
enum MCI_SEQ_SET_SLAVE=0x40000;
enum MCI_SEQ_SET_MASTER=0x80000;
enum MCI_SEQ_SET_OFFSET=0x1000000;

enum MCI_ANIM_OPEN_WS=0x10000;
enum MCI_ANIM_OPEN_PARENT=0x20000;
enum MCI_ANIM_OPEN_NOSTATIC=0x40000;
enum MCI_ANIM_PLAY_SPEED=0x10000;
enum MCI_ANIM_PLAY_REVERSE=0x20000;
enum MCI_ANIM_PLAY_FAST=0x40000;
enum MCI_ANIM_PLAY_SLOW=0x80000;
enum MCI_ANIM_PLAY_SCAN=0x100000;
enum MCI_ANIM_STEP_REVERSE=0x10000;
enum MCI_ANIM_STEP_FRAMES=0x20000;
enum MCI_ANIM_STATUS_SPEED=0x4001;
enum MCI_ANIM_STATUS_FORWARD=0x4002;
enum MCI_ANIM_STATUS_HWND=0x4003;
enum MCI_ANIM_STATUS_HPAL=0x4004;
enum MCI_ANIM_STATUS_STRETCH=0x4005;
enum MCI_ANIM_INFO_TEXT=0x10000;

enum MCI_ANIM_GETDEVCAPS_CAN_REVERSE=0x4001;
enum MCI_ANIM_GETDEVCAPS_FAST_RATE=0x4002;
enum MCI_ANIM_GETDEVCAPS_SLOW_RATE=0x4003;
enum MCI_ANIM_GETDEVCAPS_NORMAL_RATE=0x4004;
enum MCI_ANIM_GETDEVCAPS_PALETTES=0x4006;
enum MCI_ANIM_GETDEVCAPS_CAN_STRETCH=0x4007;
enum MCI_ANIM_GETDEVCAPS_MAX_WINDOWS=0x4008;

enum MCI_ANIM_REALIZE_NORM=0x10000;
enum MCI_ANIM_REALIZE_BKGD=0x20000;

enum MCI_ANIM_WINDOW_HWND=0x10000;
enum MCI_ANIM_WINDOW_STATE=0x40000;
enum MCI_ANIM_WINDOW_TEXT=0x80000;
enum MCI_ANIM_WINDOW_ENABLE_STRETCH=0x100000;
enum MCI_ANIM_WINDOW_DISABLE_STRETCH=0x200000;
enum MCI_ANIM_WINDOW_DEFAULT=0x0;

enum MCI_ANIM_RECT=0x10000;
enum MCI_ANIM_PUT_SOURCE=0x20000;
enum MCI_ANIM_PUT_DESTINATION=0x40000;
enum MCI_ANIM_WHERE_SOURCE=0x20000;
enum MCI_ANIM_WHERE_DESTINATION=0x40000;
enum MCI_ANIM_UPDATE_HDC=0x20000;

enum MCI_OVLY_OPEN_WS=0x10000;
enum MCI_OVLY_OPEN_PARENT=0x20000;
enum MCI_OVLY_STATUS_HWND=0x4001;
enum MCI_OVLY_STATUS_STRETCH=0x4002;
enum MCI_OVLY_INFO_TEXT=0x10000;
enum MCI_OVLY_GETDEVCAPS_CAN_STRETCH=0x4001;
enum MCI_OVLY_GETDEVCAPS_CAN_FREEZE=0x4002;
enum MCI_OVLY_GETDEVCAPS_MAX_WINDOWS=0x4003;
enum MCI_OVLY_WINDOW_HWND=0x10000;
enum MCI_OVLY_WINDOW_STATE=0x40000;
enum MCI_OVLY_WINDOW_TEXT=0x80000;
enum MCI_OVLY_WINDOW_ENABLE_STRETCH=0x100000;
enum MCI_OVLY_WINDOW_DISABLE_STRETCH=0x200000;
enum MCI_OVLY_WINDOW_DEFAULT=0x0;
enum MCI_OVLY_RECT=0x10000;
enum MCI_OVLY_PUT_SOURCE=0x20000;
enum MCI_OVLY_PUT_DESTINATION=0x40000;
enum MCI_OVLY_PUT_FRAME=0x80000;
enum MCI_OVLY_PUT_VIDEO=0x100000;
enum MCI_OVLY_WHERE_SOURCE=0x20000;
enum MCI_OVLY_WHERE_DESTINATION=0x40000;
enum MCI_OVLY_WHERE_FRAME=0x80000;
enum MCI_OVLY_WHERE_VIDEO=0x100000;

enum NEWTRANSPARENT=3;
enum QUERYROPSUPPORT=40;
enum SELECTDIB=41;

LONG DIBINDEX(WORD n) {
    return MAKELONG(n, 0x10FF);
}
enum CAPS1=94;
enum C1_TRANSPARENT=1;

//const SEEK_SET=0;
//const SEEK_CUR=1;
//const SEEK_END=2;
public import core.stdc.stdio : SEEK_SET, SEEK_CUR, SEEK_END;

alias DWORD MCIERROR;
alias UINT MCIDEVICEID;
extern(Windows) alias UINT function (MCIDEVICEID, DWORD) YIELDPROC;
alias UINT MMVERSION;
alias UINT MMRESULT;

struct MMTIME {
    UINT wType;
    union {
        DWORD ms;
        DWORD sample;
        DWORD cb;
        DWORD ticks;
        struct _smpte {
            BYTE hour;
            BYTE min;
            BYTE sec;
            BYTE frame;
            BYTE fps;
            BYTE dummy;
            BYTE[2] pad;
        }
        _smpte smpte;
        struct _midi {
            DWORD songptrpos;
        }
        _midi midi;
    }
}
alias MMTIME* PMMTIME, LPMMTIME;

alias TypeDef!(HANDLE) HDRVR;

struct DRVCONFIGINFO {
align(1):
    DWORD dwDCISize;
    LPCWSTR lpszDCISectionName;
    LPCWSTR lpszDCIAliasName;
}
alias DRVCONFIGINFO * PDRVCONFIGINFO, LPDRVCONFIGINFO;

struct DRVCONFIGINFOEX {
align(1):
    DWORD dwDCISize;
    LPCWSTR lpszDCISectionName;
    LPCWSTR lpszDCIAliasName;
    DWORD dnDevNode;
}
alias DRVCONFIGINFOEX* PDRVCONFIGINFOEX, LPDRVCONFIGINFOEX;

extern(Windows):

/+FIXME: I couldn't find these in MSDN.
alias void function (HDRVR, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR) DRVCALLBACK;
LRESULT DRIVERPROC (DWORD_PTR, HDRVR, UINT, LPARAM, LPARAM);
alias DRVCALLBACK* LPDRVCALLBACK, PDRVCALLBACK;

alias DRVCALLBACK WAVECALLBACK;
alias WAVECALLBACK* LPWAVECALLBACK;

alias DRVCALLBACK MIDICALLBACK;
alias MIDICALLBACK* LPMIDICALLBACK;

+/

alias TypeDef!(HANDLE) HWAVE;
alias TypeDef!(HANDLE) HWAVEIN;
alias TypeDef!(HANDLE) HWAVEOUT;

alias HWAVEIN* LPHWAVEIN;
alias HWAVEOUT* LPHWAVEOUT;

struct WAVEHDR {
    LPSTR lpData;
    DWORD dwBufferLength;
    DWORD dwBytesRecorded;
    DWORD_PTR dwUser;
    DWORD dwFlags;
    DWORD dwLoops;
    WAVEHDR *lpNext;
    DWORD_PTR reserved;
}
alias WAVEHDR* PWAVEHDR, LPWAVEHDR;

struct WAVEOUTCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwFormats;
    WORD wChannels;
    WORD wReserved1;
    DWORD dwSupport;
}
alias WAVEOUTCAPSA* PWAVEOUTCAPSA, LPWAVEOUTCAPSA;

struct WAVEOUTCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwFormats;
    WORD wChannels;
    WORD wReserved1;
    DWORD dwSupport;
}
alias WAVEOUTCAPSW* PWAVEOUTCAPSW, LPWAVEOUTCAPSW;

struct WAVEINCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwFormats;
    WORD wChannels;
    WORD wReserved1;
}
alias WAVEINCAPSA* PWAVEINCAPSA, LPWAVEINCAPSA;

struct WAVEINCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwFormats;
    WORD wChannels;
    WORD wReserved1;
}
alias WAVEINCAPSW* PWAVEINCAPSW, LPWAVEINCAPSW;

struct WAVEFORMAT {
    WORD wFormatTag;
    WORD nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD nBlockAlign;
}
alias WAVEFORMAT* PWAVEFORMAT, LPWAVEFORMAT;

struct PCMWAVEFORMAT {
    WAVEFORMAT wf;
    WORD wBitsPerSample;
}
alias PCMWAVEFORMAT* PPCMWAVEFORMAT, LPPCMWAVEFORMAT;

struct WAVEFORMATEX {
    WORD wFormatTag;
    WORD nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD nBlockAlign;
    WORD wBitsPerSample;
    WORD cbSize;
}
alias WAVEFORMATEX* PWAVEFORMATEX, LPWAVEFORMATEX;
alias const(WAVEFORMATEX)* LPCWAVEFORMATEX;

alias TypeDef!(HANDLE) HMIDI;
alias TypeDef!(HANDLE) HMIDIIN;
alias TypeDef!(HANDLE) HMIDIOUT;
alias TypeDef!(HANDLE) HMIDISTRM;

alias HMIDI* LPHMIDI;
alias HMIDIIN* LPHMIDIIN;
alias HMIDIOUT* LPHMIDIOUT;
alias HMIDISTRM* LPHMIDISTRM;

alias WORD[MIDIPATCHSIZE] PATCHARRAY;
alias WORD* LPPATCHARRAY;
alias WORD[MIDIPATCHSIZE] KEYARRAY;
alias WORD* LPKEYARRAY;

struct MIDIOUTCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    WORD wTechnology;
    WORD wVoices;
    WORD wNotes;
    WORD wChannelMask;
    DWORD dwSupport;
}
alias MIDIOUTCAPSA* PMIDIOUTCAPSA, LPMIDIOUTCAPSA;

struct MIDIOUTCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    WORD wTechnology;
    WORD wVoices;
    WORD wNotes;
    WORD wChannelMask;
    DWORD dwSupport;
}
alias MIDIOUTCAPSW* PMIDIOUTCAPSW, LPMIDIOUTCAPSW;

struct MIDIINCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwSupport;
}
alias MIDIINCAPSA* PMIDIINCAPSA, LPMIDIINCAPSA;

struct MIDIINCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    DWORD dwSupport;
}
alias MIDIINCAPSW* PMIDIINCAPSW, LPMIDIINCAPSW;

struct MIDIHDR {
align(1):
    LPSTR lpData;
    DWORD dwBufferLength;
    DWORD dwBytesRecorded;
    DWORD_PTR dwUser;
    DWORD dwFlags;
    MIDIHDR *lpNext;
    DWORD_PTR reserved;
    DWORD dwOffset;
    DWORD_PTR[8] dwReserved;
}
alias MIDIHDR* PMIDIHDR, LPMIDIHDR;

struct MIDIEVENT {
    DWORD dwDeltaTime;
    DWORD dwStreamID;
    DWORD dwEvent;
    DWORD[1] dwParms;
}

struct MIDISTRMBUFFVER {
    DWORD dwVersion;
    DWORD dwMid;
    DWORD dwOEMVersion;
}

struct MIDIPROPTIMEDIV {
    DWORD cbStruct;
    DWORD dwTimeDiv;
}
alias MIDIPROPTIMEDIV* LPMIDIPROPTIMEDIV;

struct MIDIPROPTEMPO {
    DWORD cbStruct;
    DWORD dwTempo;
}
alias MIDIPROPTEMPO* LPMIDIPROPTEMPO;

struct AUXCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    WORD wTechnology;
    WORD wReserved1;
    DWORD dwSupport;
}
alias AUXCAPSA* PAUXCAPSA, LPAUXCAPSA;

struct AUXCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    WORD wTechnology;
    WORD wReserved1;
    DWORD dwSupport;
}
alias AUXCAPSW* PAUXCAPSW, LPAUXCAPSW;

alias TypeDef!(HANDLE) HMIXEROBJ;
alias HMIXEROBJ* LPHMIXEROBJ;

alias TypeDef!(HANDLE) HMIXER;
alias HMIXER* LPHMIXER;

struct MIXERCAPSA {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    CHAR[MAXPNAMELEN] szPname = 0;
    DWORD fdwSupport;
    DWORD cDestinations;
}
alias MIXERCAPSA* PMIXERCAPSA, LPMIXERCAPSA;

struct MIXERCAPSW {
    WORD wMid;
    WORD wPid;
    MMVERSION vDriverVersion;
    WCHAR[MAXPNAMELEN] szPname = 0;
    DWORD fdwSupport;
    DWORD cDestinations;
}
alias MIXERCAPSW* PMIXERCAPSW, LPMIXERCAPSW;

struct MIXERLINEA {
align(1):
    DWORD cbStruct;
    DWORD dwDestination;
    DWORD dwSource;
    DWORD dwLineID;
    DWORD fdwLine;
    DWORD_PTR dwUser;
    DWORD dwComponentType;
    DWORD cChannels;
    DWORD cConnections;
    DWORD cControls;
    CHAR[MIXER_SHORT_NAME_CHARS] szShortName = 0;
    CHAR[MIXER_LONG_NAME_CHARS] szName = 0;
    struct _Target {
        DWORD dwType;
        DWORD dwDeviceID;
        WORD wMid;
        WORD wPid;
        MMVERSION vDriverVersion;
        CHAR[MAXPNAMELEN] szPname = 0;
    }
    _Target Target;
}
alias MIXERLINEA* PMIXERLINEA, LPMIXERLINEA;

struct MIXERLINEW {
align(1):
    DWORD cbStruct;
    DWORD dwDestination;
    DWORD dwSource;
    DWORD dwLineID;
    DWORD fdwLine;
    DWORD_PTR dwUser;
    DWORD dwComponentType;
    DWORD cChannels;
    DWORD cConnections;
    DWORD cControls;
    WCHAR[MIXER_SHORT_NAME_CHARS] szShortName = 0;
    WCHAR[MIXER_LONG_NAME_CHARS] szName = 0;
    struct _Target {
        DWORD dwType;
        DWORD dwDeviceID;
        WORD wMid;
        WORD wPid;
        MMVERSION vDriverVersion;
        WCHAR[MAXPNAMELEN] szPname = 0;
    }
    _Target Target;
}
alias MIXERLINEW* PMIXERLINEW, LPMIXERLINEW;

struct MIXERCONTROLA {
    DWORD cbStruct;
    DWORD dwControlID;
    DWORD dwControlType;
    DWORD fdwControl;
    DWORD cMultipleItems;
    CHAR[MIXER_SHORT_NAME_CHARS] szShortName = 0;
    CHAR[MIXER_LONG_NAME_CHARS] szName = 0;
    union _Bounds {
        struct {
            LONG lMinimum;
            LONG lMaximum;
        }
        struct {
            DWORD dwMinimum;
            DWORD dwMaximum;
        }
        DWORD[6] dwReserved;
    }
    _Bounds Bounds;
    union _Metrics {
        DWORD cSteps;
        DWORD cbCustomData;
        DWORD[6] dwReserved;
    }
    _Metrics Metrics;
}
alias MIXERCONTROLA* PMIXERCONTROLA, LPMIXERCONTROLA;

struct MIXERCONTROLW {
    DWORD cbStruct;
    DWORD dwControlID;
    DWORD dwControlType;
    DWORD fdwControl;
    DWORD cMultipleItems;
    WCHAR[MIXER_SHORT_NAME_CHARS] szShortName = 0;
    WCHAR[MIXER_LONG_NAME_CHARS] szName = 0;
    union _Bounds {
        struct {
            LONG lMinimum;
            LONG lMaximum;
        }
        struct {
            DWORD dwMinimum;
            DWORD dwMaximum;
        }
        DWORD[6] dwReserved;
    }
    _Bounds Bounds;
    union _Metrics {
        DWORD cSteps;
        DWORD cbCustomData;
        DWORD[6] dwReserved;
    }
    _Metrics Metrics;
}

alias MIXERCONTROLW* PMIXERCONTROLW, LPMIXERCONTROLW;

struct MIXERLINECONTROLSA {
align(1):
    DWORD cbStruct;
    DWORD dwLineID;
    union {
        DWORD dwControlID;
        DWORD dwControlType;
    }
    DWORD cControls;
    DWORD cbmxctrl;
    LPMIXERCONTROLA pamxctrl;
}
alias MIXERLINECONTROLSA* PMIXERLINECONTROLSA, LPMIXERLINECONTROLSA;

struct MIXERLINECONTROLSW {
align(1):
    DWORD cbStruct;
    DWORD dwLineID;
    union {
        DWORD dwControlID;
        DWORD dwControlType;
    }
    DWORD cControls;
    DWORD cbmxctrl;
    LPMIXERCONTROLW pamxctrl;
}
alias MIXERLINECONTROLSW* PMIXERLINECONTROLSW, LPMIXERLINECONTROLSW;

struct MIXERCONTROLDETAILS {
align(1):
    DWORD cbStruct;
    DWORD dwControlID;
    DWORD cChannels;
    union {
        HWND hwndOwner;
        DWORD cMultipleItems;
    }
    DWORD cbDetails;
    PVOID paDetails;
}
alias MIXERCONTROLDETAILS* PMIXERCONTROLDETAILS, LPMIXERCONTROLDETAILS;

struct MIXERCONTROLDETAILS_LISTTEXTA {
    DWORD dwParam1;
    DWORD dwParam2;
    CHAR[MIXER_LONG_NAME_CHARS] szName = 0;
}
alias MIXERCONTROLDETAILS_LISTTEXTA* PMIXERCONTROLDETAILS_LISTTEXTA, LPMIXERCONTROLDETAILS_LISTTEXTA;

struct MIXERCONTROLDETAILS_LISTTEXTW {
    DWORD dwParam1;
    DWORD dwParam2;
    WCHAR[MIXER_LONG_NAME_CHARS] szName = 0;
}
alias MIXERCONTROLDETAILS_LISTTEXTW* PMIXERCONTROLDETAILS_LISTTEXTW, LPMIXERCONTROLDETAILS_LISTTEXTW;

struct MIXERCONTROLDETAILS_BOOLEAN {
    LONG fValue;
}
alias MIXERCONTROLDETAILS_BOOLEAN* PMIXERCONTROLDETAILS_BOOLEAN, LPMIXERCONTROLDETAILS_BOOLEAN;

struct MIXERCONTROLDETAILS_SIGNED {
    LONG lValue;
}
alias MIXERCONTROLDETAILS_SIGNED* PMIXERCONTROLDETAILS_SIGNED, LPMIXERCONTROLDETAILS_SIGNED;

struct MIXERCONTROLDETAILS_UNSIGNED {
    DWORD dwValue;
}
alias MIXERCONTROLDETAILS_UNSIGNED* PMIXERCONTROLDETAILS_UNSIGNED, LPMIXERCONTROLDETAILS_UNSIGNED;

alias void function (UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR) LPTIMECALLBACK;

struct TIMECAPS {
    UINT wPeriodMin;
    UINT wPeriodMax;
}
alias TIMECAPS* PTIMECAPS, LPTIMECAPS;

struct JOYCAPSA {
    WORD wMid;
    WORD wPid;
    CHAR[MAXPNAMELEN] szPname = 0;
    UINT wXmin;
    UINT wXmax;
    UINT wYmin;
    UINT wYmax;
    UINT wZmin;
    UINT wZmax;
    UINT wNumButtons;
    UINT wPeriodMin;
    UINT wPeriodMax;
    UINT wRmin;
    UINT wRmax;
    UINT wUmin;
    UINT wUmax;
    UINT wVmin;
    UINT wVmax;
    UINT wCaps;
    UINT wMaxAxes;
    UINT wNumAxes;
    UINT wMaxButtons;
    CHAR[MAXPNAMELEN] szRegKey = 0;
    CHAR[MAX_JOYSTICKOEMVXDNAME] szOEMVxD = 0;
}
alias JOYCAPSA* PJOYCAPSA, LPJOYCAPSA;

struct JOYCAPSW {
    WORD wMid;
    WORD wPid;
    WCHAR[MAXPNAMELEN] szPname = 0;
    UINT wXmin;
    UINT wXmax;
    UINT wYmin;
    UINT wYmax;
    UINT wZmin;
    UINT wZmax;
    UINT wNumButtons;
    UINT wPeriodMin;
    UINT wPeriodMax;
    UINT wRmin;
    UINT wRmax;
    UINT wUmin;
    UINT wUmax;
    UINT wVmin;
    UINT wVmax;
    UINT wCaps;
    UINT wMaxAxes;
    UINT wNumAxes;
    UINT wMaxButtons;
    WCHAR[MAXPNAMELEN] szRegKey = 0;
    WCHAR[MAX_JOYSTICKOEMVXDNAME] szOEMVxD = 0;
}
alias JOYCAPSW* PJOYCAPSW, LPJOYCAPSW;

struct JOYINFO {
    UINT wXpos;
    UINT wYpos;
    UINT wZpos;
    UINT wButtons;
}
alias JOYINFO* PJOYINFO, LPJOYINFO;

struct JOYINFOEX {
    DWORD dwSize;
    DWORD dwFlags;
    DWORD dwXpos;
    DWORD dwYpos;
    DWORD dwZpos;
    DWORD dwRpos;
    DWORD dwUpos;
    DWORD dwVpos;
    DWORD dwButtons;
    DWORD dwButtonNumber;
    DWORD dwPOV;
    DWORD dwReserved1;
    DWORD dwReserved2;
}
alias JOYINFOEX* PJOYINFOEX, LPJOYINFOEX;

alias DWORD FOURCC;
alias char* HPSTR;

alias TypeDef!(HANDLE) HMMIO;

alias LRESULT function (LPSTR, UINT, LPARAM, LPARAM) LPMMIOPROC;

struct MMIOINFO {
align(1):
    DWORD dwFlags;
    FOURCC fccIOProc;
    LPMMIOPROC pIOProc;
    UINT wErrorRet;
    HTASK htask;
    LONG cchBuffer;
    HPSTR pchBuffer;
    HPSTR pchNext;
    HPSTR pchEndRead;
    HPSTR pchEndWrite;
    LONG lBufOffset;
    LONG lDiskOffset;
    DWORD[3] adwInfo;
    DWORD dwReserved1;
    DWORD dwReserved2;
    HMMIO hmmio;
}
alias MMIOINFO* PMMIOINFO, LPMMIOINFO;
alias const(MMIOINFO)* LPCMMIOINFO;

struct MMCKINFO {
    FOURCC ckid;
    DWORD cksize;
    FOURCC fccType;
    DWORD dwDataOffset;
    DWORD dwFlags;
}
alias MMCKINFO* PMMCKINFO, LPMMCKINFO;
alias const(MMCKINFO)* LPCMMCKINFO;

struct MCI_GENERIC_PARMS {
    DWORD_PTR dwCallback;
}
alias MCI_GENERIC_PARMS* PMCI_GENERIC_PARMS, LPMCI_GENERIC_PARMS;

struct MCI_OPEN_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCSTR lpstrDeviceType;
    LPCSTR lpstrElementName;
    LPCSTR lpstrAlias;
}
alias MCI_OPEN_PARMSA* PMCI_OPEN_PARMSA, LPMCI_OPEN_PARMSA;

struct MCI_OPEN_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCWSTR lpstrDeviceType;
    LPCWSTR lpstrElementName;
    LPCWSTR lpstrAlias;
}
alias MCI_OPEN_PARMSW* PMCI_OPEN_PARMSW, LPMCI_OPEN_PARMSW;

struct MCI_PLAY_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrom;
    DWORD dwTo;
}
alias MCI_PLAY_PARMS* PMCI_PLAY_PARMS, LPMCI_PLAY_PARMS;

struct MCI_SEEK_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwTo;
}
alias MCI_SEEK_PARMS* PMCI_SEEK_PARMS, LPMCI_SEEK_PARMS;

struct MCI_STATUS_PARMS {
    DWORD_PTR dwCallback;
    DWORD_PTR dwReturn;
    DWORD dwItem;
    DWORD dwTrack;
}
alias MCI_STATUS_PARMS* PMCI_STATUS_PARMS, LPMCI_STATUS_PARMS;

struct MCI_INFO_PARMSA {
    DWORD_PTR dwCallback;
    LPSTR lpstrReturn;
    DWORD dwRetSize;
}
alias MCI_INFO_PARMSA* LPMCI_INFO_PARMSA;

struct MCI_INFO_PARMSW {
    DWORD_PTR dwCallback;
    LPWSTR lpstrReturn;
    DWORD dwRetSize;
}
alias MCI_INFO_PARMSW* LPMCI_INFO_PARMSW;

struct MCI_GETDEVCAPS_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwReturn;
    DWORD dwItem;
}
alias MCI_GETDEVCAPS_PARMS* PMCI_GETDEVCAPS_PARMS, LPMCI_GETDEVCAPS_PARMS;

struct MCI_SYSINFO_PARMSA {
    DWORD_PTR dwCallback;
    LPSTR lpstrReturn;
    DWORD dwRetSize;
    DWORD dwNumber;
    UINT wDeviceType;
}
alias MCI_SYSINFO_PARMSA* PMCI_SYSINFO_PARMSA, LPMCI_SYSINFO_PARMSA;

struct MCI_SYSINFO_PARMSW {
    DWORD_PTR dwCallback;
    LPWSTR lpstrReturn;
    DWORD dwRetSize;
    DWORD dwNumber;
    UINT wDeviceType;
}
alias MCI_SYSINFO_PARMSW* PMCI_SYSINFO_PARMSW, LPMCI_SYSINFO_PARMSW;

struct MCI_SET_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwTimeFormat;
    DWORD dwAudio;
}
alias MCI_SET_PARMS* PMCI_SET_PARMS, LPMCI_SET_PARMS;

struct MCI_BREAK_PARMS {
align(1):
    DWORD_PTR dwCallback;
    int nVirtKey;
    HWND hwndBreak;
}
alias MCI_BREAK_PARMS* PMCI_BREAK_PARMS, LPMCI_BREAK_PARMS;

struct MCI_SAVE_PARMSA {
    DWORD_PTR dwCallback;
    LPCSTR lpfilename;
}
alias MCI_SAVE_PARMSA* PMCI_SAVE_PARMSA, LPMCI_SAVE_PARMSA;

struct MCI_SAVE_PARMSW {
    DWORD_PTR dwCallback;
    LPCWSTR lpfilename;
}
alias MCI_SAVE_PARMSW* PMCI_SAVE_PARMSW, LPMCI_SAVE_PARMSW;

struct MCI_LOAD_PARMSA {
    DWORD_PTR dwCallback;
    LPCSTR lpfilename;
}
alias MCI_LOAD_PARMSA* PMCI_LOAD_PARMSA, LPMCI_LOAD_PARMSA;

struct MCI_LOAD_PARMSW {
    DWORD_PTR dwCallback;
    LPCWSTR lpfilename;
}
alias MCI_LOAD_PARMSW* PMCI_LOAD_PARMSW, LPMCI_LOAD_PARMSW;

struct MCI_RECORD_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrom;
    DWORD dwTo;
}
alias MCI_RECORD_PARMS* LPMCI_RECORD_PARMS;

struct MCI_VD_PLAY_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrom;
    DWORD dwTo;
    DWORD dwSpeed;
}
alias MCI_VD_PLAY_PARMS* PMCI_VD_PLAY_PARMS, LPMCI_VD_PLAY_PARMS;

struct MCI_VD_STEP_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrames;
}
alias MCI_VD_STEP_PARMS* PMCI_VD_STEP_PARMS, LPMCI_VD_STEP_PARMS;

struct MCI_VD_ESCAPE_PARMSA {
    DWORD_PTR dwCallback;
    LPCSTR lpstrCommand;
}
alias MCI_VD_ESCAPE_PARMSA* PMCI_VD_ESCAPE_PARMSA, LPMCI_VD_ESCAPE_PARMSA;

struct MCI_VD_ESCAPE_PARMSW {
    DWORD_PTR dwCallback;
    LPCWSTR lpstrCommand;
}
alias MCI_VD_ESCAPE_PARMSW* PMCI_VD_ESCAPE_PARMSW, LPMCI_VD_ESCAPE_PARMSW;

struct MCI_WAVE_OPEN_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCSTR lpstrDeviceType;
    LPCSTR lpstrElementName;
    LPCSTR lpstrAlias;
    DWORD dwBufferSeconds;
}
alias MCI_WAVE_OPEN_PARMSA* PMCI_WAVE_OPEN_PARMSA, LPMCI_WAVE_OPEN_PARMSA;

struct MCI_WAVE_OPEN_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCWSTR lpstrDeviceType;
    LPCWSTR lpstrElementName;
    LPCWSTR lpstrAlias;
    DWORD dwBufferSeconds;
}
alias MCI_WAVE_OPEN_PARMSW* PMCI_WAVE_OPEN_PARMSW, LPMCI_WAVE_OPEN_PARMSW;

struct MCI_WAVE_DELETE_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrom;
    DWORD dwTo;
}
alias MCI_WAVE_DELETE_PARMS* PMCI_WAVE_DELETE_PARMS, LPMCI_WAVE_DELETE_PARMS;

struct MCI_WAVE_SET_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwTimeFormat;
    DWORD dwAudio;
    UINT wInput;
    UINT wOutput;
    WORD wFormatTag;
    WORD wReserved2;
    WORD nChannels;
    WORD wReserved3;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD nBlockAlign;
    WORD wReserved4;
    WORD wBitsPerSample;
    WORD wReserved5;
}
alias MCI_WAVE_SET_PARMS* PMCI_WAVE_SET_PARMS, LPMCI_WAVE_SET_PARMS;

extern (Windows) nothrow @nogc:
LRESULT CloseDriver(HDRVR, LONG, LONG);
HDRVR OpenDriver(LPCWSTR, LPCWSTR, LONG);
LRESULT SendDriverMessage(HDRVR, UINT, LONG, LONG);
HMODULE DrvGetModuleHandle(HDRVR);
HMODULE GetDriverModuleHandle(HDRVR);
LRESULT DefDriverProc(DWORD_PTR, HDRVR, UINT, LPARAM, LPARAM);
UINT mmsystemGetVersion();
// FIXME: I believe this next line is a mistake
//alias OutputDebugString OutputDebugStr;
BOOL sndPlaySoundA(LPCSTR, UINT);
BOOL sndPlaySoundW(LPCWSTR, UINT);
BOOL PlaySoundA(LPCSTR, HMODULE, DWORD);
BOOL PlaySoundW(LPCWSTR, HMODULE, DWORD);
UINT waveOutGetNumDevs();
MMRESULT waveOutGetDevCapsA(UINT_PTR, LPWAVEOUTCAPSA, UINT);
MMRESULT waveOutGetDevCapsW(UINT_PTR, LPWAVEOUTCAPSW, UINT);
MMRESULT waveOutGetVolume(HWAVEOUT, PDWORD);
MMRESULT waveOutSetVolume(HWAVEOUT, DWORD);
MMRESULT waveOutGetErrorTextA(MMRESULT, LPSTR, UINT);
MMRESULT waveOutGetErrorTextW(MMRESULT, LPWSTR, UINT);
MMRESULT waveOutOpen(LPHWAVEOUT, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT waveOutClose(HWAVEOUT);
MMRESULT waveOutPrepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
MMRESULT waveOutUnprepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
MMRESULT waveOutWrite(HWAVEOUT, LPWAVEHDR, UINT);
MMRESULT waveOutPause(HWAVEOUT);
MMRESULT waveOutRestart(HWAVEOUT);
MMRESULT waveOutReset(HWAVEOUT);
MMRESULT waveOutBreakLoop(HWAVEOUT);
MMRESULT waveOutGetPosition(HWAVEOUT, LPMMTIME, UINT);
MMRESULT waveOutGetPitch(HWAVEOUT, PDWORD);
MMRESULT waveOutSetPitch(HWAVEOUT, DWORD);
MMRESULT waveOutGetPlaybackRate(HWAVEOUT, PDWORD);
MMRESULT waveOutSetPlaybackRate(HWAVEOUT, DWORD);
MMRESULT waveOutGetID(HWAVEOUT, LPUINT);
MMRESULT waveOutMessage(HWAVEOUT, UINT, DWORD_PTR, DWORD_PTR);
UINT waveInGetNumDevs();
MMRESULT waveInGetDevCapsA(UINT_PTR, LPWAVEINCAPSA, UINT);
MMRESULT waveInGetDevCapsW(UINT_PTR, LPWAVEINCAPSW, UINT);
MMRESULT waveInGetErrorTextA(MMRESULT, LPSTR, UINT);
MMRESULT waveInGetErrorTextW(MMRESULT, LPWSTR, UINT);
MMRESULT waveInOpen(LPHWAVEIN, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT waveInClose(HWAVEIN);
MMRESULT waveInPrepareHeader(HWAVEIN, LPWAVEHDR, UINT);
MMRESULT waveInUnprepareHeader(HWAVEIN, LPWAVEHDR, UINT);
MMRESULT waveInAddBuffer(HWAVEIN, LPWAVEHDR, UINT);
MMRESULT waveInStart(HWAVEIN);
MMRESULT waveInStop(HWAVEIN);
MMRESULT waveInReset(HWAVEIN);
MMRESULT waveInGetPosition(HWAVEIN, LPMMTIME, UINT);
MMRESULT waveInGetID(HWAVEIN, LPUINT);
MMRESULT waveInMessage(HWAVEIN, UINT, DWORD_PTR, DWORD_PTR);
UINT midiOutGetNumDevs();
MMRESULT midiStreamOpen(LPHMIDISTRM, LPUINT, DWORD, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT midiStreamClose(HMIDISTRM);
MMRESULT midiStreamProperty(HMIDISTRM, LPBYTE, DWORD);
MMRESULT midiStreamPosition(HMIDISTRM, LPMMTIME, UINT);
MMRESULT midiStreamOut(HMIDISTRM, LPMIDIHDR, UINT);
MMRESULT midiStreamPause(HMIDISTRM);
MMRESULT midiStreamRestart(HMIDISTRM);
MMRESULT midiStreamStop(HMIDISTRM);
MMRESULT midiConnect(HMIDI, HMIDIOUT, PVOID);
MMRESULT midiDisconnect(HMIDI, HMIDIOUT, PVOID);
MMRESULT midiOutGetDevCapsA(UINT_PTR, LPMIDIOUTCAPSA, UINT);
MMRESULT midiOutGetDevCapsW(UINT_PTR, LPMIDIOUTCAPSW, UINT);
MMRESULT midiOutGetVolume(HMIDIOUT, PDWORD);
MMRESULT midiOutSetVolume(HMIDIOUT, DWORD);
MMRESULT midiOutGetErrorTextA(MMRESULT, LPSTR, UINT);
MMRESULT midiOutGetErrorTextW(MMRESULT, LPWSTR, UINT);
MMRESULT midiOutOpen(LPHMIDIOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT midiOutClose(HMIDIOUT);
MMRESULT midiOutPrepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
MMRESULT midiOutUnprepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
MMRESULT midiOutShortMsg(HMIDIOUT, DWORD);
MMRESULT midiOutLongMsg(HMIDIOUT, LPMIDIHDR, UINT);
MMRESULT midiOutReset(HMIDIOUT);
MMRESULT midiOutCachePatches(HMIDIOUT, UINT, LPWORD, UINT);
MMRESULT midiOutCacheDrumPatches(HMIDIOUT, UINT, LPWORD, UINT);
MMRESULT midiOutGetID(HMIDIOUT, LPUINT);
MMRESULT midiOutMessage(HMIDIOUT, UINT, DWORD_PTR, DWORD_PTR);
UINT midiInGetNumDevs();
MMRESULT midiInGetDevCapsA(UINT_PTR, LPMIDIINCAPSA, UINT);
MMRESULT midiInGetDevCapsW(UINT_PTR, LPMIDIINCAPSW, UINT);
MMRESULT midiInGetErrorTextA(MMRESULT, LPSTR, UINT);
MMRESULT midiInGetErrorTextW(MMRESULT, LPWSTR, UINT);
MMRESULT midiInOpen(LPHMIDIIN, UINT, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT midiInClose(HMIDIIN);
MMRESULT midiInPrepareHeader(HMIDIIN, LPMIDIHDR, UINT);
MMRESULT midiInUnprepareHeader(HMIDIIN, LPMIDIHDR, UINT);
MMRESULT midiInAddBuffer(HMIDIIN, LPMIDIHDR, UINT);
MMRESULT midiInStart(HMIDIIN);
MMRESULT midiInStop(HMIDIIN);
MMRESULT midiInReset(HMIDIIN);
MMRESULT midiInGetID(HMIDIIN, LPUINT);
MMRESULT midiInMessage(HMIDIIN, UINT, DWORD_PTR, DWORD_PTR);
UINT auxGetNumDevs();
MMRESULT auxGetDevCapsA(UINT_PTR, LPAUXCAPSA, UINT);
MMRESULT auxGetDevCapsW(UINT_PTR, LPAUXCAPSW, UINT);
MMRESULT auxSetVolume(UINT, DWORD);
MMRESULT auxGetVolume(UINT, PDWORD);
MMRESULT auxOutMessage(UINT, UINT, DWORD_PTR, DWORD_PTR);
UINT mixerGetNumDevs();
MMRESULT mixerGetDevCapsA(UINT_PTR, LPMIXERCAPSA, UINT);
MMRESULT mixerGetDevCapsW(UINT_PTR, LPMIXERCAPSW, UINT);
MMRESULT mixerOpen(LPHMIXER, UINT, DWORD_PTR, DWORD_PTR, DWORD);
MMRESULT mixerClose(HMIXER);
DWORD mixerMessage(HMIXER, UINT, DWORD_PTR, DWORD_PTR);
MMRESULT mixerGetLineInfoA(HMIXEROBJ, LPMIXERLINEA, DWORD);
MMRESULT mixerGetLineInfoW(HMIXEROBJ, LPMIXERLINEW, DWORD);
MMRESULT mixerGetID(HMIXEROBJ, PUINT, DWORD);
MMRESULT mixerGetLineControlsA(HMIXEROBJ, LPMIXERLINECONTROLSA, DWORD);
MMRESULT mixerGetLineControlsW(HMIXEROBJ, LPMIXERLINECONTROLSW, DWORD);
MMRESULT mixerGetControlDetailsA(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);
MMRESULT mixerGetControlDetailsW(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);
MMRESULT mixerSetControlDetails(HMIXEROBJ, LPMIXERCONTROLDETAILS, DWORD);
MMRESULT timeGetSystemTime(LPMMTIME, UINT);
DWORD timeGetTime();
MMRESULT timeSetEvent(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT);
MMRESULT timeKillEvent(UINT);
MMRESULT timeGetDevCaps(LPTIMECAPS, UINT);
MMRESULT timeBeginPeriod(UINT);
MMRESULT timeEndPeriod(UINT);
UINT joyGetNumDevs();
MMRESULT joyGetDevCapsA(UINT_PTR, LPJOYCAPSA, UINT);
MMRESULT joyGetDevCapsW(UINT_PTR, LPJOYCAPSW, UINT);
MMRESULT joyGetPos(UINT, LPJOYINFO);
MMRESULT joyGetPosEx(UINT, LPJOYINFOEX);
MMRESULT joyGetThreshold(UINT, LPUINT);
MMRESULT joyReleaseCapture(UINT);
MMRESULT joySetCapture(HWND, UINT, UINT, BOOL);
MMRESULT joySetThreshold(UINT, UINT);
FOURCC mmioStringToFOURCCA(LPCSTR, UINT);
FOURCC mmioStringToFOURCCW(LPCWSTR, UINT);
LPMMIOPROC mmioInstallIOProcA(FOURCC, LPMMIOPROC, DWORD);
LPMMIOPROC mmioInstallIOProcW(FOURCC, LPMMIOPROC, DWORD);
HMMIO mmioOpenA(LPSTR, LPMMIOINFO, DWORD);
HMMIO mmioOpenW(LPWSTR, LPMMIOINFO, DWORD);
MMRESULT mmioRenameA(LPCSTR, LPCSTR, LPCMMIOINFO, DWORD);
MMRESULT mmioRenameW(LPCWSTR, LPCWSTR, LPCMMIOINFO, DWORD);
MMRESULT mmioClose(HMMIO, UINT);
LONG mmioRead(HMMIO, HPSTR, LONG);
LONG mmioWrite(HMMIO, LPCSTR, LONG);
LONG mmioSeek(HMMIO, LONG, int);
MMRESULT mmioGetInfo(HMMIO, LPMMIOINFO, UINT);
MMRESULT mmioSetInfo(HMMIO, LPCMMIOINFO, UINT);
MMRESULT mmioSetBuffer(HMMIO, LPSTR, LONG, UINT);
MMRESULT mmioFlush(HMMIO, UINT);
MMRESULT mmioAdvance(HMMIO, LPMMIOINFO, UINT);
LRESULT mmioSendMessage(HMMIO, UINT, LPARAM, LPARAM);
MMRESULT mmioDescend(HMMIO, LPMMCKINFO, const(MMCKINFO)*, UINT);
MMRESULT mmioAscend(HMMIO, LPMMCKINFO, UINT);
MMRESULT mmioCreateChunk(HMMIO, LPMMCKINFO, UINT);
MCIERROR mciSendCommandA(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR);
MCIERROR mciSendCommandW(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR);
MCIERROR mciSendStringA(LPCSTR, LPSTR, UINT, HWND);
MCIERROR mciSendStringW(LPCWSTR, LPWSTR, UINT, HWND);
MCIDEVICEID mciGetDeviceIDA(LPCSTR);
MCIDEVICEID mciGetDeviceIDW(LPCWSTR);
MCIDEVICEID mciGetDeviceIDFromElementIDA(DWORD, LPCSTR);
MCIDEVICEID mciGetDeviceIDFromElementIDW(DWORD, LPCWSTR);
BOOL mciGetErrorStringA(MCIERROR, LPSTR, UINT);
BOOL mciGetErrorStringW(MCIERROR, LPWSTR, UINT);
BOOL mciSetYieldProc(MCIDEVICEID, YIELDPROC, DWORD);
HTASK mciGetCreatorTask(MCIDEVICEID);
YIELDPROC mciGetYieldProc(MCIDEVICEID, PDWORD);

struct MCI_SEQ_SET_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwTimeFormat;
    DWORD dwAudio;
    DWORD dwTempo;
    DWORD dwPort;
    DWORD dwSlave;
    DWORD dwMaster;
    DWORD dwOffset;
}
alias MCI_SEQ_SET_PARMS* PMCI_SEQ_SET_PARMS, LPMCI_SEQ_SET_PARMS;

struct MCI_ANIM_OPEN_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCSTR lpstrDeviceType;
    LPCSTR lpstrElementName;
    LPCSTR lpstrAlias;
    DWORD dwStyle;
    HWND hWndParent;
}
alias MCI_ANIM_OPEN_PARMSA* PMCI_ANIM_OPEN_PARMSA, LPMCI_ANIM_OPEN_PARMSA;

struct MCI_ANIM_OPEN_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCWSTR lpstrDeviceType;
    LPCWSTR lpstrElementName;
    LPCWSTR lpstrAlias;
    DWORD dwStyle;
    HWND hWndParent;
}
alias MCI_ANIM_OPEN_PARMSW* PMCI_ANIM_OPEN_PARMSW, LPMCI_ANIM_OPEN_PARMSW;

struct MCI_ANIM_PLAY_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrom;
    DWORD dwTo;
    DWORD dwSpeed;
}
alias MCI_ANIM_PLAY_PARMS* PMCI_ANIM_PLAY_PARMS, LPMCI_ANIM_PLAY_PARMS;

struct MCI_ANIM_STEP_PARMS {
    DWORD_PTR dwCallback;
    DWORD dwFrames;
}
alias MCI_ANIM_STEP_PARMS* PMCI_ANIM_STEP_PARMS, LPMCI_ANIM_STEP_PARMS;

struct MCI_ANIM_WINDOW_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    HWND hWnd;
    UINT nCmdShow;
    LPCSTR lpstrText;
}
alias MCI_ANIM_WINDOW_PARMSA* PMCI_ANIM_WINDOW_PARMSA, LPMCI_ANIM_WINDOW_PARMSA;

struct MCI_ANIM_WINDOW_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    HWND hWnd;
    UINT nCmdShow;
    LPCWSTR lpstrText;
}
alias MCI_ANIM_WINDOW_PARMSW* PMCI_ANIM_WINDOW_PARMSW, LPMCI_ANIM_WINDOW_PARMSW;

struct MCI_ANIM_RECT_PARMS {
    DWORD_PTR dwCallback;
    //#ifdef MCI_USE_OFFEXT
    //  POINT ptOffset;
    //  POINT ptExtent;
    //#else
    RECT rc;
    //#endif
}
alias MCI_ANIM_RECT_PARMS* PMCI_ANIM_RECT_PARMS, LPMCI_ANIM_RECT_PARMS;

struct MCI_ANIM_UPDATE_PARMS {
    DWORD_PTR dwCallback;
    RECT rc;
    HDC hDC;
}
alias MCI_ANIM_UPDATE_PARMS* PMCI_ANIM_UPDATE_PARMS, LPMCI_ANIM_UPDATE_PARMS;

struct MCI_OVLY_OPEN_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCSTR lpstrDeviceType;
    LPCSTR lpstrElementName;
    LPCSTR lpstrAlias;
    DWORD dwStyle;
    HWND hWndParent;
}
alias MCI_OVLY_OPEN_PARMSA* PMCI_OVLY_OPEN_PARMSA, LPMCI_OVLY_OPEN_PARMSA;

struct MCI_OVLY_OPEN_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    MCIDEVICEID wDeviceID;
    LPCWSTR lpstrDeviceType;
    LPCWSTR lpstrElementName;
    LPCWSTR lpstrAlias;
    DWORD dwStyle;
    HWND hWndParent;
}
alias MCI_OVLY_OPEN_PARMSW* PMCI_OVLY_OPEN_PARMSW, LPMCI_OVLY_OPEN_PARMSW;

struct MCI_OVLY_WINDOW_PARMSA {
align(1):
    DWORD_PTR dwCallback;
    HWND hWnd;
    UINT nCmdShow;
    LPCSTR lpstrText;
}
alias MCI_OVLY_WINDOW_PARMSA* PMCI_OVLY_WINDOW_PARMSA, LPMCI_OVLY_WINDOW_PARMSA;

struct MCI_OVLY_WINDOW_PARMSW {
align(1):
    DWORD_PTR dwCallback;
    HWND hWnd;
    UINT nCmdShow;
    LPCWSTR lpstrText;
}
alias MCI_OVLY_WINDOW_PARMSW* PMCI_OVLY_WINDOW_PARMSW, LPMCI_OVLY_WINDOW_PARMSW;

struct MCI_OVLY_RECT_PARMS {
    DWORD_PTR dwCallback;
    //#ifdef MCI_USE_OFFEXT
    //  POINT ptOffset;
    //  POINT ptExtent;
    //#else
    RECT rc;
    //#endif
}
alias MCI_OVLY_RECT_PARMS* PMCI_OVLY_RECT_PARMS, LPMCI_OVLY_RECT_PARMS;

struct MCI_OVLY_SAVE_PARMSA {
    DWORD_PTR dwCallback;
    LPCSTR lpfilename;
    RECT rc;
}
alias MCI_OVLY_SAVE_PARMSA* PMCI_OVLY_SAVE_PARMSA, LPMCI_OVLY_SAVE_PARMSA;

struct MCI_OVLY_SAVE_PARMSW {
    DWORD_PTR dwCallback;
    LPCWSTR lpfilename;
    RECT rc;
}
alias MCI_OVLY_SAVE_PARMSW* PMCI_OVLY_SAVE_PARMSW, LPMCI_OVLY_SAVE_PARMSW;

struct MCI_OVLY_LOAD_PARMSA {
    DWORD_PTR dwCallback;
    LPCSTR lpfilename;
    RECT rc;
}
alias MCI_OVLY_LOAD_PARMSA* PMCI_OVLY_LOAD_PARMSA, LPMCI_OVLY_LOAD_PARMSA;

struct MCI_OVLY_LOAD_PARMSW {
    DWORD_PTR dwCallback;
    LPCWSTR lpfilename;
    RECT rc;
}
alias MCI_OVLY_LOAD_PARMSW* PMCI_OVLY_LOAD_PARMSW, LPMCI_OVLY_LOAD_PARMSW;

version (Unicode) {
    alias WAVEOUTCAPSW WAVEOUTCAPS;
    alias WAVEINCAPSW WAVEINCAPS;
    alias MIDIOUTCAPSW MIDIOUTCAPS;
    alias MIDIINCAPSW MIDIINCAPS;
    alias AUXCAPSW AUXCAPS;
    alias MIXERCAPSW MIXERCAPS;
    alias MIXERLINEW MIXERLINE;
    alias MIXERCONTROLA MIXERCONTROL;
    alias MIXERLINECONTROLSW MIXERLINECONTROLS;
    alias MIXERCONTROLDETAILS_LISTTEXTW MIXERCONTROLDETAILS_LISTTEXT;
    alias JOYCAPSW JOYCAPS;
    alias MCI_OPEN_PARMSW MCI_OPEN_PARMS;
    alias MCI_INFO_PARMSW MCI_INFO_PARMS;
    alias MCI_SYSINFO_PARMSW MCI_SYSINFO_PARMS;
    alias MCI_SAVE_PARMSW MCI_SAVE_PARMS;
    alias MCI_LOAD_PARMSW MCI_LOAD_PARMS;
    alias MCI_VD_ESCAPE_PARMSW MCI_VD_ESCAPE_PARMS;
    alias MCI_WAVE_OPEN_PARMSW MCI_WAVE_OPEN_PARMS;
    alias MCI_ANIM_OPEN_PARMSW MCI_ANIM_OPEN_PARMS;
    alias MCI_ANIM_WINDOW_PARMSW MCI_ANIM_WINDOW_PARMS;
    alias MCI_OVLY_OPEN_PARMSW MCI_OVLY_OPEN_PARMS;
    alias MCI_OVLY_WINDOW_PARMSW MCI_OVLY_WINDOW_PARMS;
    alias MCI_OVLY_SAVE_PARMSW MCI_OVLY_SAVE_PARMS;

    alias sndPlaySoundW sndPlaySound;
    alias PlaySoundW PlaySound;
    alias waveOutGetDevCapsW waveOutGetDevCaps;
    alias waveOutGetErrorTextW waveOutGetErrorText;
    alias waveInGetDevCapsW waveInGetDevCaps;
    alias waveInGetErrorTextW waveInGetErrorText;
    alias midiOutGetDevCapsW midiOutGetDevCaps;
    alias midiOutGetErrorTextW midiOutGetErrorText;
    alias midiInGetDevCapsW midiInGetDevCaps;
    alias midiInGetErrorTextW midiInGetErrorText;
    alias auxGetDevCapsW auxGetDevCaps;
    alias mixerGetDevCapsW mixerGetDevCaps;
    alias mixerGetLineInfoW mixerGetLineInfo;
    alias mixerGetLineControlsW mixerGetLineControls;
    alias mixerGetControlDetailsW mixerGetControlDetails;
    alias joyGetDevCapsW joyGetDevCaps;
    alias mmioInstallIOProcW mmioInstallIOProc;
    alias mmioStringToFOURCCW mmioStringToFOURCC;
    alias mmioOpenW mmioOpen;
    alias mmioRenameW mmioRename;
    alias mciSendCommandW mciSendCommand;
    alias mciSendStringW mciSendString;
    alias mciGetDeviceIDW mciGetDeviceID;
    alias mciGetDeviceIDFromElementIDW mciGetDeviceIDFromElementID;
    alias mciGetErrorStringW mciGetErrorString;

} else {
    alias WAVEOUTCAPSA WAVEOUTCAPS;
    alias WAVEINCAPSA WAVEINCAPS;
    alias MIDIOUTCAPSA MIDIOUTCAPS;
    alias MIDIINCAPSA MIDIINCAPS;
    alias AUXCAPSA AUXCAPS;
    alias MIXERCAPSA MIXERCAPS;
    alias MIXERLINEA MIXERLINE;
    alias MIXERCONTROLA MIXERCONTROL;
    alias MIXERLINECONTROLSA MIXERLINECONTROLS;
    alias MIXERCONTROLDETAILS_LISTTEXTA MIXERCONTROLDETAILS_LISTTEXT;
    alias JOYCAPSA JOYCAPS;
    alias MCI_OPEN_PARMSA MCI_OPEN_PARMS;
    alias MCI_INFO_PARMSA MCI_INFO_PARMS;
    alias MCI_SYSINFO_PARMSA MCI_SYSINFO_PARMS;
    alias MCI_SAVE_PARMSA MCI_SAVE_PARMS;
    alias MCI_LOAD_PARMSA MCI_LOAD_PARMS;
    alias MCI_VD_ESCAPE_PARMSA MCI_VD_ESCAPE_PARMS;
    alias MCI_WAVE_OPEN_PARMSA MCI_WAVE_OPEN_PARMS;
    alias MCI_ANIM_OPEN_PARMSA MCI_ANIM_OPEN_PARMS;
    alias MCI_ANIM_WINDOW_PARMSA MCI_ANIM_WINDOW_PARMS;
    alias MCI_OVLY_OPEN_PARMSA MCI_OVLY_OPEN_PARMS;
    alias MCI_OVLY_WINDOW_PARMSA MCI_OVLY_WINDOW_PARMS;
    alias MCI_OVLY_SAVE_PARMSA MCI_OVLY_SAVE_PARMS;

    alias sndPlaySoundA sndPlaySound;
    alias PlaySoundA PlaySound;
    alias waveOutGetDevCapsA waveOutGetDevCaps;
    alias waveOutGetErrorTextA waveOutGetErrorText;
    alias waveInGetDevCapsA waveInGetDevCaps;
    alias waveInGetErrorTextA waveInGetErrorText;
    alias midiOutGetDevCapsA midiOutGetDevCaps;
    alias midiOutGetErrorTextA midiOutGetErrorText;
    alias midiInGetDevCapsA midiInGetDevCaps;
    alias midiInGetErrorTextA midiInGetErrorText;
    alias auxGetDevCapsA auxGetDevCaps;
    alias mixerGetDevCapsA mixerGetDevCaps;
    alias mixerGetLineInfoA mixerGetLineInfo;
    alias mixerGetLineControlsA mixerGetLineControls;
    alias mixerGetControlDetailsA mixerGetControlDetails;
    alias joyGetDevCapsA joyGetDevCaps;
    alias mmioInstallIOProcA mmioInstallIOProc;
    alias mmioStringToFOURCCA mmioStringToFOURCC;
    alias mmioOpenA mmioOpen;
    alias mmioRenameA mmioRename;
    alias mciSendCommandA mciSendCommand;
    alias mciSendStringA mciSendString;
    alias mciGetDeviceIDA mciGetDeviceID;
    alias mciGetDeviceIDFromElementIDA mciGetDeviceIDFromElementID;
    alias mciGetErrorStringA mciGetErrorString;
}

alias WAVEOUTCAPS* PWAVEOUTCAPS, LPWAVEOUTCAPS;
alias WAVEINCAPS* PWAVEINCAPS, LPWAVEINCAPS;
alias MIDIOUTCAPS* PMIDIOUTCAPS, LPMIDIOUTCAPS;
alias MIDIINCAPS* PMIDIINCAPS, LPMIDIINCAPS;
alias AUXCAPS* PAUXCAPS, LPAUXCAPS;
alias MIXERCAPS* PMIXERCAPS, LPMIXERCAPS;
alias MIXERLINE* PMIXERLINE, LPMIXERLINE;
alias MIXERCONTROL* PMIXERCONTROL, LPMIXERCONTROL;
alias MIXERLINECONTROLS* PMIXERLINECONTROLS, LPMIXERLINECONTROLS;
alias MIXERCONTROLDETAILS_LISTTEXT* PMIXERCONTROLDETAILS_LISTTEXT, LPMIXERCONTROLDETAILS_LISTTEXT;
alias JOYCAPS* PJOYCAPS, LPJOYCAPS;
alias MCI_OPEN_PARMS* PMCI_OPEN_PARMS, LPMCI_OPEN_PARMS;
alias MCI_INFO_PARMS* LPMCI_INFO_PARMS;
alias MCI_SYSINFO_PARMS* PMCI_SYSINFO_PARMS, LPMCI_SYSINFO_PARMS;
alias MCI_SAVE_PARMS* PMCI_SAVE_PARMS, LPMCI_SAVE_PARMS;
alias MCI_LOAD_PARMS* PMCI_LOAD_PARMS, LPMCI_LOAD_PARMS;
alias MCI_VD_ESCAPE_PARMS* PMCI_VD_ESCAPE_PARMS, LPMCI_VD_ESCAPE_PARMS;
alias MCI_WAVE_OPEN_PARMS* PMCI_WAVE_OPEN_PARMS, LPMCI_WAVE_OPEN_PARMS;
alias MCI_ANIM_OPEN_PARMS* PMCI_ANIM_OPEN_PARMS, LPMCI_ANIM_OPEN_PARMS;
alias MCI_ANIM_WINDOW_PARMS* PMCI_ANIM_WINDOW_PARMS, LPMCI_ANIM_WINDOW_PARMS;
alias MCI_OVLY_OPEN_PARMS* PMCI_OVLY_OPEN_PARMS, LPMCI_OVLY_OPEN_PARMS;
alias MCI_OVLY_WINDOW_PARMS* PMCI_OVLY_WINDOW_PARMS, LPMCI_OVLY_WINDOW_PARMS;
alias MCI_OVLY_SAVE_PARMS* PMCI_OVLY_SAVE_PARMS, LPMCI_OVLY_SAVE_PARMS;
