/*===========================================================================*\
 # CTMMSYS.H (revision 1.4)                                                  #
 #      Header file for CTMMSYS.SYS                                          #
 #                                                                           #
 #---------------------------------------------------------------------------#
 #               Copyright (c) Creative Technology Ltd, 1993.                #
 #                           All Rights Reserved.                            #
 #---------------------------------------------------------------------------#
 # Author: LCKwek, April 1993                                                #
\*===========================================================================*/

#ifndef _CTMMSYS_H
#define _CTMMSYS_H


#include "ctstddef.h"


#if defined(_MSC_VER)
    #pragma pack(1)                 /* Byte-wise packing */
#elif defined(__BORLANDC__) || defined(__TURBOC__)
    #pragma option -a-
#endif

#ifdef __cplusplus
extern "C" {
#endif


/*---------------------------------------------------------------------------*/

typedef DWORD   MMSTATUS;

#define MMSTATUS_SUCCESS                0x00000000
#define MMSTATUS_ERROR                  0x00000001
#define MMSTATUS_ALLOCATED              0x00000002
#define MMSTATUS_UNALLOCATED            0x00000003
#define MMSTATUS_UNSUPPORTED_MSG        0x00000004
#define MMSTATUS_BAD_HANDLE             0x00000005
#define MMSTATUS_BAD_DEVICEID           0x00000006
#define MMSTATUS_BAD_FLAG               0x00000007
#define MMSTATUS_BAD_PARAMETER          0x00000008
#define MMSTATUS_REDUNDANT_ACTION       0x00000009
#define MMSTATUS_BUFFER_TOO_SMALL       0x0000000A
#define MMSTATUS_NOT_ENABLED            0x0000000B
#define MMSTATUS_BAD_FORMAT             0x0000000C
#define MMSTATUS_STILL_ACTIVE           0x0000000D
#define MMSTATUS_NO_MEMORY              0x0000000E
#define MMSTATUS_DRIVER_BUSY            0x0000000F


/*---------------------------------------------------------------------------*/

#define PARAM_UNUSED    0

/*---------------------------------------------------------------------------*/

typedef WORD    MMDEVICE;

#define MMDEVICE_SOUNDOUT       1
#define MMDEVICE_SOUNDIN        2
#define MMDEVICE_MIDIOUT        3
#define MMDEVICE_MIDIIN         4
#define MMDEVICE_AUX            5
#define MMDEVICE_CSP            6



typedef DWORD           HANDLE;
typedef HANDLE          HMMDEVICE;
typedef HMMDEVICE FAR  *LPHMMDEVICE;


typedef MMSTATUS
        (FAR PASCAL *MMSYSPROC)(
            IN      HMMDEVICE   hDev,
            IN      MMDEVICE    MmDevice,
            IN      WORD        wMsg,
            IN OUT  DWORD       dwParam1,
            IN OUT  DWORD       dwParam2
            );


/* Assign to the MMSYSPROC instance variable before making the DOS
 * IOCtlRead call to get the entry point to CTMMSYS.SYS
 */
#define CTMM_ENTRYPOINT_KEY     0x4D6D7443      /* "CtmM" */


/*---------------------------------------------------------------------------*/

typedef struct
    {
    WORD    wType;
    union
        {
        LPBYTE  lpMem;
        struct
            {
            WORD    wHandle;
            DWORD   dwOffset;
            } xms;
        } u;

    DWORD   dwReserved;
    }       MEMORYDESC,
      FAR  *LPMEMORYDESC;

#define MEMORYDESC_MEM      0x0001
#define MEMORYDESC_XMS      0x0002


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

/* Common messages
 */
#define XXDM_QUERY_NumDevs              0x0100
#define XXDM_QUERY_Capabilities         0x0101
#define XXDM_CONFIGURATION_Query        0x0200
#define XXDM_OPEN                       0x0300
#define XXDM_CLOSE                      0x0400


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

#define SODM_QUERY_NumDevs              XXDM_QUERY_NumDevs
#define SODM_QUERY_Capabilities         XXDM_QUERY_Capabilities
#define SODM_QUERY_SamplingRange        0x0102
#define SODM_QUERY_TransferBuffer       0x0103
#define SODM_CONFIGURATION_Query        XXDM_CONFIGURATION_Query
#define SODM_OPEN                       XXDM_OPEN
#define SODM_CLOSE                      XXDM_CLOSE
#define SODM_STATE_Query                0x0500
#define SODM_STATE_Set                  0x0501
#define SODM_BUFFERQUEUE_Query          0x0600
#define SODM_BUFFERQUEUE_Add            0x0601
#define SODM_POSITION_Query             0x0700
#define SODM_MISC_SetSpeaker            0x0801


/*---------------------------------------------------------------------------*/


#define SIDM_QUERY_NumDevs              XXDM_QUERY_NumDevs
#define SIDM_QUERY_Capabilities         XXDM_QUERY_Capabilities
#define SIDM_QUERY_SamplingRange        0x0102
#define SIDM_QUERY_TransferBuffer       0x0103
#define SIDM_CONFIGURATION_Query        XXDM_CONFIGURATION_Query
#define SIDM_OPEN                       XXDM_OPEN
#define SIDM_CLOSE                      XXDM_CLOSE
#define SIDM_STATE_Query                0x0500
#define SIDM_STATE_Set                  0x0501
#define SIDM_BUFFERQUEUE_Query          0x0600
#define SIDM_BUFFERQUEUE_Add            0x0601
#define SIDM_POSITION_Query             0x0700
#define SIDM_MISC_SetSpeaker            0x0801



/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

/*** For SxDM_QUERY_NumDevs
 *
 *      Invocation
 *      ----------
 *      WORD    wNumDevs;
 *
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX, SxDM_QUERY_NumDevs,
 *                (DWORD)(LPWORD)&wNumDevs, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *
 *      Comment
 *      -------
 *      If no SoundXx devices are installed, then {wNumDevs} will be set
 *      to zero.
 */


/*----------------------------------------------------------------------*/

/*** For SxDM_QUERY_Capabilities
 *
 *      Invocation
 *      ----------
 *      SOUNDCAPS   caps;
 *
 *      caps.wDeviceID = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX,
 *                SxDM_QUERY_Capabilities,
 *                (DWORD)(LPSOUNDCAPS)&caps, PARAM_UNUSED);
 *
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 */


/* For XXXCAPS.szProductName
 */
#define MMCAPS_PRODUCTNAME_MAXLEN   32


typedef struct
    {
    IN      WORD    wDeviceID;
    OUT     DWORD   dwDriverVersion;
    OUT     WORD    wProduct;
    OUT     CHAR    szProductName[MMCAPS_PRODUCTNAME_MAXLEN];
    OUT     WORD    wChannels;
    OUT     DWORD   dwFlags;
    }       SOUNDCAPS,
      FAR  *LPSOUNDCAPS;


/* XXXCAPS.dwDriverVersion
 *
 *      Word1 = version
 *               high-byte = major
 *                low-byte = minor
 *      Word0 = build
 */


/* XXXCAPS.wProduct
 *
 *      Byte1 = family
 *      Byte0 = member  (make a new member if the programming is different)
 */
#define MMPRODUCT_SB        0x0101
#define MMPRODUCT_SB_2      0x0102
#define MMPRODUCT_SBPRO     0x0103
#define MMPRODUCT_SB16      0x0104
#define MMPRODUCT_PB        0x0201


/*----------------------------------------------------------------------*/

/*** For SxDM_QUERY_SamplingRange
 *
 *      Invocation
 *      ----------
 *      SOUNDSAMPLINGRANGE  range;
 *
 *      range.wDeviceID = 0;
 *      range.wChannels = 2;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX,
 *                SODM_QUERY_SamplingRange,
 *                (DWORD)(LPSOUNDSAMPLINGRANGE)&range, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_BAD_PARAMETER
 *      MMSTATUS_NOT_ENABLED
 */
typedef struct
    {
    IN      WORD    wDeviceID;
    IN      WORD    wChannels;
    OUT     DWORD   dwMinSamplesPerSec;
    OUT     DWORD   dwMaxSamplesPerSec;
    }       SOUNDSAMPLINGRANGE,
      FAR  *LPSOUNDSAMPLINGRANGE;


/*----------------------------------------------------------------------*/

/*** For SxDM_QUERY_TransferBuffer
 *
 *      Invocation
 *      ----------
 *      SOUNDQYXFERBUF      qy;
 *
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX,
 *                SxDM_QUERY_TransferBuffer,
 *                (DWORD)(LPSOUNDQYXFERBUF)&qy, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 */
typedef struct
    {
    IN      WORD        wDeviceID;
    OUT     WORD        wMemoryDescType;
    OUT     WORD        wBlockAlign;
    OUT     DWORD       dwcbMinSize;
    OUT     DWORD       dwcbMaxSize;
    OUT     DWORD       dwcbGranularity;
    OUT     DWORD       dwFlags;
    }       SOUNDQYXFERBUF,
      FAR  *LPSOUNDQYXFERBUF;


/* SOUNDQYXFERBUF.dwcbMinSize, .dwcbMaxSize
 *
 *      If dwcbMinSize == dwcbMaxSize == 0, then no transfer buffer is needed.
 */


/* SOUNDQYXFERBUF.dwFlags
 */
#define SOUNDQYXFERBUF_CANNOTCROSS64KBPAGE      0x00000001
#define SOUNDQYXFERBUF_CANNOTCROSS128KBPAGE     0x00000002


/*----------------------------------------------------------------------*/

/*** For SxDM_CONFIGURATION_Query
 *
 *      Invocation
 *      ----------
 *      DEVCONFIG   config;
 *
 *      config.wDeviceID = 0;
 *      config.dwFlags   = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX,
 *                SxDM_CONFIGURATION_Query,
 *                (DWORD)(LPDEVCONFIG)&config, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 *
 *      Purpose
 *      -------
 *      For the high-level voice/wave drivers (CT-VOICE et. al.) to
 *      ascertain whether the configuration of the card matches that
 *      of the BLASTER environment variable.
 */
typedef struct
    {
    IN      WORD    wDeviceID;
    IN OUT  DWORD   dwFlags;
    OUT     LPCSTR  szzConfiguration;
    }       DEVCONFIG,
      FAR  *LPDEVCONFIG;


/* DEVCONFIG.szzConfiguration
 *
 *      Minimally, points to
 *          'BLASTER=A:220 I:5 D:1 H:5',0,0
 */


/*----------------------------------------------------------------------*/

/*** For SxDM_OPEN
 *
 *      Invocation
 *      ----------
 *      VOID
 *      FAR PASCAL LOADDS
 *      SoundCallback (
 *          HMMDEVICE  hDev,
 *          WORD       wMsg,
 *          DWORD      dwCallbackData,
 *          DWORD      dwParam1,
 *          DWORD      dwParam2
 *          )
 *      {
 *      ...
 *      }
 *
 *
 *      VOID
 *      fubar (VOID)
 *      {
 *      SOUNDOPEN           SoundOpen;
 *      SOUNDFORMAT         SoundFormat;
 *      SOUNDXFERBUFDESC    SoundXferBufDesc;
 *
 *      SoundOpen.wDeviceID = 0;
 *      ... initialize SoundFormat
 *      SoundOpen.lpFormat = &SoundFormat;
 *      SoundOpen.dwFlags  = 0;
 *      SoundOpen.Callback = SoundCallback;
 *      ... initialize soundOpen.dwCallbackData
 *      ... initialize soundXferBufDesc
 *      SoundOpen.lpXferBufDesc = &SoundXferBufDesc;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_SOUNDXX, SxDM_OPEN,
 *                (DWORD)(LPSOUNDOPEN)&SoundOpen, PARAM_UNUSED);
 *      ...
 *      ...
 *      }
 *
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_ALLOCATED
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 *      MMSTATUS_BAD_FORMAT
 *      MMSTATUS_NO_MEMORY          if a transfer-buffer is required, but
 *                                    wasn't provided; or didn't satisfy
 *                                    the conditions
 *
 *      Comment
 *      -------
 *      If succesful, SOUNDOPEN.hDev is to be used with the other messages.
 */

typedef struct
    {
    IN      WORD    wFormatTag;
    IN      WORD    wFormatFamily;
    IN      WORD    wChannels;
    IN      DWORD   dwSamplesPerSec;
    IN      WORD    wBlockAlign;
    IN      WORD    wBitsPerSample;
    IN      WORD    wcbExtraSize;
    }       SOUNDFORMAT,
      FAR  *LPSOUNDFORMAT;


/* SOUNDFORMAT.wFormatFamily
 */
#define SOUNDFORMAT_FAMILY_WAVE         1
#define SOUNDFORMAT_FAMILY_CREATIVE     2


/* SOUNDFORMAT.wFormatTag
 */
    /* For SOUNDFORMAT.wFormatFamily == SOUNDFORMAT_FAMILY_WAVE
     */
    #define WAVE_FORMAT_PCM                 0x0001
    #define WAVE_FORMAT_ALAW                0x0006
    #define WAVE_FORMAT_MULAW               0x0007
    #define WAVE_FORMAT_CREATIVE_ADPCM      0x0200

    /* For SOUNDFORMAT.wFormatFamily == SOUNDFORMAT_FAMILY_CREATIVE
     */
    #define CREATIVE_FORMAT_ADPCM           0x0001  /* old 4-, 3-, 2-bit ADPCM */


/* SOUNDFORMAT.wBlockAlign
 *
 *      The user must set this field to
 *          wBlockAlign = max(1, (wBitsPerSample*wChannels)/8)
 *
 *      The driver will validate this field, and will return
 *      MMSTATUS_BAD_FORMAT if the value is wrong.
 *
 *      What is this field used for? Well, the user must make sure that,
 *      when submitting buffers to the driver, SOUNDBUFFER.dwcbBufferSize
 *      is a multiple of SOUNDFORMAT.wBlockAlign.
 */


/*------------------------------------------------------------*/

typedef VOID
(FAR PASCAL *SOUNDCALLBACK)(    /* the function should be defined with LOADDS */
    HMMDEVICE  hDev,
    WORD       wMsg,
    DWORD      dwCallbackData,
    DWORD      dwParam1,
    DWORD      dwParam2
    );


/* wMsg
 */
#define SOM_BUFFERDONE      0x0001
#define SIM_BUFFERDONE      0x0002
    /*
     * For wMsg == SxM_BUFFERDONE
     *
     *      dwParam1 = a variable of type LPSOUNDBUFFER
     *      dwParam2 = PARAM_UNUSED
     */


/*------------------------------------------------------------*/

typedef struct
    {
    IN      MEMORYDESC  Buffer;
    IN      DWORD       dwcbBufferSize;
    }       SOUNDXFERBUFDESC,
      FAR  *LPSOUNDXFERBUFDESC;


/*------------------------------------------------------------*/

typedef struct
    {
    IN      WORD                wDeviceID;
    OUT     HMMDEVICE           hDev;
    IN      LPSOUNDFORMAT       lpFormat;
    IN      DWORD               dwFlags;
    IN      SOUNDCALLBACK       Callback;
    IN      DWORD               dwCallbackData;
    IN      LPSOUNDXFERBUFDESC  lpXferBufDesc;
    }       SOUNDOPEN,
      FAR  *LPSOUNDOPEN;


/* SOUNDOPEN.dwFlags
 */
#define SOUNDOPEN_QUERYFORMAT   0x00000001


/* SOUNDOPEN.lpXferBufDesc
 *
 *      Set SOUNDOPEN.lpXferBufDesc to NULL when the call to
 *      SxDM_QUERY_TransferBuffer indicates that you don't need an
 *      intermediate transfer-buffer.
 *
 *      The transfer-buffer passed to the driver will be used only for the
 *      lifetime of the open handle. When the device is closed, leading
 *      to the handle being no longer valid, the transfer-buffer is
 *      considered by the driver to have been returned to the application.
 */


/*----------------------------------------------------------------------*/

/*** For SxDM_CLOSE
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_CLOSE,
 *                PARAM_UNUSED, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_STILL_ACTIVE
 */


/*----------------------------------------------------------------------*/

/*** For SxDM_STATE_Query
 *
 *      Invocation
 *      ----------
 *      SOUNDSTATE  SoundState;
 *
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_STATE_Query,
 *                (DWORD)(LPSOUNDSTATE)&SoundState, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */
typedef DWORD   SOUNDSTATE;
typedef SOUNDSTATE FAR  *LPSOUNDSTATE;

#define SOUNDSTATE_IDLE         0
#define SOUNDSTATE_ACTIVE       1
#define SOUNDSTATE_PAUSED       2


/*----------------------------------------------------------------------*/

/*** For SxDM_STATE_Set
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_STATE_Set,
 *                SOUNDSTATE_START, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_BAD_PARAMETER
 *      MMSTATUS_REDUNDANT_ACTION
 */
#define SOUNDSTATE_START        1
#define SOUNDSTATE_STOP         2
#define SOUNDSTATE_RESET        3


/*----------------------------------------------------------------------*/

/*** For SxDM_BUFFERQUEUE_Query
 *
 *      Invocation
 *      ----------
 *      SOUNDBUFQ   SoundBufQ;
 *
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_BUFFERQUEUE_Query,
 *                (DWORD)(LPSOUNDBUFQ)&SoundBufQ, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
    OUT     DWORD   dwcbQueuedData;
    }       SOUNDBUFQ,
      FAR  *LPSOUNDBUFQ;


/* SOUNDBUFQ.dwFlags
 */
#define SOUNDBUFQ_NEEDBUFFERS   0x00000001
            /*
             * Ran out of stuff to playback.
             * Or ran out of buffers to store the recorded stuff.
             */


/*----------------------------------------------------------------------*/

/*** For SxDM_BUFFERQUEUE_Add
 *
 *      Invocation
 *      ----------
 *      SOUNDBUFFER     SoundBuf;
 *
 *      SoundBuf.dwFlags = 0;
 *      ... initialize rest of SoundBuf
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_BUFFERQUEUE_Add,
 *                (DWORD)(LPSOUNDBUFFER)&SoundBuf, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_BAD_PARAMETER
 *      MMSTATUS_NO_MEMORY          driver ran out of memory for internal support structures
 */
typedef struct _SOUNDBUFFER
    {
    IN      MEMORYDESC                  Buffer;
    IN      DWORD                       dwcbBufferSize;
    OUT     DWORD                       dwcbRecorded;
    IN      DWORD                       dwUserData;
    IN OUT  DWORD                       dwFlags;
            struct _SOUNDBUFFER FAR    *lpNext;
            DWORD                       dwReserved;
    }       SOUNDBUFFER,
      FAR  *LPSOUNDBUFFER;


/* SOUNDBUFFER.dwcbBufferSize
 *
 *      1) A value of zero for this field is flagged as a
 *         MMSTATUS_BAD_PARAMETER.
 *
 *      2) This field must be a multiple of SOUNDFORMAT.wBlockAlign
 *
 *      3) Even after complying with point #2, if the buffer is in
 *         extended memory, the minimum value for this field is 2
 *         (yes, TWO). This is because the XMS services won't handle
 *         odd length moves. I can synthesize odd length moves of
 *         3 or greater, but there's nothing I can do about a solitary
 *         isolated byte.
 */


/* SOUNDBUFFER.dwFlags
 */
#define SOUNDBUFFER_DONE        0x00000001      /* Set by the driver */
#define SOUNDBUFFER_INQUEUE     0x00000002      /* Set by the driver */


/*----------------------------------------------------------------------*/

/*** For SxDM_POSITION_Query
 *
 *      Invocation
 *      ----------
 *      MMTIME  mmtime;
 *
 *      mmtime.wType = MMTIME_BYTES;
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_POSITION_Query,
 *                (DWORD)(LPMMTIME)&mmtime, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */
typedef struct
    {
    IN OUT  WORD    wType;
    OUT     union
                {
                DWORD   dwMillisecs;
                DWORD   dwSamples;
                DWORD   dwBytes;
                } u;
    }       MMTIME,
      FAR  *LPMMTIME;


/* MMTIME.wType
 */
#define MMTIME_MILLISECS        0x0001
#define MMTIME_SAMPLES          0x0002
#define MMTIME_BYTES            0x0004


/* Note:
 *      Stereo L/R constitutes _ONE_ sample.
 */


/*----------------------------------------------------------------------*/

/*** For SxDM_MISC_SetSpeaker
 *
 *      Set dwParam1 to SPEAKER_OFF or SPEAKER_ON
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_SOUNDXX, SxDM_MISC_SetSpeaker,
 *                SPEAKER_ON, PARAM_UNUSED);
 */

#define SPEAKER_OFF     0
#define SPEAKER_ON      1


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/


#define AUXDM_QUERY_NumDevs             XXDM_QUERY_NumDevs
#define AUXDM_QUERY_Capabilities        XXDM_QUERY_Capabilities
#define AUXDM_CONFIGURATION_Query       XXDM_CONFIGURATION_Query
#define AUXDM_OPEN                      XXDM_OPEN
#define AUXDM_CLOSE                     XXDM_CLOSE
#define AUXDM_VOLUME_QueryCaps          0x0500
#define AUXDM_VOLUME_Get                0x0501
#define AUXDM_VOLUME_Set                0x0502
#define AUXDM_MIXING_QueryCaps          0x0600
#define AUXDM_MIXING_Get                0x0601
#define AUXDM_MIXING_Set                0x0602
#define AUXDM_FILTER_QueryCaps          0x0700
#define AUXDM_FILTER_Get                0x0701
#define AUXDM_FILTER_Set                0x0702
#define AUXDM_TONE_QueryCaps            0x0800
#define AUXDM_TONE_Get                  0x0801
#define AUXDM_TONE_Set                  0x0802
#define AUXDM_GAIN_QueryCaps            0x0900
#define AUXDM_GAIN_Get                  0x0901
#define AUXDM_GAIN_Set                  0x0902
#define AUXDM_AGC_QueryCaps             0x0A00
#define AUXDM_AGC_Get                   0x0A01
#define AUXDM_AGC_Set                   0x0A02
#define AUXDM_MISC_Reset                0x0B01


/*---------------------------------------------------------------------------*/

/*** For AUXDM_QUERY_NumDevs
 *
 *      Invocation
 *      ----------
 *      WORD    wNumDevs;
 *
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_AUX, AUXDM_QUERY_NumDevs,
 *                (DWORD)(LPWORD)&wNumDevs, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *
 *      Comment
 *      -------
 *      If no Auxiliary devices are installed, then {wNumDevs} will be
 *      set to zero.
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_QUERY_Capabilities
 *
 *      Invocation
 *      ----------
 *      AUXCAPS     caps;
 *
 *      caps.wDeviceID = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_AUX, AUXDM_QUERY_Capabilities,
 *                (DWORD)(LPAUXCAPS)&caps, PARAM_UNUSED);
 *
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 */
typedef struct
    {
    IN      WORD    wDeviceID;
    OUT     DWORD   dwDriverVersion;
    OUT     WORD    wProduct;
    OUT     CHAR    szProductName[MMCAPS_PRODUCTNAME_MAXLEN];
    OUT     DWORD   dwSource;
    OUT     DWORD   dwSupport;
    }       AUXCAPS,
      FAR  *LPAUXCAPS;


/* AUXCAPS.dwDriverVersion
 *
 *      See under SxDM_QUERY_Capabilities
 */


/* AUXCAPS.wProduct
 *
 *      See under SxDM_QUERY_Capabilities
 */


/* AUXCAPS.dwSource
 */
#define AUX_SOURCE_MASTER               0x00000001
#define AUX_SOURCE_VOICE                0x00000002
#define AUX_SOURCE_MIDI                 0x00000004
#define AUX_SOURCE_CD                   0x00000008
#define AUX_SOURCE_LINEIN               0x00000010
#define AUX_SOURCE_MIC                  0x00000020
#define AUX_SOURCE_PCSPEAKER            0x00000040


/* AUXCAPS.dwSupport
 */
#define AUXCAPS_SUPPORT_VOLUME          0x00000001
#define AUXCAPS_SUPPORT_MIXING          0x00000002
#define AUXCAPS_SUPPORT_FILTER          0x00000004
#define AUXCAPS_SUPPORT_TONE            0x00000008
#define AUXCAPS_SUPPORT_GAIN            0x00000010
#define AUXCAPS_SUPPORT_AGC             0x00000020


/*----------------------------------------------------------------------*/

/*** For AUXDM_CONFIGURATION_Query
 *
 *      See under SxDM_CONFIGURATION_Query
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_OPEN
 *
 *      Invocation
 *      ----------
 *      AUXOPEN     AuxOpen;
 *
 *      AuxOpen.wDeviceID = 0;
 *      AuxOpen.dwFlags   = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_AUX, AUXDM_OPEN,
 *                (DWORD)(LPAUXOPEN)&AuxOpen, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_ALLOCATED
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 */
typedef struct
    {
    IN      WORD        wDeviceID;
    OUT     HMMDEVICE   hDev;
    IN      DWORD       dwFlags;
    }       AUXOPEN,
      FAR  *LPAUXOPEN;


/*----------------------------------------------------------------------*/

/*** For AUXDM_CLOSE
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_AUX, AUXDM_CLOSE,
 *                PARAM_UNUSED, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */


/*----------------------------------------------------------------------*/

/*  The AUXSETTINGS structure is to be used with the following messages:
 *          AUXDM_VOLUME_Get/Set
 *          AUXDM_MIXING_Get/Set
 *          AUXDM_FILTER_Get/Set
 *          AUXDM_TONE_Get/Set
 *          AUXDM_GAIN_Get/Set
 *          AUXDM_AGC_Get/Set
 *
 *  For AUXDM_VOLUME_Get/Set and AUXDM_MIXING_Get/Set, set
 *      AUXSETTINGS.dwItem  to  AUX_SOURCE_XXX.
 *  You can only specify one source at a time.
 */
typedef struct
    {
    IN      DWORD   dwItem;
    IN OUT  DWORD   dwFlags;
    IN OUT  DWORD   dwLeft;
    IN OUT  DWORD   dwRight;
    }       AUXSETTINGS,
      FAR  *LPAUXSETTINGS;


/* AUXSETTINGS.dwFlags
 *
 *      If not used, set to zero.
 */


/* Return value will be MMSTATUS_UNSUPPORTED_MSG if the feature is
 * not supported. E.g. there are no filter controls on the SB16.
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_VOLUME_QueryCaps
 *
 *      Invocation
 *      ----------
 *      AUXVOLUMECAPS   AuxVolumeCaps;
 *
 *      MmSysProc(hDev, MMDEVICE_AUX, AUXDM_VOLUME_QueryCaps,
 *                (DWORD)(LPAUXVOLUMECAPS)&AuxVolumeCaps, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_NOT_ENABLED
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
    OUT     DWORD   dwStereo;       /* Bits set according to AUX_SOURCE_XXX */
    }       AUXVOLUMECAPS,
      FAR  *LPAUXVOLUMECAPS;



/*** For AUXDM_VOLUME_Get/Set
 *
 *      AUXSETTINGS.dwItem  = AUX_SOURCE_XXX
 *      AUXSETTINGS.dwFlags = 0
 *      AUXSETTINGS.dwLeft
 *      AUXSETTINGS.dwRight = 0 if source is mono
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_MIXING_QueryCaps
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
    OUT     DWORD   dwInputSource;
    OUT     DWORD   dwOutputSource;
    }       AUXMIXINGCAPS,
      FAR  *LPAUXMIXINGCAPS;


/* AUXMIXINGCAPS.dwFlags
 */
#define AUXMIXINGCAPS_INPUT_MONO                0x00000001
#define AUXMIXINGCAPS_OUTPUT_MONO               0x00000002
#define AUXMIXINGCAPS_INPUT_STEREO              0x00000004
#define AUXMIXINGCAPS_OUTPUT_STEREO             0x00000008
#define AUXMIXINGCAPS_INPUT_INDIVIDUAL_LR       0x00000010
#define AUXMIXINGCAPS_OUTPUT_INDIVIDUAL_LR      0x00000020
#define AUXMIXINGCAPS_INPUT_MULTIPLE            0x00000040
#define AUXMIXINGCAPS_OUTPUT_MULTIPLE           0x00000080



/*** For AUXDM_MIXING_Get/Set
 *
 *      Invocation
 *      ----------
 *      AUXSETTINGS     settings;
 *
 *      settings.dwItem  = AUX_MIXING_INPUT;
 *      settings.dwFlags = AUX_MIXING_LEFT;
 *      MmSysProc(hDev, MMDEVICE_AUX, AUDXM_MIXING_Get,
 *                (DWORD)(LPAUXSETTINGS)&settings, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_BAD_FLAG
 *      MMSTATUS_BAD_PARAMETER      if the dwItem specified is not supported
 */


/* For AUXSETTINGS.dwItem
 */
#define AUX_MIXING_INPUT        1
#define AUX_MIXING_OUTPUT       2

/* For AUXSETTINGS.dwFlags
 */
#define AUX_MIXING_LEFT         0x00000001      /* These two are mutually */
#define AUX_MIXING_RIGHT        0x00000002      /*   exclusive            */

/* For AUXSETTINGS.dwLeft, .dwRight
 *
 *      Set bits according to AUX_SOURCE_XXX
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_FILTER_QueryCaps
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
            DWORD   dwReserved;
    }       AUXFILTERCAPS,
      FAR  *LPAUXFILTERCAPS;


/* AUXFILTERCAPS.dwFlags
 */
#define AUXFILTERCAPS_INPUT_MONO            0x00000001
#define AUXFILTERCAPS_OUTPUT_MONO           0x00000002
#define AUXFILTERCAPS_INPUT_STEREO          0x00000004
#define AUXFILTERCAPS_OUTPUT_STEREO         0x00000008



/*** For AUXDM_FILTER_Get/Set
 */

/* For AUXSETTINGS.dwItem
 */
#define AUX_FILTER_INPUT        1
#define AUX_FILTER_OUTPUT       2

/* For AUXSETTINGS.dwLeft, .dwRight
 */
#define AUX_FILTER_OFF          0
#define AUX_FILTER_LOW          0x0000FFFF
#define AUX_FILTER_HIGH         0xFFFF0000
#define AUX_FILTER_ON           0xFFFFFFFF


/*----------------------------------------------------------------------*/

/*** For AUXDM_TONE_QueryCaps
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
    OUT     DWORD   dwTone;
    OUT     DWORD   dwStereo;       /* Bits set according to AUX_TONE_XXX */
    }       AUXTONECAPS,
      FAR  *LPAUXTONECAPS;


/* AUXTONECAPS.dwTone
 */
#define AUX_TONE_TREBLE         1
#define AUX_TONE_BASS           2



/*** For AUXDM_TONE_Get/Set
 */

/* For AUXSETTINGS.dwItem
 *
 *    Use AUXTONECAPS.dwTone::AUX_TONE_XXX
 */


/*----------------------------------------------------------------------*/

/*** For AUXDM_GAIN_QueryCaps
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
            DWORD   dwReserved;
    }       AUXGAINCAPS,
      FAR  *LPAUXGAINCAPS;


/* AUXGAINCAPS.dwFlags
 */
#define AUXGAINCAPS_INPUT_MONO          0x00000001
#define AUXGAINCAPS_OUTPUT_MONO         0x00000002
#define AUXGAINCAPS_INPUT_STEREO        0x00000004
#define AUXGAINCAPS_OUTPUT_STEREO       0x00000008



/*** For AUXDM_GAIN_Get/Set
 */

/* For AUXSETTINGS.dwItem
 */
#define AUX_GAIN_INPUT          1
#define AUX_GAIN_OUTPUT         2

/*----------------------------------------------------------------------*/

/*** For AUXDM_AGC_QueryCaps
 */
typedef struct
    {
    OUT     DWORD   dwFlags;
    OUT     DWORD   dwSource;       /* Bits set according to AUX_SOURCE_XXX */
    }       AUXAGCCAPS,
      FAR  *LPAUXAGCCAPS;



/*** For AUXDM_AGC_Get/Set
 */

/* For AUXSETTINGS.dwItem
 *
 *    Set bits according to AUX_SOURCE_XXX
 */

/* For AUXSETTINGS.dwLeft, .dwRight
 */
#define AUX_AGC_OFF             0
#define AUX_AGC_ON              1


/*----------------------------------------------------------------------*/

/*** For AUXDM_MISC_Reset
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_AUX, AUXDM_MISC_Reset,
 *                PARAM_UNUSED, PARAM_UNUSED);
 */


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

#define CSPDM_QUERY_NumDevs             XXDM_QUERY_NumDevs
#define CSPDM_QUERY_Capabilities        XXDM_QUERY_Capabilities
#define CSPDM_CONFIGURATION_Query       XXDM_CONFIGURATION_Query
#define CSPDM_OPEN                      XXDM_OPEN
#define CSPDM_CLOSE                     XXDM_CLOSE
#define CSPDM_STATE_Query               0x0500
#define CSPDM_STATE_Set                 0x0501
#define CSPDM_CODE_Download             0x0601


/*---------------------------------------------------------------------------*/

/*** For CSPDM_QUERY_NumDevs
 *
 *      Invocation
 *      ----------
 *      WORD    wNumDevs;
 *
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_CSP, CSPDM_QUERY_NumDevs,
 *                (DWORD)(LPWORD)&wNumDevs, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *
 *      Comment
 *      -------
 *      If no CSP devices are installed, then {wNumDevs} will be
 *      set to zero.
 */


/*----------------------------------------------------------------------*/

/*** For CSPDM_QUERY_Capabilities
 *
 *      Invocation
 *      ----------
 *      CSPCAPS  caps;
 *
 *      caps.wDeviceID = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_CSP,
 *                CSPDM_QUERY_Capabilities,
 *                (DWORD)(LPCSPCAPS)&caps, PARAM_UNUSED);
 *
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 */


typedef struct
    {
    IN      WORD    wDeviceID;
    OUT     DWORD   dwDriverVersion;
    OUT     WORD    wProduct;
    OUT     CHAR    szProductName[MMCAPS_PRODUCTNAME_MAXLEN];
    OUT     DWORD   dwFlags;
            DWORD   dwReserved;
    }       CSPCAPS,
      FAR  *LPCSPCAPS;


/* For CSPCAPS.dwDriverVersion
 *
 *      See under SxDM_QUERY_Capabilities
 */


/* For CSPCAPS.wProduct
 *
 *      See under SxDM_QUERY_Capabilities
 */


/*----------------------------------------------------------------------*/

/*** For CSPDM_CONFIGURATION_Query
 *
 *      See under SxDM_CONFIGURATION_Query for the structure DEVCONFIG
 *
 *      DEVCONFIG.szzConfiguration will minimally point to
 *          'BLASTER=A:220',0,0
 */


/*----------------------------------------------------------------------*/

/*** For CSPDM_OPEN
 *
 *      Invocation
 *      ----------
 *      CSPOPEN     CspOpen;
 *
 *      CspOpen.wDeviceID     = 0;
 *      CspOpen.lpSoundFormat = &SoundFormat;
 *      CspOpen.dwFlags       = 0;
 *      MmSysProc(PARAM_UNUSED, MMDEVICE_CSP, CSPDM_OPEN,
 *                (DWORD)(LPCSPOPEN)&CspOpen, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_ALLOCATED
 *      MMSTATUS_BAD_DEVICEID
 *      MMSTATUS_NOT_ENABLED
 */
typedef struct
    {
    IN      WORD            wDeviceID;
    OUT     HMMDEVICE       hDev;
    IN      LPSOUNDFORMAT   lpSoundFormat;
    IN      DWORD           dwFlags;
    }       CSPOPEN,
      FAR  *LPCSPOPEN;


/*----------------------------------------------------------------------*/

/*** For CSPDM_CLOSE
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_CSP, CSPDM_CLOSE,
 *                PARAM_UNUSED, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */


/*----------------------------------------------------------------------*/

/*** For CSPDM_STATE_Query
 *
 *      Invocation
 *      ----------
 *      CSPSTATE    CspState;
 *
 *      MmSysProc(hDev, MMDEVICE_CSP, CSPDM_STATE_Query,
 *                (DWORD)(LPCSPSTATE)&CspState, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_BAD_HANDLE
 */
typedef DWORD   CSPSTATE;
typedef CSPSTATE FAR  *LPCSPSTATE;

#define CSPSTATE_INACTIVE   0
#define CSPSTATE_STANDBY    1
#define CSPSTATE_ACTIVE     2


/*----------------------------------------------------------------------*/

/*** For CSPDM_STATE_Set
 *
 *      Invocation
 *      ----------
 *      MmSysProc(hDev, MMDEVICE_CSP, CSPDM_STATE_Set,
 *                CSPSTATE_XXX, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_ERROR
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_BAD_PARAMETER
 */

/* Same CSPSTATE_XXX constants as for CSPDM_STATE_Query
 */

/*----------------------------------------------------------------------*/

/*** For CSPDM_CODE_Download
 *
 *      Invocation
 *      ----------
 *      CSPCODEDOWNLOAD CodeDownload;
 *      ....
 *      MmSysProc(hDev, MMDEVICE_CSP, CSPDM_CODE_DownLoad,
 *                (DWORD)(LPCSPCODEDOWNLOAD)&CodeDownload, PARAM_UNUSED);
 *
 *      Return value
 *      ------------
 *      MMSTATUS_SUCCESS
 *      MMSTATUS_ERROR
 *      MMSTATUS_BAD_HANDLE
 *      MMSTATUS_BAD_PARAMETER
 */
typedef struct
    {
    IN      LPBYTE  lpCode;
    IN      DWORD   dwcbCode;
    IN      DWORD   dwFlags;
            DWORD   dwReserved;
    }       CSPCODEDOWNLOAD,
      FAR  *LPCSPCODEDOWNLOAD;

/* For CSPCODEDOWNLOAD.dwFlags
 */
#define CSPCODEDOWNLOAD_INITCODE    0x00000001


/*----------------------------------------------------------------------*/


#ifdef __cplusplus
}
#endif


#if defined(_MSC_VER)
    #pragma pack()
#elif defined(__BORLANDC__) || defined(__TURBOC__)
    #pragma option -a.
#endif


#endif  /* #ifndef _CTMMSYS_H */

