' ########################################################################################
' Microsoft Windows
' File: MMSystem.inc
' Contents: Include file for Multimedia API's
' Version 4.00
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' 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.
' ########################################################################################
#IF NOT %DEF(PBX_MMSystem_PBI)
#DEFINE PBX_MMSystem_PBI
%EQUATE `MMSYSTEM_INC = 1
' *--------------------------------------------------------------------------
' *
' * Define: Prevent inclusion of:
' * -------------- --------------------------------------------------------
' * MMNODRV Installable driver support
' * MMNOSOUND Sound support
' * MMNOWAVE Waveform support
' * MMNOMIDI MIDI support
' * MMNOAUX Auxiliary audio support
' * MMNOMIXER Mixer support
' * MMNOTIMER Timer support
' * MMNOJOY Joystick support
' * MMNOMCI MCI support
' * MMNOMMIO Multimedia file I/O support
' *
' *==========================================================================
' */
'#ifdef _WIN32
'#include <pshpack1.h>
'#else
'#ifndef RC_INVOKED
'#pragma pack(1)
'#endif
'#endif
#INCLUDE ONCE "Core/Windows.inc"
'/****************************************************************************
' General constants and data types
'****************************************************************************/
'/* general constants */
%EQUATE `MAXPNAMELEN = 32 ' max product name length (including NULL)
%EQUATE `MAXERRORLENGTH = 256 ' max error text length (including final NULL)
%EQUATE `MAX_JOYSTICKOEMVXDNAME = 260
'/*
' * Microsoft Manufacturer and Product ID's (these have been moved to
' * MMREG.H for Windows 4.00 and above).
' */
#IF NOT %DEF(%MM_MICROSOFT)
%EQUATE `MM_MICROSOFT = 1 ' Microsoft Corporation
#ENDIF
#IF NOT %DEF(%MM_MIDI_MAPPER)
%EQUATE `MM_MIDI_MAPPER = 1 ' MIDI Mapper
%EQUATE `MM_WAVE_MAPPER = 2 ' Wave Mapper
%EQUATE `MM_SNDBLST_MIDIOUT = 3 ' Sound Blaster MIDI output port
%EQUATE `MM_SNDBLST_MIDIIN = 4 ' Sound Blaster MIDI input port
%EQUATE `MM_SNDBLST_SYNTH = 5 ' Sound Blaster internal synthesizer
%EQUATE `MM_SNDBLST_WAVEOUT = 6 ' Sound Blaster waveform output
%EQUATE `MM_SNDBLST_WAVEIN = 7 ' Sound Blaster waveform input
%EQUATE `MM_ADLIB = 9 ' Ad Lib-compatible synthesizer
%EQUATE `MM_MPU401_MIDIOUT = 10 ' MPU401-compatible MIDI output port
%EQUATE `MM_MPU401_MIDIIN = 11 ' MPU401-compatible MIDI input port
%EQUATE `MM_PC_JOYSTICK = 12 ' Joystick adapter
#ENDIF
'/* general data types */
'#ifdef _WIN32
'typedef UINT MMVERSION; /* major (high byte), minor (low byte) */
'#else
'typedef UINT VERSION; /* major (high byte), minor (low byte) */
'#endif
'typedef UINT MMRESULT; /* error return code, 0 means no error */
' /* call as if(err=xxxx(...)) Error(err); else */
'#define _MMRESULT_
'typedef UINT FAR *LPUINT;
'/* MMTIME data structure */
'typedef struct mmtime_tag
'{
' UINT wType; /* indicates the contents of the union */
' union
' {
' DWORD ms; /* milliseconds */
' DWORD sample; /* samples */
' DWORD cb; /* byte count */
' DWORD ticks; /* ticks in MIDI stream */
' /* SMPTE */
' struct
' {
' BYTE hour; /* hours */
' BYTE min; /* minutes */
' BYTE sec; /* seconds */
' BYTE frame; /* frames */
' BYTE fps; /* frames per second */
' BYTE dummy; /* pad */
'#ifdef _WIN32
' BYTE pad[2];
'#endif
' } smpte;
' /* MIDI */
' struct
' {
' DWORD songptrpos; /* song pointer position */
' } midi;
' } u;
'} MMTIME, *PMMTIME, NEAR *NPMMTIME, FAR *LPMMTIME;
' // Size = 8 bytes
TYPE MMTIME_SMPTE BYTE
 hour AS BYTE ' BYTE
 MIN AS BYTE ' BYTE
 sec AS BYTE ' BYTE
 FRAME AS BYTE ' BYTE
 fps AS BYTE ' BYTE
 dummy AS BYTE ' BYTE
 pad(1) AS BYTE ' BYTE[2]
END TYPE
' // Size = 4 bytes
TYPE MMTIME_MIDI BYTE
 songptrpos AS DWORD
END TYPE
' // Size = 8 bytes
UNION MMTIME_UNION BYTE
 ms AS DWORD
 sample AS DWORD
 cb AS DWORD
 ticks AS DWORD
 smpte AS MMTIME_SMPTE
 midi AS MMTIME_MIDI
 ' // For compatibility with PB includes
 MMTIME_SMPTE
 MMTIME_MIDI
END UNION
' // Size = 12 bytes
TYPE MMTIME BYTE
 wType AS DWORD
 MMTIME_UNION
END TYPE
'/* types for wType field in MMTIME struct */
%EQUATE `TIME_MS = &H0001 ' time in Milliseconds
%EQUATE `TIME_SAMPLES = &H0002 ' number of wave samples
%EQUATE `TIME_BYTES = &H0004 ' current byte offset
%EQUATE `TIME_SMPTE = &H0008 ' SMPTE time
%EQUATE `TIME_MIDI = &H0010 ' MIDI time
%EQUATE `TIME_TICKS = &H0020 ' /* Ticks within MIDI stream */
'/*
' *
' *
' */
'#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
' ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
' ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
#IF NOT %DEF(%MAKEFOURCC_DEFINED)
%EQUATE `MAKEFOURCC_DEFINED = 1
FUNCTION MAKEFOURCC (BYVAL st0 AS STRING, BYVAL st1 AS STRING, BYVAL st2 AS STRING, BYVAL st3 AS STRING) AS DWORD
 LOCAL ch0 AS DWORD, ch1 AS DWORD, ch2 AS DWORD, ch3 AS DWORD
 ch0 = ASC(st0)
 ch1 = ASC(st1)
 ch2 = ASC(st2)
 ch3 = ASC(st3)
 SHIFT LEFT ch1, 8
 SHIFT LEFT ch2, 16
 SHIFT LEFT ch3, 24
 FUNCTION = ch0 OR ch1 OR ch2 OR ch3
END FUNCTION
#ENDIF
'/****************************************************************************
' Multimedia Extensions Window Messages
'****************************************************************************/
%EQUATE `MM_JOY1MOVE = &H3A0 ' joystick
%EQUATE `MM_JOY2MOVE = &H3A1
%EQUATE `MM_JOY1ZMOVE = &H3A2
%EQUATE `MM_JOY2ZMOVE = &H3A3
%EQUATE `MM_JOY1BUTTONDOWN = &H3B5
%EQUATE `MM_JOY2BUTTONDOWN = &H3B6
%EQUATE `MM_JOY1BUTTONUP = &H3B7
%EQUATE `MM_JOY2BUTTONUP = &H3B8
'#define MM_MCINOTIFY 0x3B9 /* MCI */
%EQUATE `MM_MCINOTIFY = &H3B9 ' MCI
%EQUATE `MM_WOM_OPEN = &H3BB ' waveform output
%EQUATE `MM_WOM_CLOSE = &H3BC
%EQUATE `MM_WOM_DONE = &H3BD
%EQUATE `MM_WIM_OPEN = &H3BE ' waveform input
%EQUATE `MM_WIM_CLOSE = &H3BF
%EQUATE `MM_WIM_DATA = &H3C0
%EQUATE `MM_MIM_OPEN = &H3C1 ' MIDI input
%EQUATE `MM_MIM_CLOSE = &H3C2
%EQUATE `MM_MIM_DATA = &H3C3
%EQUATE `MM_MIM_LONGDATA = &H3C4
%EQUATE `MM_MIM_ERROR = &H3C5
%EQUATE `MM_MIM_LONGERROR = &H3C6
%EQUATE `MM_MOM_OPEN = &H3C7 ' MIDI output
%EQUATE `MM_MOM_CLOSE = &H3C8
%EQUATE `MM_MOM_DONE = &H3C9
'/* these are also in msvideo.h */
#IF NOT %DEF(%MM_DRVM_OPEN)
%EQUATE `MM_DRVM_OPEN = &H3D0 ' /* installable drivers */
%EQUATE `MM_DRVM_CLOSE = &H3D1
%EQUATE `MM_DRVM_DATA = &H3D2
%EQUATE `MM_DRVM_ERROR = &H3D3
#ENDIF
'/* these are used by msacm.h */
%EQUATE `MM_STREAM_OPEN = &H3D4
%EQUATE `MM_STREAM_CLOSE = &H3D5
%EQUATE `MM_STREAM_DONE = &H3D6
%EQUATE `MM_STREAM_ERROR = &H3D7
'#if(WINVER >= 0x0400)
%EQUATE `MM_MOM_POSITIONCB = &H3CA ' Callback for MEVT_POSITIONCB
#IF NOT %DEF(%MM_MCISIGNAL)
%EQUATE `MM_MCISIGNAL = &H3CB
#ENDIF
%EQUATE `MM_MIM_MOREDATA = &H3CC ' MIM_DONE w/ pending events
'#endif /* WINVER >= 0x0400 */
%EQUATE `MM_MIXM_LINE_CHANGE = &H3D0 ' /* mixer line change notify */
%EQUATE `MM_MIXM_CONTROL_CHANGE = &H3D1 ' /* mixer control change notify */
'/****************************************************************************
' String resource number bases (internal use)
'****************************************************************************/
%EQUATE `MMSYSERR_BASE = 0
%EQUATE `WAVERR_BASE = 32
%EQUATE `MIDIERR_BASE = 64
%EQUATE `TIMERR_BASE = 96 ' was 128, changed to match Win 31 Sonic
%EQUATE `JOYERR_BASE = 160
%EQUATE `MCIERR_BASE = 256
%EQUATE `MIXERR_BASE = 1024
%EQUATE `MCI_STRING_OFFSET = 512 ' if this number is changed you MUST
 ' alter the MCI_DEVTYPE_... list below
%EQUATE `MCI_VD_OFFSET = 1024
%EQUATE `MCI_CD_OFFSET = 1088
%EQUATE `MCI_WAVE_OFFSET = 1152
%EQUATE `MCI_SEQ_OFFSET = 1216
'/****************************************************************************
' General error return values
'****************************************************************************/
'/* general error return values */
%EQUATE `MMSYSERR_NOERROR = 0 ' no error
%EQUATE `MMSYSERR_ERROR = %MMSYSERR_BASE + 1 ' unspecified error
%EQUATE `MMSYSERR_BADDEVICEID = %MMSYSERR_BASE + 2 ' device ID out of range
%EQUATE `MMSYSERR_NOTENABLED = %MMSYSERR_BASE + 3 ' driver failed enable
%EQUATE `MMSYSERR_ALLOCATED = %MMSYSERR_BASE + 4 ' device already allocated
%EQUATE `MMSYSERR_INVALHANDLE = %MMSYSERR_BASE + 5 ' device xHandle is invalid
%EQUATE `MMSYSERR_NODRIVER = %MMSYSERR_BASE + 6 ' no device driver present
%EQUATE `MMSYSERR_NOMEM = %MMSYSERR_BASE + 7 ' memory allocation error
%EQUATE `MMSYSERR_NOTSUPPORTED = %MMSYSERR_BASE + 8 ' function isn't supported
%EQUATE `MMSYSERR_BADERRNUM = %MMSYSERR_BASE + 9 ' error value out of range
%EQUATE `MMSYSERR_INVALFLAG = %MMSYSERR_BASE + 10 ' invalid flag passed
%EQUATE `MMSYSERR_INVALPARAM = %MMSYSERR_BASE + 11 ' invalid parameter passed
%EQUATE `MMSYSERR_HANDLEBUSY = %MMSYSERR_BASE + 12 ' xHandle being used
 ' simultaneously on another
 ' thread (eg callback)
%EQUATE `MMSYSERR_INVALIDALIAS = %MMSYSERR_BASE + 13 ' "Specified alias not found in WIN.INI
%EQUATE `MMSYSERR_BADDB = %MMSYSERR_BASE + 14 ' /* bad registry database */
%EQUATE `MMSYSERR_KEYNOTFOUND = %MMSYSERR_BASE + 15 ' /* registry key not found */
%EQUATE `MMSYSERR_READERROR = %MMSYSERR_BASE + 16 ' /* registry read error */
%EQUATE `MMSYSERR_WRITEERROR = %MMSYSERR_BASE + 17 ' /* registry write error */
%EQUATE `MMSYSERR_DELETEERROR = %MMSYSERR_BASE + 18 ' /* registry delete error */
%EQUATE `MMSYSERR_VALNOTFOUND = %MMSYSERR_BASE + 19 ' /* registry value not found */
%EQUATE `MMSYSERR_NODRIVERCB = %MMSYSERR_BASE + 20 ' /* driver does not call DriverCallback */
%EQUATE `MMSYSERR_MOREDATA = %MMSYSERR_BASE + 21 ' /* more data to be returned */
%EQUATE `MMSYSERR_LASTERROR = %MMSYSERR_BASE + 21 ' /* last error in range */
'#if (WINVER < 0x030a) || defined(_WIN32)
'DECLARE_HANDLE(HDRVR);
'#endif /* ifdef WINVER < 0x030a */
#IF NOT %DEF(%MMNODRV)
'/****************************************************************************
' Installable driver support
'****************************************************************************/
' // Size = 16 bytes
TYPE DRVCONFIGINFOEX BYTE
 dwDCISize AS DWORD ' DWORD dwDCISize
 lpszDCISectionName AS WSTRINGZ PTR ' LPCWSTR lpszDCISectionName
 lpszDCIAliasName AS WSTRINGZ PTR ' LPCWSTR lpszDCIAliasName
 dnDevNode AS DWORD ' DWORD dnDevNode
END TYPE
'#if (WINVER < 0x030a) || defined(_WIN32)
#IF NOT %DEF(%DRV_LOAD)
'#ifndef DRV_LOAD
'/* Driver messages */
%EQUATE `DRV_LOAD = &H0001
%EQUATE `DRV_ENABLE = &H0002
%EQUATE `DRV_OPEN = &H0003
%EQUATE `DRV_CLOSE = &H0004
%EQUATE `DRV_DISABLE = &H0005
%EQUATE `DRV_FREE = &H0006
%EQUATE `DRV_CONFIGURE = &H0007
%EQUATE `DRV_QUERYCONFIGURE = &H0008
%EQUATE `DRV_INSTALL = &H0009
%EQUATE `DRV_REMOVE = &H000A
%EQUATE `DRV_EXITSESSION = &H000B
%EQUATE `DRV_POWER = &H000F
%EQUATE `DRV_RESERVED = &H0800
%EQUATE `DRV_USER = &H4000
'/* LPARAM of DRV_CONFIGURE message */
' // Size = 12 bytes
TYPE DRVCONFIGINFO BYTE
 dwDCISize AS DWORD ' DWORD dwDCISize
 lpszDCISectionName AS WSTRINGZ PTR ' LPCWSTR lpszDCISectionName
 lpszDCIAliasName AS WSTRINGZ PTR ' LPCWSTR lpszDCIAliasName
END TYPE
'/* Supported return values for DRV_CONFIGURE message */
%EQUATE `DRVCNF_CANCEL = &H0000
%EQUATE `DRVCNF_OK = &H0001
%EQUATE `DRVCNF_RESTART = &H0002
'/* installable driver function prototypes */
'#ifdef _WIN32
'typedef LRESULT (CALLBACK* DRIVERPROC)(DWORD_PTR, HDRVR, UINT, LPARAM, LPARAM);
'FUNCTION DRIVERPROC (BYVAL DWORD, BYVAL DWORD, BYVAL DWORD, BYVAL LONG, BYVAL LONG) AS LONG
DECLARE FUNCTION CloseDriver LIB "winmm.dll" ALIAS "CloseDriver" ( BYVAL hDriver AS QUAD , BYVAL lParam1 AS LONG , BYVAL lParam2 AS LONG ) AS LONG ' LRESULT
DECLARE FUNCTION OpenDriver LIB "winmm.dll" ALIAS "OpenDriver" ( BYREF szDriverName AS WSTRINGZ , BYREF szSectionName AS WSTRINGZ , BYVAL lParam2 AS LONG ) AS QUAD ' HDRVR
DECLARE FUNCTION SendDriverMessage LIB "winmm.dll" ALIAS "SendDriverMessage" ( BYVAL hDriver AS QUAD , BYVAL message AS LONG , BYVAL lParam1 AS LONG , BYVAL lParam2 AS LONG ) AS LONG ' LRESULT
DECLARE FUNCTION DrvGetModuleHandle LIB "winmm.dll" ALIAS "DrvGetModuleHandle" ( BYVAL hDriver AS QUAD ) AS QUAD ' HMODULE
DECLARE FUNCTION GetDriverModuleHandle LIB "winmm.dll" ALIAS "GetDriverModuleHandle" ( BYVAL hDriver AS QUAD ) AS QUAD ' HMODULE
DECLARE FUNCTION DefDriverProc LIB "winmm.dll" ALIAS "DefDriverProc" ( BYVAL dwDriverIdentifier AS QUAD , BYVAL hdrvr AS QUAD , BYVAL uMsg AS QUAD , BYVAL lParam1 AS LONG , BYVAL lParam2 AS LONG ) AS LONG ' LRESULT
#ENDIF ' #IF NOT %DEF(%DRV_LOAD)
'#endif /* ifdef (WINVER < 0x030a) || defined(_WIN32) */
'#if (WINVER >= 0x030a)
'/* return values from DriverProc() function */
%EQUATE `DRV_CANCEL = %DRVCNF_CANCEL
%EQUATE `DRV_OK = %DRVCNF_OK
%EQUATE `DRV_RESTART = %DRVCNF_RESTART
'#endif /* ifdef WINVER >= 0x030a */
%EQUATE `DRV_MCI_FIRST = %DRV_RESERVED
%EQUATE `DRV_MCI_LAST = %DRV_RESERVED + &HFFF
#ENDIF ' #IF NOT %DEF(%MMNODRV)
'/****************************************************************************
' Driver callback support
'****************************************************************************/
'/* flags used with waveOutOpen(), waveInOpen(), midiInOpen(), and */
'/* midiOutOpen() to specify the type of the dwCallback parameter. */
%EQUATE `CALLBACK_TYPEMASK = &H00070000 ' callback type mask
%EQUATE `CALLBACK_NULL = &H00000000 ' no callback
%EQUATE `CALLBACK_WINDOW = &H00010000 ' dwCallback is a HWND
%EQUATE `CALLBACK_TASK = &H00020000 ' dwCallback is a HTASK
%EQUATE `CALLBACK_FUNCTION = &H00030000 ' dwCallback is a FARPROC
%EQUATE `CALLBACK_THREAD = %CALLBACK_TASK ' thread ID replaces 16 bit task
%EQUATE `CALLBACK_EVENT = &H00050000 ' dwCallback is an EVENT Handle
#IF NOT %DEF(%MMNOSOUND)
'/****************************************************************************
' Sound support
'****************************************************************************/
'#ifdef _WIN32
DECLARE FUNCTION sndPlaySoundA LIB "winmm.dll" ALIAS "sndPlaySoundA" ( BYREF pszSound AS ASCIIZ , BYVAL fuSound AS QUAD ) AS LONG
DECLARE FUNCTION sndPlaySoundW LIB "winmm.dll" ALIAS "sndPlaySoundW" ( BYREF pszSound AS WSTRINGZ
 , BYVAL fuSound AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO sndPlaySound = sndPlaySoundW
#ELSE
 MACRO sndPlaySound = sndPlaySoundA
#ENDIF
'/*
' * flag values for fuSound and fdwSound arguments on [snd]PlaySound
' */
%EQUATE `SND_SYNC = &H0000 ' /* play synchronously (default) */
%EQUATE `SND_ASYNC = &H0001 ' /* play asynchronously */
%EQUATE `SND_NODEFAULT = &H0002 ' /* silence not default, if sound not found */
%EQUATE `SND_MEMORY = &H0004 ' /* lpszSoundName points to a memory file */
%EQUATE `SND_LOOP = &H0008 ' /* loop the sound until next sndPlaySound */
%EQUATE `SND_NOSTOP = &H0010 ' /* don't stop any currently playing sound */
%EQUATE `SND_NOWAIT = &H00002000 ' /* don't wait if the driver is busy */
%EQUATE `SND_ALIAS = &H00010000 ' /* name is a WIN.INI [sounds] entry */
%EQUATE `SND_ALIAS_ID = &H00110000 ' /* name is a WIN.INI [sounds] entry identifier */
%EQUATE `SND_FILENAME = &H00020000 ' /* name is a file name */
%EQUATE `SND_RESOURCE = &H00040004 ' /* name is a resource name or atom */
'#if(WINVER >= 0x0400)
%EQUATE `SND_PURGE = &H0040 ' /* purge non-static events for task */
%EQUATE `SND_APPLICATION = &H0080 ' /* look for application specific association */
'#endif /* WINVER >= 0x0400 */
%EQUATE `SND_SENTRY = &H00080000 ' /* Generate a SoundSentry event with this sound */
%EQUATE `SND_RING = &H00100000 ' /* Treat this as a "ring" from a communications app - don't duck me */
%EQUATE `SND_SYSTEM = &H00200000 ' /* Treat this as a system sound */
%EQUATE `SND_ALIAS_START = 0 ' must be > 4096 to keep strings in same section of resource file
'#ifdef _WIN32
'#define sndAlias(ch0, ch1) (SND_ALIAS_START + (DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8))
FUNCTION sndAlias (BYVAL strch0 AS STRING, BYVAL strch1 AS STRING) AS DWORD
 LOCAL ch0 AS DWORD, ch1 AS DWORD
 ch0 = ASC(strch0)
 ch1 = ASC(strch1)
 SHIFT LEFT ch1, 8
 FUNCTION = %SND_ALIAS_START + (ch0 OR ch1)
END FUNCTION
%EQUATE `SND_ALIAS_SYSTEMASTERISK = &H00002A53 ' sndAlias('S', '*')
%EQUATE `SND_ALIAS_SYSTEMQUESTION = &H00003F53 ' sndAlias('S', '?')
%EQUATE `SND_ALIAS_SYSTEMHAND = &H00004853 ' sndAlias('S', 'H')
%EQUATE `SND_ALIAS_SYSTEMEXIT = &H00004553 ' sndAlias('S', 'E')
%EQUATE `SND_ALIAS_SYSTEMSTART = &H00005353 ' sndAlias('S', 'S')
%EQUATE `SND_ALIAS_SYSTEMWELCOME = &H00005753 ' sndAlias('S', 'W')
%EQUATE `SND_ALIAS_SYSTEMEXCLAMATION = &H00002153 ' sndAlias('S', '!')
%EQUATE `SND_ALIAS_SYSTEMDEFAULT = &H00004453 ' sndAlias('S', 'D')
DECLARE FUNCTION PlaySoundA LIB "winmm.dll" ALIAS "PlaySoundA" ( BYREF pszSound AS ASCIIZ , BYVAL hmod AS QUAD , BYVAL fdwSound AS QUAD ) AS LONG
DECLARE FUNCTION PlaySoundW LIB "winmm.dll" ALIAS "PlaySoundW" ( BYREF pszSound AS WSTRINGZ
 , BYVAL hmod AS DWORD
 , BYVAL fdwSound AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO PlaySound = PlaySoundW
#ELSE
 MACRO PlaySound = PlaySoundA
#ENDIF
#ENDIF ' #IF NOT %DEF(%MMNOSOUND)
#IF NOT %DEF(%MMNOWAVE)
'/****************************************************************************
' Waveform audio support
'****************************************************************************/
'/* waveform audio error return values */
%EQUATE `WAVERR_BADFORMAT = %WAVERR_BASE + 0 ' unsupported wave format
%EQUATE `WAVERR_STILLPLAYING = %WAVERR_BASE + 1 ' still something playing
%EQUATE `WAVERR_UNPREPARED = %WAVERR_BASE + 2 ' header not prepared
%EQUATE `WAVERR_SYNC = %WAVERR_BASE + 3 ' device is synchronous
%EQUATE `WAVERR_LASTERROR = %WAVERR_BASE + 3 ' last error in range
'/* waveform audio data types */
'DECLARE_HANDLE(HWAVE);
'DECLARE_HANDLE(HWAVEIN);
'DECLARE_HANDLE(HWAVEOUT);
'typedef HWAVEIN FAR *LPHWAVEIN;
'typedef HWAVEOUT FAR *LPHWAVEOUT;
'typedef DRVCALLBACK WAVECALLBACK;
'typedef WAVECALLBACK FAR *LPWAVECALLBACK;
'/* wave callback messages */
%EQUATE `WOM_OPEN = %MM_WOM_OPEN
%EQUATE `WOM_CLOSE = %MM_WOM_CLOSE
%EQUATE `WOM_DONE = %MM_WOM_DONE
%EQUATE `WIM_OPEN = %MM_WIM_OPEN
%EQUATE `WIM_CLOSE = %MM_WIM_CLOSE
%EQUATE `WIM_DATA = %MM_WIM_DATA
'/* device ID for wave device mapper */
'#define WAVE_MAPPER ((UINT)-1)
' Declared as %WAVE_MAPPER = -1& in WIN32API.INC.
%EQUATE `WAVE_MAPPER = &HFFFFFFFF
'/* flags for dwFlags parameter in waveOutOpen() and waveInOpen() */
%EQUATE `WAVE_FORMAT_QUERY = &H0001
%EQUATE `WAVE_ALLOWSYNC = &H0002
'#if(WINVER >= 0x0400)
%EQUATE `WAVE_MAPPED = &H0004
%EQUATE `WAVE_FORMAT_DIRECT = &H0008
%EQUATE `WAVE_FORMAT_DIRECT_QUERY = %WAVE_FORMAT_QUERY OR %WAVE_FORMAT_DIRECT
%EQUATE `WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE = &H0010
'#endif /* WINVER >= 0x0400 */
'/* wave data block header */
' // Size = 32 bytes
TYPE WAVEHDR BYTE
 lpData AS ASCIIZ PTR ' LPSTR lpData /* pointer to locked data buffer */
 dwBufferLength AS DWORD ' DWORD dwBufferLength /* length of data buffer */
 dwBytesRecorded AS DWORD ' DWORD dwBytesRecorded /* used for input only */
 dwUser AS DWORD ' DWORD_PTR dwUser /* for client's use */
 dwFlags AS DWORD ' DWORD dwFlags /* assorted flags (see defines) */
 dwLoops AS DWORD ' DWORD dwLoops /* loop control counter */
 lpNext AS WAVEHDR PTR ' struct wavehdr_tag FAR *lpNext /* reserved for driver */
 reserved AS DWORD ' DWORD_PTR reserved /* reserved for driver */
END TYPE
'/* flags for dwFlags field of WAVEHDR */
%EQUATE `WHDR_DONE = &H00000001 ' done bit
%EQUATE `WHDR_PREPARED = &H00000002 ' set if this header has been prepared
%EQUATE `WHDR_BEGINLOOP = &H00000004 ' loop start block
%EQUATE `WHDR_ENDLOOP = &H00000008 ' loop end block
%EQUATE `WHDR_INQUEUE = &H00000010 ' reserved for driver
'/* waveform output device capabilities structure */
'#ifdef _WIN32
' // Size = 52 bytes
TYPE WAVEOUTCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of sources supported */
 wReserved1 AS WORD ' WORD wReserved1 /* packing */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
' // Size = 84 bytes
TYPE WAVEOUTCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of sources supported */
 wReserved1 AS WORD ' WORD wReserved1 /* packing */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
MACRO WAVEOUTCAPS = WAVEOUTCAPSA
' // Size = 100 bytes
TYPE WAVEOUTCAPS2A BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of sources supported */
 wReserved1 AS WORD ' WORD wReserved1 /* packing */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
' // Size = 132 bytes
TYPE WAVEOUTCAPS2W BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of sources supported */
 wReserved1 AS WORD ' WORD wReserved1 /* packing */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
MACRO WAVEOUTCAPS2 = WAVEOUTCAPS2A
'/* flags for dwSupport field of WAVEOUTCAPS */
%EQUATE `WAVECAPS_PITCH = &H0001 ' supports pitch control
%EQUATE `WAVECAPS_PLAYBACKRATE = &H0002 ' supports playback rate control
%EQUATE `WAVECAPS_VOLUME = &H0004 ' supports volume control
%EQUATE `WAVECAPS_LRVOLUME = &H0008 ' separate left-right volume control
%EQUATE `WAVECAPS_SYNC = &H0010 '
%EQUATE `WAVECAPS_SAMPLEACCURATE = &H0020
'/* waveform input device capabilities structure */
'#ifdef _WIN32
' // Size = 48 bytes
TYPE WAVEINCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of channels supported */
 wReserved1 AS WORD ' WORD wReserved1 /* structure packing */
END TYPE
' // Size = 80 bytes
TYPE WAVEINCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of channels supported */
 wReserved1 AS WORD ' WORD wReserved1 /* structure packing */
END TYPE
MACRO WAVEINCAPS = WAVEINCAPSA
' // Size = 96 bytes
TYPE WAVEINCAPS2A BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of channels supported */
 wReserved1 AS WORD ' WORD wReserved1 /* structure packing */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
' // Size = 128 bytes
TYPE WAVEINCAPS2W BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 dwFormats AS DWORD ' DWORD dwFormats /* formats supported */
 wChannels AS WORD ' WORD wChannels /* number of channels supported */
 wReserved1 AS WORD ' WORD wReserved1 /* structure packing */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
MACRO WAVEINCAPS2 = WAVEINCAPS2A
'/* defines for dwFormat field of WAVEINCAPS and WAVEOUTCAPS */
%EQUATE `WAVE_INVALIDFORMAT = &H00000000 ' invalid format
%EQUATE `WAVE_FORMAT_1M08 = &H00000001 ' 11.025 kHz, Mono, 8-bit
%EQUATE `WAVE_FORMAT_1S08 = &H00000002 ' 11.025 kHz, Stereo, 8-bit
%EQUATE `WAVE_FORMAT_1M16 = &H00000004 ' 11.025 kHz, Mono, 16-bit
%EQUATE `WAVE_FORMAT_1S16 = &H00000008 ' 11.025 kHz, Stereo, 16-bit
%EQUATE `WAVE_FORMAT_2M08 = &H00000010 ' 22.05 kHz, Mono, 8-bit
%EQUATE `WAVE_FORMAT_2S08 = &H00000020 ' 22.05 kHz, Stereo, 8-bit
%EQUATE `WAVE_FORMAT_2M16 = &H00000040 ' 22.05 kHz, Mono, 16-bit
%EQUATE `WAVE_FORMAT_2S16 = &H00000080 ' 22.05 kHz, Stereo, 16-bit
%EQUATE `WAVE_FORMAT_4M08 = &H00000100 ' 44.1 kHz, Mono, 8-bit
%EQUATE `WAVE_FORMAT_4S08 = &H00000200 ' 44.1 kHz, Stereo, 8-bit
%EQUATE `WAVE_FORMAT_4M16 = &H00000400 ' 44.1 kHz, Mono, 16-bit
%EQUATE `WAVE_FORMAT_4S16 = &H00000800 ' 44.1 kHz, Stereo, 16-bit
%EQUATE `WAVE_FORMAT_44M08 = &H00000100 ' /* 44.1 kHz, Mono, 8-bit */
%EQUATE `WAVE_FORMAT_44S08 = &H00000200 ' /* 44.1 kHz, Stereo, 8-bit */
%EQUATE `WAVE_FORMAT_44M16 = &H00000400 ' /* 44.1 kHz, Mono, 16-bit */
%EQUATE `WAVE_FORMAT_44S16 = &H00000800 ' /* 44.1 kHz, Stereo, 16-bit */
%EQUATE `WAVE_FORMAT_48M08 = &H00001000 ' /* 48 kHz, Mono, 8-bit */
%EQUATE `WAVE_FORMAT_48S08 = &H00002000 ' /* 48 kHz, Stereo, 8-bit */
%EQUATE `WAVE_FORMAT_48M16 = &H00004000 ' /* 48 kHz, Mono, 16-bit */
%EQUATE `WAVE_FORMAT_48S16 = &H00008000 ' /* 48 kHz, Stereo, 16-bit */
%EQUATE `WAVE_FORMAT_96M08 = &H00010000 ' /* 96 kHz, Mono, 8-bit */
%EQUATE `WAVE_FORMAT_96S08 = &H00020000 ' /* 96 kHz, Stereo, 8-bit */
%EQUATE `WAVE_FORMAT_96M16 = &H00040000 ' /* 96 kHz, Mono, 16-bit */
%EQUATE `WAVE_FORMAT_96S16 = &H00080000 ' /* 96 kHz, Stereo, 16-bit */
#IF NOT %DEF(%WAVE_FORMAT_PCM)
'/* OLD general waveform format structure (information common to all formats) */
' // Size = 14 bytes
TYPE WAVEFORMAT BYTE
 wFormatTag AS WORD ' WORD wFormatTag; /* format type */
 nChannels AS WORD ' WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
 nSamplesPerSec AS DWORD ' DWORD nSamplesPerSec; /* sample rate */
 nAvgBytesPerSec AS DWORD ' DWORD nAvgBytesPerSec; /* for buffer estimation */
 nBlockAlign AS WORD ' WORD nBlockAlign; /* block size of data */
END TYPE
'/* flags for wFormatTag field of WAVEFORMAT */
'#define WAVE_FORMAT_PCM 1
%EQUATE `WAVE_FORMAT_PCM = 1
'/* specific waveform format structure for PCM data */
' // Size = 16 bytes
TYPE PCMWAVEFORMAT BYTE
 wf AS WAVEFORMAT ' WAVEFORMAT wf
 wBitsPerSample AS WORD ' WORD wBitsPerSample
END TYPE
#ENDIF ' #IF NOT %DEF(%WAVE_FORMAT_PCM)
#IF NOT %DEF(%WAVEFORMATEX)
 %WAVEFORMATEX = 1
'/*
' * extended waveform format structure used for all non-PCM formats. this
' * structure is common to all non-PCM formats.
' */
' // Size = 18 bytes
TYPE WAVEFORMATEX BYTE
 wFormatTag AS WORD ' WORD wFormatTag; /* format type */
 nChannels AS WORD ' WORD nChannels; /* number of channels (i.e. mono, stereo...) */
 nSamplesPerSec AS DWORD ' DWORD nSamplesPerSec; /* sample rate */
 nAvgBytesPerSec AS DWORD ' DWORD nAvgBytesPerSec; /* for buffer estimation */
 nBlockAlign AS WORD ' WORD nBlockAlign; /* block size of data */
 wBitsPerSample AS WORD ' WORD wBitsPerSample; /* number of bits per sample of mono data */
 cbSize AS WORD ' WORD cbSize; /* the count in bytes of the size of */
 ' /* extra information (after cbSize) */
END TYPE
#ENDIF ' #IF NOT %DEF(%WAVEFORMATEX)
'/* waveform audio function prototypes */
DECLARE FUNCTION waveOutGetNumDevs LIB "winmm.dll" ALIAS "waveOutGetNumDevs" ( ) AS QUAD ' UINT
DECLARE FUNCTION waveOutGetDevCapsA LIB "winmm.dll" ALIAS "waveOutGetDevCapsA" ( BYVAL uDeviceID AS QUAD , BYREF pwoc AS WAVEOUTCAPSA , BYVAL cbwoc AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetDevCapsW LIB "winmm.dll" ALIAS "waveOutGetDevCapsW" ( BYVAL uDeviceID AS QUAD , BYREF pwoc AS WAVEOUTCAPSW , BYVAL cbwoc AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO waveOutGetDevCaps = waveOutGetDevCapsW
#ELSE
 MACRO waveOutGetDevCaps = waveOutGetDevCapsA
#ENDIF
'#if (WINVER >= 0x0400)
DECLARE FUNCTION waveOutGetVolume LIB "winmm.dll" ALIAS "waveOutGetVolume" ( BYVAL hwo AS QUAD , BYREF pdwVolume AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutSetVolume LIB "winmm.dll" ALIAS "waveOutSetVolume" ( BYVAL uId AS QUAD , BYVAL dwVolume AS QUAD ) AS LONG ' MMRESULT
'#endif
DECLARE FUNCTION waveOutGetErrorTextA LIB "winmm.dll" ALIAS "waveOutGetErrorTextA" ( BYVAL mmrError AS LONG , BYREF pszText AS ASCIIZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetErrorTextW LIB "winmm.dll" ALIAS "waveOutGetErrorTextW" ( BYVAL mmrError AS LONG , BYREF pszText AS WSTRINGZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO waveOutGetErrorText = waveOutGetErrorTextW
#ELSE
 MACRO waveOutGetErrorText = waveOutGetErrorTextA
#ENDIF
DECLARE FUNCTION waveOutOpen LIB "winmm.dll" ALIAS "waveOutOpen" ( BYREF phwo AS QUAD , BYVAL uDeviceID AS QUAD , BYREF pwfx AS WAVEFORMATEX , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutClose LIB "winmm.dll" ALIAS "waveOutClose" ( BYVAL hwo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutPrepareHeader LIB "winmm.dll" ALIAS "waveOutPrepareHeader" ( BYVAL hwo AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutUnprepareHeader LIB "winmm.dll" ALIAS "waveOutUnprepareHeader" ( BYVAL hwo AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutWrite LIB "winmm.dll" ALIAS "waveOutWrite" ( BYVAL hwo AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutPause LIB "winmm.dll" ALIAS "waveOutPause" ( BYVAL hwo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutRestart LIB "winmm.dll" ALIAS "waveOutRestart" ( BYVAL hwo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutReset LIB "winmm.dll" ALIAS "waveOutReset" ( BYVAL hwo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutBreakLoop LIB "winmm.dll" ALIAS "waveOutBreakLoop" ( BYVAL hwo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetPosition LIB "winmm.dll" ALIAS "waveOutGetPosition" ( BYVAL hwo AS QUAD , BYREF pmmt AS MMTIME , BYVAL cbmmt AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetPitch LIB "winmm.dll" ALIAS "waveOutGetPitch" ( BYVAL hwo AS QUAD , BYREF pdwPitch AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutSetPitch LIB "winmm.dll" ALIAS "waveOutSetPitch" ( BYVAL hwo AS QUAD , BYVAL dwPitch AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetPlaybackRate LIB "winmm.dll" ALIAS "waveOutGetPlaybackRate" ( BYVAL hwo AS QUAD , BYREF pdwRate AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutSetPlaybackRate LIB "winmm.dll" ALIAS "waveOutSetPlaybackRate" ( BYVAL hwo AS QUAD , BYVAL dwRate AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveOutGetID LIB "winmm.dll" ALIAS "waveOutGetID" ( BYVAL hwo AS QUAD , BYREF puDeviceID AS QUAD ) AS LONG ' MMRESULT
'#if (WINVER >= 0x030a)
DECLARE FUNCTION waveOutMessage LIB "winmm.dll" ALIAS "waveOutMessage" ( BYVAL hwo AS QUAD , BYVAL uMsg AS QUAD , BYVAL dw1 AS QUAD , BYVAL dw2 AS QUAD ) AS LONG ' MMRESULT
'#endif /* ifdef WINVER >= 0x030a */
DECLARE FUNCTION waveInGetNumDevs LIB "winmm.dll" ALIAS "waveInGetNumDevs" ( ) AS QUAD ' UINT
DECLARE FUNCTION waveInGetDevCapsA LIB "winmm.dll" ALIAS "waveInGetDevCapsA" ( BYVAL uDeviceID AS QUAD , BYREF pwic AS WAVEINCAPSA , BYVAL cbwic AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInGetDevCapsW LIB "winmm.dll" ALIAS "waveInGetDevCapsW" ( BYVAL uDeviceID AS QUAD , BYREF pwic AS WAVEINCAPSW , BYVAL cbwic AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO waveInGetDevCaps = waveInGetDevCapsW
#ELSE
 MACRO waveInGetDevCaps = waveInGetDevCapsA
#ENDIF
DECLARE FUNCTION waveInGetErrorTextA LIB "winmm.dll" ALIAS "waveInGetErrorTextA" ( BYVAL mmrError AS LONG , BYREF pszText AS ASCIIZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInGetErrorTextW LIB "winmm.dll" ALIAS "waveInGetErrorTextW" ( BYVAL mmrError AS LONG , BYREF pszText AS WSTRINGZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO waveInGetErrorText = waveInGetErrorTextW
#ELSE
 MACRO waveInGetErrorText = waveInGetErrorTextA
#ENDIF
DECLARE FUNCTION waveInOpen LIB "winmm.dll" ALIAS "waveInOpen" ( BYREF phwi AS QUAD , BYVAL uDeviceID AS QUAD , BYREF pwfx AS WAVEFORMATEX , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInClose LIB "winmm.dll" ALIAS "waveInClose" ( BYVAL hwi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInPrepareHeader LIB "winmm.dll" ALIAS "waveInPrepareHeader" ( BYVAL hwi AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInUnprepareHeader LIB "winmm.dll" ALIAS "waveInUnprepareHeader" ( BYVAL hwi AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ' UINT cbwh ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInAddBuffer LIB "winmm.dll" ALIAS "waveInAddBuffer" ( BYVAL hwi AS QUAD , BYREF pwh AS WAVEHDR , BYVAL cbwh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInStart LIB "winmm.dll" ALIAS "waveInStart" ( BYVAL hwi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInStop LIB "winmm.dll" ALIAS "waveInStop" ( BYVAL hwi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInReset LIB "winmm.dll" ALIAS "waveInReset" ( BYVAL hwi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInGetPosition LIB "winmm.dll" ALIAS "waveInGetPosition" ( BYVAL hwi AS QUAD , BYREF pmmt AS MMTIME , BYVAL cbmmt AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION waveInGetID LIB "winmm.dll" ALIAS "waveInGetID" ( BYVAL hwi AS QUAD , BYREF puDeviceID AS QUAD ) AS LONG ' MMRESULT
'#if (WINVER >= 0x030a)
DECLARE FUNCTION waveInMessage LIB "winmm.dll" ALIAS "waveInMessage" ( BYVAL hwi AS QUAD , BYVAL uMsg AS QUAD , BYVAL dw1 AS QUAD , BYVAL dw2 AS QUAD ) AS LONG ' MMRESULT
'#endif /* ifdef WINVER >= 0x030a */
#ENDIF ' /* ifndef MMNOWAVE */
#IF NOT %DEF(%MMNOMIDI)
'/****************************************************************************
' MIDI audio support
'****************************************************************************/
'/* MIDI error return values */
%EQUATE `MIDIERR_UNPREPARED = %MIDIERR_BASE + 0 ' header not prepared
%EQUATE `MIDIERR_STILLPLAYING = %MIDIERR_BASE + 1 ' still something playing
%EQUATE `MIDIERR_NOMAP = %MIDIERR_BASE + 2 ' no current map
%EQUATE `MIDIERR_NOTREADY = %MIDIERR_BASE + 3 ' hardware is still busy
%EQUATE `MIDIERR_NODEVICE = %MIDIERR_BASE + 4 ' port no longer connected
%EQUATE `MIDIERR_INVALIDSETUP = %MIDIERR_BASE + 5 ' invalid setup
%EQUATE `MIDIERR_BADOPENMODE = %MIDIERR_BASE + 6 ' /* operation unsupported w/ open mode */
%EQUATE `MIDIERR_DONT_CONTINUE = %MIDIERR_BASE + 7 ' /* thru device 'eating' a message */
%EQUATE `MIDIERR_LASTERROR = %MIDIERR_BASE + 7 ' /* last error in range */
'/* MIDI audio data types */
'DECLARE_HANDLE(HMIDI);
'DECLARE_HANDLE(HMIDIIN);
'DECLARE_HANDLE(HMIDIOUT);
'DECLARE_HANDLE(HMIDISTRM);
'typedef HMIDI FAR *LPHMIDI;
'typedef HMIDIIN FAR *LPHMIDIIN;
'typedef HMIDIOUT FAR *LPHMIDIOUT;
'typedef HMIDISTRM FAR *LPHMIDISTRM;
'typedef DRVCALLBACK MIDICALLBACK;
'typedef MIDICALLBACK FAR *LPMIDICALLBACK;
'#define MIDIPATCHSIZE 128
'typedef WORD PATCHARRAY[MIDIPATCHSIZE];
'typedef WORD FAR *LPPATCHARRAY;
'typedef WORD KEYARRAY[MIDIPATCHSIZE];
'typedef WORD FAR *LPKEYARRAY;
'/* MIDI callback messages */
%EQUATE `MIM_OPEN = %MM_MIM_OPEN
%EQUATE `MIM_CLOSE = %MM_MIM_CLOSE
%EQUATE `MIM_DATA = %MM_MIM_DATA
%EQUATE `MIM_LONGDATA = %MM_MIM_LONGDATA
%EQUATE `MIM_ERROR = %MM_MIM_ERROR
%EQUATE `MIM_LONGERROR = %MM_MIM_LONGERROR
%EQUATE `MOM_OPEN = %MM_MOM_OPEN
%EQUATE `MOM_CLOSE = %MM_MOM_CLOSE
%EQUATE `MOM_DONE = %MM_MOM_DONE
'#if(WINVER >= 0x0400)
%EQUATE `MIM_MOREDATA = %MM_MIM_MOREDATA
%EQUATE `MOM_POSITIONCB = %MM_MOM_POSITIONCB
'#endif /* WINVER >= 0x0400 */
'/* device ID for MIDI mapper */
%EQUATE `MIDIMAPPER = &HFFFFFFFF ' ((UINT)-1)
%EQUATE `MIDI_MAPPER = &HFFFFFFFF ' ((UINT)-1)
'#if(WINVER >= 0x0400)
'/* flags for dwFlags parm of midiInOpen() */
%EQUATE `MIDI_IO_STATUS = &H00000020&
'#endif /* WINVER >= 0x0400 */
'/* flags for wFlags parm of midiOutCachePatches(), midiOutCacheDrumPatches() */
%EQUATE `MIDI_CACHE_ALL = 1
%EQUATE `MIDI_CACHE_BESTFIT = 2
%EQUATE `MIDI_CACHE_QUERY = 3
%EQUATE `MIDI_UNCACHE = 4
'/* MIDI output device capabilities structure */
' // Size = 52 bytes
TYPE MIDIOUTCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wVoices AS WORD ' WORD wVoices /* # of voices (internal synth only) */
 wNotes AS WORD ' WORD wNotes /* max # of notes (internal synth only) */
 wChannelMask AS WORD ' WORD wChannelMask /* channels used (internal synth only) */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
' // Size = 84 bytes
TYPE MIDIOUTCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wVoices AS WORD ' WORD wVoices /* # of voices (internal synth only) */
 wNotes AS WORD ' WORD wNotes /* max # of notes (internal synth only) */
 wChannelMask AS WORD ' WORD wChannelMask /* channels used (internal synth only) */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
MACRO MIDIOUTCAPS = MIDIOUTCAPSA
' // Size = 100 bytes
TYPE MIDIOUTCAPS2A BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wVoices AS WORD ' WORD wVoices /* # of voices (internal synth only) */
 wNotes AS WORD ' WORD wNotes /* max # of notes (internal synth only) */
 wChannelMask AS WORD ' WORD wChannelMask /* channels used (internal synth only) */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
' // Size = 132 bytes
TYPE MIDIOUTCAPS2W BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wVoices AS WORD ' WORD wVoices /* # of voices (internal synth only) */
 wNotes AS WORD ' WORD wNotes /* max # of notes (internal synth only) */
 wChannelMask AS WORD ' WORD wChannelMask /* channels used (internal synth only) */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
MACRO MIDIOUTCAPS2 = MIDIOUTCAPS2A
'/* flags for wTechnology field of MIDIOUTCAPS structure */
%EQUATE `MOD_MIDIPORT = 1 ' output port
%EQUATE `MOD_SYNTH = 2 ' generic internal synth
%EQUATE `MOD_SQSYNTH = 3 ' square wave internal synth
%EQUATE `MOD_FMSYNTH = 4 ' FM internal synth
%EQUATE `MOD_MAPPER = 5 ' MIDI mapper
%EQUATE `MOD_WAVETABLE = 6 ' /* hardware wavetable synth */
%EQUATE `MOD_SWSYNTH = 7 ' /* software synth */
'/* flags for dwSupport field of MIDIOUTCAPS structure */
%EQUATE `MIDICAPS_VOLUME = &H0001 ' supports volume control
%EQUATE `MIDICAPS_LRVOLUME = &H0002 ' separate left-right volume control
%EQUATE `MIDICAPS_CACHE = &H0004
'#if(WINVER >= 0x0400)
%EQUATE `MIDICAPS_STREAM = &H0008 ' driver supports midiStreamOut directly
'#endif /* WINVER >= 0x0400 */
'/* MIDI input device capabilities structure */
' // Size = 44 bytes
TYPE MIDIINCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
'#if (WINVER >= 0x0400)
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
'#if (WINVER >= 0x0400)
END TYPE
' // Size = 76 bytes
TYPE MIDIINCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
'#if (WINVER >= 0x0400)
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
'#if (WINVER >= 0x0400)
END TYPE
MACRO MIDIINCAPS = MIDIINCAPSA
' // Size = 92 bytes
TYPE MIDIINCAPS2A BYTE
 wMid AS WORD ' WORD wMid; /* manufacturer ID */
 wPid AS WORD ' WORD wPid; /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion; /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
'#if (WINVER >= 0x0400)
 dwSupport AS DWORD ' DWORD dwSupport; /* functionality supported by driver */
'#endif
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid; /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid; /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid; /* for name lookup in registry */
END TYPE
' // Size = 124 bytes
TYPE MIDIINCAPS2W BYTE
 wMid AS WORD ' WORD wMid; /* manufacturer ID */
 wPid AS WORD ' WORD wPid; /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion; /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
'#if (WINVER >= 0x0400)
 dwSupport AS DWORD ' DWORD dwSupport; /* functionality supported by driver */
'#endif
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid; /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid; /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid; /* for name lookup in registry */
END TYPE
MACRO MIDIINCAPS2 = MIDIINCAPS2A
' // Size = 64 bytes
TYPE MIDIHDR BYTE
 lpData AS ASCIIZ PTR ' LPSTR lpData; /* pointer to locked data block */
 dwBufferLength AS DWORD ' DWORD dwBufferLength; /* length of data in data block */
 dwBytesRecorded AS DWORD ' DWORD dwBytesRecorded; /* used for input only */
 dwUser AS DWORD ' DWORD_PTR dwUser; /* for client's use */
 dwFlags AS DWORD ' DWORD dwFlags; /* assorted flags (see defines) */
 lpNext AS LONG ' struct midihdr_tag far *lpNext; /* reserved for driver */
 Reserved AS DWORD ' DWORD_PTR reserved; /* reserved for driver */
'#if (WINVER >= 0x0400)
 dwOffset AS DWORD ' DWORD dwOffset; /* Callback offset into buffer */
 dwReserved(7) AS DWORD ' DWORD_PTR dwReserved[8]; /* Reserved for MMSYSTEM */
'#endif
END TYPE
' // Size = 16 bytes
TYPE MIDIEVENT BYTE
 dwDeltaTime AS DWORD ' DWORD dwDeltaTime /* Ticks since last event */
 dwStreamID AS DWORD ' DWORD dwStreamID /* Reserved; must be zero */
 dwEvent AS DWORD ' DWORD dwEvent /* Event type and parameters */
 dwParms(0) AS DWORD ' DWORD dwParms[1] /* Parameters if this is a long event */
END TYPE
' // Size = 12 bytes
TYPE MIDISTRMBUFFVER BYTE
 dwVersion AS LONG ' DWORD dwVersion; /* Stream buffer format version */
 dwMid AS LONG ' DWORD dwMid; /* Manufacturer ID as defined in MMREG.H */
 dwOEMVersion AS LONG ' DWORD dwOEMVersion /* Manufacturer version for custom ext */
END TYPE
'#endif /* WINVER >= 0x0400 */
'/* flags for dwFlags field of MIDIHDR structure */
%EQUATE `MHDR_DONE = &H00000001 ' done bit
%EQUATE `MHDR_PREPARED = &H00000002 ' set if header prepared
%EQUATE `MHDR_INQUEUE = &H00000004 ' reserved for driver
%EQUATE `MHDR_ISSTRM = &H00000008 ' Buffer is stream buffer
'#if(WINVER >= 0x0400)
'/* */
'/* Type codes which go in the high byte of the event DWORD of a stream buffer */
'/* */
'/* Type codes 00-7F contain parameters within the low 24 bits */
'/* Type codes 80-FF contain a length of their parameter in the low 24 */
'/* bits, followed by their parameter data in the buffer. The event */
'/* DWORD contains the exact byte length; the parm data itself must be */
'/* padded to be an even multiple of 4 bytes long. */
'/* */
%EQUATE `MEVT_F_SHORT = &H00000000
%EQUATE `MEVT_F_LONG = &H80000000
%EQUATE `MEVT_F_CALLBACK = &H40000000
'#define MEVT_EVENTTYPE(x) ((BYTE)(((x)>>24)&0xFF))
'#define MEVT_EVENTPARM(x) ((DWORD)((x)&0x00FFFFFFL))
FUNCTION MEVT_EVENTTYPE (BYVAL dwEvent AS DWORD) AS BYTE
 SHIFT RIGHT dwEvent, 24
 FUNCTION = dwEvent AND &HFF
END FUNCTION
FUNCTION MEVT_EVENTPARM (BYVAL dwEvent AS DWORD) AS DWORD
 FUNCTION = dwEvent AND &H00FFFFFF
END FUNCTION
%EQUATE `MEVT_SHORTMSG = &H00 ' /* parm = shortmsg for midiOutShortMsg */
%EQUATE `MEVT_TEMPO = &H01 ' /* parm = new tempo in microsec/qn */
%EQUATE `MEVT_NOP = &H02 ' /* parm = unused; does nothing */
'/* 0x04-0x7F reserved */
%EQUATE `MEVT_LONGMSG = &H80 ' /* parm = bytes to send verbatim */
%EQUATE `MEVT_COMMENT = &H82 ' /* parm = comment data */
%EQUATE `MEVT_VERSION = &H84 ' /* parm = MIDISTRMBUFFVER struct */
'/* 0x81-0xFF reserved */
'#define MIDISTRM_ERROR (-2)
%EQUATE `MIDISTRM_ERROR = -2
'/* */
'/* Structures and defines for midiStreamProperty */
'/* */
%EQUATE `MIDIPROP_SET = &H80000000
%EQUATE `MIDIPROP_GET = &H40000000
'/* These are intentionally both non-zero so the app cannot accidentally */
'/* leave the operation off and happen to appear to work due to default */
'/* action. */
%EQUATE `MIDIPROP_TIMEDIV = &H00000001
%EQUATE `MIDIPROP_TEMPO = &H00000002
' // Size = 8 bytes
TYPE MIDIPROPTIMEDIV BYTE
 cbStruct AS DWORD ' DWORD cbStruct
 dwTimeDiv AS DWORD ' DWORD dwTimeDiv
END TYPE
' // Size = 8 bytes
TYPE MIDIPROPTEMPO BYTE
 cbStruct AS DWORD ' DWORD cbStruct
 dwTempo AS DWORD ' DWORD dwTempo
END TYPE
'#endif /* WINVER >= 0x0400 */
'/* MIDI function prototypes */
DECLARE FUNCTION midiOutGetNumDevs LIB "winmm.dll" ALIAS "midiOutGetNumDevs" ( ) AS QUAD ' UINT
'#if(WINVER >= 0x0400)
DECLARE FUNCTION midiStreamOpen LIB "winmm.dll" ALIAS "midiStreamOpen" ( BYREF phms AS QUAD , BYREF puDeviceID AS QUAD , BYVAL cMidi AS QUAD , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamClose LIB "winmm.dll" ALIAS "midiStreamClose" ( BYVAL hms AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamProperty LIB "winmm.dll" ALIAS "midiStreamProperty" ( BYVAL hms AS QUAD , BYREF lppropdata AS BYTE , BYVAL dwProperty AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamPosition LIB "winmm.dll" ALIAS "midiStreamPosition" ( BYVAL hms AS QUAD , BYREF lpmmt AS MMTIME , BYVAL cbmmt AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamOut LIB "winmm.dll" ALIAS "midiStreamOut" ( BYVAL hms AS QUAD , BYREF pmh aS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamPause LIB "winmm.dll" ALIAS "midiStreamPause" ( BYVAL hms AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamRestart LIB "winmm.dll" ALIAS "midiStreamRestart" ( BYVAL hms AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiStreamStop LIB "winmm.dll" ALIAS "midiStreamStop" ( BYVAL hms AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiConnect LIB "winmm.dll" ALIAS "midiConnect" ( BYVAL hmi AS QUAD , BYVAL hmo AS QUAD , BYVAL pReserved AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiDisconnect LIB "winmm.dll" ALIAS "midiDisconnect" ( BYVAL hmi AS QUAD , BYVAL hmo AS QUAD , BYVAL pReserved AS QUAD ) AS LONG ' MMRESULT
'#endif /* WINVER >= 0x0400 */
DECLARE FUNCTION midiOutGetDevCapsA LIB "winmm.dll" ALIAS "midiOutGetDevCapsA" ( BYVAL uDeviceID AS QUAD , BYREF pmoc AS MIDIOUTCAPSA , BYVAL cbmoc AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutGetDevCapsW LIB "winmm.dll" ALIAS "midiOutGetDevCapsW" ( BYVAL uDeviceID AS QUAD , BYREF pmoc AS MIDIOUTCAPSW , BYVAL cbmoc AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO midiOutGetDevCaps = midiOutGetDevCapsW
#ELSE
 MACRO midiOutGetDevCaps = midiOutGetDevCapsA
#ENDIF
'#if (WINVER >= 0x0400)
DECLARE FUNCTION midiOutGetVolume LIB "winmm.dll" ALIAS "midiOutGetVolume" ( BYVAL hmo AS QUAD , BYREF pdwVolume AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutSetVolume LIB "winmm.dll" ALIAS "midiOutSetVolume" ( BYVAL hmo AS QUAD , BYVAL dwVolume AS QUAD ) AS LONG ' MMRESULT
'#endif
DECLARE FUNCTION midiOutGetErrorTextA LIB "winmm.dll" ALIAS "midiOutGetErrorTextA" ( BYVAL mmrError AS LONG , BYREF pszText AS ASCIIZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutGetErrorTextW LIB "winmm.dll" ALIAS "midiOutGetErrorTextW" ( BYVAL mmrError AS LONG , BYREF pszText AS WSTRINGZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO midiOutGetErrorText = midiOutGetErrorTextW
#ELSE
 MACRO midiOutGetErrorText = midiOutGetErrorTextA
#ENDIF
DECLARE FUNCTION midiOutOpen LIB "winmm.dll" ALIAS "midiOutOpen" ( BYREF phmo AS QUAD , BYVAL uDeviceID AS QUAD , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutClose LIB "winmm.dll" ALIAS "midiOutClose" ( BYVAL hmo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutPrepareHeader LIB "winmm.dll" ALIAS "midiOutPrepareHeader" ( BYVAL hmo AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutUnprepareHeader LIB "winmm.dll" ALIAS "midiOutUnprepareHeader" ( BYVAL hmo AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutShortMsg LIB "winmm.dll" ALIAS "midiOutShortMsg" ( BYVAL hmo AS QUAD , BYVAL dwMsg AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutLongMsg LIB "winmm.dll" ALIAS "midiOutLongMsg" ( BYVAL hmo AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutReset LIB "winmm.dll" ALIAS "midiOutReset" ( BYVAL hmo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutCachePatches LIB "winmm.dll" ALIAS "midiOutCachePatches" ( BYVAL hmo AS QUAD , BYVAL uBank AS QUAD , BYREF pwpa AS QUAD , BYVAL fuCache AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutCacheDrumPatches LIB "winmm.dll" ALIAS "midiOutCacheDrumPatches" ( BYVAL hmo AS QUAD , BYVAL uPatch AS QUAD , BYREF pwkya AS QUAD , BYVAL fuCache AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiOutGetID LIB "winmm.dll" ALIAS "midiOutGetID" ( BYVAL hmo AS QUAD , BYREF puDeviceID AS QUAD ) AS LONG ' MMRESULT
'#if (WINVER >= 0x030a)
DECLARE FUNCTION midiOutMessage LIB "winmm.dll" ALIAS "midiOutMessage" ( BYVAL hmo AS QUAD , BYVAL uMsg AS QUAD , BYVAL dw1 AS QUAD , BYVAL dw2 AS QUAD ) AS LONG ' MMRESULT
'#endif /* ifdef WINVER >= 0x030a */
DECLARE FUNCTION midiInGetNumDevs LIB "winmm.dll" ALIAS "midiInGetNumDevs" ( ) AS QUAD ' UINT
DECLARE FUNCTION midiInGetDevCapsA LIB "winmm.dll" ALIAS "midiInGetDevCapsA" ( BYVAL uDeviceID AS QUAD , BYREF pmic AS MIDIINCAPSA , BYVAL cbmic AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInGetDevCapsW LIB "winmm.dll" ALIAS "midiInGetDevCapsW" ( BYVAL uDeviceID AS QUAD , BYREF pmic AS MIDIINCAPSW , BYVAL cbmic AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO midiInGetDevCaps = midiInGetDevCapsW
#ELSE
 MACRO midiInGetDevCaps = midiInGetDevCapsA
#ENDIF
DECLARE FUNCTION midiInGetErrorTextA LIB "winmm.dll" ALIAS "midiInGetErrorTextA" ( BYVAL mmrError AS LONG , BYREF pszText AS ASCIIZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInGetErrorTextW LIB "winmm.dll" ALIAS "midiInGetErrorTextW" ( BYVAL mmrError AS LONG , BYREF pszText AS WSTRINGZ , BYVAL cchText AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO midiInGetErrorText = midiInGetErrorTextW
#ELSE
 MACRO midiInGetErrorText = midiInGetErrorTextA
#ENDIF
DECLARE FUNCTION midiInOpen LIB "winmm.dll" ALIAS "midiInOpen" ( BYREF phmi AS QUAD , BYVAL uDeviceID AS QUAD , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInClose LIB "winmm.dll" ALIAS "midiInClose" ( BYVAL hmi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInPrepareHeader LIB "winmm.dll" ALIAS "midiInPrepareHeader" ( BYVAL hmi AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInUnprepareHeader LIB "winmm.dll" ALIAS "midiInUnprepareHeader" ( BYVAL hmi AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInAddBuffer LIB "winmm.dll" ALIAS "midiInAddBuffer" ( BYVAL hmi AS QUAD , BYREF pmh AS MIDIHDR , BYVAL cbmh AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInStart LIB "winmm.dll" ALIAS "midiInStart" ( BYVAL hmi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInStop LIB "winmm.dll" ALIAS "midiInStop" ( BYVAL hmi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInReset LIB "winmm.dll" ALIAS "midiInReset" ( BYVAL hmi AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION midiInGetID LIB "winmm.dll" ALIAS "midiInGetID" ( BYVAL hmi AS QUAD , BYREF puDeviceID AS QUAD ) AS LONG ' MMRESULT
'#if (WINVER >= 0x030a)
DECLARE FUNCTION midiInMessage LIB "winmm.dll" ALIAS "midiInMessage" ( BYVAL hmi AS QUAD , BYVAL uMsg AS QUAD , BYVAL dw1 AS QUAD , BYVAL dw2 AS QUAD ) AS LONG ' MMRESULT
'#endif /* ifdef WINVER >= 0x030a */
#ENDIF ' /* ifndef MMNOMIDI */
#IF NOT %DEF(%MMNOAUX)
'/****************************************************************************
' Auxiliary audio support
'****************************************************************************/
'/* device ID for aux device mapper */
%EQUATE `AUX_MAPPER = &HFFFFFFFF ' ((UINT)-1)
'/* Auxiliary audio device capabilities structure */
' // Size = 48 bytes
TYPE AUXCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wReserved1 AS WORD ' WORD wReserved1 /* padding */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
' // Size = 80 bytes
TYPE AUXCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 wReserved AS WORD ' WORD wReserved1 /* padding */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
END TYPE
MACRO AUXCAPS = AUXCAPSA
' // Size = 96 bytes
TYPE AUXCAPS2A BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 dwReserved AS WORD ' WORD wReserved1 /* padding */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
' // Size = 128 bytes
TYPE AUXCAPS2W BYTE
 wMid AS WORD ' WORD wMid /* manufacturer ID */
 wPid AS WORD ' WORD wPid /* product ID */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name (NULL terminated string) */
 wTechnology AS WORD ' WORD wTechnology /* type of device */
 dwReserved AS WORD ' WORD wReserved1 /* padding */
 dwSupport AS DWORD ' DWORD dwSupport /* functionality supported by driver */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
MACRO AUXCAPS2 = AUXCAPS2A
'/* flags for wTechnology field in AUXCAPS structure */
%EQUATE `AUXCAPS_CDAUDIO = 1 ' audio from internal CD-ROM drive
%EQUATE `AUXCAPS_AUXIN = 2 ' audio from auxiliary input jacks
'/* flags for dwSupport field in AUXCAPS structure */
%EQUATE `AUXCAPS_VOLUME = &H001 ' supports volume control
%EQUATE `AUXCAPS_LRVOLUME = &H002 ' separate left-right volume control
'/* auxiliary audio function prototypes */
DECLARE FUNCTION auxGetNumDevs LIB "winmm.dll" ALIAS "auxGetNumDevs" ( ) AS QUAD ' UINT
DECLARE FUNCTION auxGetDevCapsA LIB "winmm.dll" ALIAS "auxGetDevCapsA" ( BYVAL uDeviceID AS QUAD , BYREF pac AS AUXCAPSA , BYVAL cbac AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION auxGetDevCapsW LIB "winmm.dll" ALIAS "auxGetDevCapsW" ( BYVAL uDeviceID AS QUAD , BYREF pac AS AUXCAPSW , BYVAL cbac AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO auxGetDevCaps = auxGetDevCapsW
#ELSE
 MACRO auxGetDevCaps = auxGetDevCapsA
#ENDIF
DECLARE FUNCTION auxSetVolume LIB "winmm.dll" ALIAS "auxSetVolume" ( BYVAL uDeviceID AS QUAD , BYVAL dwVolume AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION auxGetVolume LIB "winmm.dll" ALIAS "auxGetVolume" ( BYVAL uDeviceID AS QUAD , BYREF pdwVolume AS QUAD ) AS LONG ' MMRESULT
'#if (WINVER >= 0x030a)
DECLARE FUNCTION auxOutMessage LIB "winmm.dll" ALIAS "auxOutMessage" ( BYVAL uDeviceID AS QUAD , BYVAL uMsg AS QUAD , BYVAL dw1 AS QUAD , BYVAL dw2 AS QUAD ) AS LONG ' MMRESULT
'#endif /* ifdef WINVER >= 0x030a */
#ENDIF ' /* ifndef MMNOAUX */
#IF NOT %DEF(%MMNOMIXER)
'/****************************************************************************
' Mixer Support
'****************************************************************************/
'DECLARE_HANDLE(HMIXEROBJ);
'typedef HMIXEROBJ FAR *LPHMIXEROBJ;
'DECLARE_HANDLE(HMIXER);
'typedef HMIXER FAR *LPHMIXER;
%EQUATE `MIXER_SHORT_NAME_CHARS = 16
%EQUATE `MIXER_LONG_NAME_CHARS = 64
'/* */
'/* MMRESULT error return values specific to the mixer API */
'/* */
'/* */
%EQUATE `MIXERR_INVALLINE = %MIXERR_BASE + 0
%EQUATE `MIXERR_INVALCONTROL = %MIXERR_BASE + 1
%EQUATE `MIXERR_INVALVALUE = %MIXERR_BASE + 2
%EQUATE `MIXERR_LASTERROR = %MIXERR_BASE + 2
%EQUATE `MIXER_OBJECTF_HANDLE = &H80000000
%EQUATE `MIXER_OBJECTF_MIXER = &H00000000
%EQUATE `MIXER_OBJECTF_HMIXER = %MIXER_OBJECTF_HANDLE OR %MIXER_OBJECTF_MIXER
%EQUATE `MIXER_OBJECTF_WAVEOUT = &H10000000
%EQUATE `MIXER_OBJECTF_HWAVEOUT = %MIXER_OBJECTF_HANDLE OR %MIXER_OBJECTF_WAVEOUT
%EQUATE `MIXER_OBJECTF_WAVEIN = &H20000000
%EQUATE `MIXER_OBJECTF_HWAVEIN = %MIXER_OBJECTF_HANDLE OR %MIXER_OBJECTF_WAVEIN
%EQUATE `MIXER_OBJECTF_MIDIOUT = &H30000000
%EQUATE `MIXER_OBJECTF_HMIDIOUT = %MIXER_OBJECTF_HANDLE OR %MIXER_OBJECTF_MIDIOUT
%EQUATE `MIXER_OBJECTF_MIDIIN = &H40000000
%EQUATE `MIXER_OBJECTF_HMIDIIN = %MIXER_OBJECTF_HANDLE OR %MIXER_OBJECTF_MIDIIN
%EQUATE `MIXER_OBJECTF_AUX = &H50000000
DECLARE FUNCTION mixerGetNumDevs LIB "winmm.dll" ALIAS "mixerGetNumDevs" ( ) AS QUAD ' UINT
' // Size = 48 bytes
TYPE MIXERCAPSA BYTE
 wMid AS WORD ' WORD wMid /* manufacturer id */
 wPid AS WORD ' WORD wPid /* product id */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name */
 fdwSupport AS DWORD ' DWORD fdwSupport /* misc. support bits */
 cDestinations AS DWORD ' DWORD cDestinations /* count of destinations */
END TYPE
' // Size = 80 bytes
TYPE MIXERCAPSW BYTE
 wMid AS WORD ' WORD wMid /* manufacturer id */
 wPid AS WORD ' WORD wPid /* product id */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name */
 fdwSupport AS DWORD ' DWORD fdwSupport /* misc. support bits */
 cDestinations AS DWORD ' DWORD cDestinations /* count of destinations */
END TYPE
MACRO MIXERCAPS = MIXERCAPSA
' // Size = 96 bytes
TYPE MIXERCAPS2A BYTE
 wMid AS WORD ' WORD wMid /* manufacturer id */
 wPid AS WORD ' WORD wPid /* product id */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* product name */
 fdwSupport AS DWORD ' DWORD fdwSupport /* misc. support bits */
 cDestinations AS DWORD ' DWORD cDestinations /* count of destinations */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
' // Size = 96 bytes
TYPE MIXERCAPS2W BYTE
 wMid AS WORD ' WORD wMid /* manufacturer id */
 wPid AS WORD ' WORD wPid /* product id */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* version of the driver */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* product name */
 fdwSupport AS DWORD ' DWORD fdwSupport /* misc. support bits */
 cDestinations AS DWORD ' DWORD cDestinations /* count of destinations */
 ManufacturerGuid AS GUID ' GUID ManufacturerGuid /* for extensible MID mapping */
 ProductGuid AS GUID ' GUID ProductGuid /* for extensible PID mapping */
 NameGuid AS GUID ' GUID NameGuid /* for name lookup in registry */
END TYPE
MACRO MIXERCAPS2 = MIXERCAPS2A
DECLARE FUNCTION mixerGetDevCapsA LIB "winmm.dll" ALIAS "mixerGetDevCapsA" ( BYVAL uMxId AS QUAD , BYREF pmxcaps AS MIXERCAPSA , BYVAL cbmxcaps AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerGetDevCapsW LIB "winmm.dll" ALIAS "mixerGetDevCapsW" ( BYVAL uMxId AS QUAD , BYREF pmxcaps AS MIXERCAPSW , BYVAL cbmxcaps AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO mixerGetDevCaps = mixerGetDevCapsW
#ELSE
 MACRO mixerGetDevCaps = mixerGetDevCapsA
#ENDIF
DECLARE FUNCTION mixerOpen LIB "winmm.dll" ALIAS "mixerOpen" ( BYREF phmx AS QUAD , BYVAL uMxId AS QUAD , BYVAL dwCallback AS QUAD , BYVAL dwInstance AS QUAD , BYVAL fdwOpen AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerClose LIB "winmm.dll" ALIAS "mixerClose" ( BYVAL hmx AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerMessage LIB "winmm.dll" ALIAS "mixerMessage" ( BYVAL hmx AS QUAD , BYVAL uMsg AS QUAD , BYVAL dwParam1 AS QUAD , BYVAL dwParam2 AS QUAD ) AS QUAD
'typedef struct tagMIXERLINEA {
' DWORD cbStruct; /* size of MIXERLINE structure */
' DWORD dwDestination; /* zero based destination index */
' DWORD dwSource; /* zero based source index (if source) */
' DWORD dwLineID; /* unique line id for mixer device */
' DWORD fdwLine; /* state/information about line */
' DWORD_PTR dwUser; /* driver specific information */
' DWORD dwComponentType; /* component type line connects to */
' DWORD cChannels; /* number of channels line supports */
' DWORD cConnections; /* number of connections [possible] */
' DWORD cControls; /* number of controls at this line */
' CHAR szShortName[MIXER_SHORT_NAME_CHARS];
' CHAR szName[MIXER_LONG_NAME_CHARS];
' struct {
' DWORD dwType; /* MIXERLINE_TARGETTYPE_xxxx */
' DWORD dwDeviceID; /* target device ID of device type */
' WORD wMid; /* of target device */
' WORD wPid; /* " */
' MMVERSION vDriverVersion; /* " */
' CHAR szPname[MAXPNAMELEN]; /* " */
' } Target;
'} MIXERLINEA, *PMIXERLINEA, *LPMIXERLINEA;
' // Size = 48 bytes
TYPE MIXERLINE_Target BYTE
 dwType AS DWORD ' DWORD dwType /* MIXERLINE_TARGETTYPE_xxxx */
 dwDeviceID AS DWORD ' DWORD dwDeviceID /* target device ID of device type */
 wMid AS WORD ' WORD wMid /* of target device */
 wPid AS WORD ' WORD wPid /* " */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* " */
 szPname AS ASCIIZ * %MAXPNAMELEN ' CHAR szPname[MAXPNAMELEN] /* " */
END TYPE
' // Size = 168 bytes
TYPE MIXERLINEA BYTE
 cbStruct AS DWORD ' DWORD cbStruct; /* size of MIXERLINE structure */
 dwDestination AS DWORD ' DWORD dwDestination; /* zero based destination index */
 dwSource AS DWORD ' DWORD dwSource; /* zero based source index (if source) */
 dwLineID AS DWORD ' DWORD dwLineID; /* unique line id for mixer device */
 fdwLine AS DWORD ' DWORD fdwLine; /* state/information about line */
 dwUser AS DWORD ' DWORD_PTR dwUser; /* driver specific information */
 dwComponentType AS DWORD ' DWORD dwComponentType; /* component type line connects to */
 cChannels AS DWORD ' DWORD cChannels; /* number of channels line supports */
 cConnections AS DWORD ' DWORD cConnections; /* number of connections [possible] */
 cControls AS DWORD ' DWORD cControls; /* number of controls at this line */
 szShortName AS ASCIIZ * %MIXER_SHORT_NAME_CHARS ' CHAR szShortName[MIXER_SHORT_NAME_CHARS];
 szName AS ASCIIZ * %MIXER_LONG_NAME_CHARS ' CHAR szName[MIXER_LONG_NAME_CHARS];
 lpTarget AS MIXERLINE_Target
END TYPE
' // Size = 80 bytes
TYPE MIXERLINE_TargetW BYTE
 dwType AS DWORD ' DWORD dwType /* MIXERLINE_TARGETTYPE_xxxx */
 dwDeviceID AS DWORD ' DWORD dwDeviceID /* target device ID of device type */
 wMid AS WORD ' WORD wMid /* of target device */
 wPid AS WORD ' WORD wPid /* " */
 vDriverVersion AS DWORD ' MMVERSION vDriverVersion /* " */
 szPname AS WSTRINGZ * %MAXPNAMELEN ' WCHAR szPname[MAXPNAMELEN] /* " */
END TYPE
'typedef struct tagMIXERLINEW {
' DWORD cbStruct; /* size of MIXERLINE structure */
' DWORD dwDestination; /* zero based destination index */
' DWORD dwSource; /* zero based source index (if source) */
' DWORD dwLineID; /* unique line id for mixer device */
' DWORD fdwLine; /* state/information about line */
' DWORD_PTR dwUser; /* driver specific information */
' DWORD dwComponentType; /* component type line connects to */
' DWORD cChannels; /* number of channels line supports */
' DWORD cConnections; /* number of connections [possible] */
' DWORD cControls; /* number of controls at this line */
' WCHAR szShortName[MIXER_SHORT_NAME_CHARS];
' WCHAR szName[MIXER_LONG_NAME_CHARS];
' struct {
' DWORD dwType; /* MIXERLINE_TARGETTYPE_xxxx */
' DWORD dwDeviceID; /* target device ID of device type */
' WORD wMid; /* of target device */
' WORD wPid; /* " */
' MMVERSION vDriverVersion; /* " */
' WCHAR szPname[MAXPNAMELEN]; /* " */
' } Target;
'} MIXERLINEW, *PMIXERLINEW, *LPMIXERLINEW;
' // Size = 280 bytes
TYPE MIXERLINEW BYTE
 cbStruct AS DWORD ' DWORD cbStruct; /* size of MIXERLINE structure */
 dwDestination AS DWORD ' DWORD dwDestination; /* zero based destination index */
 dwSource AS DWORD ' DWORD dwSource; /* zero based source index (if source) */
 dwLineID AS DWORD ' DWORD dwLineID; /* unique line id for mixer device */
 fdwLine AS DWORD ' DWORD fdwLine; /* state/information about line */
 dwUser AS DWORD ' DWORD_PTR dwUser; /* driver specific information */
 dwComponentType AS DWORD ' DWORD dwComponentType; /* component type line connects to */
 cChannels AS DWORD ' DWORD cChannels; /* number of channels line supports */
 cConnections AS DWORD ' DWORD cConnections; /* number of connections [possible] */
 cControls AS DWORD ' DWORD cControls; /* number of controls at this line */
 szShortName AS WSTRINGZ * %MIXER_SHORT_NAME_CHARS ' WCHAR szShortName[MIXER_SHORT_NAME_CHARS];
 szName AS WSTRINGZ * %MIXER_LONG_NAME_CHARS ' WCHAR szName[MIXER_LONG_NAME_CHARS];
 lpTarget AS MIXERLINE_TargetW
END TYPE
MACRO MIXERLINE = MIXERLINEA
'/* */
'/* MIXERLINE.fdwLine */
'/* */
'/* */
%EQUATE `MIXERLINE_LINEF_ACTIVE = &H00000001
%EQUATE `MIXERLINE_LINEF_DISCONNECTED = &H00008000
%EQUATE `MIXERLINE_LINEF_SOURCE = &H80000000
'/* */
'/* MIXERLINE.dwComponentType */
'/* */
'/* component types for destinations and sources */
'/* */
'/* */
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_FIRST = &H00000000
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_UNDEFINED = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 0
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_DIGITAL = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 1
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_LINE = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 2
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_MONITOR = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 3
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 4
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_HEADPHONES = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 5
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_TELEPHONE = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 6
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_WAVEIN = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 7
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_VOICEIN = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
%EQUATE `MIXERLINE_COMPONENTTYPE_DST_LAST = %MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_FIRST = &H00001000
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_DIGITAL = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_LINE = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_ANALOG = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
%EQUATE `MIXERLINE_COMPONENTTYPE_SRC_LAST = %MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
'/* */
'/* MIXERLINE.Target.dwType */
'/* */
'/* */
%EQUATE `MIXERLINE_TARGETTYPE_UNDEFINED = 0
%EQUATE `MIXERLINE_TARGETTYPE_WAVEOUT = 1
%EQUATE `MIXERLINE_TARGETTYPE_WAVEIN = 2
%EQUATE `MIXERLINE_TARGETTYPE_MIDIOUT = 3
%EQUATE `MIXERLINE_TARGETTYPE_MIDIIN = 4
%EQUATE `MIXERLINE_TARGETTYPE_AUX = 5
'#ifdef _WIN32
DECLARE FUNCTION mixerGetLineInfoA LIB "winmm.dll" ALIAS "mixerGetLineInfoA" ( BYVAL hmxobj AS QUAD , BYREF pmxl AS MIXERLINEA , BYVAL fdwInfo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerGetLineInfoW LIB "winmm.dll" ALIAS "mixerGetLineInfoW" ( BYVAL hmxobj AS QUAD , BYREF pmxl AS MIXERLINEW , BYVAL fdwInfo AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO mixerGetLineInfo = mixerGetLineInfoW
#ELSE
 MACRO mixerGetLineInfo = mixerGetLineInfoA
#ENDIF
%EQUATE `MIXER_GETLINEINFOF_DESTINATION = &H00000000&
%EQUATE `MIXER_GETLINEINFOF_SOURCE = &H00000001&
%EQUATE `MIXER_GETLINEINFOF_LINEID = &H00000002&
%EQUATE `MIXER_GETLINEINFOF_COMPONENTTYPE = &H00000003&
%EQUATE `MIXER_GETLINEINFOF_TARGETTYPE = &H00000004&
%EQUATE `MIXER_GETLINEINFOF_QUERYMASK = &H0000000F&
DECLARE FUNCTION mixerGetID LIB "winmm.dll" ALIAS "mixerGetID" ( BYVAL hmxobj AS QUAD , BYREF puMxId AS QUAD , BYVAL fdwId AS QUAD ) AS LONG ' MMRESULT
'/* */
'/* MIXERCONTROL */
'/* */
'/* */
'#ifdef _WIN32
'typedef struct tagMIXERCONTROLA {
' DWORD cbStruct; /* size in bytes of MIXERCONTROL */
' DWORD dwControlID; /* unique control id for mixer device */
' DWORD dwControlType; /* MIXERCONTROL_CONTROLTYPE_xxx */
' DWORD fdwControl; /* MIXERCONTROL_CONTROLF_xxx */
' DWORD cMultipleItems; /* if MIXERCONTROL_CONTROLF_MULTIPLE set */
' CHAR szShortName[MIXER_SHORT_NAME_CHARS];
' CHAR szName[MIXER_LONG_NAME_CHARS];
' union {
' struct {
' LONG lMinimum; /* signed minimum for this control */
' LONG lMaximum; /* signed maximum for this control */
' } DUMMYSTRUCTNAME;
' struct {
' DWORD dwMinimum; /* unsigned minimum for this control */
' DWORD dwMaximum; /* unsigned maximum for this control */
' } DUMMYSTRUCTNAME2;
' DWORD dwReserved[6];
' } Bounds;
' union {
' DWORD cSteps; /* # of steps between min & max */
' DWORD cbCustomData; /* size in bytes of custom data */
' DWORD dwReserved[6]; /* !!! needed? we have cbStruct.... */
' } Metrics;
'} MIXERCONTROLA, *PMIXERCONTROLA, *LPMIXERCONTROLA;
' // Size = 8 bytes
TYPE MIXERCONTROL_lBounds BYTE
 lMinimum AS LONG ' LONG lMinimum /* signed minimum for this control */
 lMaximum AS LONG ' LONG lMaximum /* signed maximum for this control */
END TYPE
' // Size = 8 bytes
TYPE MIXERCONTROL_dwBounds BYTE
 dwMinimum AS DWORD ' DWORD dwMinimum /* unsigned minimum for this control */
 dwMaximum AS DWORD ' DWORD dwMaximum /* unsigned maximum for this control */
END TYPE
' // Size = 24 bytes
UNION MIXERCONTROL_Bounds BYTE
 lMinMax AS MIXERCONTROL_lBounds
 dwMinMax AS MIXERCONTROL_dwBounds
 dwReserved(5) AS DWORD ' DWORD dwReserved[6]
END UNION
' // Size = 24 bytes
UNION MIXERCONTROL_Metrics BYTE
 cSteps AS DWORD ' DWORD cSteps; /* # of steps between min & max */
 cbCustomData AS DWORD ' DWORD cbCustomData /* size in bytes of custom data */
 dwReserved(5) AS DWORD ' DWORD dwReserved[6] /* !!! needed? we have cbStruct.... */
END UNION
' // Size = 148 bytes
TYPE MIXERCONTROLA BYTE
 cbStruct AS DWORD ' DWORD cbStruct /* size in bytes of MIXERCONTROL */
 dwControlID AS DWORD ' DWORD dwControlID /* unique control id for mixer device */
 dwControlType AS DWORD ' DWORD dwControlType /* MIXERCONTROL_CONTROLTYPE_xxx */
 fdwControl AS DWORD ' DWORD fdwControl /* MIXERCONTROL_CONTROLF_xxx */
 cMultipleItems AS DWORD ' DWORD cMultipleItems /* if MIXERCONTROL_CONTROLF_MULTIPLE set */
 szShortName AS ASCIIZ * %MIXER_SHORT_NAME_CHARS ' CHAR szShortName[MIXER_SHORT_NAME_CHARS]
 szName AS ASCIIZ * %MIXER_LONG_NAME_CHARS ' CHAR szName[MIXER_LONG_NAME_CHARS]
 Bounds AS MIXERCONTROL_Bounds
 Metrics AS MIXERCONTROL_Metrics
END TYPE
'typedef struct tagMIXERCONTROLW {
' DWORD cbStruct; /* size in bytes of MIXERCONTROL */
' DWORD dwControlID; /* unique control id for mixer device */
' DWORD dwControlType; /* MIXERCONTROL_CONTROLTYPE_xxx */
' DWORD fdwControl; /* MIXERCONTROL_CONTROLF_xxx */
' DWORD cMultipleItems; /* if MIXERCONTROL_CONTROLF_MULTIPLE set */
' WCHAR szShortName[MIXER_SHORT_NAME_CHARS];
' WCHAR szName[MIXER_LONG_NAME_CHARS];
' union {
' struct {
' LONG lMinimum; /* signed minimum for this control */
' LONG lMaximum; /* signed maximum for this control */
' } DUMMYSTRUCTNAME;
' struct {
' DWORD dwMinimum; /* unsigned minimum for this control */
' DWORD dwMaximum; /* unsigned maximum for this control */
' } DUMMYSTRUCTNAME2;
' DWORD dwReserved[6];
' } Bounds;
' union {
' DWORD cSteps; /* # of steps between min & max */
' DWORD cbCustomData; /* size in bytes of custom data */
' DWORD dwReserved[6]; /* !!! needed? we have cbStruct.... */
' } Metrics;
'} MIXERCONTROLW, *PMIXERCONTROLW, *LPMIXERCONTROLW;
' // Size = 228 bytes
TYPE MIXERCONTROLW BYTE
 cbStruct AS DWORD ' DWORD cbStruct /* size in bytes of MIXERCONTROL */
 dwControlID AS DWORD ' DWORD dwControlID /* unique control id for mixer device */
 dwControlType AS DWORD ' DWORD dwControlType /* MIXERCONTROL_CONTROLTYPE_xxx */
 fdwControl AS DWORD ' DWORD fdwControl /* MIXERCONTROL_CONTROLF_xxx */
 cMultipleItems AS DWORD ' DWORD cMultipleItems /* if MIXERCONTROL_CONTROLF_MULTIPLE set */
 szShortName AS WSTRINGZ * %MIXER_SHORT_NAME_CHARS ' WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
 szName AS WSTRINGZ * %MIXER_LONG_NAME_CHARS ' WCHAR szName[MIXER_LONG_NAME_CHARS]
 Bounds AS MIXERCONTROL_Bounds
 Metrics AS MIXERCONTROL_Metrics
END TYPE
MACRO MIXERCONTROL = MIXERCONTROLA
'/* */
'/* MIXERCONTROL.fdwControl */
'/* */
'/* */
%EQUATE `MIXERCONTROL_CONTROLF_UNIFORM = &H00000001
%EQUATE `MIXERCONTROL_CONTROLF_MULTIPLE = &H00000002
%EQUATE `MIXERCONTROL_CONTROLF_DISABLED = &H80000000
'/* */
'/* MIXERCONTROL_CONTROLTYPE_xxx building block defines */
'/* */
'/* */
%EQUATE `MIXERCONTROL_CT_CLASS_MASK = &HF0000000
%EQUATE `MIXERCONTROL_CT_CLASS_CUSTOM = &H00000000
%EQUATE `MIXERCONTROL_CT_CLASS_METER = &H10000000
%EQUATE `MIXERCONTROL_CT_CLASS_SWITCH = &H20000000
%EQUATE `MIXERCONTROL_CT_CLASS_NUMBER = &H30000000
%EQUATE `MIXERCONTROL_CT_CLASS_SLIDER = &H40000000
%EQUATE `MIXERCONTROL_CT_CLASS_FADER = &H50000000
%EQUATE `MIXERCONTROL_CT_CLASS_TIME = &H60000000
%EQUATE `MIXERCONTROL_CT_CLASS_LIST = &H70000000
%EQUATE `MIXERCONTROL_CT_SUBCLASS_MASK = &H0F000000
%EQUATE `MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = &H00000000
%EQUATE `MIXERCONTROL_CT_SC_SWITCH_BUTTON = &H01000000
%EQUATE `MIXERCONTROL_CT_SC_METER_POLLED = &H00000000
%EQUATE `MIXERCONTROL_CT_SC_TIME_MICROSECS = &H00000000
%EQUATE `MIXERCONTROL_CT_SC_TIME_MILLISECS = &H01000000
%EQUATE `MIXERCONTROL_CT_SC_LIST_SINGLE = &H00000000
%EQUATE `MIXERCONTROL_CT_SC_LIST_MULTIPLE = &H01000000
%EQUATE `MIXERCONTROL_CT_UNITS_MASK = &H00FF0000
%EQUATE `MIXERCONTROL_CT_UNITS_CUSTOM = &H00000000
%EQUATE `MIXERCONTROL_CT_UNITS_BOOLEAN = &H00010000
%EQUATE `MIXERCONTROL_CT_UNITS_SIGNED = &H00020000
%EQUATE `MIXERCONTROL_CT_UNITS_UNSIGNED = &H00030000
%EQUATE `MIXERCONTROL_CT_UNITS_DECIBELS = &H00040000
%EQUATE `MIXERCONTROL_CT_UNITS_PERCENT = &H00050000
'/* */
'/* Commonly used control types for specifying MIXERCONTROL.dwControlType */
'/* */
%EQUATE `MIXERCONTROL_CONTROLTYPE_CUSTOM = %MIXERCONTROL_CT_CLASS_CUSTOM OR %MIXERCONTROL_CT_UNITS_CUSTOM
%EQUATE `MIXERCONTROL_CONTROLTYPE_BOOLEANMETER = %MIXERCONTROL_CT_CLASS_METER OR %MIXERCONTROL_CT_SC_METER_POLLED OR %MIXERCONTROL_CT_UNITS_BOOLEAN
%EQUATE `MIXERCONTROL_CONTROLTYPE_SIGNEDMETER = %MIXERCONTROL_CT_CLASS_METER OR %MIXERCONTROL_CT_SC_METER_POLLED OR %MIXERCONTROL_CT_UNITS_SIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_PEAKMETER = %MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER = %MIXERCONTROL_CT_CLASS_METER OR %MIXERCONTROL_CT_SC_METER_POLLED OR %MIXERCONTROL_CT_UNITS_UNSIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_BOOLEAN = %MIXERCONTROL_CT_CLASS_SWITCH OR %MIXERCONTROL_CT_SC_SWITCH_BOOLEAN OR %MIXERCONTROL_CT_UNITS_BOOLEAN
%EQUATE `MIXERCONTROL_CONTROLTYPE_ONOFF = %MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_MUTE = %MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2
%EQUATE `MIXERCONTROL_CONTROLTYPE_MONO = %MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3
%EQUATE `MIXERCONTROL_CONTROLTYPE_LOUDNESS = %MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4
%EQUATE `MIXERCONTROL_CONTROLTYPE_STEREOENH = %MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5
%EQUATE `MIXERCONTROL_CONTROLTYPE_BUTTON = %MIXERCONTROL_CT_CLASS_SWITCH OR %MIXERCONTROL_CT_SC_SWITCH_BUTTON OR %MIXERCONTROL_CT_UNITS_BOOLEAN
%EQUATE `MIXERCONTROL_CONTROLTYPE_DECIBELS = %MIXERCONTROL_CT_CLASS_NUMBER OR %MIXERCONTROL_CT_UNITS_DECIBELS
%EQUATE `MIXERCONTROL_CONTROLTYPE_SIGNED = %MIXERCONTROL_CT_CLASS_NUMBER OR %MIXERCONTROL_CT_UNITS_SIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_UNSIGNED = %MIXERCONTROL_CT_CLASS_NUMBER OR %MIXERCONTROL_CT_UNITS_UNSIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_PERCENT = %MIXERCONTROL_CT_CLASS_NUMBER OR %MIXERCONTROL_CT_UNITS_PERCENT
%EQUATE `MIXERCONTROL_CONTROLTYPE_SLIDER = %MIXERCONTROL_CT_CLASS_SLIDER OR %MIXERCONTROL_CT_UNITS_SIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_PAN = %MIXERCONTROL_CONTROLTYPE_SLIDER + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_QSOUNDPAN = %MIXERCONTROL_CONTROLTYPE_SLIDER + 2
%EQUATE `MIXERCONTROL_CONTROLTYPE_FADER = %MIXERCONTROL_CT_CLASS_FADER OR %MIXERCONTROL_CT_UNITS_UNSIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_VOLUME = %MIXERCONTROL_CONTROLTYPE_FADER + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_BASS = %MIXERCONTROL_CONTROLTYPE_FADER + 2
%EQUATE `MIXERCONTROL_CONTROLTYPE_TREBLE = %MIXERCONTROL_CONTROLTYPE_FADER + 3
%EQUATE `MIXERCONTROL_CONTROLTYPE_EQUALIZER = %MIXERCONTROL_CONTROLTYPE_FADER + 4
%EQUATE `MIXERCONTROL_CONTROLTYPE_SINGLESELECT = %MIXERCONTROL_CT_CLASS_LIST OR %MIXERCONTROL_CT_SC_LIST_SINGLE OR %MIXERCONTROL_CT_UNITS_BOOLEAN
%EQUATE `MIXERCONTROL_CONTROLTYPE_MUX = %MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT = %MIXERCONTROL_CT_CLASS_LIST OR %MIXERCONTROL_CT_SC_LIST_MULTIPLE OR %MIXERCONTROL_CT_UNITS_BOOLEAN
%EQUATE `MIXERCONTROL_CONTROLTYPE_MIXER = %MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1
%EQUATE `MIXERCONTROL_CONTROLTYPE_MICROTIME = %MIXERCONTROL_CT_CLASS_TIME OR %MIXERCONTROL_CT_SC_TIME_MICROSECS OR %MIXERCONTROL_CT_UNITS_UNSIGNED
%EQUATE `MIXERCONTROL_CONTROLTYPE_MILLITIME = %MIXERCONTROL_CT_CLASS_TIME OR %MIXERCONTROL_CT_SC_TIME_MILLISECS OR %MIXERCONTROL_CT_UNITS_UNSIGNED
'/* */
'/* MIXERLINECONTROLS */
'/* */
'#ifdef _WIN32
'typedef struct tagMIXERLINECONTROLSA {
' DWORD cbStruct; /* size in bytes of MIXERLINECONTROLS */
' DWORD dwLineID; /* line id (from MIXERLINE.dwLineID) */
' union {
' DWORD dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */
' DWORD dwControlType; /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
' } DUMMYUNIONNAME;
' DWORD cControls; /* count of controls pmxctrl points to */
' DWORD cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */
' LPMIXERCONTROLA pamxctrl; /* pointer to first MIXERCONTROL array */
'} MIXERLINECONTROLSA, *PMIXERLINECONTROLSA, *LPMIXERLINECONTROLSA;
' // Size = 4 bytes
UNION MIXERLINECONTROLS_UNION BYTE
 dwControlID AS DWORD ' DWORD dwControlID /* MIXER_GETLINECONTROLSF_ONEBYID */
 dwControlType AS DWORD ' DWORD dwControlType /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
END UNION
' // Size = 24 bytes
TYPE MIXERLINECONTROLSA BYTE
 cbStruct AS DWORD ' DWORD cbStruct /* size in bytes of MIXERLINECONTROLS */
 dwLineID AS DWORD ' DWORD dwLineID /* line id (from MIXERLINE.dwLineID) */
 MIXERLINECONTROLS_UNION
 cControls AS DWORD ' DWORD cControls /* count of controls pmxctrl points to */
 cbmxctrl AS DWORD ' DWORD cbmxctrl /* size in bytes of _one_ MIXERCONTROL */
 pamxctrl AS MIXERCONTROL PTR ' LPMIXERCONTROLA pamxctrl /* pointer to first MIXERCONTROL array */
END TYPE
'typedef struct tagMIXERLINECONTROLSW {
' DWORD cbStruct; /* size in bytes of MIXERLINECONTROLS */
' DWORD dwLineID; /* line id (from MIXERLINE.dwLineID) */
' union {
' DWORD dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */
' DWORD dwControlType; /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
' } DUMMYUNIONNAME;
' DWORD cControls; /* count of controls pmxctrl points to */
' DWORD cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */
' LPMIXERCONTROLW pamxctrl; /* pointer to first MIXERCONTROL array */
'} MIXERLINECONTROLSW, *PMIXERLINECONTROLSW, *LPMIXERLINECONTROLSW;
' // Size = 24 bytes
TYPE MIXERLINECONTROLSW BYTE
 cbStruct AS DWORD ' DWORD cbStruct /* size in bytes of MIXERLINECONTROLS */
 dwLineID AS DWORD ' DWORD dwLineID /* line id (from MIXERLINE.dwLineID) */
 MIXERLINECONTROLS_UNION
 cControls AS DWORD ' DWORD cControls /* count of controls pmxctrl points to */
 cbmxctrl AS DWORD ' DWORD cbmxctrl /* size in bytes of _one_ MIXERCONTROL */
 pamxctrl AS MIXERCONTROLW PTR ' LPMIXERCONTROLW pamxctrl /* pointer to first MIXERCONTROL array */
END TYPE
MACRO MIXERLINECONTROLS = MIXERLINECONTROLSA
'/* */
'/* */
'/* */
DECLARE FUNCTION mixerGetLineControlsA LIB "winmm.dll" ALIAS "mixerGetLineControlsA" ( BYVAL hmxobj AS QUAD , BYREF pmxlc AS MIXERLINECONTROLSA , BYVAL fdwControls AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerGetLineControlsW LIB "winmm.dll" ALIAS "mixerGetLineControlsW" ( BYVAL hmxobj AS QUAD , BYREF pmxlc AS MIXERLINECONTROLSW , BYVAL fdwControls AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO mixerGetLineControls = mixerGetLineControlsW
#ELSE
 MACRO mixerGetLineControls = mixerGetLineControlsA
#ENDIF
%EQUATE `MIXER_GETLINECONTROLSF_ALL = &H00000000
%EQUATE `MIXER_GETLINECONTROLSF_ONEBYID = &H00000001
%EQUATE `MIXER_GETLINECONTROLSF_ONEBYTYPE = &H00000002
%EQUATE `MIXER_GETLINECONTROLSF_QUERYMASK = &H0000000F
'typedef struct tMIXERCONTROLDETAILS {
' DWORD cbStruct; /* size in bytes of MIXERCONTROLDETAILS */
' DWORD dwControlID; /* control id to get/set details on */
' DWORD cChannels; /* number of channels in paDetails array */
' union {
' HWND hwndOwner; /* for MIXER_SETCONTROLDETAILSF_CUSTOM */
' DWORD cMultipleItems; /* if _MULTIPLE, the number of items per channel */
' } DUMMYUNIONNAME;
' DWORD cbDetails; /* size of _one_ details_XX struct */
' LPVOID paDetails; /* pointer to array of details_XX structs */
'} MIXERCONTROLDETAILS, *PMIXERCONTROLDETAILS, FAR *LPMIXERCONTROLDETAILS;
' // Size = 4 bytes
UNION MIXERCONTROLDETAILS_UNION BYTE
 hwndOwner AS DWORD ' HWND hwndOwner /* for MIXER_SETCONTROLDETAILSF_CUSTOM */
 cMultipleItems AS DWORD ' DWORD cMultipleItems /* if _MULTIPLE, the number of items per channel */
END UNION
' // Size = 24 bytes
TYPE MIXERCONTROLDETAILS BYTE
 cbStruct AS DWORD ' DWORD cbStruct /* size in bytes of MIXERCONTROLDETAILS */
 dwControlID AS DWORD ' DWORD dwControlID /* control id to get/set details on */
 cChannels AS DWORD ' DWORD cChannels /* number of channels in paDetails array */
 MIXERCONTROLDETAILS_UNION
 cbDetails AS DWORD ' DWORD cbDetails /* size of _one_ details_XX struct */
 paDetails AS LONG ' LPVOID paDetails /* pointer to array of details_XX structs */
END TYPE
'/* */
'/* MIXER_GETCONTROLDETAILSF_LISTTEXT */
'/* */
'/* */
' // Size = 72 bytes
TYPE MIXERCONTROLDETAILS_LISTTEXTA BYTE
 dwParam1 AS DWORD ' DWORD dwParam1
 dwParam2 AS DWORD ' DWORD dwParam2
 szName AS ASCIIZ * %MIXER_LONG_NAME_CHARS ' CHAR szName[MIXER_LONG_NAME_CHARS]
END TYPE
' // Size = 136 bytes
TYPE MIXERCONTROLDETAILS_LISTTEXTW
 dwParam1 AS DWORD ' DWORD dwParam1
 dwParam2 AS DWORD ' DWORD dwParam2
 szName AS WSTRINGZ * %MIXER_LONG_NAME_CHARS ' WCHAR szName[MIXER_LONG_NAME_CHARS]
END TYPE
MACRO MIXERCONTROLDETAILS_LISTTEXT = MIXERCONTROLDETAILS_LISTTEXTA
'/* */
'/* MIXER_GETCONTROLDETAILSF_VALUE */
'/* */
'/* */
' // Size = 4 bytes
TYPE MIXERCONTROLDETAILS_BOOLEAN BYTE
 fValue AS LONG ' LONG fValue
END TYPE
' // Size = 4 bytes
TYPE MIXERCONTROLDETAILS_SIGNED BYTE
 lValue AS LONG ' LONG lValue
END TYPE
' // Size = 4 bytes
TYPE MIXERCONTROLDETAILS_UNSIGNED BYTE
 dwValue AS DWORD ' DWORD dwValue
END TYPE
DECLARE FUNCTION mixerGetControlDetailsA LIB "winmm.dll" ALIAS "mixerGetControlDetailsA" ( BYVAL hmxobj AS QUAD , BYREF pmxcd AS MIXERCONTROLDETAILS , BYVAL fdwDetails AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mixerGetControlDetailsW LIB "winmm.dll" ALIAS "mixerGetControlDetailsW" ( BYVAL hmxobj AS QUAD , BYREF pmxcd AS MIXERCONTROLDETAILS , BYVAL fdwDetails AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO mixerGetControlDetails = mixerGetControlDetailsW
#ELSE
 MACRO mixerGetControlDetails = mixerGetControlDetailsA
#ENDIF
%EQUATE `MIXER_GETCONTROLDETAILSF_VALUE = &H00000000
%EQUATE `MIXER_GETCONTROLDETAILSF_LISTTEXT = &H00000001
%EQUATE `MIXER_GETCONTROLDETAILSF_QUERYMASK = &H0000000F
DECLARE FUNCTION mixerSetControlDetails LIB "winmm.dll" ALIAS "mixerSetControlDetails" ( BYVAL hmxobj AS QUAD , BYREF pmxcd AS MIXERCONTROLDETAILS , BYVAL fdwDetails AS QUAD ) AS LONG ' MMRESULT
%EQUATE `MIXER_SETCONTROLDETAILSF_VALUE = &H00000000
%EQUATE `MIXER_SETCONTROLDETAILSF_CUSTOM = &H00000001
%EQUATE `MIXER_SETCONTROLDETAILSF_QUERYMASK = &H0000000F
#ENDIF ' IF NOT %DEF(%MMNOMIXER)
#IF NOT %DEF(%MMNOTIMER)
'/****************************************************************************
' Timer support
'****************************************************************************/
'/* timer error return values */
%EQUATE `TIMERR_NOERROR = 0 ' no error
%EQUATE `TIMERR_NOCANDO = %TIMERR_BASE + 1 ' request not completed
%EQUATE `TIMERR_STRUCT = %TIMERR_BASE + 33 ' time struct size
'/* timer data types */
'typedef void (CALLBACK TIMECALLBACK)(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
'DECLARE SUB TIMECALLBACK (BYVAL uTimerID AS DWORD, BYVAL uMsg AS DWORD, BYVAL dwUser AS DWORD, BYVAL dw1 AS DWORD, BYVAL dw2 AS DWORD)
'typedef TIMECALLBACK FAR *LPTIMECALLBACK;
'/* flags for fuEvent parameter of timeSetEvent() function */
%EQUATE `TIME_ONESHOT = &H0000 ' program timer for single event
%EQUATE `TIME_PERIODIC = &H0001 ' program for continuous periodic event
%EQUATE `TIME_CALLBACK_FUNCTION = &H0000 ' /* callback is function */
%EQUATE `TIME_CALLBACK_EVENT_SET = &H0010 ' /* callback is event - use SetEvent */
%EQUATE `TIME_CALLBACK_EVENT_PULSE = &H0020 ' /* callback is event - use PulseEvent */
'#if WINVER >= 0x0501
%EQUATE `TIME_KILL_SYNCHRONOUS = &H0100 ' /* This flag prevents the event from occurring */
' ' /* after the user calls timeKillEvent() to */
' ' /* destroy it. */
'#endif // WINVER >= 0x0501
'/* timer device capabilities data structure */
' // Size = 8 bytes
TYPE TIMECAPS BYTE
 wPeriodMin AS DWORD ' UINT wPeriodMin /* minimum period supported */
 wPeriodMax AS DWORD ' UINT wPeriodMax /* maximum period supported */
END TYPE
'/* timer function prototypes */
DECLARE FUNCTION timeGetSystemTime LIB "winmm.dll" ALIAS "timeGetSystemTime" ( BYREF pmmt AS MMTIME , BYVAL cbmmt AS QUAD ) AS QUAD ' MMRESULT
DECLARE FUNCTION timeGetTime LIB "winmm.dll" ALIAS "timeGetTime" ( ) AS QUAD
DECLARE FUNCTION timeSetEvent LIB "winmm.dll" ALIAS "timeSetEvent" ( BYVAL uDelay AS QUAD , BYVAL uResolution AS QUAD
 , BYVAL fptc AS DWORD
 , BYVAL dwUser AS DWORD
 , BYVAL fuEvent AS DWORD
 ) AS DWORD ' MMRESULT
DECLARE FUNCTION timeKillEvent LIB "winmm.dll" ALIAS "timeKillEvent" ( BYVAL uTimerID AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION timeGetDevCaps LIB "winmm.dll" ALIAS "timeGetDevCaps" ( BYREF ptc AS TIMECAPS , BYVAL cbtc AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION timeBeginPeriod LIB "winmm.dll" ALIAS "timeBeginPeriod" ( BYVAL uPeriod AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION timeEndPeriod LIB "winmm.dll" ALIAS "timeEndPeriod" ( BYVAL uPeriod AS QUAD ) AS LONG ' MMRESULT
#ENDIF ' /* ifndef MMNOTIMER */
#IF NOT %DEF(%MMNOJOY)
'/****************************************************************************
' Joystick support
'****************************************************************************/
'/* joystick error return values */
%EQUATE `JOYERR_NOERROR = 0 ' no error
%EQUATE `JOYERR_PARMS = %JOYERR_BASE + 5 ' bad parameters
%EQUATE `JOYERR_NOCANDO = %JOYERR_BASE + 6 ' request not completed
%EQUATE `JOYERR_UNPLUGGED = %JOYERR_BASE + 7 ' joystick is unplugged
'/* constants used with JOYINFO and JOYINFOEX structures and MM_JOY* messages */
%EQUATE `JOY_BUTTON1 = &H0001
%EQUATE `JOY_BUTTON2 = &H0002
%EQUATE `JOY_BUTTON3 = &H0004
%EQUATE `JOY_BUTTON4 = &H0008
%EQUATE `JOY_BUTTON1CHG = &H0100
%EQUATE `JOY_BUTTON2CHG = &H0200
%EQUATE `JOY_BUTTON3CHG = &H0400
%EQUATE `JOY_BUTTON4CHG = &H0800
'/* constants used with JOYINFOEX */
%EQUATE `JOY_BUTTON5 = &H00000010
%EQUATE `JOY_BUTTON6 = &H00000020
%EQUATE `JOY_BUTTON7 = &H00000040
%EQUATE `JOY_BUTTON8 = &H00000080
%EQUATE `JOY_BUTTON9 = &H00000100
%EQUATE `JOY_BUTTON10 = &H00000200
%EQUATE `JOY_BUTTON11 = &H00000400
%EQUATE `JOY_BUTTON12 = &H00000800
%EQUATE `JOY_BUTTON13 = &H00001000
%EQUATE `JOY_BUTTON14 = &H00002000
%EQUATE `JOY_BUTTON15 = &H00004000
%EQUATE `JOY_BUTTON16 = &H00008000
%EQUATE `JOY_BUTTON17 = &H00010000
%EQUATE `JOY_BUTTON18 = &H00020000
%EQUATE `JOY_BUTTON19 = &H00040000
%EQUATE `JOY_BUTTON20 = &H00080000
%EQUATE `JOY_BUTTON21 = &H00100000
%EQUATE `JOY_BUTTON22 = &H00200000
%EQUATE `JOY_BUTTON23 = &H00400000
%EQUATE `JOY_BUTTON24 = &H00800000
%EQUATE `JOY_BUTTON25 = &H01000000
%EQUATE `JOY_BUTTON26 = &H02000000
%EQUATE `JOY_BUTTON27 = &H04000000
%EQUATE `JOY_BUTTON28 = &H08000000
%EQUATE `JOY_BUTTON29 = &H10000000
%EQUATE `JOY_BUTTON30 = &H20000000
%EQUATE `JOY_BUTTON31 = &H40000000
%EQUATE `JOY_BUTTON32 = &H80000000
'/* constants used with JOYINFOEX structure */
%EQUATE `JOY_POVCENTERED = &HFFFF ' (WORD) -1
%EQUATE `JOY_POVFORWARD = 0
%EQUATE `JOY_POVRIGHT = 9000
%EQUATE `JOY_POVBACKWARD = 18000
%EQUATE `JOY_POVLEFT = 27000
%EQUATE `JOY_RETURNX = &H00000001
%EQUATE `JOY_RETURNY = &H00000002
%EQUATE `JOY_RETURNZ = &H00000004
%EQUATE `JOY_RETURNR = &H00000008
%EQUATE `JOY_RETURNU = &H00000010 ' /* axis 5 */
%EQUATE `JOY_RETURNV = &H00000020 ' /* axis 6 */
%EQUATE `JOY_RETURNPOV = &H00000040
%EQUATE `JOY_RETURNBUTTONS = &H00000080
%EQUATE `JOY_RETURNRAWDATA = &H00000100
%EQUATE `JOY_RETURNPOVCTS = &H00000200
%EQUATE `JOY_RETURNCENTERED = &H00000400
%EQUATE `JOY_USEDEADZONE = &H00000800
%EQUATE `JOY_RETURNALL = %JOY_RETURNX OR %JOY_RETURNY OR %JOY_RETURNZ OR %JOY_RETURNR OR %JOY_RETURNU OR %JOY_RETURNV OR %JOY_RETURNPOV OR %JOY_RETURNBUTTONS
%EQUATE `JOY_CAL_READALWAYS = &H00010000
%EQUATE `JOY_CAL_READXYONLY = &H00020000
%EQUATE `JOY_CAL_READ3 = &H00040000
%EQUATE `JOY_CAL_READ4 = &H00080000
%EQUATE `JOY_CAL_READXONLY = &H00100000
%EQUATE `JOY_CAL_READYONLY = &H00200000
%EQUATE `JOY_CAL_READ5 = &H00400000
%EQUATE `JOY_CAL_READ6 = &H00800000
%EQUATE `JOY_CAL_READZONLY = &H01000000
%EQUATE `JOY_CAL_READRONLY = &H02000000
%EQUATE `JOY_CAL_READUONLY = &H04000000
%EQUATE `JOY_CAL_READVONLY = &H08000000
'/* joystick ID constants */
%EQUATE `JOYSTICKID1 = 0
%EQUATE `JOYSTICKID2 = 1
'/* joystick driver capabilites */
%EQUATE `JOYCAPS_HASZ = &H0001
%EQUATE `JOYCAPS_HASR = &H0002
%EQUATE `JOYCAPS_HASU = &H0004
%EQUATE `JOYCAPS_HASV = &H0008
%EQUATE `JOYCAPS_HASPOV = &H0010
%EQUATE `JOYCAPS_POV4DIR = &H0020
%EQUATE `JOYCAPS_POVCTS = &H0040
'/* joystick device capabilities data structure */
'#ifdef _WIN32
'typedef struct tagJOYCAPSA {
' WORD wMid; /* manufacturer ID */
' WORD wPid; /* product ID */
' CHAR szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
' UINT wXmin; /* minimum x position value */
' UINT wXmax; /* maximum x position value */
' UINT wYmin; /* minimum y position value */
' UINT wYmax; /* maximum y position value */
' UINT wZmin; /* minimum z position value */
' UINT wZmax; /* maximum z position value */
' UINT wNumButtons; /* number of buttons */
' UINT wPeriodMin; /* minimum message period when captured */
' UINT wPeriodMax; /* maximum message period when captured */
'#if (WINVER >= 0x0400)
' UINT wRmin; /* minimum r position value */
' UINT wRmax; /* maximum r position value */
' UINT wUmin; /* minimum u (5th axis) position value */
' UINT wUmax; /* maximum u (5th axis) position value */
' UINT wVmin; /* minimum v (6th axis) position value */
' UINT wVmax; /* maximum v (6th axis) position value */
' UINT wCaps; /* joystick capabilites */
' UINT wMaxAxes; /* maximum number of axes supported */
' UINT wNumAxes; /* number of axes in use */
' UINT wMaxButtons; /* maximum number of buttons supported */
' CHAR szRegKey[MAXPNAMELEN];/* registry key */
' CHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; /* OEM VxD in use */
'#endif
'} JOYCAPSA, *PJOYCAPSA, *NPJOYCAPSA, *LPJOYCAPSA;
' // Size = 404 bytes
TYPE JOYCAPSA BYTE
 wMid AS WORD
 wPid AS WORD
 szPname AS ASCIIZ * %MAXPNAMELEN
 wXmin AS DWORD
 wXmax AS DWORD
 wYmin AS DWORD
 wYmax AS DWORD
 wZmin AS DWORD
 wZmax AS DWORD
 wNumButtons AS DWORD
 wPeriodMin AS DWORD
 wPeriodMax AS DWORD
 wRmin AS DWORD
 wRmax AS DWORD
 wUmin AS DWORD
 wUmax AS DWORD
 wVmin AS DWORD
 wVmax AS DWORD
 wCaps AS DWORD
 wMaxAxes AS DWORD
 wNumAxes AS DWORD
 wMaxButtons AS DWORD
 szRegKey AS ASCIIZ * %MAXPNAMELEN
 szOEMVxD AS ASCIIZ * %MAX_JOYSTICKOEMVXDNAME
END TYPE
'typedef struct tagJOYCAPSW {
' WORD wMid; /* manufacturer ID */
' WORD wPid; /* product ID */
' WCHAR szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
' UINT wXmin; /* minimum x position value */
' UINT wXmax; /* maximum x position value */
' UINT wYmin; /* minimum y position value */
' UINT wYmax; /* maximum y position value */
' UINT wZmin; /* minimum z position value */
' UINT wZmax; /* maximum z position value */
' UINT wNumButtons; /* number of buttons */
' UINT wPeriodMin; /* minimum message period when captured */
' UINT wPeriodMax; /* maximum message period when captured */
'#if (WINVER >= 0x0400)
' UINT wRmin; /* minimum r position value */
' UINT wRmax; /* maximum r position value */
' UINT wUmin; /* minimum u (5th axis) position value */
' UINT wUmax; /* maximum u (5th axis) position value */
' UINT wVmin; /* minimum v (6th axis) position value */
' UINT wVmax; /* maximum v (6th axis) position value */
' UINT wCaps; /* joystick capabilites */
' UINT wMaxAxes; /* maximum number of axes supported */
' UINT wNumAxes; /* number of axes in use */
' UINT wMaxButtons; /* maximum number of buttons supported */
' WCHAR szRegKey[MAXPNAMELEN];/* registry key */
' WCHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; /* OEM VxD in use */
'#endif
'} JOYCAPSW, *PJOYCAPSW, *NPJOYCAPSW, *LPJOYCAPSW;
' // Size = 728 bytes
TYPE JOYCAPSW BYTE
 wMid AS WORD
 wPid AS WORD
 szPname AS WSTRINGZ * %MAXPNAMELEN
 wXmin AS DWORD
 wXmax AS DWORD
 wYmin AS DWORD
 wYmax AS DWORD
 wZmin AS DWORD
 wZmax AS DWORD
 wNumButtons AS DWORD
 wPeriodMin AS DWORD
 wPeriodMax AS DWORD
 wRmin AS DWORD
 wRmax AS DWORD
 wUmin AS DWORD
 wUmax AS DWORD
 wVmin AS DWORD
 wVmax AS DWORD
 wCaps AS DWORD
 wMaxAxes AS DWORD
 wNumAxes AS DWORD
 wMaxButtons AS DWORD
 szRegKey AS WSTRINGZ * %MAXPNAMELEN
 szOEMVxD AS WSTRINGZ * %MAX_JOYSTICKOEMVXDNAME
END TYPE
MACRO JOYCAPS = JOYCAPSA
'typedef struct tagJOYCAPS2A {
' WORD wMid; /* manufacturer ID */
' WORD wPid; /* product ID */
' CHAR szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
' UINT wXmin; /* minimum x position value */
' UINT wXmax; /* maximum x position value */
' UINT wYmin; /* minimum y position value */
' UINT wYmax; /* maximum y position value */
' UINT wZmin; /* minimum z position value */
' UINT wZmax; /* maximum z position value */
' UINT wNumButtons; /* number of buttons */
' UINT wPeriodMin; /* minimum message period when captured */
' UINT wPeriodMax; /* maximum message period when captured */
' UINT wRmin; /* minimum r position value */
' UINT wRmax; /* maximum r position value */
' UINT wUmin; /* minimum u (5th axis) position value */
' UINT wUmax; /* maximum u (5th axis) position value */
' UINT wVmin; /* minimum v (6th axis) position value */
' UINT wVmax; /* maximum v (6th axis) position value */
' UINT wCaps; /* joystick capabilites */
' UINT wMaxAxes; /* maximum number of axes supported */
' UINT wNumAxes; /* number of axes in use */
' UINT wMaxButtons; /* maximum number of buttons supported */
' CHAR szRegKey[MAXPNAMELEN];/* registry key */
' CHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; /* OEM VxD in use */
' GUID ManufacturerGuid; /* for extensible MID mapping */
' GUID ProductGuid; /* for extensible PID mapping */
' GUID NameGuid; /* for name lookup in registry */
'} JOYCAPS2A, *PJOYCAPS2A, *NPJOYCAPS2A, *LPJOYCAPS2A;
' // Size = 452 bytes
TYPE JOYCAPS2A BYTE
 wMid AS WORD
 wPid AS WORD
 szPname AS ASCIIZ * %MAXPNAMELEN
 wXmin AS DWORD
 wXmax AS DWORD
 wYmin AS DWORD
 wYmax AS DWORD
 wZmin AS DWORD
 wZmax AS DWORD
 wNumButtons AS DWORD
 wPeriodMin AS DWORD
 wPeriodMax AS DWORD
 wRmin AS DWORD
 wRmax AS DWORD
 wUmin AS DWORD
 wUmax AS DWORD
 wVmin AS DWORD
 wVmax AS DWORD
 wCaps AS DWORD
 wMaxAxes AS DWORD
 wNumAxes AS DWORD
 wMaxButtons AS DWORD
 szRegKey AS ASCIIZ * %MAXPNAMELEN
 szOEMVxD AS ASCIIZ * %MAX_JOYSTICKOEMVXDNAME
 ManufacturerGuid AS GUID
 ProductGuid AS GUID
 NameGuid AS GUID
END TYPE
'typedef struct tagJOYCAPS2W {
' WORD wMid; /* manufacturer ID */
' WORD wPid; /* product ID */
' WCHAR szPname[MAXPNAMELEN];/* product name (NULL terminated string) */
' UINT wXmin; /* minimum x position value */
' UINT wXmax; /* maximum x position value */
' UINT wYmin; /* minimum y position value */
' UINT wYmax; /* maximum y position value */
' UINT wZmin; /* minimum z position value */
' UINT wZmax; /* maximum z position value */
' UINT wNumButtons; /* number of buttons */
' UINT wPeriodMin; /* minimum message period when captured */
' UINT wPeriodMax; /* maximum message period when captured */
' UINT wRmin; /* minimum r position value */
' UINT wRmax; /* maximum r position value */
' UINT wUmin; /* minimum u (5th axis) position value */
' UINT wUmax; /* maximum u (5th axis) position value */
' UINT wVmin; /* minimum v (6th axis) position value */
' UINT wVmax; /* maximum v (6th axis) position value */
' UINT wCaps; /* joystick capabilites */
' UINT wMaxAxes; /* maximum number of axes supported */
' UINT wNumAxes; /* number of axes in use */
' UINT wMaxButtons; /* maximum number of buttons supported */
' WCHAR szRegKey[MAXPNAMELEN];/* registry key */
' WCHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; /* OEM VxD in use */
' GUID ManufacturerGuid; /* for extensible MID mapping */
' GUID ProductGuid; /* for extensible PID mapping */
' GUID NameGuid; /* for name lookup in registry */
'} JOYCAPS2W, *PJOYCAPS2W, *NPJOYCAPS2W, *LPJOYCAPS2W;
' // Size = 776 bytes
TYPE JOYCAPS2W BYTE
 wMid AS WORD
 wPid AS WORD
 szPname AS WSTRINGZ * %MAXPNAMELEN
 wXmin AS DWORD
 wXmax AS DWORD
 wYmin AS DWORD
 wYmax AS DWORD
 wZmin AS DWORD
 wZmax AS DWORD
 wNumButtons AS DWORD
 wPeriodMin AS DWORD
 wPeriodMax AS DWORD
 wRmin AS DWORD
 wRmax AS DWORD
 wUmin AS DWORD
 wUmax AS DWORD
 wVmin AS DWORD
 wVmax AS DWORD
 wCaps AS DWORD
 wMaxAxes AS DWORD
 wNumAxes AS DWORD
 wMaxButtons AS DWORD
 szRegKey AS WSTRINGZ * %MAXPNAMELEN
 szOEMVxD AS WSTRINGZ * %MAX_JOYSTICKOEMVXDNAME
 ManufacturerGuid AS GUID
 ProductGuid AS GUID
 NameGuid AS GUID
END TYPE
MACRO JOYCAPS2 = JOYCAPS2A
'/* joystick information data structure */
'typedef struct joyinfo_tag {
' UINT wXpos; /* x position */
' UINT wYpos; /* y position */
' UINT wZpos; /* z position */
' UINT wButtons; /* button states */
'} JOYINFO, *PJOYINFO, NEAR *NPJOYINFO, FAR *LPJOYINFO;
' // Size = 16 bytes
TYPE JOYINFO BYTE
 wXpos AS DWORD
 wYpos AS DWORD
 wZpos AS DWORD
 wButtons AS DWORD
END TYPE
'#if(WINVER >= 0x0400)
'typedef struct joyinfoex_tag {
' DWORD dwSize; /* size of structure */
' DWORD dwFlags; /* flags to indicate what to return */
' DWORD dwXpos; /* x position */
' DWORD dwYpos; /* y position */
' DWORD dwZpos; /* z position */
' DWORD dwRpos; /* rudder/4th axis position */
' DWORD dwUpos; /* 5th axis position */
' DWORD dwVpos; /* 6th axis position */
' DWORD dwButtons; /* button states */
' DWORD dwButtonNumber; /* current button number pressed */
' DWORD dwPOV; /* point of view state */
' DWORD dwReserved1; /* reserved for communication between winmm & driver */
' DWORD dwReserved2; /* reserved for future expansion */
'} JOYINFOEX, *PJOYINFOEX, NEAR *NPJOYINFOEX, FAR *LPJOYINFOEX;
'#endif /* WINVER >= 0x0400 */
' // Size = 52 bytes
TYPE JOYINFOEX BYTE
 dwSize AS DWORD ' size of structure
 dwFlags AS DWORD ' flags to indicate what to return
 dwXpos AS DWORD ' x position
 dwYpos AS DWORD ' y position
 dwZpos AS DWORD ' z position
 dwRpos AS DWORD ' rudder/4th axis position
 dwUpos AS DWORD ' 5th axis position
 dwVpos AS DWORD ' 6th axis position
 dwButtons AS DWORD ' button states
 dwButtonNumber AS DWORD ' current button number pressed
 dwPOV AS DWORD ' point of view state
 dwReserved1 AS DWORD ' reserved for communication between winmm driver
 dwReserved2 AS DWORD ' reserved for future expansion
END TYPE
'/* joystick function prototypes */
DECLARE FUNCTION joyGetNumDevs LIB "winmm.dll" ALIAS "joyGetNumDevs" ( ) AS QUAD ' UINT
DECLARE FUNCTION joyGetDevCapsA LIB "winmm.dll" ALIAS "joyGetDevCapsA" ( BYVAL uJoyID AS LONG , BYREF pjc AS JOYCAPSA , BYVAL cbjc AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION joyGetDevCapsW LIB "winmm.dll" ALIAS "joyGetDevCapsW" ( BYVAL uJoyID AS LONG , BYREF pjc AS JOYCAPSW , BYVAL cbjc AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO joyGetDevCaps = joyGetDevCapsW
#ELSE
 MACRO joyGetDevCaps = joyGetDevCapsA
#ENDIF
DECLARE FUNCTION joyGetPos LIB "winmm.dll" ALIAS "joyGetPos" ( BYVAL uJoyID AS QUAD , BYREF pji AS JOYINFO ) AS LONG ' MMRESULT
'#if(WINVER >= 0x0400)
'WINMMAPI MMRESULT WINAPI joyGetPosEx( IN UINT uJoyID, OUT LPJOYINFOEX pji);
DECLARE FUNCTION joyGetPosEx LIB "winmm.dll" ALIAS "joyGetPosEx" ( BYVAL uJoyID AS QUAD , BYREF pji AS JOYINFOEX ) AS LONG ' MMRESULT
'#endif /* WINVER >= 0x0400 */
DECLARE FUNCTION joyGetThreshold LIB "winmm.dll" ALIAS "joyGetThreshold" ( BYVAL uJoyID AS QUAD , BYREF puThreshold AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION joyReleaseCapture LIB "winmm.dll" ALIAS "joyReleaseCapture" ( BYVAL uJoyID AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION joySetCapture LIB "winmm.dll" ALIAS "joySetCapture" ( BYVAL hwnd AS QUAD , BYVAL uJoyID AS QUAD , BYVAL uPeriod AS QUAD , BYVAL fChanged AS LONG ) AS LONG ' MMRESULT
DECLARE FUNCTION joySetThreshold LIB "winmm.dll" ALIAS "joySetThreshold" ( BYVAL uJoyID AS QUAD , BYVAL uThreshold AS QUAD ) AS LONG ' MMRESULT
#ENDIF ' /* ifndef MMNOJOY */
#IF NOT %DEF(%MMNOMMIO)
'/****************************************************************************
' Multimedia File I/O support
'****************************************************************************/
'/* MMIO error return values */
%EQUATE `MMIOERR_BASE = 256
%EQUATE `MMIOERR_FILENOTFOUND = %MMIOERR_BASE + 1 ' file not found
%EQUATE `MMIOERR_OUTOFMEMORY = %MMIOERR_BASE + 2
%EQUATE `MMIOERR_CANNOTOPEN = %MMIOERR_BASE + 3 ' cannot open
%EQUATE `MMIOERR_CANNOTCLOSE = %MMIOERR_BASE + 4 ' cannot close
%EQUATE `MMIOERR_CANNOTREAD = %MMIOERR_BASE + 5 ' cannot read
%EQUATE `MMIOERR_CANNOTWRITE = %MMIOERR_BASE + 6 ' cannot write
%EQUATE `MMIOERR_CANNOTSEEK = %MMIOERR_BASE + 7 ' cannot seek
%EQUATE `MMIOERR_CANNOTEXPAND = %MMIOERR_BASE + 8 ' cannot expand file
%EQUATE `MMIOERR_CHUNKNOTFOUND = %MMIOERR_BASE + 9 ' chunk not found
%EQUATE `MMIOERR_UNBUFFERED = %MMIOERR_BASE + 10 ' file is unbuffered
%EQUATE `MMIOERR_PATHNOTFOUND = %MMIOERR_BASE + 11 ' path incorrect
%EQUATE `MMIOERR_ACCESSDENIED = %MMIOERR_BASE + 12 ' file was protected
%EQUATE `MMIOERR_SHARINGVIOLATION = %MMIOERR_BASE + 13 ' file in use
%EQUATE `MMIOERR_NETWORKERROR = %MMIOERR_BASE + 14 ' network not responding
%EQUATE `MMIOERR_TOOMANYOPENFILES = %MMIOERR_BASE + 15 ' no more file handles
%EQUATE `MMIOERR_INVALIDFILE = %MMIOERR_BASE + 16 ' default error file error
'/* MMIO constants */
$CFSEPCHAR = "+" ' compound file name separator char.
'/* MMIO data types */
'typedef DWORD FOURCC; /* a four character code */
'typedef char _huge * HPSTR; /* a huge version of LPSTR */
'DECLARE_HANDLE(HMMIO); /* a handle to an open file */
'typedef LRESULT (CALLBACK MMIOPROC)(LPSTR lpmmioinfo, UINT uMsg,
' LPARAM lParam1, LPARAM lParam2);
'typedef MMIOPROC FAR *LPMMIOPROC;
'DECLARE FUNCTION MMIOPROC (BYREF lpmmioinfo AS ASCIIZ, BYVAL uMsg AS DWORD, BYVAL lParam1 AS LONG, BYVAL lParam2 AS LONG)
'/* general MMIO information data structure */
'typedef struct _MMIOINFO
'{
' /* general fields */
' DWORD dwFlags; /* general status flags */
' FOURCC fccIOProc; /* pointer to I/O procedure */
' LPMMIOPROC pIOProc; /* pointer to I/O procedure */
' UINT wErrorRet; /* place for error to be returned */
' HTASK htask; /* alternate local task */
' /* fields maintained by MMIO functions during buffered I/O */
' LONG cchBuffer; /* size of I/O buffer (or 0L) */
' HPSTR pchBuffer; /* start of I/O buffer (or NULL) */
' HPSTR pchNext; /* pointer to next byte to read/write */
' HPSTR pchEndRead; /* pointer to last valid byte to read */
' HPSTR pchEndWrite; /* pointer to last byte to write */
' LONG lBufOffset; /* disk offset of start of buffer */
' /* fields maintained by I/O procedure */
' LONG lDiskOffset; /* disk offset of next read or write */
' DWORD adwInfo[3]; /* data specific to type of MMIOPROC */
' /* other fields maintained by MMIO */
' DWORD dwReserved1; /* reserved for MMIO use */
' DWORD dwReserved2; /* reserved for MMIO use */
' HMMIO hmmio; /* handle to open file */
'} MMIOINFO, *PMMIOINFO, NEAR *NPMMIOINFO, FAR *LPMMIOINFO;
'typedef const MMIOINFO FAR *LPCMMIOINFO;
' // Size = 72 bytes
TYPE MMIOINFO BYTE
 dwFlags AS DWORD
 fccIOProc AS DWORD
 pIOProc AS LONG
 wErrorRet AS DWORD
 htask AS DWORD
 cchBuffer AS LONG
 pchBuffer AS ASCIIZ PTR
 pchNext AS ASCIIZ PTR
 pchEndRead AS ASCIIZ PTR
 pchEndWrite AS ASCIIZ PTR
 lBufOffset AS LONG
 lDiskOffset AS LONG
 adwInfo(2) AS DWORD
 dwReserved1 AS DWORD
 dwReserved2 AS DWORD
 hmmio AS DWORD
END TYPE
'/* RIFF chunk information data structure */
'typedef struct _MMCKINFO
'{
' FOURCC ckid; /* chunk ID */
' DWORD cksize; /* chunk size */
' FOURCC fccType; /* form type or list type */
' DWORD dwDataOffset; /* offset of data portion of chunk */
' DWORD dwFlags; /* flags used by MMIO functions */
'} MMCKINFO, *PMMCKINFO, NEAR *NPMMCKINFO, FAR *LPMMCKINFO;
'typedef const MMCKINFO *LPCMMCKINFO;
' // Size = 20 bytes
TYPE MMCKINFO BYTE
 ckid AS DWORD
 ckSize AS DWORD
 fccType AS DWORD
 dwDataOffset AS DWORD
 dwFlags AS DWORD
END TYPE
'/* bit field masks */
%EQUATE `MMIO_RWMODE = &H00000003 ' mask to get bits used for opening
%EQUATE `MMIO_SHAREMODE = &H00000070 ' file sharing mode number
'/* constants for dwFlags field of MMIOINFO */
%EQUATE `MMIO_CREATE = &H00001000 ' create new file (or truncate file)
%EQUATE `MMIO_PARSE = &H00000100 ' parse new file returning path
%EQUATE `MMIO_DELETE = &H00000200 ' create new file (or truncate file)
%EQUATE `MMIO_EXIST = &H00004000 ' checks for existence of file
%EQUATE `MMIO_ALLOCBUF = &H00010000 ' mmioOpen() should allocate a buffer
%EQUATE `MMIO_GETTEMP = &H00020000 ' mmioOpen() should retrieve temp name
%EQUATE `MMIO_DIRTY = &H10000000 ' I/O buffer is dirty
'/* read/write mode numbers (bit field MMIO_RWMODE) */
%EQUATE `MMIO_READ = &H00000000 ' open file for reading only
%EQUATE `MMIO_WRITE = &H00000001 ' open file for writing only
%EQUATE `MMIO_READWRITE = &H00000002 ' open file for reading and writing
'/* share mode numbers (bit field MMIO_SHAREMODE) */
%EQUATE `MMIO_COMPAT = &H00000000 ' compatibility mode
%EQUATE `MMIO_EXCLUSIVE = &H00000010 ' exclusive-access mode
%EQUATE `MMIO_DENYWRITE = &H00000020 ' deny writing to other processes
%EQUATE `MMIO_DENYREAD = &H00000030 ' deny reading to other processes
%EQUATE `MMIO_DENYNONE = &H00000040 ' deny nothing to other processes
'/* various MMIO flags */
%EQUATE `MMIO_FHOPEN = &H0010 ' mmioClose(): keep file xHandle open
%EQUATE `MMIO_EMPTYBUF = &H0010 ' mmioFlush(): empty the I/O buffer
%EQUATE `MMIO_TOUPPER = &H0010 ' mmioStringToFOURCC(): cvt. to u-case
%EQUATE `MMIO_INSTALLPROC = &H00010000 ' mmioInstallIOProc(): install MMIOProc
%EQUATE `MMIO_GLOBALPROC = &H10000000 ' mmioInstallIOProc: install Globally
%EQUATE `MMIO_REMOVEPROC = &H00020000 ' mmioInstallIOProc(): remove MMIOProc
%EQUATE `MMIO_UNICODEPROC = &H01000000 ' mmioInstallIOProc(): Unicode MMIOProc
%EQUATE `MMIO_FINDPROC = &H00040000 ' mmioInstallIOProc(): find an MMIOProc
%EQUATE `MMIO_FINDCHUNK = &H0010 ' mmioDescend(): find a chunk by ID
%EQUATE `MMIO_FINDRIFF = &H0020 ' mmioDescend(): find a LIST chunk
%EQUATE `MMIO_FINDLIST = &H0040 ' mmioDescend(): find a RIFF chunk
%EQUATE `MMIO_CREATERIFF = &H0020 ' mmioCreateChunk(): make a LIST chunk
%EQUATE `MMIO_CREATELIST = &H0040 ' mmioCreateChunk(): make a RIFF chunk
'/* message numbers for MMIOPROC I/O procedure functions */
'#if (WINVER >= 0x030a)
'#define MMIOM_RENAME 6 /* rename specified file */
'#endif /* ifdef WINVER >= 0x030a */
'#define MMIOM_USER 0x8000 /* beginning of user-defined messages */
%EQUATE `MMIOM_READ = %MMIO_READ ' read (must equal MMIO_READ!)
%EQUATE `MMIOM_WRITE = %MMIO_WRITE ' write (must equal MMIO_WRITE!)
%EQUATE `MMIOM_SEEK = 2 ' seek to a new position in file
%EQUATE `MMIOM_OPEN = 3 ' open file
%EQUATE `MMIOM_CLOSE = 4 ' close file
%EQUATE `MMIOM_WRITEFLUSH = 5 ' write and flush
%EQUATE `MMIOM_RENAME = 6 ' rename specified file
%EQUATE `MMIOM_USER = &H00008000 ' beginning of user-defined messages
'/* standard four character codes */
'#define FOURCC_RIFF mmioFOURCC('R', 'I', 'F', 'F')
'#define FOURCC_LIST mmioFOURCC('L', 'I', 'S', 'T')
%EQUATE `FOURCC_RIFF = &H46464952
%EQUATE `FOURCC_LIST = &H5453494C
'/* four character codes used to identify standard built-in I/O procedures */
'#define FOURCC_DOS mmioFOURCC('D', 'O', 'S', ' ')
'#define FOURCC_MEM mmioFOURCC('M', 'E', 'M', ' ')
%EQUATE `FOURCC_DOS = &HFF534F44
%EQUATE `FOURCC_MEM = &HFF4D454D
'/* flags for mmioSeek() */
#IF NOT %DEF(%SEEK_SET)
%EQUATE `SEEK_SET = 0 ' seek to an absolute position
%EQUATE `SEEK_CUR = 1 ' seek relative to current position
%EQUATE `SEEK_END = 2 ' seek relative to end of file
#ENDIF
'/* other constants */
%EQUATE `MMIO_DEFAULTBUFFER = 8192 ' default buffer size
'/* MMIO macros */
'#define mmioFOURCC(ch0, ch1, ch2, ch3) MAKEFOURCC(ch0, ch1, ch2, ch3)
#IF NOT %DEF(%MMIOFOURCC_DEFINED)
%EQUATE `MMIOFOURCC_DEFINED = 1
FUNCTION mmioFOURCC (BYVAL st0 AS STRING, BYVAL st1 AS STRING, BYVAL st2 AS STRING, BYVAL st3 AS STRING) AS DWORD
 LOCAL ch0 AS DWORD, ch1 AS DWORD, ch2 AS DWORD, ch3 AS DWORD
 ch0 = ASC(st0)
 ch1 = ASC(st1)
 ch2 = ASC(st2)
 ch3 = ASC(st3)
 SHIFT LEFT ch1, 8
 SHIFT LEFT ch2, 16
 SHIFT LEFT ch3, 24
 FUNCTION = ch0 OR ch1 OR ch2 OR ch3
END FUNCTION
#ENDIF
'/* MMIO function prototypes */
DECLARE FUNCTION mmioStringToFOURCCA LIB "winmm.dll" ALIAS "mmioStringToFOURCCA" ( BYREF sz AS ASCIIZ , BYVAL uFlags AS QUAD ) AS QUAD ' FOURCC
DECLARE FUNCTION mmioStringToFOURCCW LIB "winmm.dll" ALIAS "mmioStringToFOURCCW" ( BYREF sz AS WSTRINGZ , BYVAL uFlags AS QUAD ) AS QUAD ' FOURCC
#IF %DEF(%UNICODE)
 MACRO mmioStringToFOURCC = mmioStringToFOURCCW
#ELSE
 MACRO mmioStringToFOURCC = mmioStringToFOURCCA
#ENDIF
DECLARE FUNCTION mmioInstallIOProcA LIB "winmm.dll" ALIAS "mmioInstallIOProcA" ( BYVAL fccIOProc AS QUAD , BYVAL pIOProc AS QUAD , BYVAL dwFlags AS QUAD ) AS QUAD
DECLARE FUNCTION mmioInstallIOProcW LIB "winmm.dll" ALIAS "mmioInstallIOProcW" ( BYVAL fccIOProc AS QUAD
 , BYVAL pIOProc AS DWORD
 , BYVAL dwFlags AS DWORD
 ) AS DWORD
#IF %DEF(%UNICODE)
 MACRO mmioInstallIOProc = mmioInstallIOProcW
#ELSE
 MACRO mmioInstallIOProc = mmioInstallIOProcA
#ENDIF
DECLARE FUNCTION mmioOpenA LIB "winmm.dll" ALIAS "mmioOpenA" ( BYREF pszFileName AS ASCIIZ , BYREF pmmioinfo AS MMIOINFO , BYVAL fdwOpen AS QUAD ) AS QUAD ' HMMIO
DECLARE FUNCTION mmioOpenW LIB "winmm.dll" ALIAS "mmioOpenW" ( BYREF pszFileName AS WSTRINGZ , BYREF pmmioinfo AS MMIOINFO , BYVAL fdwOpen AS QUAD ) AS QUAD ' HMMIO
#IF %DEF(%UNICODE)
 MACRO mmioOpen = mmioOpenW
#ELSE
 MACRO mmioOpen = mmioOpenA
#ENDIF
DECLARE FUNCTION mmioRenameA LIB "winmm.dll" ALIAS "mmioRenameA" ( BYREF pszFileName AS ASCIIZ , BYREF pszNewFileName AS ASCIIZ , BYREF pmmioinfo AS MMIOINFO , BYVAL fdwRename AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioRenameW LIB "winmm.dll" ALIAS "mmioRenameW" ( BYREF pszFileName AS WSTRINGZ , BYREF pszNewFileName AS WSTRINGZ , BYREF pmmioinfo AS MMIOINFO , BYVAL fdwRename AS QUAD ) AS LONG ' MMRESULT
#IF %DEF(%UNICODE)
 MACRO mmioRename = mmioRenameW
#ELSE
 MACRO mmioRename = mmioRenameA
#ENDIF
DECLARE FUNCTION mmioClose LIB "winmm.dll" ALIAS "mmioClose" ( BYVAL hmmio AS QUAD , BYVAL fuClose AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioRead LIB "winmm.dll" ALIAS "mmioRead" ( BYVAL hmmio AS QUAD , BYREF pch AS ANY , BYVAL cch AS LONG ) AS LONG
DECLARE FUNCTION mmioWrite LIB "winmm.dll" ALIAS "mmioWrite" ( BYVAL hmmio AS QUAD
 , BYREF pch AS ANY
 , BYVAL cch AS LONG
 ) AS LONG
DECLARE FUNCTION mmioSeek LIB "winmm.dll" ALIAS "mmioSeek" ( BYVAL hmmio AS DWORD
 , BYVAL lOffset AS LONG
 , BYVAL iOrigin AS LONG
 ) AS LONG
DECLARE FUNCTION mmioGetInfo LIB "winmm.dll" ALIAS "mmioGetInfo" ( BYVAL hmmio AS DWORD
 , BYREF pmmioinfo AS MMIOINFO
 , BYVAL fuInfo AS DWORD
 ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioSetInfo LIB "winmm.dll" ALIAS "mmioSetInfo" ( BYVAL hmmio AS QUAD , BYREF pmmioinfo AS MMIOINFO , BYVAL fuInfo AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioSetBuffer LIB "winmm.dll" ALIAS "mmioSetBuffer" ( BYVAL hmmio AS QUAD , BYREF pchBuffer AS ASCIIZ , BYVAL cchBuffer AS LONG , BYVAL fuBuffer AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioFlush LIB "winmm.dll" ALIAS "mmioFlush" ( BYVAL hmmio AS QUAD , BYVAL fuFlush AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioAdvance LIB "winmm.dll" ALIAS "mmioAdvance" ( BYVAL hmmio AS QUAD , BYREF pmmioinfo AS MMIOINFO , BYVAL fuAdvance AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioSendMessage LIB "winmm.dll" ALIAS "mmioSendMessage" ( BYVAL hmmio AS QUAD , BYVAL uMsg AS QUAD , BYVAL lParam1 AS LONG , BYVAL lParam2 AS LONG ) AS LONG ' LRESULT
DECLARE FUNCTION mmioDescend LIB "winmm.dll" ALIAS "mmioDescend" ( BYVAL hmmio AS QUAD , BYREF pmmcki AS MMCKINFO , BYREF pmmckiParent AS MMCKINFO , BYVAL fuDescend AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioAscend LIB "winmm.dll" ALIAS "mmioAscend" ( BYVAL hmmio AS QUAD , BYREF pmmcki AS MMCKINFO , BYVAL fuAscend AS QUAD ) AS LONG ' MMRESULT
DECLARE FUNCTION mmioCreateChunk LIB "winmm.dll" ALIAS "mmioCreateChunk" ( BYVAL hmmio AS QUAD , BYREF pmmcki AS MMCKINFO , BYVAL fuCreate AS QUAD ) AS LONG ' MMRESULT
#ENDIF ' /* ifndef MMNOMMIO */
#IF NOT %DEF(%MMNOMCI)
'/****************************************************************************
' MCI support
'****************************************************************************/
'#ifndef _MCIERROR_ /* MCIERROR is defined in some post 3.1 apps */
'#define _MCIERROR_
'typedef DWORD MCIERROR; /* error return code, 0 means no error */
'#endif
'#ifndef _MCIDEVICEID_ /* Same with MCIDEVICEID */
'#define _MCIDEVICEID_
'typedef UINT MCIDEVICEID; /* MCI device ID type */
'#endif
'typedef UINT (CALLBACK *YIELDPROC)(MCIDEVICEID mciId, DWORD dwYieldData);
'DECLARE FUNCTION YIELDPROC (BYVAL mciId AS DWORD, BYVAL dwYieldData AS DWORD) AS DWORD
'/* MCI function prototypes */
DECLARE FUNCTION mciSendCommandA LIB "winmm.dll" ALIAS "mciSendCommandA" ( BYVAL mciId AS QUAD , BYVAL uMsg AS QUAD , BYVAL dwParam1 AS QUAD , BYVAL dwParam2 AS QUAD ) AS QUAD ' MCIERROR
DECLARE FUNCTION mciSendCommandW LIB "winmm.dll" ALIAS "mciSendCommandW" ( BYVAL mciId AS QUAD , BYVAL uMsg AS QUAD , BYVAL dwParam1 AS QUAD , BYVAL dwParam2 AS QUAD ) AS QUAD ' MCIERROR
#IF %DEF(%UNICODE)
 MACRO mciSendCommand = mciSendCommandW
#ELSE
 MACRO mciSendCommand = mciSendCommandA
#ENDIF
DECLARE FUNCTION mciSendStringA LIB "winmm.dll" ALIAS "mciSendStringA" ( BYREF lpstrCommand AS ASCIIZ , BYREF lpstrReturnString AS ASCIIZ , BYVAL uReturnLength AS QUAD , BYVAL hwndCallback AS QUAD ) AS QUAD ' MCIERROR
DECLARE FUNCTION mciSendStringW LIB "winmm.dll" ALIAS "mciSendStringW" ( BYREF lpstrCommand AS WSTRINGZ , BYREF lpstrReturnString AS WSTRINGZ , BYVAL uReturnLength AS QUAD , BYVAL hwndCallback AS QUAD ) AS QUAD ' MCIERROR
#IF %DEF(%UNICODE)
 MACRO mciSendString = mciSendStringW
#ELSE
 MACRO mciSendString = mciSendStringA
#ENDIF
DECLARE FUNCTION mciGetDeviceIDA LIB "winmm.dll" ALIAS "mciGetDeviceIDA" ( BYREF pszDevice AS ASCIIZ ) AS QUAD ' MCIDEVICEID
DECLARE FUNCTION mciGetDeviceIDW LIB "winmm.dll" ALIAS "mciGetDeviceIDW" ( BYREF pszDevice AS WSTRINGZ ) AS QUAD ' MCIDEVICEID
#IF %DEF(%UNICODE)
 MACRO mciGetDeviceID = mciGetDeviceIDW
#ELSE
 MACRO mciGetDeviceID = mciGetDeviceIDA
#ENDIF
DECLARE FUNCTION mciGetDeviceIDFromElementIDA LIB "winmm.dll" ALIAS "mciGetDeviceIDFromElementIDA" ( BYVAL dwElementID AS QUAD , BYREF lpstrType AS ASCIIZ ) AS QUAD ' MCIDEVICEID
DECLARE FUNCTION mciGetDeviceIDFromElementIDW LIB "winmm.dll" ALIAS "mciGetDeviceIDFromElementIDW" ( BYVAL dwElementID AS QUAD , BYREF lpstrType AS WSTRINGZ ) AS QUAD ' MCIDEVICEID
#IF %DEF(%UNICODE)
 MACRO mciGetDeviceIDFromElementID = mciGetDeviceIDFromElementIDW
#ELSE
 MACRO mciGetDeviceIDFromElementID = mciGetDeviceIDFromElementIDA
#ENDIF
DECLARE FUNCTION mciGetErrorStringA LIB "winmm.dll" ALIAS "mciGetErrorStringA" ( BYVAL mcierr AS QUAD , BYREF pszText AS ASCIIZ , BYVAL cchText AS QUAD ) AS LONG
DECLARE FUNCTION mciGetErrorStringW LIB "winmm.dll" ALIAS "mciGetErrorStringW" ( BYVAL mcierr AS QUAD
 , BYREF pszText AS WSTRINGZ
 , BYVAL cchText AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO mciGetErrorString = mciGetErrorStringW
#ELSE
 MACRO mciGetErrorString = mciGetErrorStringA
#ENDIF
DECLARE FUNCTION mciSetYieldProc LIB "winmm.dll" ALIAS "mciSetYieldProc" ( BYVAL mciId AS QUAD , BYVAL fpYieldProc AS QUAD , BYVAL dwYieldData AS QUAD ) AS LONG
'#if (WINVER >= 0x030a)
DECLARE FUNCTION mciGetCreatorTask LIB "winmm.dll" ALIAS "mciGetCreatorTask" ( BYVAL mciId AS QUAD ) AS QUAD ' HTASK
DECLARE FUNCTION mciGetYieldProc LIB "winmm.dll" ALIAS "mciGetYieldProc" ( BYVAL mciId AS QUAD , BYREF pdwYieldData AS QUAD ) AS QUAD ' YIELDPROC
'#endif /* ifdef WINVER >= 0x030a */
'#if (WINVER < 0x030a)
DECLARE FUNCTION mciExecute LIB "winmm.dll" ALIAS "mciExecute" ( BYREF pszCommand AS ASCIIZ ) AS LONG ' LPCSTR pszCommand
'#endif /* ifdef WINVER < 0x030a */
'/* MCI error return values */
%EQUATE `MCIERR_INVALID_DEVICE_ID = %MCIERR_BASE + 1
%EQUATE `MCIERR_UNRECOGNIZED_KEYWORD = %MCIERR_BASE + 3
%EQUATE `MCIERR_UNRECOGNIZED_COMMAND = %MCIERR_BASE + 5
%EQUATE `MCIERR_HARDWARE = %MCIERR_BASE + 6
%EQUATE `MCIERR_INVALID_DEVICE_NAME = %MCIERR_BASE + 7
%EQUATE `MCIERR_OUT_OF_MEMORY = %MCIERR_BASE + 8
%EQUATE `MCIERR_DEVICE_OPEN = %MCIERR_BASE + 9
%EQUATE `MCIERR_CANNOT_LOAD_DRIVER = %MCIERR_BASE + 10
%EQUATE `MCIERR_MISSING_COMMAND_STRING = %MCIERR_BASE + 11
%EQUATE `MCIERR_PARAM_OVERFLOW = %MCIERR_BASE + 12
%EQUATE `MCIERR_MISSING_STRING_ARGUMENT = %MCIERR_BASE + 13
%EQUATE `MCIERR_BAD_INTEGER = %MCIERR_BASE + 14
%EQUATE `MCIERR_PARSER_INTERNAL = %MCIERR_BASE + 15
%EQUATE `MCIERR_DRIVER_INTERNAL = %MCIERR_BASE + 16
%EQUATE `MCIERR_MISSING_PARAMETER = %MCIERR_BASE + 17
%EQUATE `MCIERR_UNSUPPORTED_FUNCTION = %MCIERR_BASE + 18
%EQUATE `MCIERR_FILE_NOT_FOUND = %MCIERR_BASE + 19
%EQUATE `MCIERR_DEVICE_NOT_READY = %MCIERR_BASE + 20
%EQUATE `MCIERR_INTERNAL = %MCIERR_BASE + 21
%EQUATE `MCIERR_DRIVER = %MCIERR_BASE + 22
%EQUATE `MCIERR_CANNOT_USE_ALL = %MCIERR_BASE + 23
%EQUATE `MCIERR_MULTIPLE = %MCIERR_BASE + 24
%EQUATE `MCIERR_EXTENSION_NOT_FOUND = %MCIERR_BASE + 25
%EQUATE `MCIERR_OUTOFRANGE = %MCIERR_BASE + 26
%EQUATE `MCIERR_FLAGS_NOT_COMPATIBLE = %MCIERR_BASE + 28
%EQUATE `MCIERR_FILE_NOT_SAVED = %MCIERR_BASE + 30
%EQUATE `MCIERR_DEVICE_TYPE_REQUIRED = %MCIERR_BASE + 31
%EQUATE `MCIERR_DEVICE_LOCKED = %MCIERR_BASE + 32
%EQUATE `MCIERR_DUPLICATE_ALIAS = %MCIERR_BASE + 33
%EQUATE `MCIERR_BAD_CONSTANT = %MCIERR_BASE + 34
%EQUATE `MCIERR_MUST_USE_SHAREABLE = %MCIERR_BASE + 35
%EQUATE `MCIERR_MISSING_DEVICE_NAME = %MCIERR_BASE + 36
%EQUATE `MCIERR_BAD_TIME_FORMAT = %MCIERR_BASE + 37
%EQUATE `MCIERR_NO_CLOSING_QUOTE = %MCIERR_BASE + 38
%EQUATE `MCIERR_DUPLICATE_FLAGS = %MCIERR_BASE + 39
%EQUATE `MCIERR_INVALID_FILE = %MCIERR_BASE + 40
%EQUATE `MCIERR_NULL_PARAMETER_BLOCK = %MCIERR_BASE + 41
%EQUATE `MCIERR_UNNAMED_RESOURCE = %MCIERR_BASE + 42
%EQUATE `MCIERR_NEW_REQUIRES_ALIAS = %MCIERR_BASE + 43
%EQUATE `MCIERR_NOTIFY_ON_AUTO_OPEN = %MCIERR_BASE + 44
%EQUATE `MCIERR_NO_ELEMENT_ALLOWED = %MCIERR_BASE + 45
%EQUATE `MCIERR_NONAPPLICABLE_FUNCTION = %MCIERR_BASE + 46
%EQUATE `MCIERR_ILLEGAL_FOR_AUTO_OPEN = %MCIERR_BASE + 47
%EQUATE `MCIERR_FILENAME_REQUIRED = %MCIERR_BASE + 48
%EQUATE `MCIERR_EXTRA_CHARACTERS = %MCIERR_BASE + 49
%EQUATE `MCIERR_DEVICE_NOT_INSTALLED = %MCIERR_BASE + 50
%EQUATE `MCIERR_GET_CD = %MCIERR_BASE + 51
%EQUATE `MCIERR_SET_CD = %MCIERR_BASE + 52
%EQUATE `MCIERR_SET_DRIVE = %MCIERR_BASE + 53
%EQUATE `MCIERR_DEVICE_LENGTH = %MCIERR_BASE + 54
%EQUATE `MCIERR_DEVICE_ORD_LENGTH = %MCIERR_BASE + 55
%EQUATE `MCIERR_NO_INTEGER = %MCIERR_BASE + 56
%EQUATE `MCIERR_WAVE_OUTPUTSINUSE = %MCIERR_BASE + 64
%EQUATE `MCIERR_WAVE_SETOUTPUTINUSE = %MCIERR_BASE + 65
%EQUATE `MCIERR_WAVE_INPUTSINUSE = %MCIERR_BASE + 66
%EQUATE `MCIERR_WAVE_SETINPUTINUSE = %MCIERR_BASE + 67
%EQUATE `MCIERR_WAVE_OUTPUTUNSPECIFIED = %MCIERR_BASE + 68
%EQUATE `MCIERR_WAVE_INPUTUNSPECIFIED = %MCIERR_BASE + 69
%EQUATE `MCIERR_WAVE_OUTPUTSUNSUITABLE = %MCIERR_BASE + 70
%EQUATE `MCIERR_WAVE_SETOUTPUTUNSUITABLE = %MCIERR_BASE + 71
%EQUATE `MCIERR_WAVE_INPUTSUNSUITABLE = %MCIERR_BASE + 72
%EQUATE `MCIERR_WAVE_SETINPUTUNSUITABLE = %MCIERR_BASE + 73
%EQUATE `MCIERR_SEQ_DIV_INCOMPATIBLE = %MCIERR_BASE + 80
%EQUATE `MCIERR_SEQ_PORT_INUSE = %MCIERR_BASE + 81
%EQUATE `MCIERR_SEQ_PORT_NONEXISTENT = %MCIERR_BASE + 82
%EQUATE `MCIERR_SEQ_PORT_MAPNODEVICE = %MCIERR_BASE + 83
%EQUATE `MCIERR_SEQ_PORT_MISCERROR = %MCIERR_BASE + 84
%EQUATE `MCIERR_SEQ_TIMER = %MCIERR_BASE + 85
%EQUATE `MCIERR_SEQ_PORTUNSPECIFIED = %MCIERR_BASE + 86
%EQUATE `MCIERR_SEQ_NOMIDIPRESENT = %MCIERR_BASE + 87
%EQUATE `MCIERR_NO_WINDOW = %MCIERR_BASE + 90
%EQUATE `MCIERR_CREATEWINDOW = %MCIERR_BASE + 91
%EQUATE `MCIERR_FILE_READ = %MCIERR_BASE + 92
%EQUATE `MCIERR_FILE_WRITE = %MCIERR_BASE + 93
%EQUATE `MCIERR_NO_IDENTITY = %MCIERR_BASE + 94
'/* all custom device driver errors must be >= than this value */
%EQUATE `MCIERR_CUSTOM_DRIVER_BASE = %MCIERR_BASE + 256
%EQUATE `MCI_FIRST = %DRV_MCI_FIRST ' &H0800
'/* MCI command message identifiers */
%EQUATE `MCI_OPEN = &H0803
%EQUATE `MCI_CLOSE = &H0804
%EQUATE `MCI_ESCAPE = &H0805
%EQUATE `MCI_PLAY = &H0806
%EQUATE `MCI_SEEK = &H0807
%EQUATE `MCI_STOP = &H0808
%EQUATE `MCI_PAUSE = &H0809
%EQUATE `MCI_INFO = &H080A
%EQUATE `MCI_GETDEVCAPS = &H080B
%EQUATE `MCI_SPIN = &H080C
%EQUATE `MCI_SET = &H080D
%EQUATE `MCI_STEP = &H080E
%EQUATE `MCI_RECORD = &H080F
%EQUATE `MCI_SYSINFO = &H0810
%EQUATE `MCI_BREAK = &H0811
%EQUATE `MCI_SOUND = &H0812
%EQUATE `MCI_SAVE = &H0813
%EQUATE `MCI_STATUS = &H0814
%EQUATE `MCI_CUE = &H0830
%EQUATE `MCI_REALIZE = &H0840
%EQUATE `MCI_WINDOW = &H0841
%EQUATE `MCI_PUT = &H0842
%EQUATE `MCI_WHERE = &H0843
%EQUATE `MCI_FREEZE = &H0844
%EQUATE `MCI_UNFREEZE = &H0845
%EQUATE `MCI_LOAD = &H0850
%EQUATE `MCI_CUT = &H0851
%EQUATE `MCI_COPY = &H0852
%EQUATE `MCI_PASTE = &H0853
%EQUATE `MCI_UPDATE = &H0854
%EQUATE `MCI_RESUME = &H0855
%EQUATE `MCI_DELETE = &H0856
'/* all custom MCI command messages must be >= than this value */
%EQUATE `MCI_USER_MESSAGES = &H400 + %MCI_FIRST
%EQUATE `MCI_LAST = &HFFF
'/* device ID for "all devices" */
'#define MCI_ALL_DEVICE_ID ((MCIDEVICEID)-1)
'%MCI_ALL_DEVICE_ID = -1 ' Matches all MCI devices
%EQUATE `MCI_ALL_DEVICE_ID = &HFFFFFFFF
'/* constants for predefined MCI device types */
%EQUATE `MCI_DEVTYPE_VCR = 513
%EQUATE `MCI_DEVTYPE_VIDEODISC = 514
%EQUATE `MCI_DEVTYPE_OVERLAY = 515
%EQUATE `MCI_DEVTYPE_CD_AUDIO = 516
%EQUATE `MCI_DEVTYPE_DAT = 517
%EQUATE `MCI_DEVTYPE_SCANNER = 518
%EQUATE `MCI_DEVTYPE_ANIMATION = 519
%EQUATE `MCI_DEVTYPE_DIGITAL_VIDEO = 520
%EQUATE `MCI_DEVTYPE_OTHER = 521
%EQUATE `MCI_DEVTYPE_WAVEFORM_AUDIO = 522
%EQUATE `MCI_DEVTYPE_SEQUENCER = 523
%EQUATE `MCI_DEVTYPE_FIRST = %MCI_DEVTYPE_VCR
%EQUATE `MCI_DEVTYPE_LAST = %MCI_DEVTYPE_SEQUENCER
'#define MCI_DEVTYPE_FIRST_USER 0x1000
%EQUATE `MCI_DEVTYPE_FIRST_USER = &H1000
'/* return values for 'status mode' command */
%EQUATE `MCI_MODE_NOT_READY = %MCI_STRING_OFFSET + 12
%EQUATE `MCI_MODE_STOP = %MCI_STRING_OFFSET + 13
%EQUATE `MCI_MODE_PLAY = %MCI_STRING_OFFSET + 14
%EQUATE `MCI_MODE_RECORD = %MCI_STRING_OFFSET + 15
%EQUATE `MCI_MODE_SEEK = %MCI_STRING_OFFSET + 16
%EQUATE `MCI_MODE_PAUSE = %MCI_STRING_OFFSET + 17
%EQUATE `MCI_MODE_OPEN = %MCI_STRING_OFFSET + 18
'/* constants used in 'set time format' and 'status time format' commands */
%EQUATE `MCI_FORMAT_MILLISECONDS = 0
%EQUATE `MCI_FORMAT_HMS = 1
%EQUATE `MCI_FORMAT_MSF = 2
%EQUATE `MCI_FORMAT_FRAMES = 3
%EQUATE `MCI_FORMAT_SMPTE_24 = 4
%EQUATE `MCI_FORMAT_SMPTE_25 = 5
%EQUATE `MCI_FORMAT_SMPTE_30 = 6
%EQUATE `MCI_FORMAT_SMPTE_30DROP = 7
%EQUATE `MCI_FORMAT_BYTES = 8
%EQUATE `MCI_FORMAT_SAMPLES = 9
%EQUATE `MCI_FORMAT_TMSF = 10
'/* MCI time format conversion macros */
'#define MCI_MSF_MINUTE(msf) ((BYTE)(msf))
FUNCTION MCI_MSF_MINUTE (BYVAL msf AS DWORD) AS BYTE
 ! MOV AL, msf[0]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_MSF_SECOND(msf) ((BYTE)(((WORD)(msf)) >> 8))
FUNCTION MCI_MSF_SECOND (BYVAL msf AS DWORD) AS BYTE
 ! MOV AL, msf[1]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_MSF_FRAME(msf) ((BYTE)((msf)>>16))
FUNCTION MCI_MSF_FRAME (BYVAL msf AS DWORD) AS BYTE
 ! MOV AL, msf[2]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_MAKE_MSF(m, s, f) ((DWORD)(((BYTE)(m) | \
' ((WORD)(s)<<8)) | \
' (((DWORD)(BYTE)(f))<<16)))
FUNCTION MCI_MAKE_MSF (BYVAL m AS BYTE, BYVAL s AS BYTE, BYVAL f AS BYTE) AS DWORD
 ! MOV AL, m
 ! MOV AH, s
 ! MOV DL, f
 ! Sub DH, DH
 ! MOV FUNCTION[0], AX
 ! MOV FUNCTION[2], DX
END FUNCTION
'#define MCI_TMSF_TRACK(tmsf) ((BYTE)(tmsf))
FUNCTION MCI_TMSF_TRACK (BYVAL tmsf AS DWORD) AS BYTE
 ! MOV AL, tmsf[0]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_TMSF_MINUTE(tmsf) ((BYTE)(((WORD)(tmsf)) >> 8))
FUNCTION MCI_TMSF_MINUTE (BYVAL tmsf AS DWORD) AS BYTE
 ! MOV AL, tmsf[1]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_TMSF_SECOND(tmsf) ((BYTE)((tmsf)>>16))
FUNCTION MCI_TMSF_SECOND (BYVAL tmsf AS DWORD) AS BYTE
 ! MOV AL, tmsf[2]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_TMSF_FRAME(tmsf) ((BYTE)((tmsf)>>24))
FUNCTION MCI_TMSF_FRAME (BYVAL tmsf AS DWORD) AS BYTE
 ! MOV AL, tmsf[3]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_MAKE_TMSF(t, m, s, f) ((DWORD)(((BYTE)(t) | \
' ((WORD)(m)<<8)) | \
' (((DWORD)(BYTE)(s) | \
' ((WORD)(f)<<8))<<16)))
FUNCTION MCI_MAKE_TMSF(BYVAL t AS BYTE, BYVAL m AS BYTE, BYVAL s AS BYTE, BYVAL f AS BYTE) AS DWORD
 ! MOV AL, t
 ! MOV AH, m
 ! MOV DL, s
 ! MOV DH, f
 ! MOV FUNCTION[0], AX
 ! MOV FUNCTION[2], DX
END FUNCTION
'#define MCI_HMS_HOUR(hms) ((BYTE)(hms))
FUNCTION MCI_HMS_HOUR (BYVAL hms AS DWORD) AS BYTE
 ! MOV AL, hms[0]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_HMS_MINUTE(hms) ((BYTE)(((WORD)(hms)) >> 8))
FUNCTION MCI_HMS_MINUTE (BYVAL hms AS DWORD) AS BYTE
 ! MOV AL, hms[1]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_HMS_SECOND(hms) ((BYTE)((hms)>>16))
FUNCTION MCI_HMS_SECOND (BYVAL hms AS DWORD) AS BYTE
 ! MOV AL, hms[2]
 ! MOV FUNCTION, AL
END FUNCTION
'#define MCI_MAKE_HMS(h, m, s) ((DWORD)(((BYTE)(h) | \
' ((WORD)(m)<<8)) | \
' (((DWORD)(BYTE)(s))<<16)))
FUNCTION MCI_MAKE_HMS (BYVAL h AS BYTE, BYVAL m AS BYTE, BYVAL s AS BYTE) AS DWORD
 ! MOV AL, h
 ! MOV AH, m
 ! MOV DL, s
 ! Sub DH, DH
 ! MOV FUNCTION[0], AX
 ! MOV FUNCTION[2], DX
END FUNCTION
'/* flags for wParam of MM_MCINOTIFY message */
%EQUATE `MCI_NOTIFY_SUCCESSFUL = &H0001
%EQUATE `MCI_NOTIFY_SUPERSEDED = &H0002
%EQUATE `MCI_NOTIFY_ABORTED = &H0004
%EQUATE `MCI_NOTIFY_FAILURE = &H0008
'/* common flags for dwFlags parameter of MCI command messages */
%EQUATE `MCI_NOTIFY = &H00000001
%EQUATE `MCI_WAIT = &H00000002
%EQUATE `MCI_FROM = &H00000004
%EQUATE `MCI_TO = &H00000008
%EQUATE `MCI_TRACK = &H00000010
'/* flags for dwFlags parameter of MCI_OPEN command message */
%EQUATE `MCI_OPEN_SHAREABLE = &H00000100
%EQUATE `MCI_OPEN_ELEMENT = &H00000200
%EQUATE `MCI_OPEN_ALIAS = &H00000400
%EQUATE `MCI_OPEN_ELEMENT_ID = &H00000800
%EQUATE `MCI_OPEN_TYPE_ID = &H00001000
%EQUATE `MCI_OPEN_TYPE = &H00002000
'/* flags for dwFlags parameter of MCI_SEEK command message */
%EQUATE `MCI_SEEK_TO_START = &H00000100
%EQUATE `MCI_SEEK_TO_END = &H00000200
'/* flags for dwFlags parameter of MCI_STATUS command message */
%EQUATE `MCI_STATUS_ITEM = &H00000100
%EQUATE `MCI_STATUS_START = &H00000200
'/* flags for dwItem field of the MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_STATUS_LENGTH = &H00000001
%EQUATE `MCI_STATUS_POSITION = &H00000002
%EQUATE `MCI_STATUS_NUMBER_OF_TRACKS = &H00000003
%EQUATE `MCI_STATUS_MODE = &H00000004
%EQUATE `MCI_STATUS_MEDIA_PRESENT = &H00000005
%EQUATE `MCI_STATUS_TIME_FORMAT = &H00000006
%EQUATE `MCI_STATUS_READY = &H00000007
%EQUATE `MCI_STATUS_CURRENT_TRACK = &H00000008
'/* flags for dwFlags parameter of MCI_INFO command message */
%EQUATE `MCI_INFO_PRODUCT = &H00000100
%EQUATE `MCI_INFO_FILE = &H00000200
%EQUATE `MCI_INFO_MEDIA_UPC = &H00000400
%EQUATE `MCI_INFO_MEDIA_IDENTITY = &H00000800
%EQUATE `MCI_INFO_NAME = &H00001000
%EQUATE `MCI_INFO_COPYRIGHT = &H00002000
'/* flags for dwFlags parameter of MCI_GETDEVCAPS command message */
%EQUATE `MCI_GETDEVCAPS_ITEM = &H00000100
'/* flags for dwItem field of the MCI_GETDEVCAPS_PARMS parameter block */
%EQUATE `MCI_GETDEVCAPS_CAN_RECORD = &H00000001
%EQUATE `MCI_GETDEVCAPS_HAS_AUDIO = &H00000002
%EQUATE `MCI_GETDEVCAPS_HAS_VIDEO = &H00000003
%EQUATE `MCI_GETDEVCAPS_DEVICE_TYPE = &H00000004
%EQUATE `MCI_GETDEVCAPS_USES_FILES = &H00000005
%EQUATE `MCI_GETDEVCAPS_COMPOUND_DEVICE = &H00000006
%EQUATE `MCI_GETDEVCAPS_CAN_EJECT = &H00000007
%EQUATE `MCI_GETDEVCAPS_CAN_PLAY = &H00000008
%EQUATE `MCI_GETDEVCAPS_CAN_SAVE = &H00000009
'/* flags for dwFlags parameter of MCI_SYSINFO command message */
%EQUATE `MCI_SYSINFO_QUANTITY = &H00000100
%EQUATE `MCI_SYSINFO_OPEN = &H00000200
%EQUATE `MCI_SYSINFO_NAME = &H00000400
%EQUATE `MCI_SYSINFO_INSTALLNAME = &H00000800
'/* flags for dwFlags parameter of MCI_SET command message */
%EQUATE `MCI_SET_DOOR_OPEN = &H00000100
%EQUATE `MCI_SET_DOOR_CLOSED = &H00000200
%EQUATE `MCI_SET_TIME_FORMAT = &H00000400
%EQUATE `MCI_SET_AUDIO = &H00000800
%EQUATE `MCI_SET_VIDEO = &H00001000
%EQUATE `MCI_SET_ON = &H00002000
%EQUATE `MCI_SET_OFF = &H00004000
'/* flags for dwAudio field of MCI_SET_PARMS or MCI_SEQ_SET_PARMS */
%EQUATE `MCI_SET_AUDIO_ALL = &H00000001
%EQUATE `MCI_SET_AUDIO_LEFT = &H00000002
%EQUATE `MCI_SET_AUDIO_RIGHT = &H00000003
'/* flags for dwFlags parameter of MCI_BREAK command message */
%EQUATE `MCI_BREAK_KEY = &H00000100
%EQUATE `MCI_BREAK_HWND = &H00000200
%EQUATE `MCI_BREAK_OFF = &H00000400
'/* flags for dwFlags parameter of MCI_RECORD command message */
%EQUATE `MCI_RECORD_INSERT = &H00000100
%EQUATE `MCI_RECORD_OVERWRITE = &H00000200
'/* flags for dwFlags parameter of MCI_SAVE command message */
%EQUATE `MCI_SAVE_FILE = &H00000100
'/* flags for dwFlags parameter of MCI_LOAD command message */
%EQUATE `MCI_LOAD_FILE = &H00000100
'/* generic parameter block for MCI command messages with no special parameters */
'typedef struct tagMCI_GENERIC_PARMS {
' DWORD_PTR dwCallback;
'} MCI_GENERIC_PARMS, *PMCI_GENERIC_PARMS, FAR *LPMCI_GENERIC_PARMS;
' // Size = 4 bytes
TYPE MCI_GENERIC_PARMS BYTE
 dwCallback AS DWORD
END TYPE
'/* parameter block for MCI_OPEN command message */
' // Size = 20 bytes
TYPE MCI_OPEN_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceId AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS ASCIIZ PTR ' LPCSTR lpstrDeviceType
 lpstrElementName AS ASCIIZ PTR ' LPCSTR lpstrElementName
 lpstrAlias AS ASCIIZ PTR ' LPCSTR lpstrAlias
END TYPE
' // Size = 20 bytes
TYPE MCI_OPEN_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceId AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS WSTRINGZ PTR ' LPCWSTR lpstrDeviceType
 lpstrElementName AS WSTRINGZ PTR ' LPCWSTR lpstrElementName
 lpstrAlias AS WSTRINGZ PTR ' LPCWSTR lpstrAlias
END TYPE
MACRO MCI_OPEN_PARMS = MCI_OPEN_PARMSA
'/* parameter block for MCI_PLAY command message */
' // Size = 12 bytes
TYPE MCI_PLAY_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrom AS DWORD ' DWORD dwFrom
 dwTo AS DWORD ' DWORD dwTo
END TYPE
'/* parameter block for MCI_SEEK command message */
' // Size = 8 bytes
TYPE MCI_SEEK_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwTo AS DWORD ' DWORD dwTo
END TYPE
'/* parameter block for MCI_STATUS command message */
' // Size = 16 bytes
TYPE MCI_STATUS_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwReturn AS DWORD ' DWORD_PTR dwReturn
 dwItem AS DWORD ' DWORD dwItem
 dwTrack AS DWORD ' DWORD dwTrack
END TYPE
'/* parameter block for MCI_INFO command message */
' // Size = 12 bytes
TYPE MCI_INFO_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrReturn AS ASCIIZ PTR ' LPSTR lpstrReturn
 dwRetSize AS DWORD ' DWORD dwRetSize
END TYPE
' // Size = 12 bytes
TYPE MCI_INFO_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrReturn AS WSTRINGZ PTR ' LPWSTR lpstrReturn
 dwRetSize AS DWORD ' DWORD dwRetSize
END TYPE
MACRO MCI_INFO_PARMS = MCI_INFO_PARMSA
'/* parameter block for MCI_GETDEVCAPS command message */
' // Size = 12 bytes
TYPE MCI_GETDEVCAPS_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwReturn AS DWORD ' DWORD dwReturn
 dwItem AS DWORD ' DWORD dwItem
END TYPE
'/* parameter block for MCI_SYSINFO command message */
'#ifdef _WIN32
' // Size = 20 bytes
TYPE MCI_SYSINFO_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrReturn AS ASCIIZ PTR ' LPSTR lpstrReturn
 dwRetSize AS DWORD ' DWORD dwRetSize
 dwNumber AS DWORD ' DWORD dwNumber
 wDeviceType AS DWORD ' UINT wDeviceType
END TYPE
' // Size = 20 bytes
TYPE MCI_SYSINFO_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrReturn AS WSTRINGZ PTR ' LPWSTR lpstrReturn
 dwRetSize AS DWORD ' DWORD dwRetSize
 dwNumber AS DWORD ' DWORD dwNumber
 wDeviceType AS DWORD ' UINT wDeviceType
END TYPE
MACRO MCI_SYSINFO_PARMS = MCI_SYSINFO_PARMSA
'/* parameter block for MCI_SET command message */
' // Size = 12 bytes
TYPE MCI_SET_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwTimeFormat AS DWORD ' DWORD dwTimeFormat
 dwAudio AS DWORD ' DWORD dwAudio
END TYPE
'/* parameter block for MCI_BREAK command message */
' // Size = 12 bytes
TYPE MCI_BREAK_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 nVirtKey AS LONG ' int nVirtKey
 hwndBreak AS LONG ' HWND hwndBreak
END TYPE
'/* parameter block for MCI_SAVE command message */
' // Size = 8 bytes
TYPE MCI_SAVE_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS ASCIIZ PTR ' LPCSTR lpfilename
END TYPE
' // Size = 8 bytes
TYPE MCI_SAVE_PARMSW
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS WSTRINGZ PTR ' LPCWSTR lpfilename
END TYPE
MACRO MCI_SAVE_PARMS = MCI_SAVE_PARMSA
'/* parameter block for MCI_LOAD command message */
'#ifdef _WIN32
' // Size = 8 bytes
TYPE MCI_LOAD_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS ASCIIZ PTR ' LPCSTR lpfilename
END TYPE
' // Size = 8 bytes
TYPE MCI_LOAD_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS WSTRINGZ PTR ' LPCWSTR lpfilename
END TYPE
MACRO MCI_LOAD_PARMS = MCI_LOAD_PARMSA
'/* parameter block for MCI_RECORD command message */
' // Size = 12 bytes
TYPE MCI_RECORD_PARMS
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrom AS DWORD ' DWORD dwFrom
 dwTo AS DWORD ' DWORD dwTo
END TYPE
'/* MCI extensions for videodisc devices */
'/* flag for dwReturn field of MCI_STATUS_PARMS */
'/* MCI_STATUS command, (dwItem == MCI_STATUS_MODE) */
%EQUATE `MCI_VD_MODE_PARK = %MCI_VD_OFFSET + 1
'/* flag for dwReturn field of MCI_STATUS_PARMS */
'/* MCI_STATUS command, (dwItem == MCI_VD_STATUS_MEDIA_TYPE) */
%EQUATE `MCI_VD_MEDIA_CLV = %MCI_VD_OFFSET + 2
%EQUATE `MCI_VD_MEDIA_CAV = %MCI_VD_OFFSET + 3
%EQUATE `MCI_VD_MEDIA_OTHER = %MCI_VD_OFFSET + 4
%EQUATE `MCI_VD_FORMAT_TRACK = &H00004001
'/* flags for dwFlags parameter of MCI_PLAY command message */
%EQUATE `MCI_VD_PLAY_REVERSE = &H00010000
%EQUATE `MCI_VD_PLAY_FAST = &H00020000
%EQUATE `MCI_VD_PLAY_SPEED = &H00040000
%EQUATE `MCI_VD_PLAY_SCAN = &H00080000
%EQUATE `MCI_VD_PLAY_SLOW = &H00100000
'/* flag for dwFlags parameter of MCI_SEEK command message */
%EQUATE `MCI_VD_SEEK_REVERSE = &H00010000
'/* flags for dwItem field of MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_VD_STATUS_SPEED = &H00004002
%EQUATE `MCI_VD_STATUS_FORWARD = &H00004003
%EQUATE `MCI_VD_STATUS_MEDIA_TYPE = &H00004004
%EQUATE `MCI_VD_STATUS_SIDE = &H00004005
%EQUATE `MCI_VD_STATUS_DISC_SIZE = &H00004006
'/* flags for dwFlags parameter of MCI_GETDEVCAPS command message */
%EQUATE `MCI_VD_GETDEVCAPS_CLV = &H00010000
%EQUATE `MCI_VD_GETDEVCAPS_CAV = &H00020000
%EQUATE `MCI_VD_SPIN_UP = &H00010000
%EQUATE `MCI_VD_SPIN_DOWN = &H00020000
'/* flags for dwItem field of MCI_GETDEVCAPS_PARMS parameter block */
%EQUATE `MCI_VD_GETDEVCAPS_CAN_REVERSE = &H00004002
%EQUATE `MCI_VD_GETDEVCAPS_FAST_RATE = &H00004003
%EQUATE `MCI_VD_GETDEVCAPS_SLOW_RATE = &H00004004
%EQUATE `MCI_VD_GETDEVCAPS_NORMAL_RATE = &H00004005
'/* flags for the dwFlags parameter of MCI_STEP command message */
%EQUATE `MCI_VD_STEP_FRAMES = &H00010000
%EQUATE `MCI_VD_STEP_REVERSE = &H00020000
'/* flag for the MCI_ESCAPE command message */
%EQUATE `MCI_VD_ESCAPE_STRING = &H00000100
'/* parameter block for MCI_PLAY command message */
' // Size = 16 bytes
TYPE MCI_VD_PLAY_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrom AS DWORD ' DWORD dwFrom
 dwTo AS DWORD ' DWORD dwTo
 dwSpeed AS DWORD ' DWORD dwSpeed
END TYPE
'/* parameter block for MCI_STEP command message */
' // Size = 8 bytes
TYPE MCI_VD_STEP_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrames AS DWORD ' DWORD dwFrames
END TYPE
'/* parameter block for MCI_ESCAPE command message */
' // Size = 8 bytes
TYPE MCI_VD_ESCAPE_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrCommand AS ASCIIZ PTR ' LPCSTR lpstrCommand
END TYPE
' // Size = 8 bytes
TYPE MCI_VD_ESCAPE_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpstrCommand AS WSTRINGZ PTR ' LPCWSTR lpstrCommand
END TYPE
MACRO MCI_VD_ESCAPE_PARMS = MCI_VD_ESCAPE_PARMSA
'/* MCI extensions for CD audio devices */
'/* flags for the dwItem field of the MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_CDA_STATUS_TYPE_TRACK = &H00004001
'/* flags for the dwReturn field of MCI_STATUS_PARMS parameter block */
'/* MCI_STATUS command, (dwItem == MCI_CDA_STATUS_TYPE_TRACK) */
%EQUATE `MCI_CDA_TRACK_AUDIO = %MCI_CD_OFFSET + 0
%EQUATE `MCI_CDA_TRACK_OTHER = %MCI_CD_OFFSET + 1
'/* MCI extensions for waveform audio devices */
%EQUATE `MCI_WAVE_PCM = %MCI_WAVE_OFFSET + 0
%EQUATE `MCI_WAVE_MAPPER = %MCI_WAVE_OFFSET + 1
'/* flags for the dwFlags parameter of MCI_OPEN command message */
%EQUATE `MCI_WAVE_OPEN_BUFFER = &H00010000
'/* flags for the dwFlags parameter of MCI_SET command message */
%EQUATE `MCI_WAVE_SET_FORMATTAG = &H00010000
%EQUATE `MCI_WAVE_SET_CHANNELS = &H00020000
%EQUATE `MCI_WAVE_SET_SAMPLESPERSEC = &H00040000
%EQUATE `MCI_WAVE_SET_AVGBYTESPERSEC = &H00080000
%EQUATE `MCI_WAVE_SET_BLOCKALIGN = &H00100000
%EQUATE `MCI_WAVE_SET_BITSPERSAMPLE = &H00200000
'/* flags for the dwFlags parameter of MCI_STATUS, MCI_SET command messages */
%EQUATE `MCI_WAVE_INPUT = &H00400000
%EQUATE `MCI_WAVE_OUTPUT = &H00800000
'/* flags for the dwItem field of MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_WAVE_STATUS_FORMATTAG = &H00004001
%EQUATE `MCI_WAVE_STATUS_CHANNELS = &H00004002
%EQUATE `MCI_WAVE_STATUS_SAMPLESPERSEC = &H00004003
%EQUATE `MCI_WAVE_STATUS_AVGBYTESPERSEC = &H00004004
%EQUATE `MCI_WAVE_STATUS_BLOCKALIGN = &H00004005
%EQUATE `MCI_WAVE_STATUS_BITSPERSAMPLE = &H00004006
%EQUATE `MCI_WAVE_STATUS_LEVEL = &H00004007
'/* flags for the dwFlags parameter of MCI_SET command message */
%EQUATE `MCI_WAVE_SET_ANYINPUT = &H04000000
%EQUATE `MCI_WAVE_SET_ANYOUTPUT = &H08000000
'/* flags for the dwFlags parameter of MCI_GETDEVCAPS command message */
%EQUATE `MCI_WAVE_GETDEVCAPS_INPUTS = &H00004001
%EQUATE `MCI_WAVE_GETDEVCAPS_OUTPUTS = &H00004002
'/* parameter block for MCI_OPEN command message */
'#ifdef _WIN32
' // Size = 24 bytes
TYPE MCI_WAVE_OPEN_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceID AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS ASCIIZ PTR ' LPCSTR lpstrDeviceType
 lpstrElementName AS ASCIIZ PTR ' LPCSTR lpstrElementName
 lpstrAlias AS ASCIIZ PTR ' LPCSTR lpstrAlias
 dwBufferSeconds AS DWORD ' DWORD dwBufferSeconds
END TYPE
' // Size = 24 bytes
TYPE MCI_WAVE_OPEN_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceID AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS WSTRINGZ PTR ' LPCWSTR lpstrDeviceType
 lpstrElementName AS WSTRINGZ PTR ' LPCWSTR lpstrElementName
 lpstrAlias AS WSTRINGZ PTR ' LPCWSTR lpstrAlias
 dwBufferSeconds AS DWORD ' DWORD dwBufferSeconds
END TYPE
MACRO MCI_WAVE_OPEN_PARMS = MCI_WAVE_OPEN_PARMSA
'/* parameter block for MCI_DELETE command message */
' // Size = 12 bytes
TYPE MCI_WAVE_DELETE_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrom AS DWORD ' DWORD dwFrom
 dwTo AS DWORD ' DWORD dwTo
END TYPE
'/* parameter block for MCI_SET command message */
' // Size = 44 bytes
TYPE MCI_WAVE_SET_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwTimeFormat AS DWORD ' DWORD dwTimeFormat
 dwAudio AS DWORD ' DWORD dwAudio
 wInput AS DWORD ' UINT wInput
 wOutput AS DWORD ' UINT wOutput
 wFormatTag AS WORD ' WORD wFormatTag
 wReserved2 AS WORD ' WORD wReserved2
 nChannels AS WORD ' WORD nChannels
 wReserved3 AS WORD ' WORD wReserved3
 nSamplesPerSec AS DWORD ' DWORD nSamplesPerSec
 nAvgBytesPerSec AS DWORD ' DWORD nAvgBytesPerSec
 nBlockAlign AS WORD ' WORD nBlockAlign
 wReserved4 AS WORD ' WORD wReserved4
 wBitsPerSample AS WORD ' WORD wBitsPerSample
 wReserved5 AS WORD ' WORD wReserved5
END TYPE
'/* MCI extensions for MIDI sequencer devices */
'/* flags for the dwReturn field of MCI_STATUS_PARMS parameter block */
'/* MCI_STATUS command, (dwItem == MCI_SEQ_STATUS_DIVTYPE) */
%EQUATE `MCI_SEQ_DIV_PPQN = %MCI_SEQ_OFFSET
%EQUATE `MCI_SEQ_DIV_SMPTE_24 = %MCI_SEQ_OFFSET + 1
%EQUATE `MCI_SEQ_DIV_SMPTE_25 = %MCI_SEQ_OFFSET + 2
%EQUATE `MCI_SEQ_DIV_SMPTE_30DROP = %MCI_SEQ_OFFSET + 3
%EQUATE `MCI_SEQ_DIV_SMPTE_30 = %MCI_SEQ_OFFSET + 4
'/* flags for the dwMaster field of MCI_SEQ_SET_PARMS parameter block */
'/* MCI_SET command, (dwFlags == MCI_SEQ_SET_MASTER) */
%EQUATE `MCI_SEQ_FORMAT_SONGPTR = &H00004001
%EQUATE `MCI_SEQ_FILE = &H00004002
%EQUATE `MCI_SEQ_MIDI = &H00004003
%EQUATE `MCI_SEQ_SMPTE = &H00004004
%EQUATE `MCI_SEQ_NONE = 65533
%EQUATE `MCI_SEQ_MAPPER = 65535
'/* flags for the dwItem field of MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_SEQ_STATUS_TEMPO = &H00004002
%EQUATE `MCI_SEQ_STATUS_PORT = &H00004003
%EQUATE `MCI_SEQ_STATUS_SLAVE = &H00004007
%EQUATE `MCI_SEQ_STATUS_MASTER = &H00004008
%EQUATE `MCI_SEQ_STATUS_OFFSET = &H00004009
%EQUATE `MCI_SEQ_STATUS_DIVTYPE = &H0000400A
%EQUATE `MCI_SEQ_STATUS_NAME = &H0000400B
%EQUATE `MCI_SEQ_STATUS_COPYRIGHT = &H0000400C
'/* flags for the dwFlags parameter of MCI_SET command message */
%EQUATE `MCI_SEQ_SET_TEMPO = &H00010000
%EQUATE `MCI_SEQ_SET_PORT = &H00020000
%EQUATE `MCI_SEQ_SET_SLAVE = &H00040000
%EQUATE `MCI_SEQ_SET_MASTER = &H00080000
%EQUATE `MCI_SEQ_SET_OFFSET = &H01000000
'/* parameter block for MCI_SET command message */
' // Size = 32 bytes
TYPE MCI_SEQ_SET_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwTimeFormat AS DWORD ' DWORD dwTimeFormat
 dwAudio AS DWORD ' DWORD dwAudio
 dwTempo AS DWORD ' DWORD dwTempo
 dwPort AS DWORD ' DWORD dwPort
 dwSlave AS DWORD ' DWORD dwSlave
 dwMaster AS DWORD ' DWORD dwMaster
 dwOffset AS DWORD ' DWORD dwOffset
END TYPE
'/* MCI extensions for animation devices */
'/* flags for dwFlags parameter of MCI_OPEN command message */
%EQUATE `MCI_ANIM_OPEN_WS = &H00010000
%EQUATE `MCI_ANIM_OPEN_PARENT = &H00020000
%EQUATE `MCI_ANIM_OPEN_NOSTATIC = &H00040000
'/* flags for dwFlags parameter of MCI_PLAY command message */
%EQUATE `MCI_ANIM_PLAY_SPEED = &H00010000
%EQUATE `MCI_ANIM_PLAY_REVERSE = &H00020000
%EQUATE `MCI_ANIM_PLAY_FAST = &H00040000
%EQUATE `MCI_ANIM_PLAY_SLOW = &H00080000
%EQUATE `MCI_ANIM_PLAY_SCAN = &H00100000
'/* flags for dwFlags parameter of MCI_STEP command message */
%EQUATE `MCI_ANIM_STEP_REVERSE = &H00010000
%EQUATE `MCI_ANIM_STEP_FRAMES = &H00020000
'/* flags for dwItem field of MCI_STATUS_PARMS parameter block */
%EQUATE `MCI_ANIM_STATUS_SPEED = &H00004001
%EQUATE `MCI_ANIM_STATUS_FORWARD = &H00004002
%EQUATE `MCI_ANIM_STATUS_HWND = &H00004003
%EQUATE `MCI_ANIM_STATUS_HPAL = &H00004004
%EQUATE `MCI_ANIM_STATUS_STRETCH = &H00004005
'/* flags for the dwFlags parameter of MCI_INFO command message */
'#define MCI_ANIM_INFO_TEXT 0x00010000L
%EQUATE `MCI_ANIM_INFO_TEXT = &H00010000
'/* flags for dwItem field of MCI_GETDEVCAPS_PARMS parameter block */
%EQUATE `MCI_ANIM_GETDEVCAPS_CAN_REVERSE = &H00004001
%EQUATE `MCI_ANIM_GETDEVCAPS_FAST_RATE = &H00004002
%EQUATE `MCI_ANIM_GETDEVCAPS_SLOW_RATE = &H00004003
%EQUATE `MCI_ANIM_GETDEVCAPS_NORMAL_RATE = &H00004004
%EQUATE `MCI_ANIM_GETDEVCAPS_PALETTES = &H00004006
%EQUATE `MCI_ANIM_GETDEVCAPS_CAN_STRETCH = &H00004007
%EQUATE `MCI_ANIM_GETDEVCAPS_MAX_WINDOWS = &H00004008
'/* flags for the MCI_REALIZE command message */
%EQUATE `MCI_ANIM_REALIZE_NORM = &H00010000
%EQUATE `MCI_ANIM_REALIZE_BKGD = &H00020000
'/* flags for dwFlags parameter of MCI_WINDOW command message */
%EQUATE `MCI_ANIM_WINDOW_HWND = &H00010000
%EQUATE `MCI_ANIM_WINDOW_STATE = &H00040000
%EQUATE `MCI_ANIM_WINDOW_TEXT = &H00080000
%EQUATE `MCI_ANIM_WINDOW_ENABLE_STRETCH = &H00100000
%EQUATE `MCI_ANIM_WINDOW_DISABLE_STRETCH = &H00200000
'/* flags for hWnd field of MCI_ANIM_WINDOW_PARMS parameter block */
'/* MCI_WINDOW command message, (dwFlags == MCI_ANIM_WINDOW_HWND) */
%EQUATE `MCI_ANIM_WINDOW_DEFAULT = &H00000000
'/* flags for dwFlags parameter of MCI_PUT command message */
%EQUATE `MCI_ANIM_RECT = &H00010000
%EQUATE `MCI_ANIM_PUT_SOURCE = &H00020000
%EQUATE `MCI_ANIM_PUT_DESTINATION = &H00040000
'/* flags for dwFlags parameter of MCI_WHERE command message */
%EQUATE `MCI_ANIM_WHERE_SOURCE = &H00020000
%EQUATE `MCI_ANIM_WHERE_DESTINATION = &H00040000
'/* flags for dwFlags parameter of MCI_UPDATE command message */
%EQUATE `MCI_ANIM_UPDATE_HDC = &H00020000
'/* parameter block for MCI_OPEN command message */
' // Size = 28 bytes
TYPE MCI_ANIM_OPEN_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceID AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS ASCIIZ PTR ' LPCSTR lpstrDeviceType
 lpstrElementName AS ASCIIZ PTR ' LPCSTR lpstrElementName
 lpstrAlias AS ASCIIZ PTR ' LPCSTR lpstrAlias
 dwStyle AS DWORD ' DWORD dwStyle
 hwndParent AS DWORD ' HWND hWndParent
END TYPE
' // Size = 28 bytes
TYPE MCI_ANIM_OPEN_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceID AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS WSTRINGZ PTR ' LPCWSTR lpstrDeviceType
 lpstrElementName AS WSTRINGZ PTR ' LPCWSTR lpstrElementName
 lpstrAlias AS WSTRINGZ PTR ' LPCWSTR lpstrAlias
 dwStyle AS DWORD ' DWORD dwStyle
 hwndParent AS DWORD ' HWND hWndParent
END TYPE
MACRO MCI_ANIM_OPEN_PARMS = MCI_ANIM_OPEN_PARMSA
'/* parameter block for MCI_PLAY command message */
' // Size = 16 bytes
TYPE MCI_ANIM_PLAY_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrom AS DWORD ' DWORD dwFrom
 dwTo AS DWORD ' DWORD dwTo
 dwSpeed AS DWORD ' DWORD dwSpeed
END TYPE
'/* parameter block for MCI_STEP command message */
' // Size = 8 bytes
TYPE MCI_ANIM_STEP_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 dwFrames AS DWORD ' DWORD dwFrames
END TYPE
'/* parameter block for MCI_WINDOW command message */
' // Size = 16 bytes
TYPE MCI_ANIM_WINDOW_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 hWnd AS DWORD ' HWND hWnd
 nCmdShow AS DWORD ' UINT nCmdShow
 lpstrText AS ASCIIZ PTR ' LPCSTR lpstrText
END TYPE
' // Size = 16 bytes
TYPE MCI_ANIM_WINDOW_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 hWnd AS DWORD ' HWND hWnd
 nCmdShow AS DWORD ' UINT nCmdShow
 lpstrText AS WSTRINGZ PTR ' LPCWSTR lpstrText
END TYPE
MACRO MCI_ANIM_WINDOW_PARMS = MCI_ANIM_WINDOW_PARMSA
'/* parameter block for MCI_PUT, MCI_UPDATE, MCI_WHERE command messages */
' // Size = 20 bytes
TYPE MCI_ANIM_RECT_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 rc AS RECT ' RECT rc
END TYPE
'/* parameter block for MCI_UPDATE PARMS */
' // Size = 24 bytes
TYPE MCI_ANIM_UPDATE_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 rc AS RECT ' RECT rc
 hDC AS DWORD ' HDC hDC
END TYPE
'/* MCI extensions for video overlay devices */
'/* flags for dwFlags parameter of MCI_OPEN command message */
%EQUATE `MCI_OVLY_OPEN_WS = &H00010000
%EQUATE `MCI_OVLY_OPEN_PARENT = &H00020000
'/* flags for dwFlags parameter of MCI_STATUS command message */
%EQUATE `MCI_OVLY_STATUS_HWND = &H00004001
%EQUATE `MCI_OVLY_STATUS_STRETCH = &H00004002
'/* flags for dwFlags parameter of MCI_INFO command message */
%EQUATE `MCI_OVLY_INFO_TEXT = &H00010000
'/* flags for dwItem field of MCI_GETDEVCAPS_PARMS parameter block */
%EQUATE `MCI_OVLY_GETDEVCAPS_CAN_STRETCH = &H00004001
%EQUATE `MCI_OVLY_GETDEVCAPS_CAN_FREEZE = &H00004002
%EQUATE `MCI_OVLY_GETDEVCAPS_MAX_WINDOWS = &H00004003
'/* flags for dwFlags parameter of MCI_WINDOW command message */
%EQUATE `MCI_OVLY_WINDOW_HWND = &H00010000
%EQUATE `MCI_OVLY_WINDOW_STATE = &H00040000
%EQUATE `MCI_OVLY_WINDOW_TEXT = &H00080000
%EQUATE `MCI_OVLY_WINDOW_ENABLE_STRETCH = &H00100000
%EQUATE `MCI_OVLY_WINDOW_DISABLE_STRETCH = &H00200000
'/* flags for hWnd parameter of MCI_OVLY_WINDOW_PARMS parameter block */
%EQUATE `MCI_OVLY_WINDOW_DEFAULT = &H00000000
'/* flags for dwFlags parameter of MCI_PUT command message */
%EQUATE `MCI_OVLY_RECT = &H00010000
%EQUATE `MCI_OVLY_PUT_SOURCE = &H00020000
%EQUATE `MCI_OVLY_PUT_DESTINATION = &H00040000
%EQUATE `MCI_OVLY_PUT_FRAME = &H00080000
%EQUATE `MCI_OVLY_PUT_VIDEO = &H00100000
'/* flags for dwFlags parameter of MCI_WHERE command message */
%EQUATE `MCI_OVLY_WHERE_SOURCE = &H00020000
%EQUATE `MCI_OVLY_WHERE_DESTINATION = &H00040000
%EQUATE `MCI_OVLY_WHERE_FRAME = &H00080000
%EQUATE `MCI_OVLY_WHERE_VIDEO = &H00100000
'/* parameter block for MCI_OPEN command message */
'#ifdef _WIN32
' // Size = 28 bytes
TYPE MCI_OVLY_OPEN_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceId AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS ASCIIZ PTR ' LPCSTR lpstrDeviceType
 lpstrElementName AS ASCIIZ PTR ' LPCSTR lpstrElementName
 lpstrAlias AS ASCIIZ PTR ' LPCSTR lpstrAlias
 dwStyle AS DWORD ' DWORD dwStyle
 hwndParent AS DWORD ' HWND hWndParent
END TYPE
' // Size = 28 bytes
TYPE MCI_OVLY_OPEN_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 wDeviceId AS DWORD ' MCIDEVICEID wDeviceID
 lpstrDeviceType AS WSTRINGZ PTR ' LPCWSTR lpstrDeviceType
 lpstrElementName AS WSTRINGZ PTR ' LPCWSTR lpstrElementName
 lpstrAlias AS WSTRINGZ PTR ' LPCWSTR lpstrAlias
 dwStyle AS DWORD ' DWORD dwStyle
 hwndParent AS DWORD ' HWND hWndParent
END TYPE
MACRO MCI_OVLY_OPEN_PARMS = MCI_OVLY_OPEN_PARMSA
'/* parameter block for MCI_WINDOW command message */
'#ifdef _WIN32
' // Size = 16 bytes
TYPE MCI_OVLY_WINDOW_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 hWnd AS DWORD ' HWND hWnd
 nCmdShow AS DWORD ' UINT nCmdShow
 lpstrText AS ASCIIZ PTR ' LPCSTR lpstrText
END TYPE
' // Size = 16 bytes
TYPE MCI_OVLY_WINDOW_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 hWnd AS DWORD ' HWND hWnd
 nCmdShow AS DWORD ' UINT nCmdShow
 lpstrText AS WSTRINGZ PTR ' LPCWSTR lpstrText
END TYPE
MACRO MCI_OVLY_WINDOW_PARMS = MCI_OVLY_WINDOW_PARMSA
'/* parameter block for MCI_PUT, MCI_UPDATE, and MCI_WHERE command messages */
' // Size = 20 bytes
TYPE MCI_OVLY_RECT_PARMS BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 rc AS RECT ' RECT rc
END TYPE
'/* parameter block for MCI_SAVE command message */
' // Size = 24 bytes
TYPE MCI_OVLY_SAVE_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS ASCIIZ PTR ' LPCSTR lpfilename
 rc AS RECT ' RECT rc
END TYPE
' // Size = 24 bytes
TYPE MCI_OVLY_SAVE_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS WSTRINGZ PTR ' LPCWSTR lpfilename
 rc AS RECT ' RECT rc
END TYPE
MACRO MCI_OVLY_SAVE_PARMS = MCI_OVLY_SAVE_PARMSA
'/* parameter block for MCI_LOAD command message */
' // Size = 24 bytes
TYPE MCI_OVLY_LOAD_PARMSA BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS ASCIIZ PTR ' LPCSTR lpfilename
 rc AS RECT ' RECT rc
END TYPE
' // Size = 24 bytes
TYPE MCI_OVLY_LOAD_PARMSW BYTE
 dwCallback AS DWORD ' DWORD_PTR dwCallback
 lpFileName AS WSTRINGZ PTR ' LPCWSTR lpfilename
 rc AS RECT ' RECT rc
END TYPE
MACRO MCI_OVLY_LOAD_PARMS = MCI_OVLY_LOAD_PARMSA
#ENDIF ' #IF NOT %DEF(%MMNOMCI)
'/****************************************************************************
' DISPLAY Driver extensions
'****************************************************************************/
' CAPS1 and C1_TRANSPARENT aren't defined in the Vista SDK
%EQUATE `CAPS1 = 94 ' other caps
%EQUATE `C1_TRANSPARENT = &H1 ' new raster cap
'#IF NOT %DEF(%NEWTRANSPARENT)
%EQUATE `NEWTRANSPARENT = 3 ' use with SetBkMode()
%EQUATE `QUERYROPSUPPORT = 40 ' use to determine ROP support
'#ENDIF
'/****************************************************************************
' DIB Driver extensions
'****************************************************************************/
%EQUATE `SELECTDIB = 41 ' DIB.DRV select dib escape
'#define DIBINDEX(n) MAKELONG((n),0x10FF)
MACRO DIBINDEX(n) = MAK(LONG, n, &H10FF)
'/****************************************************************************
' ScreenSaver support
' The current application will receive a syscommand of SC_SCREENSAVE just
' before the screen saver is invoked. If the app wishes to prevent a
' screen save, return non-zero value, otherwise call DefWindowProc().
'****************************************************************************/
#IF NOT %DEF(%SC_SCREENSAVE)
 %SC_SCREENSAVE = &HF140
#ENDIF
'#ifdef _WIN32
'#include <poppack.h>
'#else
'#ifndef RC_INVOKED
'#pragma pack()
'#endif
'#endif
#ENDIF
