//############################################################################
//##																		##
//##  Miles Sound System													##
//##																		##
//##  MSS.H: Miles Sound System main header file							##
//##																		##
//##  Version 1.00 of 15-Feb-95: Initial, derived from AIL.H V3.02		  ##
//##		  1.01 of 19-Jun-95: Added various functions for V3.03 release  ##
//##		  1.02 of 22-Nov-95: C++ typedef problem fixed, declspecs added ##
//##		  1.03 of 15-Feb-96: Changes for 16 bit callbacks and multiple  ##
//##							 16 bit DLL loads (JKR)					 ##
//##		  1.04 of  2-Nov-97: Changes made to handle DLS in future	   ##
//##							 versions								   ##
//##		  1.05 of  1-Jan-98: Massive changes for version 4.0			##
//##		  1.06 of 17-Sep-98: Massive changes for version 5.0			##
//##		  1.07 of  2-Feb-99: Changes for new input API				  ##
//##		  1.08 of  8-Feb-99: Changes for new filter helper functions	##
//##																		##
//##  Author: John Miles													##
//##																		##
//############################################################################
//##																		##
//##  Contact RAD Game Tools at 425-893-4300 for technical support.		 ##
//##																		##
//############################################################################

#ifndef MSS_VERSION

#define MSS_VERSION	  "5.0q"
#define MSS_VERSION_DATE "06-Aug-99"

#define MSS_COPYRIGHT "Copyright (C) 1991-99 RAD Game Tools, Inc."

#endif

#ifndef MSS_H
#define MSS_H

// IS_DOS for DOS
// IS_WINDOWS for Windows or Win32s
// IS_WIN32 for Win32s
// IS_WIN16 for Windows
// IS_32 for 32-bit DOS or Win32s
// IS_16 for 16-bit Windows

#ifdef IS_DOS
#undef IS_DOS
#endif

#ifdef IS_WINDOWS
#undef IS_WINDOWS
#endif

#ifdef IS_WIN32
#undef IS_WIN32
#endif

#ifdef IS_WIN16
#undef IS_WIN16
#endif

#ifdef IS_32
#undef IS_32
#endif

#ifdef IS_16
#undef IS_16
#endif

#ifdef __DOS__
  #define IS_DOS
  #define IS_32
#else
  #ifdef _WIN32
	#define IS_WINDOWS
	#define IS_WIN32
	#define IS_32
  #else
	#ifdef WIN32
	  #define IS_WINDOWS
	  #define IS_WIN32
	  #define IS_32
	#else
	  #ifdef __NT__
		#define IS_WINDOWS
		#define IS_WIN32
		#define IS_32
	  #else
		#ifdef __WIN32__
		  #define IS_WINDOWS
		  #define IS_WIN32
		  #define IS_32
		#else
		  #ifdef _WINDOWS
			#define IS_WINDOWS
			#define IS_WIN16
			#define IS_16
		  #else
			#ifdef _WINDLL
			  #define IS_WINDOWS
			  #define IS_WIN16
			  #define IS_16
			#else
			  #ifdef WINDOWS
				#define IS_WINDOWS
				#define IS_WIN16
				#define IS_16
			  #else
				#ifdef __WINDOWS__
				  #define IS_WINDOWS
				  #define IS_WIN16
				  #define IS_16
				#else
				  #ifdef _Windows
					#define IS_WINDOWS
					#define IS_WIN16
					#define IS_16
				  #endif
				#endif
			  #endif
			#endif
		  #endif
		#endif
	  #endif
	#endif
  #endif
#endif

#if (!defined(IS_DOS) && !defined(IS_WINDOWS))
  #error MSS.H did not detect your platform.  Define __DOS__, _WINDOWS, or WIN32.
#endif


#ifdef _PUSHPOP_SUPPORTED
  #pragma pack(push,1)
#else
  #pragma pack(1)
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef IS_DOS

#define AILCALLBACK __pascal
#define AILEXPORT cdecl
#define DXDEC extern
#define DXDEF
#define AILCALL cdecl
#define FAR
#define HIWORD(ptr) (((U32)ptr)>>16)
#define LOWORD(ptr) ((U16)((U32)ptr))

#define FOURCC U32

#define MAKEFOURCC(ch0, ch1, ch2, ch3)							  \
		((U32)(U8)(ch0) | ((U32)(U8)(ch1) << 8) |   \
		((U32)(U8)(ch2) << 16) | ((U32)(U8)(ch3) << 24 ))

#define mmioFOURCC(w,x,y,z) MAKEFOURCC(w,x,y,z)

#define AILLIBCALLBACK __pascal

#else

#define AILLIBCALLBACK WINAPI

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#ifndef WIN32_EXTRA_LEAN
#define WIN32_EXTRA_LEAN
#endif

#ifndef STRICT
#define STRICT
#endif

#include <windows.h>
#include <mmsystem.h>

//
// If compiling MSS DLL, use __declspec(dllexport) for both
// declarations and definitions
//
// If compiling MSS16 library or application, use "extern" in declarations
// and nothing in definitions
//

#ifdef IS_WIN32

  #define AILEXPORT WINAPI

  #ifdef BUILD_MSS
	#define DXDEC __declspec(dllexport)
	#define DXDEF __declspec(dllexport)
  #else

	#ifdef __BORLANDC__
	  #define DXDEC extern
	#else
	  #define DXDEC __declspec(dllimport)
	#endif

  #endif

  #define MSSDLLNAME "MSS32.DLL"

#else

  #define AILEXPORT __export WINAPI

  #define DXDEC  extern
  #define DXDEF

  #define MSSDLLNAME "MSS16.DLL"

#endif

#define AILCALL WINAPI
#define AILCALLBACK AILEXPORT

typedef LPVOID AILLPDIRECTSOUND;
typedef LPVOID AILLPDIRECTSOUNDBUFFER;

#endif

#ifndef NULL
#define NULL 0
#endif

//
// Misc. constant definitions
//

#define MAX_DRVRS				16	   // Max. # of simultaneous drivers
#define MAX_TIMERS			   16	   // Max. # of simultaneous timers
#define MAX_NOTES				32	   // Max # of notes "on"
#define FOR_NEST				 4		// # of nested XMIDI FOR loops
#define NUM_CHANS				16	   // # of possible MIDI channels
#define MAX_W_VOICES			 16	   // Max virtual wave synth voice cnt
#define MAX_W_ENTRIES			512	  // 512 wave library entries max.

#define MIN_CHAN				 ( 1-1)   // Min channel recognized (0-based)
#define MAX_CHAN				 (16-1)   // Max channel recognized
#define MIN_LOCK_CHAN			( 2-1)   // Min channel available for locking
#define MAX_LOCK_CHAN			( 9-1)   // Max channel available for locking
#define PERCUSS_CHAN			 (10-1)   // Percussion channel (no locking)

#define AIL_MAX_FILE_HEADER_SIZE 5120	 // AIL_set_named_sample_file() requires at least 4K
										  // of data or the entire file image, whichever is less,
										  // to determine sample format
#define DIG_F_16BITS_MASK		1
#define DIG_F_STEREO_MASK		2
#define DIG_F_ADPCM_MASK	4

#define DIG_F_MONO_8			 0		// PCM data formats
#define DIG_F_MONO_16			(DIG_F_16BITS_MASK)
#define DIG_F_STEREO_8		   (DIG_F_STEREO_MASK)
#define DIG_F_STEREO_16		  (DIG_F_STEREO_MASK|DIG_F_16BITS_MASK)
#define	DIG_F_ADPCM_MONO_16	  (DIG_F_ADPCM_MASK |DIG_F_16BITS_MASK)
#define	DIG_F_ADPCM_STEREO_16	(DIG_F_ADPCM_MASK |DIG_F_16BITS_MASK|DIG_F_STEREO_MASK)
#define DIG_F_USING_ASI		  16

#define DIG_PCM_SIGN			 0x0001   // (obsolete)
#define DIG_PCM_ORDER			0x0002

#define DIG_PCM_POLARITY		 0x0004   // PCM flags used by driver hardware
#define DIG_PCM_SPLIT			0x0008
#define DIG_BUFFER_SERVICE	   0x0010
#define DIG_DUAL_DMA			 0x0020
#define DIG_RECORDING_SUPPORTED  0x8000

#define WAVE_FORMAT_PCM		 1
#define WAVE_FORMAT_IMA_ADPCM   0x0011

#ifdef IS_DOS

#define AIL3DIG				  0		// .DIG driver
#define AIL3MDI				  1		// .MDI driver

#define DIG_DETECT_8_BIT_ONLY	0x0001   // Detect 8-bit DMA only
#define DIG_DETECT_16_BIT_ONLY   0x0002   // Detect 16-bit DMA only
#define DIG_DETECT_8_AND_16_BITS 0x0003   // Detect both 8- and 16-bit DMA

#define DRV_INIT		  0x300	 // Functions common to .MDI and .DIG
#define DRV_GET_INFO	  0x301	 // drivers
#define DRV_SERVE		 0x302
#define DRV_PARSE_ENV	 0x303
#define DRV_VERIFY_IO	 0x304
#define DRV_INIT_DEV	  0x305
#define DRV_SHUTDOWN_DEV  0x306

#define DIG_HW_VOLUME	 0x400	 // .DIG driver functions
#define DIG_START_P_CMD   0x401
#define DIG_STOP_P_REQ	0x402
#define DIG_START_R_CMD   0x403
#define DIG_STOP_R_REQ	0x404
#define DIG_VSE		   0x405

#define MDI_HW_VOLUME	 0x500	 // .MDI driver functions
#define MDI_INIT_INS_MGR  0x501
#define MDI_MIDI_XMIT	 0x502
#define MDI_INSTALL_T_SET 0x503
#define MDI_GET_T_STATUS  0x504
#define MDI_PROT_UNPROT_T 0x505
#define MDI_VSE		   0x506

#else

//
// Pass to AIL_midiOutOpen for NULL MIDI driver
//

#define MIDI_NULL_DRIVER ((U32)(S32)-2)

#endif


//
// Non-specific XMIDI/MIDI controllers and event types
//

#define SYSEX_BYTE		105
#define PB_RANGE		  106
#define CHAN_MUTE		 107
#define CALLBACK_PFX	  108
#define SEQ_BRANCH		109
#define CHAN_LOCK		 110
#define CHAN_PROTECT	  111
#define VOICE_PROTECT	 112
#define TIMBRE_PROTECT	113
#define PATCH_BANK_SEL	114
#define INDIRECT_C_PFX	115
#define FOR_LOOP		  116
#define NEXT_LOOP		 117
#define CLEAR_BEAT_BAR	118
#define CALLBACK_TRIG	 119
#define SEQ_INDEX		 120

#define GM_BANK_MSB	   0
#define MODULATION		1
#define DATA_MSB		  6
#define PART_VOLUME	   7
#define PANPOT			10
#define EXPRESSION		11
#define GM_BANK_LSB	   32
#define DATA_LSB		  38
#define SUSTAIN		   64
#define REVERB			91
#define CHORUS			93
#define RPN_LSB		   100
#define RPN_MSB		   101
#define RESET_ALL_CTRLS   121
#define ALL_NOTES_OFF	 123

#define EV_NOTE_OFF	   0x80
#define EV_NOTE_ON		0x90
#define EV_POLY_PRESS	 0xa0
#define EV_CONTROL		0xb0
#define EV_PROGRAM		0xc0
#define EV_CHAN_PRESS	 0xd0
#define EV_PITCH		  0xe0
#define EV_SYSEX		  0xf0
#define EV_ESC			0xf7
#define EV_META		   0xff

#define META_EOT		  0x2f
#define META_TEMPO		0x51
#define META_TIME_SIG	 0x58

//
// SAMPLE.system_data[] usage
//

#define SSD_EOD_CALLBACK  0  // Application end-of-data callback if not NULL
#define VOC_BLK_PTR	   1  // Pointer to current block
#define VOC_REP_BLK	   2  // Pointer to beginning of repeat loop block
#define VOC_N_REPS		3  // # of iterations left in repeat loop
#define VOC_MARKER		4  // Marker to search for, or -1 if all
#define VOC_MARKER_FOUND  5  // Desired marker found if 1, else 0
#define SSD_RELEASE	   6  // Release sample handle upon termination if >0
#ifdef IS_WINDOWS
#define SSD_EOD_CB_WIN32S 7  // Application end-of-data callback is in Win32s
#else
#define SSD_TEMP		  7  // Temporary storage location for general use
#endif

//
// Timer status values
//

#define AILT_FREE		 0		 // Timer handle is free for allocation
#define AILT_STOPPED	  1		 // Timer is stopped
#define AILT_RUNNING	  2		 // Timer is running

//
// SAMPLE.status flag values
//

#define SMP_FREE		  0x0001	// Sample is available for allocation

#define SMP_DONE		  0x0002	// Sample has finished playing, or has
									// never been started

#define SMP_PLAYING	   0x0004	// Sample is playing

#define SMP_STOPPED	   0x0008	// Sample has been stopped

#define SMP_PLAYINGBUTRELEASED 0x0010 // Sample is playing, but digital handle
									  // has been temporarily released



//
// SEQUENCE.status flag values
//

#define SEQ_FREE		  0x0001	// Sequence is available for allocation

#define SEQ_DONE		  0x0002	// Sequence has finished playing, or has
									// never been started

#define SEQ_PLAYING	   0x0004	// Sequence is playing

#define SEQ_STOPPED	   0x0008	// Sequence has been stopped

#define SEQ_PLAYINGBUTRELEASED 0x0010 // Sequence is playing, but MIDI handle
									  // has been temporarily released

#ifdef IS_DOS

//
// MIDI driver types
//

#define MDIDRVRTYPE_GM	0		 // General MIDI driver (Roland-compatible)
#define MDIDRVRTYPE_FM_2  1		 // 2-operator FM MIDI driver (OPL2)
#define MDIDRVRTYPE_FM_4  2		 // 4-operator FM MIDI driver (OPL3)
#define MDIDRVRTYPE_SPKR  3		 // Tandy or PC speaker "beep" driver

//
// .INI installation result codes
//

#define AIL_INIT_SUCCESS  0		 // Driver installed successfully
#define AIL_NO_INI_FILE   1		 // No MDI.INI or DIG.INI file exists
#define AIL_INIT_FAILURE  2		 // Driver could not be initialized

#ifdef __BORLANDC__

 #ifndef REALPTR
 #define REALPTR(x) ((void *) (U32) ((((U32) (x))>>16<<4) + ((x) & 0xffff) \
					- AIL_sel_base(_DS)))
 #endif

#else

 #ifndef REALPTR
 #define REALPTR(x) ((void *) (U32) ((((U32) (x))>>16<<4) + ((x) & 0xffff)))
 #endif

#endif

#else

//
// AIL_set_direct_buffer_control() command values
//

#define AILDS_RELINQUISH  0		 // App returns control of secondary buffer
#define AILDS_SEIZE	   1		 // App takes control of secondary buffer
#define AILDS_SEIZE_LOOP  2		 // App wishes to loop the secondary buffer

#endif

//
// General type definitions for portability
//

#ifndef C8
#define C8 char
#endif

#ifndef U8
#define U8 unsigned char
#endif

#ifndef S8
#define S8 signed char
#endif

#ifndef U16
#define U16 unsigned short
#endif

#ifndef S16
#define S16 signed short
#endif

#ifndef U32
#define U32 unsigned long
#endif

#ifndef S32
#define S32 signed long
#endif

#ifndef F32
#define F32 float
#endif

#ifndef F64
#define F64 double
#endif


#ifndef REALFAR
#define REALFAR unsigned long
#endif

#ifndef FILE_ERRS
#define FILE_ERRS

#define AIL_NO_ERROR		0
#define AIL_IO_ERROR		1
#define AIL_OUT_OF_MEMORY   2
#define AIL_FILE_NOT_FOUND  3
#define AIL_CANT_WRITE_FILE 4
#define AIL_CANT_READ_FILE  5
#define AIL_DISK_FULL	   6

#endif

#define MIN_VAL 0
#define NOM_VAL 1
#define MAX_VAL 2

#ifndef YES
#define YES 1
#endif

#ifndef NO
#define NO  0
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE  0
#endif

//
// Preference names and default values
//

#define DIG_RESAMPLING_TOLERANCE   0
#define DEFAULT_DRT				655	// Resampling triggered at +/- 1%

#define DIG_MIXER_CHANNELS		 1
#define DEFAULT_DMC				64	 // 64 allocatable SAMPLE structures

#define DIG_DEFAULT_VOLUME		 2
#define DEFAULT_DDV				127	// Default sample volume = 127 (0-127)

#define MDI_SERVICE_RATE		   3
#define DEFAULT_MSR				120	// XMIDI sequencer timing = 120 Hz

#define MDI_SEQUENCES			  4
#define DEFAULT_MS				 8	  // 8 sequence handles/driver

#define MDI_DEFAULT_VOLUME		 5
#define DEFAULT_MDV				127	// Default sequence volume = 127 (0-127)

#define MDI_QUANT_ADVANCE		  6
#define DEFAULT_MQA				1	  // Beat/bar count +1 interval

#define MDI_ALLOW_LOOP_BRANCHING   7
#define DEFAULT_ALB				NO	 // Branches cancel XMIDI FOR loops

#define MDI_DEFAULT_BEND_RANGE	 8
#define DEFAULT_MDBR			   2	  // Default pitch-bend range = 2

#define MDI_DOUBLE_NOTE_OFF		9
#define DEFAULT_MDNO			   NO	 // For stuck notes on SB daughterboards

#define DIG_ENABLE_RESAMPLE_FILTER 31	 // Enable resampling filter by
#define DEFAULT_DERF			   YES	// default

#define DIG_DECODE_BUFFER_SIZE	 32	 // 2K decode buffer size by default
#define DEFAULT_DDBS			   2048

#ifdef IS_WINDOWS

#define DIG_USE_MSS_MIXER		  33
#define DEFAULT_DUMM			   YES	// Use MSS mixer with DirectSound

#define DIG_DS_FRAGMENT_SIZE	   34
#define DEFAULT_DDFS			   8	  // Use 8 millisecond buffer fragments with DirectSound if MSS mixer in use

#define DIG_DS_FRAGMENT_CNT		35
#define DEFAULT_DDFC			   96	 // Use 96 buffer fragments with DirectSound if MSS mixer in use

#define DIG_DS_MIX_FRAGMENT_CNT	42
#define DEFAULT_DDMFC			  8	  // Mix ahead 8 buffer fragments

#define DIG_DS_USE_PRIMARY		 36
#define DEFAULT_DDUP			   NO	 // Mix into secondary DirectSound buffer by default

#define DIG_DS_DSBCAPS_CTRL3D	  37
#define DEFAULT_DDDC			   NO	 // Do not use DSBCAPS_CTRL3D by default

#define DIG_DS_CREATION_HANDLER	38
#define DEFAULT_DDCH			   NULL   // Use DirectSoundCreate() by default

#define MDI_SYSEX_BUFFER_SIZE	  10
#define DEFAULT_MSBS			   1536   // Default sysex buffer = 1536 bytes

#define DIG_OUTPUT_BUFFER_SIZE	 11
#define DEFAULT_DOBS			   49152  // 48K output buffer size

#define AIL_MM_PERIOD			  12
#define DEFAULT_AMP				5	  // Default MM timer period = 5 msec.

#define AIL_TIMERS				 13
#define DEFAULT_AT				 16	 // 16 allocatable HTIMER handles

#define DIG_MIN_CHAIN_ELEMENT_SIZE 14
#define DEFAULT_MCES			   2048   // 2048 bytes/waveOut buffer

#define DIG_USE_WAVEOUT			15
#define DEFAULT_DUW				NO	 // Use DirectSound by default

#define DIG_DS_SECONDARY_SIZE	  16
#define DEFAULT_DDSS			   (32*1024L)  // Must be 2^n -- use 32K by default

#define DIG_DS_SAMPLE_CEILING	  17
#define DEFAULT_DDSC			   44100  // Allow up to 44 kHz samples

#define AIL_LOCK_PROTECTION		18
#define DEFAULT_ALP				YES	// Suspend foreground thread by default

#define AIL_WIN32S_CALLBACK_SIZE   19
#define DEFAULT_WCS				4096   // Size of callback data in bytes

#else

#define DIG_SERVICE_RATE		  10
#define DEFAULT_DSR			   200	 // DMA buffer-polling rate = 200 Hz

#define DIG_HARDWARE_SAMPLE_RATE  11
#define DEFAULT_DHSR			  NOM_VAL // Use nominal sample rate by default

#define DIG_DMA_RESERVE		   12
#define DEFAULT_DDR			   32768   // Reserve 32K real-mode mem for DMA

#define DIG_LATENCY			   13
#define DEFAULT_DL				100	 // Half-buffer size in ms = 100

#define DIG_USE_STEREO			14
#define DEFAULT_DUS			   NO	  // Use mono output only

#define DIG_USE_16_BITS		   15
#define DEFAULT_DU16			  NO	  // Use 8-bit output by default

#define DIG_ALLOW_16_BIT_DMA	  16
#define DEFAULT_DA16DMA		   YES	 // OK to use 16-bit DMA if necessary

#define DIG_SS_LOCK			   17
#define DEFAULT_DSL			   NO	  // Don't disable IRQs while mixing

#define AIL_SCAN_FOR_HARDWARE	 18
#define DEFAULT_ASH			   YES	 // Scan for I/O settings if necessary

#define AIL_ALLOW_VDM_EXECUTION   19
#define DEFAULT_AVE			   YES	 // Allow Windows "DOS box" execution

#endif

// ----------------------------------
// DLS Preference names and default values
// Unless otherwise specified, values must be established
// BEFORE calling DLSMSSOpen()!
// ----------------------------------

#define DLS_TIMEBASE			   20
#define DEFAULT_DTB				120  // 120 intervals/second by default

#define DLS_VOICE_LIMIT			21
#define DEFAULT_DVL				24   // 24 voices supported

#define DLS_BANK_SELECT_ALIAS	  22
#define DEFAULT_DBSA			   NO   // Do not treat controller 114 as bank

#define DLS_STREAM_BOOTSTRAP	   23   // Don't submit first stream buffer
#define DEFAULT_DSB				YES  // until at least 2 available

#define DLS_VOLUME_BOOST		   24
#define DEFAULT_DVB				0	// Boost final volume by 0 dB

#define DLS_ENABLE_FILTERING	   25   // Filtering = on by default
#define DEFAULT_DEF				YES  // (may be changed at any time)

#define AIL_ENABLE_MMX_SUPPORT	 27   // Enable MMX support if present
#define DEFAULT_AEMS			   YES  // (may be changed at any time)

#define DLS_GM_PASSTHROUGH		 28   // Pass unrecognized traffic on to
#define DEFAULT_DGP				YES  // default GM driver layer
										// (may be changed at any time)

#define DLS_ADPCM_TO_ASI_THRESHOLD 39   // Size in samples to switch to ASI
#define DEFAULT_DATAT			  32768

#ifdef OLD_DLS_REVERB_PREFERENCES

// these preferences are obsolete - move to the new DLS reverb function.
//   these defines now control nothing and will disappear completely
//   in MSS 6.0

#define DLS_ENABLE_GLOBAL_REVERB   26   // Global reverb disabled by default
#define DEFAULT_DEGR			   NO

#define DLS_GLOBAL_REVERB_LEVEL	29   // Reverb level 0-127
#define DEFAULT_GRL				20   // (may be changed at any time)

#define DLS_GLOBAL_REVERB_TIME	 30   // Reverb time in stream buffers
#define DEFAULT_GRT				1

#endif

//
// Add'l platform-independent prefs
//

#define DIG_REVERB_BUFFER_SIZE	 40
#define DEFAULT_DRBS			   0	// No reverb support by default

#define DIG_INPUT_LATENCY		  41   // Use >= 250-millisecond input buffers if
#define DEFAULT_DIL				250  // explicit size request cannot be satisfied

#define DIG_USE_WAVEIN			 43
#define DEFAULT_DUWI			   YES  // Use waveIn for input by default

#define N_PREFS 44					  // # of preference types

typedef struct _AILSOUNDINFO {
  S32 format;
  void FAR* data_ptr;
  U32 data_len;
  U32 rate;
  S32 bits;
  S32 channels;
  U32 samples;
  U32 block_size;
  void FAR* initial_ptr;
} AILSOUNDINFO;

// for multi-processor machines

#ifdef IS_WIN32

#ifdef BUILD_MSS

  #define MSSLockedIncrement(var) _asm { lock inc [var] }
  #define MSSLockedDecrement(var) _asm { lock dec [var] }

  static void __MSSLockedIncrementAddr(void * addr)
  {
	_asm {
	  mov eax,[addr]
	  lock inc dword ptr [eax]
	}
  }

  static void __MSSLockedDecrementAddr(void * addr)
  {
	_asm {
	  mov eax,[addr]
	  lock dec dword ptr [eax]
	}
  }

  #define MSSLockedIncrementPtr(var) __MSSLockedIncrementAddr(&(var))
  #define MSSLockedDecrementPtr(var) __MSSLockedDecrementAddr(&(var))

#else

  #define MSSLockedIncrement(var) (++var)
  #define MSSLockedDecrement(var) (--var)

  #define MSSLockedIncrementPtr(var) (++var)
  #define MSSLockedDecrementPtr(var) (--var)

#endif

#else
  #define MSSLockedIncrement(var) (++var)
  #define MSSLockedDecrement(var) (--var)

  #define MSSLockedIncrementPtr(var) (++var)
  #define MSSLockedDecrementPtr(var) (--var)
#endif

#ifndef RIB_H		// RIB.H contents included if RIB.H not already included

// #include "rib.h"

#define RIB_H
#define ARY_CNT(x) (sizeof((x)) / sizeof((x)[0]))

// ----------------------------------
// RIB data types
// ----------------------------------

typedef S32 RIBRESULT;

#define RIB_NOERR					0   // Success -- no error
#define RIB_NOT_ALL_AVAILABLE		1   // Some requested functions/attribs not available
#define RIB_NOT_FOUND				2   // Resource not found
#define RIB_OUT_OF_MEM			   3   // Out of system RAM

//
// Handle to interface provider
//

typedef U32 HPROVIDER;

//
// Handle representing token used to obtain attribute or preference
// data from RIB provider
//

typedef U32 HATTRIB;

//
// Handle representing an enumerated interface entry
//
// RIB_enumerate_interface() returns 1 if valid next entry found, else
// 0 if end of list reached
//

typedef U32 HINTENUM;
#define HINTENUM_FIRST 0

//
// Handle representing an enumerated provider entry
//
// RIB_enumerate_providers() returns 1 if valid next entry found, else
// 0 if end of list reached
//

typedef U32 HPROENUM;
#define HPROENUM_FIRST 0

//
// Data types for RIB attributes and preferences
//

typedef enum
{
   RIB_NONE = 0, // No type
   RIB_CUSTOM,   // Used for pointers to application-specific structures
   RIB_DEC,	  // Used for 32-bit integer values to be reported in decimal
   RIB_HEX,	  // Used for 32-bit integer values to be reported in hex
   RIB_FLOAT,	// Used for 32-bit single-precision FP values
   RIB_PERCENT,  // Used for 32-bit single-precision FP values to be reported as percentages
   RIB_BOOL,	 // Used for Boolean-constrained integer values to be reported as TRUE or FALSE
   RIB_STRING	// Used for pointers to null-terminated ASCII strings
}
RIB_DATA_SUBTYPE;

//
// RIB_ENTRY_TYPE structure, used to register an interface or request one
//

typedef enum
{
   RIB_FUNCTION = 0,
   RIB_ATTRIBUTE,	 // Attribute: read-only data type used for status/info communication
   RIB_PREFERENCE	 // Preference: read/write data type used to control behavior
}
RIB_ENTRY_TYPE;

//
// RIB_INTERFACE_ENTRY, used to represent a function or data entry in an
// interface
//

typedef struct
{
   RIB_ENTRY_TYPE   type;		// See list above
   C8 FAR		  *entry_name;  // Name of desired function or attribute
   U32			  token;	   // Function pointer or attribute token
   RIB_DATA_SUBTYPE subtype;	 // Data (attrib or preference) subtype
}
RIB_INTERFACE_ENTRY;

//
// Standard RAD Interface Broker provider identification attributes
//

#define PROVIDER_NAME	(-100)  // RIB_STRING name of decoder
#define PROVIDER_VERSION (-101)  // RIB_HEX BCD version number

//
// Standard function to obtain provider attributes (see PROVIDER_ defines
// above)
//
// Each provider of a searchable interface must export this function
//

typedef U32 (AILCALL FAR *PROVIDER_QUERY_ATTRIBUTE) (HATTRIB index);

//
// Macros to simplify interface registrations/requests for functions,
// attributes, and preferences
//

#define FN(entry_name)		{ RIB_FUNCTION, #entry_name, (U32) &(entry_name), RIB_NONE }
#define REG_FN(entry_name)	{ RIB_FUNCTION, #entry_name, (U32) &(entry_name), RIB_NONE }

#define AT(entry_name,ID)			 { RIB_ATTRIBUTE, (entry_name), (U32) &(ID), RIB_NONE }
#define REG_AT(entry_name,ID,subtype) { RIB_ATTRIBUTE, (entry_name), (U32)  (ID), subtype  }

#define PR(entry_name,ID)			 { RIB_PREFERENCE, (entry_name), (U32) &(ID), RIB_NONE }
#define REG_PR(entry_name,ID,subtype) { RIB_PREFERENCE, (entry_name), (U32)  (ID), subtype  }

#define RIB_register(x,y,z)   RIB_register_interface  (HPROVIDER(x), y, ARY_CNT(z), z)
#define RIB_unregister(x,y,z) RIB_unregister_interface(HPROVIDER(x), y, ARY_CNT(z), z)
#define RIB_unregister_all(x) RIB_unregister_interface(HPROVIDER(x), NULL, 0, NULL)
#define RIB_free_libraries()  RIB_free_provider_library(HPROVIDER(NULL));
#define RIB_request(x,y,z)	RIB_request_interface   (x, y, ARY_CNT(z), z)

// ----------------------------------
// Standard RIB API prototypes
// ----------------------------------

DXDEC  HPROVIDER  AILCALL RIB_alloc_provider_handle   (U32			module);
DXDEC  void	   AILCALL RIB_free_provider_handle	(HPROVIDER	  provider);

DXDEC  HPROVIDER  AILCALL RIB_load_provider_library   (C8 FAR		*filename);
DXDEC  void	   AILCALL RIB_free_provider_library   (HPROVIDER	  provider);

DXDEC  HPROVIDER  AILCALL RIB_provider_library_handle (void);

DXDEC  RIBRESULT  AILCALL RIB_register_interface	  (HPROVIDER					  provider,
													   C8 FAR						*interface_name,
													   S32							entry_count,
													   const RIB_INTERFACE_ENTRY FAR *rlist);

DXDEC  RIBRESULT  AILCALL RIB_unregister_interface	(HPROVIDER					  provider,
													   C8 FAR						*interface_name,
													   S32							entry_count,
													   const RIB_INTERFACE_ENTRY FAR *rlist);

DXDEC  RIBRESULT  AILCALL RIB_request_interface	   (HPROVIDER				provider,
													   C8 FAR				  *interface_name,
													   S32					  entry_count,
													   RIB_INTERFACE_ENTRY FAR *rlist);

DXDEC  RIBRESULT  AILCALL RIB_request_interface_entry (HPROVIDER				provider,
													   C8 FAR				  *interface_name,
													   RIB_ENTRY_TYPE		   entry_type,
													   C8 FAR				  *entry_name,
													   U32 FAR				 *token);

DXDEC  S32		AILCALL RIB_enumerate_interface	 (HPROVIDER				provider,
													   C8 FAR				  *interface_name,
													   RIB_ENTRY_TYPE		   type,
													   HINTENUM FAR			*next,
													   RIB_INTERFACE_ENTRY FAR *dest);

DXDEC  S32		AILCALL RIB_enumerate_providers	 (C8 FAR				  *interface_name,
													   HPROENUM FAR			*next,
													   HPROVIDER FAR		   *dest);

DXDEC  C8 FAR *   AILCALL RIB_type_string			 (U32					  data,
													   RIB_DATA_SUBTYPE		 subtype);

DXDEC  HPROVIDER  AILCALL RIB_find_file_provider	  (C8 FAR				  *interface_name,
													   C8 FAR				  *attribute_name,
													   C8 FAR				  *file_suffix);

DXDEC  HPROVIDER  AILCALL RIB_find_provider		   (C8 FAR				  *interface_name,
													   C8 FAR				  *attribute_name,
													   C8 FAR				  *attribute_value);

DXDEC  S32		AILCALL RIB_load_application_providers
													  (C8 FAR *filespec);

DXDEC  void	   AILCALL RIB_set_provider_user_data  (HPROVIDER provider,
													   U32	   index,
													   S32	   value);

DXDEC  S32		AILCALL RIB_provider_user_data	  (HPROVIDER provider,
													   U32	   index);

DXDEC  void	   AILCALL RIB_set_provider_system_data
													  (HPROVIDER provider,
													   U32	   index,
													   S32	   value);

DXDEC  S32		AILCALL RIB_provider_system_data	(HPROVIDER provider,
													   U32	   index);

DXDEC  C8 FAR *   AILCALL RIB_error				   (void);

#endif

#ifndef MSS_ASI_VERSION // MSSASI.H contents included if MSSASI.H not already included

// #include "mssasi.h"

#define AIL_ASI_VERSION  1
#define AIL_ASI_REVISION 0

//
// Handle to stream being managed by ASI codec
//

typedef S32 HASISTREAM;

//
// ASI result codes
//

typedef S32 ASIRESULT;

#define ASI_NOERR				   0   // Success -- no error
#define ASI_NOT_ENABLED			 1   // ASI not enabled
#define ASI_ALREADY_STARTED		 2   // ASI already started
#define ASI_INVALID_PARAM		   3   // Invalid parameters used
#define ASI_INTERNAL_ERR			4   // Internal error in ASI driver
#define ASI_OUT_OF_MEM			  5   // Out of system RAM
#define ASI_ERR_NOT_IMPLEMENTED	 6   // Feature not implemented
#define ASI_NOT_FOUND			   7   // ASI supported device not found
#define ASI_NOT_INIT				8   // ASI not initialized
#define ASI_CLOSE_ERR			   9   // ASI not closed correctly

// ----------------------------------
// Application-provided ASI callbacks
// ----------------------------------

//
// AILASIFETCHCB: Called by ASI to obtain data from stream source
//
// offset normally will be either 0 at the first call made by the codec
// or -1 to specify a continuous stream, except when ASI_stream_seek()
// is called to restart the stream codec at a new stream offset.  In this
// case, the application must execute the seek operation on the ASI codec's
// behalf.
//
// In response to this callback, the application should read the requested
// data and copy it to the specified destination buffer, returning the number
// of bytes copied (which can be less than bytes_requested if the end of
// the stream is reached).
//

typedef S32 (AILCALLBACK FAR * AILASIFETCHCB) (U32	   user,			// User value passed to ASI_open_stream()
											   void FAR *dest,			// Location to which stream data should be copied by app
											   S32	   bytes_requested, // # of bytes requested by ASI codec
											   S32	   offset);		 // If not -1, application should seek to this point in stream

//############################################################################
//##																		##
//## Interface "ASI codec"												  ##
//##																		##
//############################################################################

//
// Initialize ASI stream codec
//
// No other ASI functions may be called outside an ASI_startup() /
// ASI_shutdown() pair, except for the standard RIB function
// PROVIDER_query_attribute().  All provider attributes must be accessible
// without starting up the codec.
//

typedef ASIRESULT (AILCALL FAR *ASI_STARTUP)(void);

//
// Shut down ASI codec
//

typedef ASIRESULT (AILCALL FAR *ASI_SHUTDOWN)(void);

//
// Return codec error message, or NULL if no errors have occurred since
// last call
//
// The ASI error text state is global to all streams
//

typedef C8 FAR *  (AILCALL FAR *ASI_ERROR)(void);

//############################################################################
//##																		##
//## Interface "ASI stream"												 ##
//##																		##
//############################################################################

//
// Open a stream, returning handle to stream
//

typedef HASISTREAM (AILCALL FAR *ASI_STREAM_OPEN) (U32		   user,			  // User value passed to fetch callback
												   AILASIFETCHCB fetch_CB,		  // Source data fetch handler
												   U32		   total_size);	   // Total size for %-done calculations (0=unknown)

//
// Translate data in stream, returning # of bytes actually decoded or encoded
// 
// Any number of bytes may be requested.  Requesting more data than is 
// available in the codec's internal buffer will cause the AILASIFETCHCB
// handler to be called to fetch more data from the stream.
// 

typedef S32  (AILCALL FAR *ASI_STREAM_PROCESS) (HASISTREAM  stream,			  // Handle of stream
												void FAR   *buffer,			  // Destination for processed data
												S32		 buffer_size);		// # of bytes to return in buffer

//
// Restart stream decoding process at new offset
//
// Relevant for decoders only
//
// Seek destination is given as offset in bytes from beginning of stream
//
// At next ASI_stream_process() call, decoder will seek to the closest possible
// point in the stream which occurs at or after the specified position
//
// This function has no effect for decoders which do not support random 
// seeks on a given stream type
//
// Warning: some decoders may need to implement seeking by reparsing
// the entire stream up to the specified offset, through multiple calls
// to the data-fetch callback.  This operation may be extremely
// time-consuming on large files or slow network connections.
//
// A stream_offset value of -1 may be used to inform the decoder that the
// application has changed the input stream offset on its own, e.g. for a
// double-buffering application where the ASI decoder is not accessing the
// stream directly.  ASI decoders should respond to this by flushing all
// internal buffers and resynchronizing themselves to the data stream.
//

typedef ASIRESULT (AILCALL FAR *ASI_STREAM_SEEK)	(HASISTREAM stream,
													 S32		stream_offset);

//
// Retrieve an ASI stream attribute or preference value by index
//

typedef S32 (AILCALL FAR *ASI_STREAM_ATTRIBUTE) (HASISTREAM stream,
												 HATTRIB	attrib);

//
// Set an ASI stream preference value by index
//

typedef S32 (AILCALL FAR *ASI_STREAM_SET_PREFERENCE) (HASISTREAM stream,
													  HATTRIB	preference,
													  void FAR*  value);

//
// Close stream, freeing handle and all internally-allocated resources
//

typedef ASIRESULT (AILCALL FAR *ASI_STREAM_CLOSE) (HASISTREAM stream);

#endif

//############################################################################
//##																		##
//## Interface "MSS 3D audio services"									  ##
//##																		##
//############################################################################

//
// 3D positioning services
//


typedef struct h3DPOBJECT
{
  U32 junk;
} h3DPOBJECT;

typedef h3DPOBJECT FAR * H3DPOBJECT;
typedef H3DPOBJECT H3DSAMPLE;

//
// M3D result codes
//

typedef S32 M3DRESULT;

#define M3D_NOERR				   0   // Success -- no error
#define M3D_NOT_ENABLED			 1   // M3D not enabled
#define M3D_ALREADY_STARTED		 2   // M3D already started
#define M3D_INVALID_PARAM		   3   // Invalid parameters used
#define M3D_INTERNAL_ERR			4   // Internal error in M3D driver
#define M3D_OUT_OF_MEM			  5   // Out of system RAM
#define M3D_ERR_NOT_IMPLEMENTED	 6   // Feature not implemented
#define M3D_NOT_FOUND			   7   // M3D supported device not found
#define M3D_NOT_INIT				8   // M3D not initialized
#define M3D_CLOSE_ERR			   9   // M3D not closed correctly


typedef M3DRESULT (AILCALL FAR *M3D_STARTUP)(void);

typedef M3DRESULT (AILCALL FAR *M3D_SHUTDOWN)(void);

typedef C8 FAR *  (AILCALL FAR *M3D_ERROR)(void);

typedef S32	   (AILCALL FAR *M3D_SET_PROVIDER_PREFERENCE)(HATTRIB preference,
															 void FAR*  value);

typedef M3DRESULT  (AILCALL FAR * M3D_ACTIVATE)(S32 enable);

typedef H3DSAMPLE  (AILCALL FAR * M3D_ALLOCATE_3D_SAMPLE_HANDLE)(void);
									   

typedef void	   (AILCALL FAR * M3D_RELEASE_3D_SAMPLE_HANDLE)(H3DSAMPLE samp);
									   

typedef void	   (AILCALL FAR * M3D_START_3D_SAMPLE)(H3DSAMPLE samp);


typedef void	   (AILCALL FAR * M3D_STOP_3D_SAMPLE)(H3DSAMPLE samp);
									   

typedef void	   (AILCALL FAR * M3D_RESUME_3D_SAMPLE)(H3DSAMPLE samp);
									  
typedef void	   (AILCALL FAR * M3D_END_3D_SAMPLE)(H3DSAMPLE samp);

typedef S32		(AILCALL FAR * M3D_SET_3D_SAMPLE_DATA)(H3DSAMPLE		 samp,
														  AILSOUNDINFO FAR *info);

typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_VOLUME)(H3DSAMPLE samp,
															S32	   volume);
										
typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_PLAYBACK_RATE)(H3DSAMPLE samp,
																   S32	   playback_rate);

typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_OFFSET)(H3DSAMPLE samp,
															U32	   offset);


typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_LOOP_COUNT)(H3DSAMPLE samp,
																U32	   loops);

typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_LOOP_BLOCK)(H3DSAMPLE S,
																S32	   loop_start_offset,
																S32	   loop_end_offset);

typedef U32		(AILCALL FAR * M3D_3D_SAMPLE_STATUS)(H3DSAMPLE samp);

typedef U32		(AILCALL FAR * M3D_3D_SAMPLE_ATTRIBUTE)(H3DSAMPLE samp, HATTRIB index);

typedef S32		(AILCALL FAR * M3D_3D_SET_SAMPLE_PREFERENCE)(H3DSAMPLE samp, HATTRIB preference, void FAR* value);

typedef S32		(AILCALL FAR * M3D_3D_SAMPLE_VOLUME)(H3DSAMPLE samp);

typedef S32		(AILCALL FAR * M3D_3D_SAMPLE_PLAYBACK_RATE)(H3DSAMPLE samp);

typedef U32		(AILCALL FAR * M3D_3D_SAMPLE_OFFSET)(H3DSAMPLE	 samp);

typedef U32		(AILCALL FAR * M3D_3D_SAMPLE_LENGTH)(H3DSAMPLE	 samp);

typedef U32		(AILCALL FAR * M3D_3D_SAMPLE_LOOP_COUNT)(H3DSAMPLE samp);

typedef void	   (AILCALL FAR * M3D_SET_3D_SAMPLE_DISTANCES)(H3DSAMPLE samp,
															   F32	   max_front_dist,
															   F32	   min_front_dist,
															   F32	   max_back_dist,
															   F32	   min_back_dist);


typedef void	   (AILCALL FAR * M3D_3D_SAMPLE_DISTANCES)(H3DSAMPLE samp,
														   F32 FAR * max_front_dist,
														   F32 FAR * min_front_dist,
														   F32 FAR * max_back_dist,
														   F32 FAR * min_back_dist);

typedef  S32	  (AILCALL FAR * M3D_ACTIVE_3D_SAMPLE_COUNT)(void);

typedef H3DPOBJECT (AILCALL FAR * M3D_3D_OPEN_LISTENER)(void);

typedef void	   (AILCALL FAR * M3D_3D_CLOSE_LISTENER)(H3DPOBJECT listener);

typedef H3DPOBJECT (AILCALL FAR * M3D_3D_OPEN_OBJECT)(void);

typedef void	   (AILCALL FAR * M3D_3D_CLOSE_OBJECT)(H3DPOBJECT obj);

typedef void	   (AILCALL FAR * M3D_SET_3D_POSITION)(H3DPOBJECT obj,
													   F32	 X,
													   F32	 Y,
													   F32	 Z);

typedef void	   (AILCALL FAR * M3D_SET_3D_VELOCITY)(H3DPOBJECT obj,
													   F32	 dX_per_ms,
													   F32	 dY_per_ms,
													   F32	 dZ_per_ms,
													   F32	 magnitude);

typedef void	   (AILCALL FAR * M3D_SET_3D_VELOCITY_VECTOR)(H3DPOBJECT obj,
															  F32	 dX_per_ms,
															  F32	 dY_per_ms,
															  F32	 dZ_per_ms);

typedef void	   (AILCALL FAR * M3D_SET_3D_ORIENTATION)(H3DPOBJECT obj,
														  F32	 X_face,
														  F32	 Y_face,
														  F32	 Z_face,
														  F32	 X_up,
														  F32	 Y_up,
														  F32	 Z_up);

typedef void	   (AILCALL FAR * M3D_3D_POSITION)(H3DPOBJECT  obj,
												   F32 FAR *X,
												   F32 FAR *Y,
												   F32 FAR *Z);

typedef void	   (AILCALL FAR * M3D_3D_VELOCITY)(H3DPOBJECT  obj,
												   F32 FAR *dX_per_ms,
												   F32 FAR *dY_per_ms,
												   F32 FAR *dZ_per_ms);

typedef void	   (AILCALL FAR * M3D_3D_ORIENTATION)(H3DPOBJECT  obj,
													  F32 FAR *X_face,
													  F32 FAR *Y_face,
													  F32 FAR *Z_face,
													  F32 FAR *X_up,
													  F32 FAR *Y_up,
													  F32 FAR *Z_up);

typedef void	   (AILCALL FAR * M3D_3D_UPDATE_POSITION)(H3DPOBJECT obj,
														  F32	 dt_milliseconds);

typedef void	   (AILCALL FAR * M3D_3D_AUTO_UPDATE_POSITION)(H3DPOBJECT obj,
															   S32		enable);

//############################################################################
//##																		##
//## Interface "MSS mixer services"										 ##
//##																		##
//############################################################################

//
// Operation flags used by mixer module
//

#define M_DEST_STEREO 1	   // Set to enable stereo mixer output
#define M_SRC_16	  2	   // Set to enable mixing of 16-bit samples
#define M_FILTER	  4	   // Set to enable filtering when resampling
#define M_SRC_STEREO  8	   // Set to enable mixing of stereo input samples
#define M_VOL_SCALING 16	  // Set to enable volume scalars other than 2047
#define M_RESAMPLE	32	  // Set to enable playback ratios other than 65536
#define M_ORDER	   64	  // Set to reverse L/R stereo order for sample

#ifdef IS_32

//
// Initialize mixer
//
// No other mixer functions may be called outside a MIXER_startup() /
// MIXER_shutdown() pair, except for the standard RIB function
// PROVIDER_query_attribute().  All provider attributes must be accessible
// without starting up the module.
//

typedef void (AILCALL FAR *MIXER_STARTUP)(void);

//
// Shut down mixer
//

typedef void (AILCALL FAR *MIXER_SHUTDOWN)(void);

//
// Flush mixer buffer
//

typedef void (AILCALL FAR *MIXER_FLUSH)   (S32 FAR *dest,
										   S32	  len,
										   S32 FAR *reverb_buffer,
										   S32	  reverb_level,
										   U32	  MMX_available);

//
// Perform audio mixing operation
//

typedef void (AILCALL FAR *MIXER_MERGE)   (void FAR * FAR *src,
										   U32		FAR *src_fract,
										   void FAR	   *src_end,
										   S32  FAR * FAR *dest,
										   void FAR	   *dest_end,
										   S32  FAR	   *left_val,
										   S32  FAR	   *right_val,
										   S32			 playback_ratio,
										   S32			 scale_left,
										   S32			 scale_right,
										   U32			 operation,
										   U32			 MMX_available);

//
// Translate mixer buffer contents to final output format
//

typedef void (AILCALL FAR *MIXER_COPY) (void FAR *src,
										S32	   src_len,
										void FAR *dest,
										U32	   operation,
										U32	   MMX_available);
#else

//
// Initialize mixer
//
// No other mixer functions may be called outside a MIXER_startup() /
// MIXER_shutdown() pair, except for the standard RIB function
// PROVIDER_query_attribute().  All provider attributes must be accessible
// without starting up the module.
//

typedef void (AILCALL FAR *MIXER_STARTUP)(void);

//
// Shut down mixer
//

typedef void (AILCALL FAR *MIXER_SHUTDOWN)(void);

//
// Flush mixer buffer
//

typedef void (AILCALL FAR *MIXER_FLUSH)   (S32 FAR *dest,
										   S32	  len,
										   S32 FAR *reverb_buffer,
										   S32	  reverb_level,
										   U32	  MMX_available);

//
// Perform audio mixing operation
//

typedef void (AILCALL FAR *MIXER_MERGE)   (U32			 src_sel,
										   U32			 dest_sel,
										   U32		FAR *src_fract,
										   U32		FAR *src_offset,
										   U32		FAR *dest_offset,
										   U32			 src_end_offset,
										   U32			 dest_end_offset,
										   S32  FAR	   *left_val,
										   S32  FAR	   *right_val,
										   S32			 playback_ratio,
										   S32			 scale_both,
										   U32			 operation);

//
// Translate mixer buffer contents to final output format
//

typedef void (AILCALL FAR *MIXER_COPY) (void FAR *src,
										S32	   src_len,
										void FAR *dest,
										U32	   operation,
										U32	   MMX_available);
#endif

//
// Type definitions
//

struct _DIG_DRIVER;

struct _MDI_DRIVER;

typedef struct _DIG_DRIVER FAR * HDIGDRIVER;	// Handle to digital driver

typedef struct _MDI_DRIVER FAR * HMDIDRIVER;	// Handle to XMIDI driver

typedef struct _SAMPLE FAR * HSAMPLE;		   // Handle to sample

typedef struct _SEQUENCE FAR * HSEQUENCE;	   // Handle to sequence

typedef S32 HTIMER;							 // Handle to timer

#ifdef IS_DOS

//
// Type definitions
//

typedef struct					  // I/O parameters structure
{
   S16 IO;
   S16 IRQ;
   S16 DMA_8_bit;
   S16 DMA_16_bit;
   S32 IO_reserved[4];
}
IO_PARMS;

typedef struct					  // Standard MSS 3.X VDI driver header
{
   S8	 ID[8];					// "AIL3xxx" ID string, followed by ^Z

   U32	driver_version;

   REALFAR  common_IO_configurations;
   U16	num_IO_configurations;

   REALFAR  environment_string;

   IO_PARMS IO;

   S16	 service_rate;

   U16	busy;

   U16	driver_num;			 // Driver number

   U16	this_ISR;			   // Offset of INT 66H dispatcher
   REALFAR  prev_ISR;			   // Pointer to previous INT 66H ISR

   S8	 scratch[128];		   // Shared scratch workspace

   S8	 dev_name[80];		   // Device name (VDI version >= 1.12 only)
}
VDI_HDR;

typedef struct
{
   U16 minimum_physical_sample_rate;
   U16 nominal_physical_sample_rate;
   U16 maximum_physical_sample_rate;

   U16 minimum_DMA_half_buffer_size;
   U16 maximum_DMA_half_buffer_size;

   U32 flags;
}
DIG_MODE;

typedef struct
{
   U8	format_supported[16];
   DIG_MODE format_data[16];
}
DIG_DDT;

typedef struct
{
   REALFAR  DMA_buffer_A;
   REALFAR  DMA_buffer_B;
   S16	 active_buffer;
}
DIG_DST;

typedef struct
{
   REALFAR  library_environment;
   REALFAR  GTL_suffix;

   U16	num_voices;

   U16	max_melodic_channel;
   U16	min_melodic_channel;
   U16	percussion_channel;
}
MDI_DDT;

typedef struct
{
   S8	 library_directory[128];
   S8	 GTL_filename[128];

   S8	 MIDI_data[512];
}
MDI_DST;

typedef struct				   // Initialization file structure
{
   char	 device_name[128];	// Device name
   char	 driver_name[128];	// Driver filename
   IO_PARMS IO;				  // I/O parameters for driver
}
AIL_INI;

typedef struct				   // Handle to driver
{
   REALFAR  seg;				 // Seg:off pointer to driver (off=0)
   U32	sel;				   // Selector for driver (off=0)
   void	*buf;				 // Protected-mode pointer to driver
   U32	size;				  // Size of driver image
   VDI_HDR *VHDR;				// Pointer to driver header (same as buf)
   S32	 type;				 // AIL3DIG or AIL3MDI (see below)

   S32	 initialized;		  // 1 if hardware successfully init'd, else 0

   S32	 PM_ISR;			   // -1 if no PM ISR hooked, else IRQ #

   HTIMER   server;			  // DRV_SERVE periodic timer, if requested

								 // Vector to high-level destructor, if any

   void (AILCALL *destructor)(HDIGDRIVER);

								 // High-level descriptor (DIG_ or MDI_DRIVER)
   void		*descriptor;
}
AIL_DRIVER;

typedef struct					 // VDI interface register structure
{
   S16 AX;
   S16 BX;
   S16 CX;
   S16 DX;
   S16 SI;
   S16 DI;
}
VDI_CALL;

#endif

//
// Function pointer types
//

typedef void (AILCALLBACK FAR* AILINCB)	   (void FAR *data, S32 len, U32 user);

typedef void (AILCALLBACK FAR* AILTIMERCB)	(U32 user);

typedef void (AILCALLBACK FAR* AILSAMPLECB)   (HSAMPLE sample);

typedef S32  (AILCALLBACK FAR* AILEVENTCB)	(HMDIDRIVER hmi,HSEQUENCE seq,S32 status,S32 data_1,S32 data_2);

typedef S32  (AILCALLBACK FAR* AILTIMBRECB)   (HMDIDRIVER hmi,S32 bank,S32 patch);

typedef S32  (AILCALLBACK FAR* AILPREFIXCB)   (HSEQUENCE seq,S32 log,S32 data);

typedef void (AILCALLBACK FAR* AILTRIGGERCB)  (HSEQUENCE seq,S32 log,S32 data);

typedef void (AILCALLBACK FAR* AILBEATCB)	 (HMDIDRIVER hmi,HSEQUENCE seq,S32 beat,S32 measure);

typedef void (AILCALLBACK FAR* AILSEQUENCECB) (HSEQUENCE seq);

//
// Handle to sample and driver being managed by pipeline filter
//

typedef S32 HSAMPLESTATE;
typedef S32 HDRIVERSTATE;

//
// Digital pipeline stages
//
// These are the points at which external modules may be installed into
// a given HSAMPLE or HDIGDRIVER's processing pipeline
//

typedef enum
{
   DP_ASI_DECODER=0,   // Must be "ASI codec stream" provider
   DP_FILTER,		// Must be "MSS pipeline filter" provider
   DP_MERGE,		 // Must be "MSS mixer" provider
   N_SAMPLE_STAGES,  // Placeholder for end of list (= # of valid stages)
   SAMPLE_ALL_STAGES // Used to signify all pipeline stages, for shutdown
}
SAMPLESTAGE;

typedef enum
{
   DP_FLUSH = 0,	 // Must be "MSS mixer" provider
   DP_DEFAULT_FILTER, // Must be "MSS pipeline filter" provider (sets the default)
   DP_DEFAULT_MERGE,  // Must be "MSS mixer" provider (sets the default)
   DP_COPY,		  // Must be "MSS mixer" provider
   N_DIGDRV_STAGES,  // Placeholder for end of list (= # of valid stages)
   DIGDRV_ALL_STAGES // Used to signify all pipeline stages, for shutdown
}
DIGDRVSTAGE;

typedef struct
   {
   ASI_STREAM_OPEN		   ASI_stream_open;
   ASI_STREAM_PROCESS		ASI_stream_process;
   ASI_STREAM_SEEK		   ASI_stream_seek;
   ASI_STREAM_CLOSE		  ASI_stream_close;
   ASI_STREAM_ATTRIBUTE	  ASI_stream_attribute;
   ASI_STREAM_SET_PREFERENCE ASI_stream_set_preference;

   HATTRIB INPUT_BIT_RATE;
   HATTRIB INPUT_SAMPLE_RATE;
   HATTRIB INPUT_BITS;
   HATTRIB INPUT_CHANNELS;
   HATTRIB OUTPUT_BIT_RATE;
   HATTRIB OUTPUT_SAMPLE_RATE;
   HATTRIB OUTPUT_BITS;
   HATTRIB OUTPUT_CHANNELS;
   HATTRIB POSITION;
   HATTRIB PERCENT_DONE;
   HATTRIB MIN_INPUT_BLOCK_SIZE;
   HATTRIB RAW_RATE;
   HATTRIB RAW_BITS;
   HATTRIB RAW_CHANNELS;
   HATTRIB REQUESTED_RATE;
   HATTRIB REQUESTED_BITS;
   HATTRIB REQUESTED_CHANS;

   HASISTREAM stream;
   }
ASISTAGE;

typedef struct
   {
   MIXER_FLUSH MSS_mixer_flush;
   MIXER_MERGE MSS_mixer_merge;
   MIXER_COPY  MSS_mixer_copy;
   }
MIXSTAGE;

typedef struct
   {
   struct _FLTPROVIDER FAR *provider;
   HSAMPLESTATE			 sample_state;
   }
FLTSTAGE;

typedef struct
{
   S32	   active;	// Pass-through if 0, active if 1
   HPROVIDER provider;

   union
	  {
	  ASISTAGE ASI;
	  MIXSTAGE MIX;
	  FLTSTAGE FLT;
	  }
   TYPE;
}
DPINFO;

//
// Other data types
//

typedef enum _AILDUPMODE
{
   AIL_HALF_DUPLEX,
   AIL_FULL_DUPLEX
}
AILDUPMODE;

#define AIL_FORCE_DUPLEX  1	// Force specified duplex mode to be used, else fail
#define AIL_FORCE_MODE	2	// Force specified format/rate to be used, else fail
#define AIL_FORCE_BUFSIZE 4	// Force specified input buffer size to be used, else fail

typedef struct _AILINPUTINFO		// Input descriptor type
{
   U32		device_ID;	   // DS LPGUID or wave device ID
   U32		hardware_format; // e.g., DIG_F_STEREO_16
   U32		hardware_rate;   // e.g., 22050
   AILDUPMODE duplex_mode;	 // AIL_HALF_DUPLEX | AIL_FULL_DUPLEX
   AILINCB	callback;		// Callback function to receive incoming data
   S32		buffer_size;	 // Maximum # of bytes to be passed to callback (-1 to use DIG_INPUT_LATENCY)
}
AILINPUTINFO;

typedef struct _AILTIMER				 // Timer instance
{
   U32	  status;
   AILTIMERCB callback;
   U32	  user;

   S32	  elapsed;
   S32	  value;
   S32	  callingCT;		   // Calling EXE's task number (16 bit only)
   S32	  callingDS;		   // Calling EXE's DS (used in 16 bit only)
   S32	  IsWin32s;			// Is this a Win32s callback
} AILTIMERSTR;

typedef struct _ADPCMDATATAG
{
  U32 blocksize;
  U32 extrasamples;
  U32 blockleft;
  U32 step;
  U32 savesrc;
  U32 sample;
  U32 destend;
  U32 srcend;
  U32 samplesL;
  U32 samplesR;
  U16 moresamples[16];
} ADPCMDATA;

typedef struct _SAMPLE		   // Sample instance
{
   char	   tag[4];			// HSAM

   HDIGDRIVER driver;			// Driver for playback

   U32	  status;			  // SMP_ flags: _FREE, _DONE, _PLAYING

   void FAR *start[2];		   // Sample buffer address (W)
   U32	   len  [2];		   // Sample buffer size in bytes (W)
   U32	   pos  [2];		   // Index to next byte (R/W)
   U32	   done [2];		   // Nonzero if buffer with len=0 sent by app

   U32	  src_fract;		   // Fractional part of source address
   S32	  left_val;			// Mixer source value from end of last buffer
   S32	  right_val;		   // Mixer source value from end of last buffer

   S32	  current_buffer;	  // Buffer # active (0/1)
   S32	  last_buffer;		 // Last active buffer (for double-buffering)
   S32	  starved;			 // Buffer stream has run out of data

   S32	  loop_count;		  // # of cycles-1 (1=one-shot, 0=indefinite)
   S32	  loop_start;		  // Starting offset of loop block (0=SOF)
   S32	  loop_end;			// End offset of loop block (-1=EOF)

   S32	  format;			  // DIG_F format (8/16 bits, mono/stereo)
   U32	  flags;			   // DIG_PCM_SIGN / DIG_PCM_ORDER (stereo only)

   S32	  playback_rate;	   // Playback rate in hertz

   S32	  volume;			  // Sample volume 0-127
   S32	  pan;				 // Mono panpot/stereo balance (0=L ... 127=R)

   S32	  left_scale;		  // Left/mono volume scalar 0-2047
   S32	  right_scale;		 // Right volume scalar 0-2047

   S32	  service_type;		// 1 if single-buffered; 2 if streamed

   AILSAMPLECB  SOB;			 // Start-of-block callback function
   AILSAMPLECB  EOB;			 // End-of-buffer callback function
   AILSAMPLECB  EOS;			 // End-of-sample callback function

   S32	  user_data  [8];	  // Miscellaneous user data
   S32	  system_data[8];	  // Miscellaneous system data

   ADPCMDATA adpcm;

#ifdef IS_WINDOWS

   S32	  SOB_IsWin32s;		// Is this a Win32s callback
   S32	  EOB_IsWin32s;		// Is this a Win32s callback
   S32	  EOS_IsWin32s;		// Is this a Win32s callback

   //
   // DirectSound-specific data
   //

   S32	  secondary_buffer;	// Secondary buffer index

   S32	  service_interval;	// Service sample every n ms
   S32	  service_tick;		// Current service countdown value
   S32	  buffer_segment_size; // Buffer segment size to fill

   S32	  prev_segment;		// Previous segment # (0...n)
   S32	  prev_cursor;		 // Previous play cursor location

   S32	  bytes_remaining;	 // # of bytes left to play (if not -1)

   S32	  direct_control;	  // 1 if app controls buffer, 0 if MSS

#endif

   S32	  doeob;			   // Flags to trigger callbacks
   S32	  dosob;
   S32	  doeos;

   //
   // Sample pipeline stages
   //

   DPINFO   pipeline[N_SAMPLE_STAGES];

   //
   // Reverb parms
   //

   F32	  reverb_level;		   // Level [0.0, 1.0]
   F32	  reverb_reflect_time;	// Reflect time in milliseconds
   F32	  reverb_decay_time;	  // Decay time [0.1, 20.0]
   S32	  base_scale;			 // Original 12-bit volume scalar
} 
SAMPLE;

#ifdef IS_WINDOWS

typedef struct _DIG_INPUT_DRIVER FAR *HDIGINPUT; // Handle to digital input driver

typedef struct _DIG_INPUT_DRIVER	// Handle to digital input driver
{
   C8	 tag[4];				   // HDIN

   HTIMER background_timer;		 // Background timer handle

   AILINPUTINFO info;			   // Input device descriptor
   U32		  callback_user;	  // Callback user value

   //
   // Provider-independent data
   //

   U32	   DMA_size;			  // Size of each DMA sub-buffer in bytes
   void FAR *DMA[2];				// Simulated DMA buffers

   U8		silence;			   // Silence value for current format (0 or 128)

   S32	   input_enabled;		 // 1 if enabled, 0 if not
   S32	   device_active;		 // 1 if buffers submittable, 0 if not

   //
   // waveOut-specific data
   //

   HWAVEIN		  hWaveIn;		// Handle to wave input device
   volatile WAVEHDR wavehdr[2];	 // Handles to wave headers
}
DIG_INPUT_DRIVER;

#endif

typedef struct _DIG_DRIVER		  // Handle to digital audio driver
{
   char	 tag[4];				 // HDIG

   HTIMER	  backgroundtimer;	 // Background timer handle

   S32		 quiet;			   // # of consecutive quiet sample periods

   S32		 n_active_samples;	// # of samples being processed

   S32		 master_volume;	   // Master sample volume 0-127

   S32		 DMA_rate;			// Hardware sample rate
   S32		 hw_format;		   // DIG_F code in use
   U32		 hw_mode_flags;	   // DIG_PCM_ flags for mode in use

   S32		 channels_per_sample; // # of channels per sample (1 or 2)
   S32		 bytes_per_channel;   // # of bytes per channel (1 or 2)
   S32		 channels_per_buffer; // # of channels per half-buffer
   S32		 samples_per_buffer;  // # of samples per half-buffer

   S32		 playing;			 // Playback active if non-zero

   HSAMPLE	 samples;			 // Pointer to list of SAMPLEs
   S32		 n_samples;		   // # of SAMPLEs

   S32		 build_size;		  // # of bytes in build buffer
   S32	FAR *build_buffer;		// Build buffer (4 * samples_per_buffer)

   S32		 system_data[8];	  // Miscellaneous system data

   S32		 buffer_size;		 // Size of each output buffer

#ifdef IS_WINDOWS

   //
   // waveOut-specific interface data
   //

   HWAVEOUT	hWaveOut;			// Wave output driver

   U32		 reset_works;		 // TRUE if OK to do waveOutReset
   U32		 request_reset;	   // If nonzero, do waveOutReset ASAP

   LPWAVEHDR   first;			   // Pointer to first WAVEHDR in chain
   S32		 n_buffers;		   // # of output WAVEHDRs in chain

   LPWAVEHDR volatile FAR *return_list; // Circular list of returned WAVEHDRs
   S32	   volatile	  return_head; // Head of WAVEHDR list (insertion point)
   S32	   volatile	  return_tail; // Tail of WAVEHDR list (retrieval point)


   U32		 deviceid;			// id from waveout open
   PCMWAVEFORMAT  wformat;		  // format from waveout open

   //
   // DirectSound-specific interface data
   //

   U32					guid;		// The guid id of the ds driver
   AILLPDIRECTSOUND	   pDS;		 // DirectSound output driver (don't
									   // use with Smacker directly anymore!)

   S32					emulated_ds; // is ds emulated or not?
   AILLPDIRECTSOUNDBUFFER lppdsb;	  // primary buffer or null

   U32					dsHwnd;	  // HWND used with DirectSound

   AILLPDIRECTSOUNDBUFFER FAR * lpbufflist;   // List of pointers to secondary buffers
   HSAMPLE		 FAR *samp_list;	  // HSAMPLE associated with each buffer
   S32			 FAR *sec_format;	 // DIG_F_ format for secondary buffer
   S32				  max_buffs;	  // Max. allowable # of secondary buffers

   //
   // Misc. data
   //

   S32		 released;			// has the sound manager been released?

   U32		 foreground_timer;	// Foreground timer handle

   HDIGDRIVER  next;				// Pointer to next HDIGDRIVER in use
   S32	  callingCT;			  // Calling EXE's task number (16 bit only)
   S32	  callingDS;			  // Calling EXE's DS (used in 16 bit only)

   //
   // Vars for waveOut emulation
   //

   S32 DS_initialized;

   AILLPDIRECTSOUNDBUFFER DS_sec_buff;	// Secondary buffer (or NULL if none)
   AILLPDIRECTSOUNDBUFFER DS_out_buff;	// Output buffer (may be sec or prim)
   S32 DS_buffer_size;					// Size of entire output buffer

   S32 DS_frag_cnt;				 // Total fragment count and size, and
   S32 DS_frag_size;				// last fragment occupied by play cursor
   S32 DS_last_frag;
   S32 DS_last_write;
   S32 DS_last_timer;
   S32 DS_skip_time;

   S32 DS_use_default_format;	   // 1 to force use of default DS primary buffer format

#else

   // must be first in the DOS section
   void	   *DMA[2];			  // Protected-mode pointers to half-buffers
									// (note that DMA[0] may != DMA_buf)


   REALFAR	 DMA_seg;			 // Seg:off pointer to DMA buffers (off=0)
   U32		 DMA_sel;			 // Selector for DMA buffers (off=0)
   void	   *DMA_buf;			 // Protected-mode pointer to DMA buffers

   S16		*buffer_flag;		 // Protected-mode pointer to buffer flag
   S32		 last_buffer;		 // Last active buffer flag value in driver

   AIL_DRIVER *drvr;				// Base driver descriptor

   DIG_DDT	*DDT;				 // Protected-mode pointer to DDT
   DIG_DST	*DST;				 // Protected-mode pointer to DST

#endif

   S32		 use_MMX;			 // Use MMX with this driver if TRUE

   void   FAR *decode_buffer;	   // Buffer used by optional ASI pipeline decoder
   S32		 decode_buffer_size;  // # of bytes in decode buffer

   U32 us_count;
   U32 ms_count;
   U32 last_ms_polled;
   U32 last_percent;

   //
   // Digital driver pipeline stages
   //

   DPINFO   pipeline[N_DIGDRV_STAGES];

   //
   // Reverb buffer
   //

   S32 FAR *reverb_buffer;
   S32	  reverb_buffer_size;
   S32	  reverb_buffer_position;
}
DIG_DRIVER;

typedef struct					  // MIDI status log structure
   {
   S32	  program   [NUM_CHANS];  // Program Change
   S32	  pitch_l   [NUM_CHANS];  // Pitch Bend LSB
   S32	  pitch_h   [NUM_CHANS];  // Pitch Bend MSB

   S32	  c_lock	[NUM_CHANS];  // Channel Lock
   S32	  c_prot	[NUM_CHANS];  // Channel Lock Protection
   S32	  c_mute	[NUM_CHANS];  // Channel Mute
   S32	  c_v_prot  [NUM_CHANS];  // Voice Protection
   S32	  bank	  [NUM_CHANS];  // Patch Bank Select
   S32	  gm_bank_l [NUM_CHANS];  // GM Bank Select
   S32	  gm_bank_m [NUM_CHANS];  // GM Bank Select
   S32	  indirect  [NUM_CHANS];  // ICA indirect controller value
   S32	  callback  [NUM_CHANS];  // Callback Trigger

   S32	  mod	   [NUM_CHANS];  // Modulation
   S32	  vol	   [NUM_CHANS];  // Volume
   S32	  pan	   [NUM_CHANS];  // Panpot
   S32	  exp	   [NUM_CHANS];  // Expression
   S32	  sus	   [NUM_CHANS];  // Sustain
   S32	  reverb	[NUM_CHANS];  // Reverb
   S32	  chorus	[NUM_CHANS];  // Chorus

   S32	  bend_range[NUM_CHANS];  // Bender Range (data MSB, RPN 0 assumed)

   S32	  RPN_L	 [NUM_CHANS];  // RPN # LSB
   S32	  RPN_M	 [NUM_CHANS];  // RPN # MSB
   }
CTRL_LOG;

typedef struct _SEQUENCE				  // XMIDI sequence state table
{
   char	 tag[4];					   // HSEQ

   HMDIDRIVER driver;					 // Driver for playback

   U32	  status;					   // SEQ_ flags

   void	FAR *TIMB;					 // XMIDI IFF chunk pointers
   void	FAR *RBRN;
   void	FAR *EVNT;

   U8	  FAR *EVNT_ptr;				 // Current event pointer

   U8	  FAR *ICA;					  // Indirect Controller Array

   AILPREFIXCB   prefix_callback;		 // XMIDI Callback Prefix handler
   AILTRIGGERCB  trigger_callback;		// XMIDI Callback Trigger handler
   AILBEATCB	 beat_callback;		   // XMIDI beat/bar change handler
   AILSEQUENCECB EOS;					 // End-of-sequence callback function

   S32	  loop_count;				   // 0=one-shot, -1=indefinite, ...

   S32	  interval_count;			   // # of intervals until next event
   S32	  interval_num;				 // # of intervals since start

   S32	  volume;					   // Sequence volume 0-127
   S32	  volume_target;				// Target sequence volume 0-127
   S32	  volume_accum;				 // Accumulated volume period
   S32	  volume_period;				// Period for volume stepping

   S32	  tempo_percent;				// Relative tempo percentage 0-100
   S32	  tempo_target;				 // Target tempo 0-100
   S32	  tempo_accum;				  // Accumulated tempo period
   S32	  tempo_period;				 // Period for tempo stepping
   S32	  tempo_error;				  // Error counter for tempo DDA

   S32	  beat_count;				   // Sequence playback position
   S32	  measure_count;

   S32	  time_numerator;			   // Sequence timing data
   S32	  time_fraction;
   S32	  beat_fraction;
   S32	  time_per_beat;

   void FAR *FOR_ptrs	  [FOR_NEST];	// Loop stack
   S32	  FOR_loop_count [FOR_NEST];

   S32	  chan_map	   [NUM_CHANS];   // Physical channel map for sequence

   CTRL_LOG shadow;					   // Controller values for sequence

   S32	  note_count;				   // # of notes "on"

   S32	  note_chan	  [MAX_NOTES];   // Channel for queued note (-1=free)
   S32	  note_num	   [MAX_NOTES];   // Note # for queued note
   S32	  note_time	  [MAX_NOTES];   // Remaining duration in intervals

   S32	  user_data  [8];			   // Miscellaneous user data
   S32	  system_data[8];			   // Miscellaneous system data

#ifdef IS_WINDOWS
   S32	  PREFIX_IsWin32s;			  // Is this a Win32s callback
   S32	  TRIGGER_IsWin32s;			 // Is this a Win32s callback
   S32	  BEAT_IsWin32s;				// Is this a Win32s callback
   S32	  EOS_IsWin32s;				 // Is this a Win32s callback
#endif
} SEQUENCE;

typedef struct _MDI_DRIVER		  // Handle to XMIDI driver
{
   char	 tag[4];				 // HMDI

   HTIMER	  timer;			   // XMIDI quantization timer
   S32		 interval_time;	   // XMIDI quantization timer interval in uS

   S32		 disable;			 // > 0 to disable XMIDI service

   HSEQUENCE   sequences;		   // Pointer to list of SEQUENCEs
   S32		 n_sequences;		 // # of SEQUENCEs

   S32		 lock  [NUM_CHANS];   // 1 if locked, 2 if protected, else 0
   HSEQUENCE   locker[NUM_CHANS];   // HSEQUENCE which locked channel
   HSEQUENCE   owner [NUM_CHANS];   // HSEQUENCE which owned locked channel
   HSEQUENCE   user  [NUM_CHANS];   // Last sequence to use channel
   S32		 state [NUM_CHANS];   // Lock state prior to being locked

   S32		 notes [NUM_CHANS];   // # of active notes in channel

   AILEVENTCB  event_trap;		  // MIDI event trap callback function
   AILTIMBRECB timbre_trap;		 // Timbre request callback function

   S32		 master_volume;	   // Master XMIDI note volume 0-127

   S32		 system_data[8];	  // Miscellaneous system data

#ifdef IS_WINDOWS

   S32	  EVENT_IsWin32s;		 // Is this a Win32s callback
   S32	  TIMBRE_IsWin32s;		// Is this a Win32s callback

   MIDIHDR FAR *mhdr;			   // SysEx header
   U8	  FAR *sysdata;			// SysEx buffer

   HMDIDRIVER  next;				// Pointer to next HMDIDRIVER in use
   S32	  callingCT;			  // Calling EXE's task number (16 bit only)
   S32	  callingDS;			  // Calling EXE's DS (used in 16 bit only)

   HMIDIOUT	hMidiOut;			// MIDI output driver
   U32		 deviceid;			// ID of the MIDI device
   S32		 released;			// has the hmidiout handle been released

#else

   S32		message_count;	   // MIDI message count
   S32		offset;			  // MIDI buffer offset

   AIL_DRIVER *drvr;			   // Base driver descriptor

   MDI_DDT	*DDT;				// Protected-mode pointer to DDT
   MDI_DST	*DST;				// Protected-mode pointer to DST

#endif
}
MDI_DRIVER;

typedef struct					  // XMIDI TIMB IFF chunk
   {
   S8	name[4];

   U8	msb;
   U8	lsb;
   U8	lsb2;
   U8	lsb3;

   U16   n_entries;

   U16   timbre[1];
   }
TIMB_chunk;

typedef struct					  // XMIDI RBRN IFF entry
   {
   S16   bnum;
   U32   offset;
   }
RBRN_entry;

typedef struct					  // Wave library entry
{
   S32   bank;					  // XMIDI bank, MIDI patch for sample
   S32   patch;

   S32   root_key;				  // Root MIDI note # for sample (or -1)

   U32   file_offset;			   // Offset of wave data from start-of-file
   U32   size;					  // Size of wave sample in bytes

   S32   format;					// DIG_F format (8/16 bits, mono/stereo)
   U32   flags;					 // DIG_PCM_SIGN / DIG_PCM_ORDER (stereo)
   S32   playback_rate;			 // Playback rate in hertz
}
WAVE_ENTRY;

typedef struct					  // Virtual "wave synthesizer" descriptor
{
   HMDIDRIVER mdi;				  // MIDI driver for use with synthesizer
   HDIGDRIVER dig;				  // Digital driver for use with synthesizer

   WAVE_ENTRY FAR *library;		 // Pointer to wave library

   AILEVENTCB  prev_event_fn;	   // Previous MIDI event trap function
   AILTIMBRECB prev_timb_fn;		// Previous timbre request trap function

   CTRL_LOG	controls;			// MIDI controller states

   WAVE_ENTRY FAR *wave [NUM_CHANS];// Pointer to WAVE_ENTRY for each channel

   HSAMPLE	 S	[MAX_W_VOICES]; // List of HSAMPLE voices
   S32		 n_voices;			// Actual # of voices allocated to synth

   S32		 chan [MAX_W_VOICES]; // MIDI channel for each voice, or -1
   S32		 note [MAX_W_VOICES]; // MIDI note number for voice
   S32		 root [MAX_W_VOICES]; // MIDI root note for voice
   S32		 rate [MAX_W_VOICES]; // Playback rate for voice
   S32		 vel  [MAX_W_VOICES]; // MIDI note velocity for voice
   U32		 time [MAX_W_VOICES]; // Timestamp for voice

   U32		 event;			   // Event counter for LRU timestamps
}
WAVE_SYNTH;

typedef WAVE_SYNTH FAR * HWAVESYNTH;// Handle to virtual wave synthesizer

//
// Handle to thread which called AIL_startup()
//
// This thread is suspended by MSS callback threads, to simulate DOS-style
// interrupt handler behavior
//

#ifdef IS_WIN32

extern HANDLE hAppThread;

#endif

//
// Background flag for timers
//

extern volatile S32   AIL_bkgnd_flag;

//
// Global preference array
//

extern S32			AIL_preference   [N_PREFS];

//
// DIG_DRIVER list
//

extern HDIGDRIVER	 DIG_first;

//
// MDI_DRIVER list
//

extern HMDIDRIVER	 MDI_first;

//
// Miscellaneous system services
//

#define FILE_READ_WITH_SIZE ((void FAR*)(S32)-1)

#ifndef NO_OLD_SYS_FUNCTIONS

#define MEM_alloc_lock AIL_mem_alloc_lock
#define MEM_free_lock  AIL_mem_free_lock
#define FILE_error	 AIL_file_error
#define FILE_size	  AIL_file_size
#define FILE_read	  AIL_file_read
#define FILE_write	 AIL_file_write

#ifdef IS_DOS

#define MEM_alloc		AIL_mem_alloc
#define MEM_free		 AIL_mem_free
#define MEM_use_malloc   AIL_mem_use_malloc
#define MEM_use_free	 AIL_mem_use_free
#define MEM_alloc_DOS	AIL_mem_alloc_DOS
#define MEM_free_DOS	 AIL_mem_free_DOS
#define VMM_lock_range   AIL_vmm_lock_range
#define VMM_unlock_range AIL_vmm_unlock_range
#define VMM_lock		 AIL_vmm_lock
#define VMM_unlock	   AIL_vmm_unlock

#endif

#endif

extern S32 AILCALLBACK DP_ASI_DECODER_callback(U32	   user,
											   void FAR *dest,
											   S32	   bytes_requested,
											   S32	   offset);

DXDEC  void FAR * AILCALL AIL_mem_alloc_lock(U32	   size);
DXDEC  void	   AILCALL AIL_mem_free_lock (void FAR *ptr);

DXDEC  S32		AILCALL AIL_file_error   (void);

DXDEC  S32		AILCALL AIL_file_size	(char FAR   *filename);

DXDEC  void FAR * AILCALL AIL_file_read	(char FAR   *filename,
										   void FAR *dest);

DXDEC  S32		AILCALL AIL_file_write   (char FAR   *filename,
											void FAR *buf,
											U32	   len);

DXDEC  S32		AILCALL AIL_WAV_file_write
										   (char FAR   *filename,
											void FAR *buf,
											U32	   len,
											S32	   rate,
											S32	   format);

DXDEC  S32		AILCALL AIL_file_append  (char FAR*filename,
											void FAR*buf, U32 len);
#ifdef IS_DOS

extern void * AILCALLBACK (*AIL_mem_alloc) (U32);
extern void   AILCALLBACK (*AIL_mem_free)  (void *);

void * cdecl AIL_mem_use_malloc(void * AILCALLBACK (*fn)(U32));
void * cdecl AIL_mem_use_free  (void AILCALLBACK (*fn)(void *));

//
// Other memory-management functions
//

DXDEC  S32   AILCALL AIL_mem_alloc_DOS (U32  n_paras,
										void **protected_ptr,
										U32 *segment_far_ptr,
										U32 *selector);

DXDEC  void  AILCALL AIL_mem_free_DOS (void  *protected_ptr,
									   U32  segment_far_ptr,
									   U32  selector);

DXDEC  S32   AILCALL AIL_vmm_lock_range   (void  *p1, void *p2);
DXDEC  S32   AILCALL AIL_vmm_unlock_range (void  *p1, void *p2);

DXDEC  S32   AILCALL AIL_vmm_lock		 (void  *start, U32 size);
DXDEC  S32   AILCALL AIL_vmm_unlock	   (void  *start, U32 size);

DXDEC  U32  AILCALL AIL_sel_base		 (U32  sel);

DXDEC  void   AILCALL AIL_sel_set_limit  (U32  sel,
										  U32  limit);
//
// Last IO_PARMS structure used to attempt device detection
//

extern IO_PARMS	   AIL_last_IO_attempt;

//
// Low-level support services
//

DXDEC REALFAR AILCALL  AIL_get_real_vect			(U32	   vectnum);

DXDEC void	AILCALL  AIL_set_real_vect			(U32	   vectnum,
													 REALFAR   real_ptr);

DXDEC void	AILCALL  AIL_set_USE16_ISR			(S32		IRQ,
													 REALFAR	real_base,
													 U32		ISR_offset);

DXDEC void	AILCALL  AIL_restore_USE16_ISR		(S32		IRQ);

DXDEC U32	 AILCALL  AIL_disable_interrupts	   (void);
DXDEC void	AILCALL  AIL_restore_interrupts	   (U32		FD_register);

DXDEC void	AILCALL  AIL_switch_stack			 (void	   *stack,
													 U32		size,
													 U32		*SS,
													 void	   **ESP,
													 void	   **EBP);

DXDEC void	AILCALL  AIL_restore_stack			(U32		SS,
													 void	   *ESP,
													 void	   *EBP);

DXDEC S32	 AILCALL  AIL_call_driver			  (AIL_DRIVER *drvr,
													 S32		fn,
													 VDI_CALL   *in,
													 VDI_CALL   *out);

DXDEC S32	 AILCALL  AIL_read_INI				 (AIL_INI	*INI,
													 char	   *filename);

DXDEC U32	 AILCALL  AIL_interrupt_divisor		(void);

#endif


#ifdef __WATCOMC__

void MSSBreakPoint();
#pragma aux MSSBreakPoint = "int 3";

#else

#define MSSBreakPoint() __asm {int 3}

#endif


//
// High-level support services
//

#ifdef IS_DOS

#ifdef IS_WATCOM

#if !defined(max) // Watcom stdlib.h doesn't define these for C++
#define max(a,b)  (((a) > (b)) ? (a) : (b))
#endif
#if !defined(min)
#define min(a,b)  (((a) < (b)) ? (a) : (b))
#endif

#endif

#ifdef __SW_3R
extern S32 AILCALL AIL_startup_reg			   (void);
#define AIL_startup AIL_startup_reg
#else
extern S32 AILCALL AIL_startup_stack			 (void);
#define AIL_startup AIL_startup_stack
#endif

#define AIL_quick_startup(ud,um,opr,opb,ops) AIL_quick_startup_with_start(&AIL_startup,ud,um,opr,opb,ops)

extern S8		   AIL_driver_directory [256];

DXDEC char FAR* AILCALL AIL_set_driver_directory	  (char  FAR*dir);

#define AIL_get_preference(number) (AIL_preference[number])

#else

DXDEC  S32	 AILCALL  AIL_startup				   (void);

DXDEC  S32	 AILCALL  AIL_get_preference			(U32		 number);

#endif

DXDEC  void	AILCALL  AIL_shutdown				  (void);

DXDEC  S32	 AILCALL  AIL_set_preference			(U32		 number,
													  S32		  value);

DXDEC char FAR *AILCALL  AIL_last_error				(void);

DXDEC  void	AILCALL  AIL_set_error				 (char FAR* error_msg);

//
// Low-level support services
//

DXDEC  void	__cdecl  AIL_debug_printf			  (C8 FAR *fmt, ...);
DXDEC  U32	 AILCALL  AIL_MMX_available			 (void);

DXDEC  void	AILCALL  AIL_lock					  (void);
DXDEC  void	AILCALL  AIL_unlock					(void);

DXDEC  void	AILCALL  AIL_delay					 (S32		 intervals);

DXDEC  S32	 AILCALL  AIL_background				(void);

//
// Process services
//

DXDEC  HTIMER  AILCALL  AIL_register_timer			(AILTIMERCB  fn);

DXDEC  U32	 AILCALL  AIL_set_timer_user			(HTIMER	  timer,
													  U32		 user);

DXDEC  void	AILCALL  AIL_set_timer_period		  (HTIMER	  timer,
													  U32		 microseconds);

DXDEC  void	AILCALL  AIL_set_timer_frequency	   (HTIMER	  timer,
													  U32		 hertz);

DXDEC  void	AILCALL  AIL_set_timer_divisor		 (HTIMER	  timer,
													  U32		 PIT_divisor);

DXDEC  void	AILCALL  AIL_start_timer			   (HTIMER	  timer);
DXDEC  void	AILCALL  AIL_start_all_timers		  (void);

DXDEC  void	AILCALL  AIL_stop_timer				(HTIMER	  timer);
DXDEC  void	AILCALL  AIL_stop_all_timers		   (void);

DXDEC  void	AILCALL  AIL_release_timer_handle	  (HTIMER	  timer);
DXDEC  void	AILCALL  AIL_release_all_timers		(void);

#ifdef IS_WIN32

DXDEC  U32	 AILCALL  AIL_get_timer_highest_delay   (void);

DXDEC  HWND	AILCALL  AIL_HWND					  (void);

#endif

//
// high-level digital services
//

#ifdef IS_WINDOWS

#define AIL_DLL_version(str,len)		\
{									   \
  HINSTANCE l=LoadLibrary(MSSDLLNAME);  \
  if ((U32)l<=32)					   \
	*(str)=0;						   \
  else {								\
	LoadString(l,1,str,len);			\
	FreeLibrary(l);					 \
  }									 \
}

DXDEC  S32		  AILCALL AIL_waveOutOpen		  (HDIGDRIVER   FAR *drvr,
													  LPHWAVEOUT   FAR *lphWaveOut,
													  S32			 wDeviceID,
													  LPWAVEFORMAT	  lpFormat);

DXDEC  void		 AILCALL AIL_waveOutClose		  (HDIGDRIVER drvr);

DXDEC  S32		  AILCALL AIL_digital_handle_release(HDIGDRIVER drvr);

DXDEC  S32		  AILCALL AIL_digital_handle_reacquire
													 (HDIGDRIVER drvr);

DXDEC  void		 AILCALL AIL_serve(void);

#else

//
// DOS installation services
//

DXDEC IO_PARMS *   AILCALL AIL_get_IO_environment	(AIL_DRIVER *drvr);

DXDEC AIL_DRIVER*  AILCALL AIL_install_driver		(U8	  *driver_image,
													  U32	   n_bytes);

DXDEC void		 AILCALL AIL_uninstall_driver	  (AIL_DRIVER *drvr);

DXDEC S32		 AILCALL AIL_install_DIG_INI	   (HDIGDRIVER *dig);

DXDEC HDIGDRIVER   AILCALL AIL_install_DIG_driver_file
													(char	   *filename,
													 IO_PARMS   *IO);

DXDEC void		 AILCALL AIL_uninstall_DIG_driver  (HDIGDRIVER  dig);


DXDEC HDIGDRIVER   AILCALL AIL_install_DIG_driver_image
													(void	 *driver_image,
													 U32	 size,
													 IO_PARMS *IO);
#endif

DXDEC  S32		  AILCALL AIL_digital_CPU_percent(HDIGDRIVER dig);

DXDEC  HSAMPLE	  AILCALL AIL_allocate_sample_handle
													(HDIGDRIVER dig);

DXDEC  HSAMPLE	  AILCALL AIL_allocate_file_sample  (HDIGDRIVER dig,
													 void	   FAR *file_image,
													 S32		 block);

DXDEC  void		 AILCALL AIL_release_sample_handle (HSAMPLE S);

DXDEC  void		 AILCALL AIL_init_sample		   (HSAMPLE S);

DXDEC  S32		  AILCALL AIL_set_sample_file	   (HSAMPLE   S,
													   void FAR *file_image,
													   S32	   block);

DXDEC  S32		  AILCALL AIL_set_named_sample_file (HSAMPLE   S,
													   C8   FAR *file_type_suffix,
													   void FAR *file_image,
													   S32	   file_size,
													   S32	   block);

DXDEC  HPROVIDER	AILCALL AIL_set_sample_processor  (HSAMPLE	 S,
													   SAMPLESTAGE pipeline_stage,
													   HPROVIDER   provider);

DXDEC  HPROVIDER	AILCALL AIL_set_digital_driver_processor
													  (HDIGDRIVER  dig,
													   DIGDRVSTAGE pipeline_stage,
													   HPROVIDER   provider);

DXDEC  void		 AILCALL AIL_set_sample_adpcm_block_size
													 (HSAMPLE S,
													 U32	 blocksize);

DXDEC  void		 AILCALL AIL_set_sample_address	(HSAMPLE S,
													 void   FAR *start,
													 U32	 len);

DXDEC  void		 AILCALL AIL_set_sample_type	   (HSAMPLE S,
													 S32	 format,
													 U32	 flags);

DXDEC  void		 AILCALL AIL_start_sample		  (HSAMPLE S);

DXDEC  void		 AILCALL AIL_stop_sample		   (HSAMPLE S);

DXDEC  void		 AILCALL AIL_resume_sample		 (HSAMPLE S);

DXDEC  void		 AILCALL AIL_end_sample			(HSAMPLE S);

DXDEC  void		 AILCALL AIL_set_sample_playback_rate
													 (HSAMPLE S,
													 S32	 playback_rate);

DXDEC  void		 AILCALL AIL_set_sample_volume	 (HSAMPLE S,
													 S32	 volume);

DXDEC  void		 AILCALL AIL_set_sample_pan		(HSAMPLE S,
													 S32	 pan);

DXDEC  void		 AILCALL AIL_set_sample_loop_count (HSAMPLE S,
													 S32	 loop_count);

DXDEC  void		 AILCALL AIL_set_sample_loop_block (HSAMPLE S,
													 S32	 loop_start_offset,
													 S32	 loop_end_offset);

DXDEC  U32		  AILCALL AIL_sample_status		 (HSAMPLE S);

DXDEC  S32		  AILCALL AIL_sample_playback_rate  (HSAMPLE S);

DXDEC  S32		  AILCALL AIL_sample_volume		 (HSAMPLE S);

DXDEC  S32		  AILCALL AIL_sample_pan			(HSAMPLE S);

DXDEC  S32		  AILCALL AIL_sample_loop_count	 (HSAMPLE S);

DXDEC  void		 AILCALL AIL_set_digital_master_volume
													 (HDIGDRIVER dig,
													 S32		 master_volume);

DXDEC  S32		  AILCALL AIL_digital_master_volume (HDIGDRIVER dig);

DXDEC  void		 AILCALL AIL_set_sample_reverb(HSAMPLE S,
														F32	 reverb_level,
														F32	 reverb_reflect_time,
														F32	 reverb_decay_time);

DXDEC  void		 AILCALL AIL_sample_reverb	(HSAMPLE S,
														F32 FAR *reverb_level,
														F32 FAR *reverb_reflect_time,
														F32 FAR *reverb_decay_time);

//
// low-level digital services
//

DXDEC  S32	  AILCALL AIL_minimum_sample_buffer_size(HDIGDRIVER dig,
													 S32		 playback_rate,
													 S32		 format);

DXDEC  S32	  AILCALL AIL_sample_buffer_ready	  (HSAMPLE S);

DXDEC  void	 AILCALL AIL_load_sample_buffer	   (HSAMPLE S,
													 U32	 buff_num,
													 void   FAR *buffer,
													 U32	 len);

DXDEC  S32	  AILCALL AIL_sample_buffer_info	  (HSAMPLE S, //)
													U32	 FAR *pos0,
													U32	 FAR *len0,
													U32	 FAR *pos1,
													U32	 FAR *len1);

DXDEC  U32	  AILCALL AIL_sample_granularity	  (HSAMPLE S);

DXDEC  void	 AILCALL AIL_set_sample_position	  (HSAMPLE S,
													  U32	 pos);

DXDEC  U32	  AILCALL AIL_sample_position		  (HSAMPLE S);

DXDEC  AILSAMPLECB AILCALL AIL_register_SOB_callback
													(HSAMPLE S,
													 AILSAMPLECB SOB);

DXDEC  AILSAMPLECB AILCALL AIL_register_EOB_callback
													(HSAMPLE S,
													 AILSAMPLECB EOB);

DXDEC  AILSAMPLECB AILCALL AIL_register_EOS_callback
													(HSAMPLE S,
													 AILSAMPLECB EOS);

DXDEC  AILSAMPLECB AILCALL AIL_register_EOF_callback
													(HSAMPLE S,
													 AILSAMPLECB EOFILE);

DXDEC  void	 AILCALL AIL_set_sample_user_data   (HSAMPLE S,
													 U32	 index,
													 S32	 value);

DXDEC  S32	  AILCALL AIL_sample_user_data	   (HSAMPLE S,
													 U32	 index);

DXDEC  S32	  AILCALL AIL_active_sample_count	(HDIGDRIVER dig);

DXDEC  void	 AILCALL AIL_digital_configuration  (HDIGDRIVER dig,
													  S32   FAR *rate,
													  S32   FAR *format,
													  char  FAR *string);
#ifdef IS_WIN32

DXDEC  S32	  AILCALL AIL_set_direct_buffer_control (HSAMPLE S,
													 U32	  command);

DXDEC  void	 AILCALL AIL_get_DirectSound_info  (HSAMPLE			  S,
												   AILLPDIRECTSOUND	*lplpDS,
												   AILLPDIRECTSOUNDBUFFER *lplpDSB);

DXDEC  S32	  AILCALL AIL_set_DirectSound_HWND(HDIGDRIVER dig, HWND wnd);

#endif

DXDEC  void	 AILCALL AIL_set_sample_ms_position (HSAMPLE	S, //)
													S32		milliseconds);

DXDEC  void	 AILCALL AIL_sample_ms_position	 (HSAMPLE	S, //)
													S32 FAR *  total_milliseconds,
													S32 FAR *  current_milliseconds);


//
// Digital input services
//

#ifdef IS_WINDOWS

DXDEC HDIGINPUT AILCALL AIL_input_open			 (AILINPUTINFO FAR *info,
													U32			   constraints,
													U32			   callback_user_value);

DXDEC void	  AILCALL AIL_input_close			(HDIGINPUT		 dig);

DXDEC AILINPUTINFO FAR *
				AILCALL AIL_input_info			 (HDIGINPUT		 dig);

DXDEC S32	   AILCALL AIL_set_input_state		(HDIGINPUT		 dig,
													S32			   enable);
#endif


//
// High-level XMIDI services
//

#ifdef IS_WINDOWS

DXDEC  S32		  AILCALL AIL_midiOutOpen(HMDIDRIVER FAR *drvr,
											LPHMIDIOUT FAR *lphMidiOut,
											S32		   dwDeviceID);

DXDEC  void		 AILCALL AIL_midiOutClose	  (HMDIDRIVER mdi);

DXDEC  S32		  AILCALL AIL_MIDI_handle_release
												 (HMDIDRIVER mdi);

DXDEC  S32		  AILCALL AIL_MIDI_handle_reacquire
												 (HMDIDRIVER mdi);

#else

DXDEC S32		 AILCALL AIL_install_MDI_INI	   (HMDIDRIVER *mdi);

DXDEC HMDIDRIVER   AILCALL AIL_install_MDI_driver_file
													(char	   *filename,
													 IO_PARMS   *IO);

DXDEC void		 AILCALL AIL_uninstall_MDI_driver  (HMDIDRIVER  mdi);


DXDEC HMDIDRIVER   AILCALL AIL_install_MDI_driver_image
													(void	   *driver_image,
													 U32	   size,
													 IO_PARMS   *IO);

DXDEC S32	 AILCALL AIL_MDI_driver_type		   (HMDIDRIVER  mdi);

DXDEC void	AILCALL AIL_set_GTL_filename_prefix   (char	  *prefix);

DXDEC S32	 AILCALL AIL_timbre_status			 (HMDIDRIVER  mdi,
													 S32		bank,
													 S32		patch);

DXDEC S32	 AILCALL AIL_install_timbre			(HMDIDRIVER  mdi,
													 S32		bank,
													 S32		patch);

DXDEC void	AILCALL AIL_protect_timbre			(HMDIDRIVER  mdi,
													 S32		bank,
													 S32		patch);

DXDEC void	AILCALL AIL_unprotect_timbre		  (HMDIDRIVER  mdi,
													 S32		bank,
													 S32		patch);

#endif

DXDEC  HSEQUENCE	AILCALL AIL_allocate_sequence_handle
													 (HMDIDRIVER mdi);

DXDEC  void		 AILCALL AIL_release_sequence_handle
													 (HSEQUENCE S);

DXDEC  S32		  AILCALL AIL_init_sequence		 (HSEQUENCE S,
													 void	 FAR *start,
													 S32	   sequence_num);

DXDEC  void		 AILCALL AIL_start_sequence		(HSEQUENCE S);

DXDEC  void		 AILCALL AIL_stop_sequence		 (HSEQUENCE S);

DXDEC  void		 AILCALL AIL_resume_sequence	   (HSEQUENCE S);

DXDEC  void		 AILCALL AIL_end_sequence		  (HSEQUENCE S);

DXDEC  void		 AILCALL AIL_set_sequence_tempo	(HSEQUENCE S,
													 S32	   tempo,
													 S32	   milliseconds);

DXDEC  void		 AILCALL AIL_set_sequence_volume   (HSEQUENCE S,
													 S32	   volume,
													 S32	   milliseconds);

DXDEC  void		 AILCALL AIL_set_sequence_loop_count
													 (HSEQUENCE S,
													 S32	   loop_count);

DXDEC  U32		  AILCALL AIL_sequence_status	   (HSEQUENCE S);

DXDEC  S32		  AILCALL AIL_sequence_tempo		(HSEQUENCE S);

DXDEC  S32		  AILCALL AIL_sequence_volume	   (HSEQUENCE S);

DXDEC  S32		  AILCALL AIL_sequence_loop_count   (HSEQUENCE S);

DXDEC  void		 AILCALL AIL_set_XMIDI_master_volume
													 (HMDIDRIVER mdi,
													 S32		 master_volume);

DXDEC  S32		  AILCALL AIL_XMIDI_master_volume   (HMDIDRIVER mdi);


//
// Low-level XMIDI services
//

DXDEC  S32	  AILCALL AIL_active_sequence_count	 (HMDIDRIVER mdi);

DXDEC  S32	  AILCALL AIL_controller_value		  (HSEQUENCE S,
													  S32	   channel,
													  S32	   controller_num);

DXDEC  S32	  AILCALL AIL_channel_notes			 (HSEQUENCE S,
													  S32	   channel);

DXDEC  void	 AILCALL AIL_sequence_position		 (HSEQUENCE S,
													  S32	  FAR *beat,
													  S32	  FAR *measure);

DXDEC  void	 AILCALL AIL_branch_index			  (HSEQUENCE  S,
													  U32		marker);

DXDEC  AILPREFIXCB AILCALL AIL_register_prefix_callback
													 (HSEQUENCE  S,
													  AILPREFIXCB callback);

DXDEC  AILTRIGGERCB AILCALL AIL_register_trigger_callback
													 (HSEQUENCE  S,
													  AILTRIGGERCB callback);

DXDEC  AILSEQUENCECB AILCALL AIL_register_sequence_callback
													 (HSEQUENCE  S,
													  AILSEQUENCECB callback);

DXDEC  AILBEATCB AILCALL AIL_register_beat_callback   (HSEQUENCE  S,
													  AILBEATCB callback);

DXDEC  AILEVENTCB AILCALL AIL_register_event_callback (HMDIDRIVER mdi,
													  AILEVENTCB callback);

DXDEC  AILTIMBRECB AILCALL AIL_register_timbre_callback
													 (HMDIDRIVER mdi,
													  AILTIMBRECB callback);

DXDEC  void	 AILCALL AIL_set_sequence_user_data	(HSEQUENCE S,
													  U32	   index,
													  S32	   value);

DXDEC  S32	  AILCALL AIL_sequence_user_data		(HSEQUENCE S,
													  U32	   index);

DXDEC  void	 AILCALL AIL_register_ICA_array		(HSEQUENCE S,
													  U8	   FAR *array);

DXDEC  S32	  AILCALL AIL_lock_channel			  (HMDIDRIVER mdi);

DXDEC  void	 AILCALL AIL_release_channel		   (HMDIDRIVER mdi,
													  S32		 channel);

DXDEC  void	 AILCALL AIL_map_sequence_channel	  (HSEQUENCE S,
													  S32	   seq_channel,
													  S32	   new_channel);

DXDEC  S32	  AILCALL AIL_true_sequence_channel	 (HSEQUENCE S,
													  S32	   seq_channel);

DXDEC  void	 AILCALL AIL_send_channel_voice_message
													 (HMDIDRIVER  mdi,
													  HSEQUENCE   S,
													  S32		 status,
													  S32		 data_1,
													  S32		 data_2);

DXDEC  void	 AILCALL AIL_send_sysex_message		(HMDIDRIVER mdi,
													   void	   FAR *buffer);

DXDEC  HWAVESYNTH
				AILCALL AIL_create_wave_synthesizer   (HDIGDRIVER dig,
													HMDIDRIVER mdi,
													   void	   FAR *wave_lib,
													   S32		 polyphony);

DXDEC  void	 AILCALL AIL_destroy_wave_synthesizer  (HWAVESYNTH W);

DXDEC  void	 AILCALL AIL_set_sequence_ms_position  (HSEQUENCE S, //)
													   S32	   milliseconds);

DXDEC  void	 AILCALL AIL_sequence_ms_position(HSEQUENCE S, //)
												 S32 FAR *total_milliseconds,
												 S32 FAR *current_milliseconds);



//
// red book functions
//

#ifdef IS_DOS
typedef struct _REDBOOKTRACKINFO {
  U32 tracks;
  U32 trackstarts[100];
} REDBOOKTRACKINFO;
#endif

typedef struct _REDBOOK {
  U32 DeviceID;
  U32 paused;
  U32 pausedsec;
  U32 lastendsec;
#ifdef IS_DOS
  U32 readcontents;
  REDBOOKTRACKINFO info;
#endif
} REDBOOK;

typedef struct _REDBOOK FAR* HREDBOOK;

#define REDBOOK_ERROR	0
#define REDBOOK_PLAYING  1
#define REDBOOK_PAUSED   2
#define REDBOOK_STOPPED  3


DXDEC  HREDBOOK   AILCALL AIL_redbook_open(U32 which);

DXDEC  HREDBOOK   AILCALL AIL_redbook_open_drive(S32 drive);

DXDEC  void	   AILCALL AIL_redbook_close(HREDBOOK hand);

DXDEC  void	   AILCALL AIL_redbook_eject(HREDBOOK hand);

DXDEC  void	   AILCALL AIL_redbook_retract(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_status(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_tracks(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_track(HREDBOOK hand);

DXDEC  void	   AILCALL AIL_redbook_track_info(HREDBOOK hand,U32 tracknum,
													 U32 FAR* startmsec,U32 FAR* endmsec);

DXDEC  U32		AILCALL AIL_redbook_id(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_position(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_play(HREDBOOK hand,U32 startmsec, U32 endmsec);

DXDEC  U32		AILCALL AIL_redbook_stop(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_pause(HREDBOOK hand);

DXDEC  U32		AILCALL AIL_redbook_resume(HREDBOOK hand);

DXDEC  S32		AILCALL AIL_redbook_volume(HREDBOOK hand);

DXDEC  S32		AILCALL AIL_redbook_set_volume(HREDBOOK hand, S32 volume);

#ifdef IS_WIN16
  #define AIL_ms_count timeGetTime
  DXDEC U32 AILCALL AIL_us_count(void);
#else
  DXDEC U32 AILCALL AIL_ms_count(void);
  DXDEC U32 AILCALL AIL_us_count(void);
#endif


typedef struct _STREAM FAR* HSTREAM;		   // Handle to stream

typedef void (AILCALLBACK FAR* AILSTREAMCB)   (HSTREAM stream);

typedef struct _STREAM {

  S32 block_oriented; // 1 if this is an ADPCM or ASI-compressed stream
  S32 using_ASI;	  // 1 if using ASI decoder to uncompress stream data
  ASISTAGE FAR *ASI;  // handy pointer to our ASI coded

  HSAMPLE samp;	   // the sample handle

  U32 fileh;	   // the open file handle

  U8 FAR* bufs[3]; // the data buffers
  U32 bufsizes[3]; // the size of each buffer

  S32 bufsize;	 // size of each buffer
  S32 readsize;	// size of each read block

  U32 buf1;		// 0,1,2 (current buffer that we are reading into)
  S32 size1;	   // holds the current amount of data read

  U32 buf2;		// 0,1,2 (the next buffer that we are reading into)
  S32 size2;	   // next buffer loaded up to

  U32 buf3;		// 0,1,2 (the next buffer that we are reading into)
  S32 size3;	   // next buffer loaded up to

  U32 datarate;	// datarate in bytes per second
  S32 filerate;	// original datarate of the file
  S32 filetype;	// file format type
  U32 fileflags;   // file format flags (signed or unsigned)
  S32 totallen;	// total length of the sound data

  U32 blocksize;   // ADPCM block size
  S32 padding;	 // padding to be done
  S32 padded;	  // padding done

  S32 loadedsize;  // size that has been loaded
  S32 loadedsome;  // have we done any loads?

  U32 startpos;	// point that the sound data begins
  U32 totalread;   // total bytes read from the disk

  U32 loopsleft;   // how many loops are left

  U32 error;	   // read error has occurred

  S32 preload;	 // preload the file into the first buffer
  S32 dontclose;   // don't close the file
  S32 noback;	  // no background processing
  S32 alldone;	 // alldone
  S32 primeamount; // amount to load after a seek
  S32 readatleast; // forced amount to read on next service

  S32 playcontrol; // control: 0=stopped, 1=started, |8=paused, |16=sample paused

  AILSTREAMCB callback;  // end of stream callback

  S32 user_data[8];	  // Miscellaneous user data
  void FAR* next;		// pointer to next stream

#ifdef IS_WINDOWS
  S32 autostreaming;	 // are we autostreaming this stream
  S32 cb_IsWin32s;	   // Is the callback win32s?
#endif

  S32 docallback;  // set when it time to poll for a callback

} STREAM_TYPE;


DXDEC HSTREAM AILCALL AIL_open_stream(HDIGDRIVER dig, char FAR* filename, S32 stream_mem);

DXDEC void AILCALL AIL_close_stream(HSTREAM stream);

DXDEC S32 AILCALL AIL_service_stream(HSTREAM stream, S32 fillup);

DXDEC void AILCALL AIL_start_stream(HSTREAM stream);

DXDEC void AILCALL AIL_pause_stream(HSTREAM stream, S32 onoff);

DXDEC void AILCALL AIL_set_stream_volume(HSTREAM stream,S32 volume);

DXDEC void AILCALL AIL_set_stream_pan(HSTREAM stream,S32 pan);

DXDEC S32 AILCALL AIL_stream_volume(HSTREAM stream);

DXDEC S32 AILCALL AIL_stream_pan(HSTREAM stream);

DXDEC void AILCALL AIL_set_stream_playback_rate(HSTREAM stream, S32 rate);

DXDEC S32 AILCALL AIL_stream_playback_rate(HSTREAM stream);

DXDEC S32 AILCALL AIL_stream_loop_count(HSTREAM stream);

DXDEC void AILCALL AIL_set_stream_loop_count(HSTREAM stream, S32 count);

DXDEC S32 AILCALL AIL_stream_status(HSTREAM stream);

DXDEC void AILCALL AIL_set_stream_position(HSTREAM stream,S32 offset);

DXDEC S32 AILCALL AIL_stream_position(HSTREAM stream);

DXDEC void AILCALL AIL_stream_info(HSTREAM stream, S32 FAR* datarate, S32 FAR* sndtype, S32 FAR* length, S32 FAR* memory);

DXDEC AILSTREAMCB AILCALL AIL_register_stream_callback(HSTREAM stream, AILSTREAMCB callback);

DXDEC void AILCALL AIL_auto_service_stream(HSTREAM stream, S32 onoff);

DXDEC void	 AILCALL AIL_set_stream_user_data   (HSTREAM S,
													 U32	 index,
													 S32	 value);

DXDEC S32	  AILCALL AIL_stream_user_data	   (HSTREAM S,
													 U32	 index);

DXDEC  void	 AILCALL AIL_set_stream_ms_position   (HSTREAM S,
													  S32		milliseconds);

DXDEC  void	 AILCALL AIL_stream_ms_position	 (HSTREAM	S, //)
													S32 FAR *  total_milliseconds,
													S32 FAR *  current_milliseconds);

DXDEC  void	 AILCALL AIL_set_stream_reverb(HSTREAM S,
											  F32	 reverb_level,
											  F32	 reverb_reflect_time,
											  F32	 reverb_decay_time);

DXDEC  void	AILCALL AIL_stream_reverb	 (HSTREAM S,
											  F32 FAR *reverb_level,
											  F32 FAR *reverb_reflect_time,
											  F32 FAR *reverb_decay_time);


//
// High-level DLS functions
//

typedef struct _DLSFILEID {
  S32 id;
  struct _DLSFILEID FAR* next;
} DLSFILEID;

typedef struct _DLSFILEID FAR* HDLSFILEID;

typedef struct _DLSDEVICE {
  void FAR* pGetPref;
  void FAR* pSetPref;
  void FAR* pMSSOpen;
  void FAR* pOpen;
  void FAR* pClose;
  void FAR* pLoadFile;
  void FAR* pLoadMem;
  void FAR* pUnloadFile;
  void FAR* pUnloadAll;
  void FAR* pGetInfo;
  void FAR* pCompact;
  void FAR* pSetAttr;
  S32 DLSHandle;
  U32 format;
  U32 buffer_size;
  void FAR* buffer[2];
  HSAMPLE sample;
  HMDIDRIVER mdi;
  HDIGDRIVER dig;
  HDLSFILEID first;
#ifdef IS_WINDOWS
  HMODULE lib;
#else
  char FAR* DOSname;
#endif
} DLSDEVICE;

typedef struct _DLSDEVICE FAR* HDLSDEVICE;

typedef struct _AILDLSINFO {
  char Description[128];
  S32 MaxDLSMemory;
  S32 CurrentDLSMemory;
  S32 LargestSize;
  S32 GMAvailable;
  S32 GMBankSize;
} AILDLSINFO;

#ifdef IS_DOS

typedef struct _AILDOSDLS {
  char FAR* description;
  void FAR* pDLSOpen;
  void FAR* pMSSOpen;
  void FAR* pOpen;
  void FAR* pClose;
  void FAR* pLoadFile;
  void FAR* pLoadMem;
  void FAR* pUnloadFile;
  void FAR* pUnloadAll;
  void FAR* pGetInfo;
  void FAR* pCompact;
  void FAR* pSetAttr;
} AILDOSDLS;

#endif


DXDEC  HDLSDEVICE AILCALL AIL_DLS_open(HMDIDRIVER mdi, HDIGDRIVER dig,
#ifdef IS_WINDOWS
										  char FAR* libname,
#else
										  AILDOSDLS FAR* dosdls,
#endif
										  U32 flags, U32 rate, S32 bits, S32 channels);

//
// Parameters for the dwFlag used in DLSClose() and flags in AIL_DLS_close
//

#define RETAIN_DLS_COLLECTION   0x00000001
#define RETURN_TO_BOOTUP_STATE  0x00000002
#define RETURN_TO_GM_ONLY_STATE 0x00000004
#define DLS_COMPACT_MEMORY	  0x00000008

DXDEC  void   AILCALL AIL_DLS_close(HDLSDEVICE dls, U32 flags);

DXDEC  HDLSFILEID AILCALL AIL_DLS_load_file(HDLSDEVICE dls, char FAR* filename, U32 flags);

DXDEC  HDLSFILEID AILCALL AIL_DLS_load_memory(HDLSDEVICE dls, void FAR* memfile, U32 flags);

//
// other parameters for AIL_DLS_unload
//

#define AIL_DLS_UNLOAD_MINE 0
#define AIL_DLS_UNLOAD_ALL  ((HDLSFILEID)(U32)(S32)-1)

DXDEC  void   AILCALL AIL_DLS_unload(HDLSDEVICE dls, HDLSFILEID dlsid);

DXDEC  void   AILCALL AIL_DLS_compact(HDLSDEVICE dls);

DXDEC  void   AILCALL AIL_DLS_get_info(HDLSDEVICE dls, AILDLSINFO FAR* info, S32 FAR* PercentCPU);

DXDEC  void   AILCALL AIL_DLS_set_reverb(HDLSDEVICE dls,
										 F32	 reverb_level,
										 F32	 reverb_reflect_time,
										 F32	 reverb_decay_time);

DXDEC  void   AILCALL AIL_DLS_get_reverb(HDLSDEVICE dls,
										 F32 FAR*	reverb_level,
										 F32 FAR*	reverb_reflect_time,
										 F32 FAR*	reverb_decay_time);


//
// Quick-integration service functions and data types
//

typedef struct
{
   U32 FAR *data;
   S32  size;
   S32  type;
   void FAR *handle;
   S32  status;
   void FAR* next;
   S32  speed;
   S32  volume;
   S32  extravol;
   F32  rlevel;
   F32  rrtime;
   F32  rdtime;
   HDLSFILEID dlsid;
   void FAR* dlsmem;
   void FAR* dlsmemunc;
   S32  milliseconds;
   S32  length;
   S32  userdata;
}
AUDIO_TYPE;


#define QSTAT_DONE		  1	   // Data has finished playing
#define QSTAT_LOADED		2	   // Data has been loaded, but not yet played
#define QSTAT_PLAYING	   3	   // Data is currently playing

typedef AUDIO_TYPE FAR * HAUDIO;		// Generic handle to any audio data type

#define AIL_QUICK_USE_WAVEOUT			 2
#define AIL_QUICK_MIDI_AND_DLS			2
#define AIL_QUICK_DLS_ONLY				3
#define AIL_QUICK_MIDI_AND_VORTEX_DLS	 4
#define AIL_QUICK_MIDI_AND_SONICVIBES_DLS 5

DXDEC S32	 AILCALL
#ifdef IS_WINDOWS
					   AIL_quick_startup		   (
#else
					   AIL_quick_startup_with_start(void*	   startup,
#endif
													S32		 use_digital,
													S32		 use_MIDI,
													U32		 output_rate,
													S32		 output_bits,
													S32		 output_channels);

DXDEC void	AILCALL AIL_quick_shutdown			(void);

DXDEC void	AILCALL AIL_quick_handles			 (HDIGDRIVER FAR* pdig,
													 HMDIDRIVER FAR* pmdi,
													 HDLSDEVICE FAR* pdls );

DXDEC HAUDIO  AILCALL AIL_quick_load				(char   FAR *filename);

DXDEC HAUDIO  AILCALL AIL_quick_load_mem			(void   FAR *mem,
													U32	size);

DXDEC HAUDIO  AILCALL AIL_quick_copy				(HAUDIO	  audio);

DXDEC void	AILCALL AIL_quick_unload			  (HAUDIO	  audio);

DXDEC S32	 AILCALL AIL_quick_play				(HAUDIO	  audio,
													U32		 loop_count);

DXDEC void	AILCALL AIL_quick_halt				(HAUDIO	  audio);

DXDEC S32	 AILCALL AIL_quick_status			  (HAUDIO	  audio);

DXDEC HAUDIO  AILCALL AIL_quick_load_and_play	   (char   FAR *filename,
													U32		 loop_count,
													S32		 wait_request);

DXDEC void   AILCALL AIL_quick_set_speed (HAUDIO audio, S32 speed);

DXDEC void   AILCALL AIL_quick_set_volume (HAUDIO audio, S32 volume, S32 extravol);

DXDEC void   AILCALL AIL_quick_set_reverb (HAUDIO audio,
										   F32	 reverb_level,
										   F32	 reverb_reflect_time,
										   F32	 reverb_decay_time);

DXDEC void   AILCALL AIL_quick_set_ms_position(HAUDIO audio,S32 milliseconds);

DXDEC S32	AILCALL AIL_quick_ms_position(HAUDIO audio);

DXDEC S32	AILCALL AIL_quick_ms_length(HAUDIO audio);


#define AIL_QUICK_XMIDI_TYPE		1
#define AIL_QUICK_DIGITAL_TYPE	  2
#define AIL_QUICK_DLS_XMIDI_TYPE	3
#define AIL_QUICK_MPEG_DIGITAL_TYPE 4

DXDEC S32	AILCALL AIL_quick_type(HAUDIO audio);

//
// used for AIL_process
//

typedef struct _AILMIXINFO {
  AILSOUNDINFO Info;
  ADPCMDATA mss_adpcm;
  U32 src_fract;
  S32 left_val;
  S32 right_val;
} AILMIXINFO;



DXDEC S32 AILCALL AIL_WAV_info(void FAR* data, AILSOUNDINFO FAR* info);

DXDEC S32 AILCALL AIL_size_processed_digital_audio(
								 U32			 dest_rate,
								 U32			 dest_format,
								 S32			 num_srcs,
								 AILMIXINFO FAR* src);

DXDEC S32 AILCALL AIL_process_digital_audio(
								 void FAR	   *dest_buffer,
								 S32			 dest_buffer_size,
								 U32			 dest_rate,
								 U32			 dest_format,
								 S32			 num_srcs,
								 AILMIXINFO FAR* src);

#define AIL_LENGTHY_INIT		   0
#define AIL_LENGTHY_SET_PREFERENCE 1
#define AIL_LENGTHY_UPDATE		 2
#define AIL_LENGTHY_DONE		   3

typedef S32 (AILCALLBACK FAR* AILLENGTHYCB)(U32 state,U32 user);

typedef S32 (AILCALLBACK FAR* AILCODECSETPREF)(char FAR* preference,U32 value);

DXDEC S32 AILCALL AIL_compress_ASI(AILSOUNDINFO FAR* info, //)
								   char FAR* filename_ext,
								   void FAR* FAR* outdata,
								   U32 FAR* outsize,
								   AILLENGTHYCB callback);

DXDEC S32 AILCALL AIL_decompress_ASI(void FAR* indata, //)
									 U32 insize,
									 char FAR* filename_ext,
									 void FAR* FAR* wav,
									 U32 FAR* wavsize,
									 AILLENGTHYCB callback);

DXDEC S32 AILCALL AIL_compress_ADPCM(AILSOUNDINFO FAR * info,
									 void FAR* FAR* outdata, U32 FAR* outsize);

DXDEC S32 AILCALL AIL_decompress_ADPCM(AILSOUNDINFO FAR * info,
									   void FAR* FAR* outdata, U32 FAR* outsize);

DXDEC S32 AILCALL AIL_compress_DLS(void FAR* dls,
								   char FAR* compression_extension,
								   void FAR* FAR* mls, U32 FAR* mlssize,
								   AILLENGTHYCB callback);

DXDEC S32 AILCALL AIL_merge_DLS_with_XMI(void FAR* xmi, void FAR* dls,
										 void FAR* FAR* mss, U32 FAR* msssize);

DXDEC  S32 AILCALL AIL_extract_DLS( void FAR	   *source_image, //)
									S32			 source_size,
									void FAR * FAR *XMI_output_data,
									S32  FAR	   *XMI_output_size,
									void FAR * FAR *DLS_output_data,
									S32  FAR	   *DLS_output_size,
									AILLENGTHYCB   callback);

#define AILFILTERDLS_USINGLIST 1

DXDEC S32 AILCALL AIL_filter_DLS_with_XMI(void FAR* xmi, void FAR* dls,
										 void FAR* FAR* dlsout, U32 FAR* dlssize,
										 S32  flags, AILLENGTHYCB callback);

#define AILMIDITOXMI_USINGLIST 1
#define AILMIDITOXMI_TOLERANT  2

DXDEC  S32 AILCALL AIL_MIDI_to_XMI	   (void FAR*  MIDI,
										 U32		MIDI_size,
										 void FAR*  FAR*XMIDI,
										 U32  FAR*  XMIDI_size,
										 S32		flags);

#define AILMIDILIST_ROLANDSYSEX 1
#define AILMIDILIST_ROLANDUN	2
#define AILMIDILIST_ROLANDAB	4

DXDEC  S32		  AILCALL AIL_list_MIDI		 (void FAR* MIDI,
												  U32	   MIDI_size,
												  char FAR* FAR* lst,
												  U32  FAR* lst_size,
												  S32	   flags);
#define AILDLSLIST_ARTICULATION 1
#define AILDLSLIST_DUMP_WAVS	2

DXDEC  S32		  AILCALL AIL_list_DLS		  (void FAR* DLS,
												   char FAR* FAR* lst,
												   U32  FAR* lst_size,
												   S32	   flags,
												   C8   FAR* title);

#define AILFILETYPE_UNKNOWN	 0
#define AILFILETYPE_PCM_WAV	 1
#define AILFILETYPE_ADPCM_WAV   2
#define AILFILETYPE_OTHER_WAV   3
#define AILFILETYPE_VOC		 4
#define AILFILETYPE_MIDI		5
#define AILFILETYPE_XMIDI	   6
#define AILFILETYPE_XMIDI_DLS   7
#define AILFILETYPE_XMIDI_MLS   8
#define AILFILETYPE_DLS		 9
#define AILFILETYPE_MLS		10
#define AILFILETYPE_MPEG_L1_AUDIO 11
#define AILFILETYPE_MPEG_L2_AUDIO 12
#define AILFILETYPE_MPEG_L3_AUDIO 13

DXDEC S32 AILCALL AIL_file_type(void FAR* data, U32 size);

DXDEC S32 AILCALL AIL_find_DLS	   (void FAR*	  data, U32 size,
									  void FAR* FAR* xmi, U32 FAR* xmisize,
									  void FAR* FAR* dls, U32 FAR* dlssize);

#ifdef IS_WIN32

//
// Auxiliary 2D interface calls
//

DXDEC HDIGDRIVER AILCALL AIL_primary_digital_driver  (HDIGDRIVER new_primary);

//
// Filter result codes
//

typedef S32 FLTRESULT;

#define FLT_NOERR				   0   // Success -- no error
#define FLT_NOT_ENABLED			 1   // FLT not enabled
#define FLT_ALREADY_STARTED		 2   // FLT already started
#define FLT_INVALID_PARAM		   3   // Invalid parameters used
#define FLT_INTERNAL_ERR			4   // Internal error in FLT driver
#define FLT_OUT_OF_MEM			  5   // Out of system RAM
#define FLT_ERR_NOT_IMPLEMENTED	 6   // Feature not implemented
#define FLT_NOT_FOUND			   7   // FLT supported device not found
#define FLT_NOT_INIT				8   // FLT not initialized
#define FLT_CLOSE_ERR			   9   // FLT not closed correctly

//############################################################################
//##																		##
//## Interface "MSS pipeline filter"										##
//##																		##
//############################################################################

typedef FLTRESULT (AILCALL FAR *FLT_STARTUP)(void);

typedef FLTRESULT (AILCALL FAR *FLT_SHUTDOWN)(void);

typedef C8 FAR *  (AILCALL FAR *FLT_ERROR)(void);

typedef S32	   (AILCALL FAR *FLT_SET_PROVIDER_PREFERENCE)(HATTRIB preference,
															 void FAR*   value);

typedef HDRIVERSTATE (AILCALL FAR *FLT_OPEN_DRIVER) (HDIGDRIVER dig, 
													 S32 FAR   *build_buffer,
													 S32		build_buffer_size);

typedef FLTRESULT	(AILCALL FAR *FLT_CLOSE_DRIVER) (HDRIVERSTATE state);

typedef void		 (AILCALL FAR *FLT_PREMIX_PROCESS) (HDRIVERSTATE driver);

typedef void		 (AILCALL FAR *FLT_POSTMIX_PROCESS) (HDRIVERSTATE driver);

//############################################################################
//##																		##
//## Interface "Pipeline filter sample services"							##
//##																		##
//############################################################################

typedef HSAMPLESTATE (AILCALL FAR * FLTSMP_OPEN_SAMPLE) (HDRIVERSTATE driver, 
														 HSAMPLE	  S);

typedef FLTRESULT	(AILCALL FAR * FLTSMP_CLOSE_SAMPLE) (HSAMPLESTATE state);

typedef S32		  (AILCALL FAR * FLTSMP_SAMPLE_PROCESS) (HSAMPLESTATE	state,  
															void FAR * FAR *orig_src,
															U32  FAR *	  orig_src_fract,
															void FAR *	  orig_src_end,
															S32  FAR * FAR *build_dest,
															void FAR *	  build_dest_end,
															S32  FAR *	  left_val,
															S32  FAR *	  right_val,
															S32			 playback_ratio,
															S32			 left_scale,
															S32			 right_scale,
															S32			 base_scale,
															MIXSTAGE FAR *  mixer_provider,
															U32			 mixer_operation);

typedef S32		  (AILCALL FAR * FLTSMP_SAMPLE_ATTRIBUTE) (HSAMPLESTATE state,
															  HATTRIB	  attribute);

typedef S32		  (AILCALL FAR * FLTSMP_SET_SAMPLE_PREFERENCE) (HSAMPLESTATE state,
																   HATTRIB	  preference,
																   void FAR*	value);

//
// Pipeline filter calls
//

DXDEC S32		AILCALL AIL_enumerate_filters  (HPROENUM  FAR *next,
												 HPROVIDER FAR *dest,
												 C8  FAR * FAR *name);

DXDEC HDRIVERSTATE
				 AILCALL AIL_open_filter		(HPROVIDER  lib,
												 HDIGDRIVER dig);

DXDEC void	   AILCALL AIL_close_filter	   (HDRIVERSTATE filter);

DXDEC S32		AILCALL AIL_enumerate_filter_attributes
												(HPROVIDER				  lib,
												 HINTENUM FAR *			 next,
												 RIB_INTERFACE_ENTRY FAR *  dest);

DXDEC void	   AILCALL AIL_filter_attribute   (HPROVIDER  lib,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC void	   AILCALL AIL_set_filter_preference
												(HPROVIDER  lib,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  S32	  AILCALL AIL_enumerate_filter_sample_attributes
												(HPROVIDER				 lib,
												 HINTENUM FAR *			next,
												 RIB_INTERFACE_ENTRY FAR * dest);

DXDEC  void	 AILCALL AIL_filter_sample_attribute
												(HSAMPLE	S,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  void	 AILCALL AIL_filter_stream_attribute
												(HSTREAM	S,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  void	 AILCALL AIL_filter_DLS_attribute
												(HDLSDEVICE dls,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  void	 AILCALL AIL_set_filter_sample_preference
												(HSAMPLE	S,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  void	 AILCALL AIL_set_filter_stream_preference
												(HSTREAM	S,
												 C8 FAR *   name,
												 void FAR * val);

DXDEC  void	 AILCALL AIL_set_filter_DLS_preference
												(HDLSDEVICE dls,
												 C8 FAR *   name,
												 void FAR * val);

typedef struct _FLTPROVIDER
{
   PROVIDER_QUERY_ATTRIBUTE		PROVIDER_query_attribute;

   FLT_STARTUP					 startup;
   FLT_ERROR					   error;
   FLT_SHUTDOWN					shutdown;
   FLT_SET_PROVIDER_PREFERENCE	 set_provider_preference;
   FLT_OPEN_DRIVER				 open_driver;
   FLT_CLOSE_DRIVER				close_driver;
   FLT_PREMIX_PROCESS			  premix_process;
   FLT_POSTMIX_PROCESS			 postmix_process;

   FLTSMP_OPEN_SAMPLE			  open_sample;
   FLTSMP_CLOSE_SAMPLE			 close_sample;
   FLTSMP_SAMPLE_PROCESS		   sample_process;
   FLTSMP_SAMPLE_ATTRIBUTE		 sample_attribute;
   FLTSMP_SET_SAMPLE_PREFERENCE	set_sample_preference;

   HDIGDRIVER   dig;
   HPROVIDER	provider;
   HDRIVERSTATE driver_state;

   struct _FLTPROVIDER FAR *next;
}
FLTPROVIDER;

//
// 3D provider calls
//

DXDEC S32		AILCALL AIL_enumerate_3D_providers  (HPROENUM  FAR *next,
													  HPROVIDER FAR *dest,
													  C8  FAR * FAR *name);

DXDEC M3DRESULT  AILCALL AIL_open_3D_provider		(HPROVIDER lib);

DXDEC void	   AILCALL AIL_close_3D_provider	   (HPROVIDER lib);

DXDEC S32		AILCALL AIL_enumerate_3D_provider_attributes
													 (HPROVIDER				  lib,
													  HINTENUM FAR *			 next,
													  RIB_INTERFACE_ENTRY FAR *  dest);

DXDEC void	   AILCALL AIL_3D_provider_attribute   (HPROVIDER   lib,
													  C8 FAR *	name, 
													  void FAR *  val);

DXDEC void	   AILCALL AIL_set_3D_provider_preference(HPROVIDER   lib,
														C8 FAR *	name,
														void FAR *  val);

struct H3D
{
   H3DPOBJECT actual;
   HPROVIDER  owner;
   S32		user_data[8];
};

typedef struct _M3DPROVIDER
{
   PROVIDER_QUERY_ATTRIBUTE		PROVIDER_query_attribute;
   M3D_STARTUP					 startup;
   M3D_ERROR					   error;
   M3D_SHUTDOWN					shutdown;
   M3D_SET_PROVIDER_PREFERENCE	 set_provider_preference;
   M3D_ACTIVATE					activate;
   M3D_ALLOCATE_3D_SAMPLE_HANDLE   allocate_3D_sample_handle;
   M3D_RELEASE_3D_SAMPLE_HANDLE	release_3D_sample_handle;
   M3D_START_3D_SAMPLE			 start_3D_sample;
   M3D_STOP_3D_SAMPLE			  stop_3D_sample;
   M3D_RESUME_3D_SAMPLE			resume_3D_sample;
   M3D_END_3D_SAMPLE			   end_3D_sample;
   M3D_SET_3D_SAMPLE_DATA		  set_3D_sample_data;
   M3D_SET_3D_SAMPLE_VOLUME		set_3D_sample_volume;
   M3D_SET_3D_SAMPLE_PLAYBACK_RATE set_3D_sample_playback_rate;
   M3D_SET_3D_SAMPLE_OFFSET		set_3D_sample_offset;
   M3D_SET_3D_SAMPLE_LOOP_COUNT	set_3D_sample_loop_count;
   M3D_SET_3D_SAMPLE_LOOP_BLOCK	set_3D_sample_loop_block;
   M3D_3D_SAMPLE_STATUS			sample_status;
   M3D_3D_SAMPLE_VOLUME			sample_volume;
   M3D_3D_SAMPLE_PLAYBACK_RATE	 sample_playback_rate;
   M3D_3D_SAMPLE_OFFSET			sample_offset;
   M3D_3D_SAMPLE_LENGTH			sample_length;
   M3D_3D_SAMPLE_LOOP_COUNT		sample_loop_count;
   M3D_SET_3D_SAMPLE_DISTANCES	 set_3D_sample_distances;
   M3D_3D_SAMPLE_DISTANCES		 sample_distances;
   M3D_ACTIVE_3D_SAMPLE_COUNT	  active_3D_sample_count;
   M3D_3D_OPEN_LISTENER			open_listener;
   M3D_3D_CLOSE_LISTENER		   close_listener;
   M3D_3D_OPEN_OBJECT			  open_object;
   M3D_3D_CLOSE_OBJECT			 close_object;
   M3D_SET_3D_POSITION			 set_3D_position;
   M3D_SET_3D_VELOCITY			 set_3D_velocity;
   M3D_SET_3D_VELOCITY_VECTOR	  set_3D_velocity_vector;
   M3D_SET_3D_ORIENTATION		  set_3D_orientation;
   M3D_3D_POSITION				 position;
   M3D_3D_VELOCITY				 velocity;
   M3D_3D_ORIENTATION			  orientation;
   M3D_3D_UPDATE_POSITION		  update_position;
   M3D_3D_AUTO_UPDATE_POSITION	 auto_update_position;
   M3D_3D_SAMPLE_ATTRIBUTE		 sample_query_attribute;
   M3D_3D_SET_SAMPLE_PREFERENCE	set_sample_preference;
} M3DPROVIDER;

//
// Sample calls
//

DXDEC H3DSAMPLE  AILCALL AIL_allocate_3D_sample_handle
													 (HPROVIDER lib);


DXDEC void	   AILCALL AIL_release_3D_sample_handle
													 (H3DSAMPLE S);


DXDEC void	   AILCALL AIL_start_3D_sample		 (H3DSAMPLE S);


DXDEC void	   AILCALL AIL_stop_3D_sample		  (H3DSAMPLE S);


DXDEC void	   AILCALL AIL_resume_3D_sample		(H3DSAMPLE S);

DXDEC void	   AILCALL AIL_end_3D_sample		   (H3DSAMPLE S);

DXDEC S32		AILCALL AIL_set_3D_sample_file	  (H3DSAMPLE S,
													  void FAR *file_image);

DXDEC S32		AILCALL AIL_set_3D_sample_info	  (H3DSAMPLE		 S,
													  AILSOUNDINFO FAR *info);

DXDEC void	   AILCALL AIL_set_3D_sample_volume	(H3DSAMPLE S,
													  S32	   volume);

DXDEC void	   AILCALL AIL_set_3D_sample_offset	(H3DSAMPLE S,
													  U32	   offset);

DXDEC void	   AILCALL AIL_set_3D_sample_playback_rate
													 (H3DSAMPLE S,
													  S32	   playback_rate);

DXDEC void	   AILCALL AIL_set_3D_sample_loop_count(H3DSAMPLE S,
													  U32	   loops);

DXDEC void	   AILCALL AIL_set_3D_sample_loop_block(H3DSAMPLE S,
													  S32	   loop_start_offset,
													  S32	   loop_end_offset);

DXDEC U32		AILCALL AIL_3D_sample_status		(H3DSAMPLE S);

DXDEC S32		AILCALL AIL_3D_sample_volume		(H3DSAMPLE S);

DXDEC U32		AILCALL AIL_3D_sample_offset		(H3DSAMPLE S);

DXDEC S32		AILCALL AIL_3D_sample_playback_rate (H3DSAMPLE S);

DXDEC U32		AILCALL AIL_3D_sample_length		(H3DSAMPLE S);

DXDEC U32		AILCALL AIL_3D_sample_loop_count	(H3DSAMPLE S);

#define AIL_set_3D_sample_distances AIL_set_3D_sample_float_distances
#define AIL_3D_sample_distances AIL_3D_sample_float_distances

DXDEC void	   AILCALL AIL_set_3D_sample_float_distances
													 (H3DSAMPLE S,
													  F32	   max_front_dist,
													  F32	   min_front_dist,
													  F32	   max_back_dist,
													  F32	   min_back_dist);


DXDEC void	   AILCALL AIL_3D_sample_float_distances
													 (H3DSAMPLE S,
													  F32 FAR * max_front_dist,
													  F32 FAR * min_front_dist,
													  F32 FAR * max_back_dist,
													  F32 FAR * min_back_dist);

DXDEC  S32	  AILCALL AIL_active_3D_sample_count   (HPROVIDER lib);

DXDEC  S32	  AILCALL AIL_enumerate_3D_sample_attributes
													 (HPROVIDER				  lib,
													  HINTENUM FAR *			 next,
													  RIB_INTERFACE_ENTRY FAR *  dest);

DXDEC  void	 AILCALL AIL_3D_sample_attribute	  (H3DSAMPLE   samp,
													  C8 FAR *	name,
													  void FAR *  val);


DXDEC  void	 AILCALL AIL_set_3D_sample_preference (H3DSAMPLE   samp,
													  C8 FAR *	name,
													  void FAR *  val);

//
// Positioning-object allocation calls
//

DXDEC H3DPOBJECT AILCALL AIL_open_3D_listener		(HPROVIDER lib);

DXDEC void	   AILCALL AIL_close_3D_listener	   (H3DPOBJECT listener);

DXDEC H3DPOBJECT AILCALL AIL_open_3D_object		  (HPROVIDER lib);

DXDEC void	   AILCALL AIL_close_3D_object		 (H3DPOBJECT obj);

//
// 3D object calls
//

DXDEC void	   AILCALL AIL_set_3D_position		 (H3DPOBJECT obj,
													  F32	 X,
													  F32	 Y,
													  F32	 Z);

DXDEC void	   AILCALL AIL_set_3D_velocity		 (H3DPOBJECT obj,
													  F32	 dX_per_ms,
													  F32	 dY_per_ms,
													  F32	 dZ_per_ms,
													  F32	 magnitude);

DXDEC void	   AILCALL AIL_set_3D_velocity_vector  (H3DPOBJECT obj,
													  F32	 dX_per_ms,
													  F32	 dY_per_ms,
													  F32	 dZ_per_ms);

DXDEC void	   AILCALL AIL_set_3D_orientation	  (H3DPOBJECT obj,
													  F32	 X_face,
													  F32	 Y_face,
													  F32	 Z_face,
													  F32	 X_up,
													  F32	 Y_up,
													  F32	 Z_up);

DXDEC void	   AILCALL AIL_3D_position			 (H3DPOBJECT  obj,
													  F32 FAR *X,
													  F32 FAR *Y,
													  F32 FAR *Z);

DXDEC void	   AILCALL AIL_3D_velocity			 (H3DPOBJECT  obj,
													  F32 FAR *dX_per_ms,
													  F32 FAR *dY_per_ms,
													  F32 FAR *dZ_per_ms);

DXDEC void	   AILCALL AIL_3D_orientation		  (H3DPOBJECT  obj,
													  F32 FAR *X_face,
													  F32 FAR *Y_face,
													  F32 FAR *Z_face,
													  F32 FAR *X_up,
													  F32 FAR *Y_up,
													  F32 FAR *Z_up);

DXDEC void	   AILCALL AIL_3D_update_position	  (H3DPOBJECT obj,
													  F32	 dt_milliseconds);

DXDEC void	   AILCALL AIL_3D_auto_update_position (H3DPOBJECT obj,
													  S32		enable);

DXDEC  void	 AILCALL AIL_set_3D_user_data		 (H3DPOBJECT obj,
													  U32		index,
													  S32		value);

DXDEC  S32	  AILCALL AIL_3D_user_data			 (H3DPOBJECT obj,
													  U32		index);

// Obsolete 3D function names:
#define AIL_set_3D_object_user_data AIL_set_3D_user_data
#define AIL_3D_object_user_data AIL_3D_user_data
#define AIL_3D_open_listener AIL_open_3D_listener
#define AIL_3D_close_listener AIL_close_3D_listener
#define AIL_3D_open_object AIL_open_3D_object
#define AIL_3D_close_object AIL_close_3D_object

//
// enumerated values for EAX
//

#ifndef EAX_H_INCLUDED

enum
{
	EAX_ENVIRONMENT_GENERIC,				// factory default
	EAX_ENVIRONMENT_PADDEDCELL,
	EAX_ENVIRONMENT_ROOM,			  // standard environments
	EAX_ENVIRONMENT_BATHROOM,
	EAX_ENVIRONMENT_LIVINGROOM,
	EAX_ENVIRONMENT_STONEROOM,
	EAX_ENVIRONMENT_AUDITORIUM,
	EAX_ENVIRONMENT_CONCERTHALL,
	EAX_ENVIRONMENT_CAVE,
	EAX_ENVIRONMENT_ARENA,
	EAX_ENVIRONMENT_HANGAR,
	EAX_ENVIRONMENT_CARPETEDHALLWAY,
	EAX_ENVIRONMENT_HALLWAY,
	EAX_ENVIRONMENT_STONECORRIDOR,
	EAX_ENVIRONMENT_ALLEY,
	EAX_ENVIRONMENT_FOREST,
	EAX_ENVIRONMENT_CITY,
	EAX_ENVIRONMENT_MOUNTAINS,
	EAX_ENVIRONMENT_QUARRY,
	EAX_ENVIRONMENT_PLAIN,
	EAX_ENVIRONMENT_PARKINGLOT,
	EAX_ENVIRONMENT_SEWERPIPE,
	EAX_ENVIRONMENT_UNDERWATER,
	EAX_ENVIRONMENT_DRUGGED,
	EAX_ENVIRONMENT_DIZZY,
	EAX_ENVIRONMENT_PSYCHOTIC,

	EAX_ENVIRONMENT_COUNT		   // total number of environments
};

#define EAX_REVERBMIX_USEDISTANCE (-1.0F)

#endif

#else

typedef struct _FLTPROVIDER
{
  U32 junk;
} FLTPROVIDER;

#endif

#ifdef __cplusplus
}
#endif


#ifdef _PUSHPOP_SUPPORTED
  #pragma pack(pop)
#else
  #pragma pack()
#endif


#endif
