/* SCCSID = "src/dev/usb/USBAUDIO/AUDIODAT.C, usb, c.basedd 98/07/10" */
/*
*   Licensed Material -- Property of IBM
*
*   (c) Copyright IBM Corp. 1998  All Rights Reserved
*/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  AUDIODAT.C                                            */
/*                                                                            */
/*   DESCRIPTIVE NAME: Audio device driver GLOBAL data                        */
/*                                                                            */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS: N/A                                                        */
/*                                                                            */
/*   EXTERNAL REFERENCES:	None  										               */
/*				                                                                  */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer          Comment                             */
/*  ----    --------  ----------          -------                             */
/*          98/10/17  Vjacheslav Chibis   Original developer.                 */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/



#define         INCL_NOPMAPI
#define         INCL_DOS
#define         INCL_DOSDEVICES
#define         INCL_ERRORS


/****************************************************************************/
/*                      D A T A                                             */
/****************************************************************************/


#define DEV_CAPS 0x00000000

/*************************************************************************/
/* Device driver header.                                                 */
/*************************************************************************/



#include        "usbaud.h"


PSZ    gVMessages[]={ "IUSBAUDIO.SYS: USB Audio Device Class Driver v.%dd.%dd loaded",
       "EUSBAUDIO.SYS: USBD Driver not found",
       "EUSBAUDIO.SYS: Invalid numeric value in CONFIG.SYS line at column %dddd",
       "EUSBAUDIO.SYS: Invalid parameter in CONFIG.SYS line at column %dddd"
       };

PUSBIDCEntry   gpUSBDIDC = NULL;  // USB Driver IDC routine entry point
USHORT         gUSBDds = 0;  // USB Driver DS value
CHAR           gUSBDName[9] = "USBD$   ";  // USB Driver name
IDCTABLE       gDDTable =  { { 0, 0, 0 }, 0, 0 };
UCHAR          gAltInterface = 0;  // Active Alternative interfcae value 
USHORT         gNoOfActiveAudioDevices = 0; // number of attached USB audio devices

AudioDevice gAudioDevices[MAX_AUDIO_DEVICES];   // active device list served by USBAUDIO


VOID FAR *DevHlp;  // devhlp entry

GLOBAL  GlobalTable = {NULL,  //    paStream dynamically allocated
   (DWORD) NULL,              //    driver inited
   DEFAULTSTREAMS,            //    number of streams
   0xFF,                      //    ucActiveDeviceIndex
   TRUE,                      //    bFirstEntry
   FALSE                      //    bRegistered
};  

PFN      Device_Help    = NULL;  // devhelp entry point; used by dhcalls.lib //
BOOL gStartReject=FALSE;



PROTOCOLTABLE ProtocolTable[NPROTOCOLS] =
{ //  ulDataType           ulDataSubType   ulBufSize ulNumBufs  ulSampleRate usChannels   usBitsPerSample
   { DATATYPE_MIDI,     SUBTYPE_NONE,        512L,  3, 0,     0, 0},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_8M08, 4*1024L,  4, 8000,  1, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_8S08, 4*1024L,  4, 8000,  2, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_8M16, 4*1024L,  4, 8000,  1, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_8S16, 4*1024L,  4, 8000,  2, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_1M08, 4*1024L,  3, 11025, 1, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_1S08, 8*1024L,  3, 11025, 2, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_1M16, 8*1024L,  4, 11025, 1, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_1S16, 16*1024L, 4, 11025, 2, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_2M08, 8*1024L,  3, 22050, 1, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_2S08, 16*1024L, 4, 22050, 2, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_2M16, 16*1024L, 4, 22050, 1, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_2S16, 32*1024L, 4, 22050, 2, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_4M08, 16*1024L, 4, 44100, 1, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_4S08, 32*1024L, 4, 44100, 2, 8},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_4M16, 32*1024L, 4, 44100, 1, 16},
   { DATATYPE_WAVEFORM, WAVE_FORMAT_4S16, 60*1024L, 6, 44100, 2, 16},
   { DATATYPE_MULAW,    MULAW_8B8KS,      60*1024L, 6, 8000,  2, 8},  /* 8k 8b Mu-Law   */
   { DATATYPE_MULAW,    MULAW_8B11KS,     60*1024L, 6, 11025, 2, 8},  /* 11K            */
   { DATATYPE_MULAW,    MULAW_8B22KS,     60*1024L, 6, 22050, 2, 8},  /* 22k 8b Mu-Law  */
   { DATATYPE_MULAW,    MULAW_8B44KS,     60*1024L, 6, 44100, 2, 8},  /* 44k 8b Mu-Law  */
   { DATATYPE_ALAW,     ALAW_8B8KS,       60*1024L, 6, 8000,  2, 8},  /* 8k 8b Mu-Law   */
   { DATATYPE_ALAW,     ALAW_8B11KS,      60*1024L, 6, 11025, 2, 8},  /* 11k 8b Mu-Law  */
   { DATATYPE_ALAW,     ALAW_8B22KS,      60*1024L, 6, 22050, 2, 8},  /* 22k 8b Mu-Law  */
   { DATATYPE_ALAW,     ALAW_8B44KS,      60*1024L, 6, 44100, 2, 8}  /* 44k 8b Mu-Law  */
};



RC (*gAudioIOCTLFuncs[])(PREQPACKET pRP) =
{
   Audio_IOCTL_Init,            // 0
   Audio_IOCTL_Status,          // 1
   Audio_IOCTL_Control,         // 2
   Audio_IOCTL_Buffer,          // 3
   Audio_IOCTL_Load,            // 4
   Audio_IOCTL_Wait,            // 5
   Audio_IOCTL_Hpi,             // 6
   Audio_IOCTL_Update,          // 7
   Audio_IOCTL_Capability       // 8
};

USHORT  gMaxAudioIOCTLFuncs = sizeof(gAudioIOCTLFuncs)/sizeof(USHORT);  

//*******************************************************
// IOCTL jump table                                     *
// Request packet function jump table                   *
//*******************************************************
RC   (*gIOCTLFuncs[])(PREQPACKET rp) = 
{
   IOCTL_Init,     // 0x00
   IOCTL_Invalid,  // 0x01
   IOCTL_Invalid,  // 0x02
   IOCTL_Invalid,  // 0x03
   IOCTL_Invalid,  // 0x04
   IOCTL_Invalid,  // 0x05
   IOCTL_Invalid,  // 0x06
   IOCTL_Invalid,  // 0x07
   IOCTL_Invalid,  // 0x08
   IOCTL_Invalid,  // 0x09
   IOCTL_Invalid,  // 0x0A
   IOCTL_Invalid,  // 0x0B
   IOCTL_Invalid,  // 0x0C
   IOCTL_Open,     // 0x0D
   IOCTL_Close,    // 0x0E
   IOCTL_Invalid,  // 0x0F
   IOCTL_GenIOCtl, // 0x10
   IOCTL_Invalid,  // 0x11  reset uncertain media          */
   IOCTL_Invalid,  /* 0x12  get Logical Drive Map          */
   IOCTL_Invalid,  /* 0x13  set Logical Drive Map          */
   IOCTL_Invalid,  /* 0x14  de-Install this device         */
   IOCTL_Invalid,  /* 0x15  reserved                       */
   IOCTL_Invalid,  /* 0x16  get number of partitions       */
   IOCTL_Invalid,  /* 0x17  get unit map                   */
   IOCTL_Invalid,  /* 0x18  no caching read                */
   IOCTL_Invalid,  /* 0x19  no caching write               */
   IOCTL_Invalid,  /* 0x1A  no caching write/verify        */
   IOCTL_Invalid,  /* 0x1B  initialize device driver       */
   IOCTL_Invalid,  /* 0x1C  reserved for Request List code */
   IOCTL_Invalid,  /* 0x1D  get driver capabilities        */
   IOCTL_Invalid,  /* 0x1E  reserved                       */
   IOCTL_InitComplete /* 0x1F  initialization complete     */
};
USHORT  gMaxIOCTLFuncs = sizeof(gIOCTLFuncs)/sizeof(USHORT);



ULONG gFlags=0;

UCHAR guch;
CHAR  gch;


ULONG gPCMTable[NUMFREQS][BPSTYPES][MONOSTEREO] = {
   WAVE_FORMAT_1M08,    /* 11.025kHz, 8-bit  Mono   */
   WAVE_FORMAT_1S08,    /* 11.025kHz, 8-bit  Stereo */
   WAVE_FORMAT_1M16,    /* 11.025kHz, 16-bit Mono   */
   WAVE_FORMAT_1S16,    /* 11.025kHz, 16-bit Stereo */
   WAVE_FORMAT_2M08,    /* 22.05kHz , 8-bit  Mono   */
   WAVE_FORMAT_2S08,    /* 22.05kHz , 8-bit  Stereo */
   WAVE_FORMAT_2M16,    /* 22.05kHz , 16-bit Mono   */
   WAVE_FORMAT_2S16,    /* 22.05kHz , 16-bit Stereo */
   WAVE_FORMAT_4M08,    /* 44.1kHz  , 8-bit  Mono   */
   WAVE_FORMAT_4S08,    /* 44.1kHz  , 8-bit  Stereo */
   WAVE_FORMAT_4M16,    /* 44.1kHz  , 16-bit Mono   */
   WAVE_FORMAT_4S16,    /* 44.1kHz  , 16-bit Stereo */
   WAVE_FORMAT_8M08,    /*  8.0kHz  , 8-bit  Mono   */
   WAVE_FORMAT_8S08,    /*  8.0kHz  , 8-bit  Stereo */
   WAVE_FORMAT_8M16,    /*  8.0kHz  , 16-bit Mono   */
   WAVE_FORMAT_8S16     /*  8.0kHz  , 16-bit Stereo */
};

/* The following 2-D array defines the subtypes for DATATYPE_ALAW */
ULONG gALaw[NUMFREQS][MONOSTEREO] = {
   ALAW_8B11KM,      /* 8bit 11kHz mono*/
   ALAW_8B11KS,      /* 8bit 11kHz stereo*/
   ALAW_8B22KM,      /* 8bit 22kHz mono*/
   ALAW_8B22KS,      /* 8bit 22kHz stereo*/
   ALAW_8B44KM,      /* 8bit 44kHz mono*/
   ALAW_8B44KS,      /* 8bit 44kHz stereo*/
   ALAW_8B8KM ,      /* 8bit 8kHz mono*/
   ALAW_8B8KS        /* 8bit 8kHz stereo*/
};

/* the following 2-D array defines the subtypes for DATATYPE_MULAW */
ULONG gMuLaw[NUMFREQS][MONOSTEREO] = {
   MULAW_8B11KM,     /* 8bit 11kHz mono*/
   MULAW_8B11KS,     /* 8bit 11kHz stereo*/
   MULAW_8B22KM,     /* 8bit 22kHz mono*/
   MULAW_8B22KS,     /* 8bit 22kHz stereo*/
   MULAW_8B44KM,     /* 8bit 44kHz mono*/
   MULAW_8B44KS,     /* 8bit 44kHz stereo*/
   MULAW_8B8KM ,     /* 8bit 8kHz mono*/
   MULAW_8B8KS       /* 8bit 8kHz stereo*/
};


#ifdef   DEBUG
USHORT         gAMsg=0x0;       // debug message level
#endif

SetupPacket gSetupPacket[MAX_SETUP_PACKETS];
SetupPacket gReadSetupPacket[MAX_READ_SETUP_PACKETS];
UCHAR   gSPIdx = 0;
UCHAR   gReadSPIdx = 0;
BOOL    gbTimerIntHooked = FALSE;

USHORT   gNumOfOpens;
ULONG    gRBHandle;

USHORT  gTicks;

USHORT   usInUse = AVAILABLE;    // device ready flag
ULONG    ulActiveSysFileNum;     // the current active instance file num
USHORT   usGDT[NUMGDTS];         // array of GDTs to allocate
USHORT   usNumOS2Opens;          // Number of OS2 processes that opened driver
ULONG trk; // device track #            


// OS/2 MCI Audio change data structures
MCI_AUDIO_CHANGE  gAC;
MCI_AUDIO_CHANGE  gOLDAC;
MCI_AUDIO_CHANGE  FAR *gpRP_AC;

USB_AUDIO_CHANGE gUSBAC;
USBDetach gDetachData;

RP_GENIOCTL gRP;  // IOCTL request packet
PRP_GENIOCTL gpRP; // ptr to IOCTL request packet

BOOL gbISOOpened=FALSE;

ULONG    gulSamplingFreq;  // active stream sampling freq
ULONG    gulBitsPerSample; // active stream bits per sample values
USHORT   gusChannels;   // active stream data format channnels number

USBSetConf gSC;   // set configuration data structure 
SetupPacket gsp ; 

/*****************************************************************************/

ATTACHAREA   AttachArea;
SZ      szDevName[9];                   /* null terminated */

PSTREAM  pStreamVirt;  // saved at InitStreams()          
ULONG gSupp;
EVENT_QUEUE aEventQueue[DEFAULTSTREAMS][MAX_EVENT_QUEUE]; // events queue
BOOL   gbActiveDeviceSupport=FALSE; // shows if the active device can suppport current stream data format
BOOL   gbByPassBuffer=FALSE; // shows if we have to bypass playback of buffer
                             

USHORT        gVerbose = 0; //Verbose parameter



USHORT            gMessageIDs[MAX_INIT_MESSAGE_COUNT];//verbose messages
USHORT            gMessageCount = 0;//verbose messages counter

// Verbose messages //
#define MSG_REPLACEMENT_STRING  1178
MSGTABLE  gInitMsg = { MSG_REPLACEMENT_STRING, 1, 0 };	//	structure used to write out message during initialization
