MMPM/2 Device Driver Reference:Vendor-Specific Driver Commands

The vendor-specific driver (VSD) commands enable communication between vendor-specific drivers (VSDs) and an application such as the user-level audio stream handler or amplifier mixer MCI driver. The interface to the VSD is DLL-based. First, a DosLoadModule function is issued for the VSD's DLL. The DosLoadModule function returns a handle for the VSD. Next, using the VSD handle, DosQueryProcAddr is issued to receive the VSD entry point address. This must be done prior to issuing any VSD commands. Once the entry point address is received, calls to the VSD are made to VSDEntry entry point.

VSDEntry
This entry point enables communication between vendor-specific drivers (VSDs) and an application such as the user-level audio stream handler or amplifier mixer. For audio VSDs, be sure to define INCL_AUDIO_VSD before including the VSDCMDS.H header file.
 * 1) define INCL_AUDIO_VSD
 * 2) include 
 * 3) include 

HVSD    hvsd;      /*  Handle to VSD instance. */ ULONG   ulFunc;    /*  Function code. */ ULONG   ulFlags;   /*  Flags for driver. */ PVOID   pRequest;  /*  Request parameter block value. */ ULONG   rc;        /*  Return codes. */

rc = VSDEntry(hvsd, ulFunc, ulFlags, pRequest);

Parameters

 * hvsd (HVSD) - input:This parameter is the handle to the VSD instance.
 * ulFunc (ULONG) - input:The VSD command to be issued. The following commands are supported for audio VSDs.
 * ulFlags (ULONG) - input:The ulFlags parameter is used to further qualify the command specified in ulFunc. In many cases it is used as a subcommand. For more information on ulFlags, see the specific ulFunc parameter.
 * pRequest (PVOID) - input:Specifies the pointer to the request packet. The caller of the VSD supplies all request buffers. See individual commands for more detailed information.

Return Value

 * rc (ULONG) - returns:The return codes are listed for each command and will vary based on the command sent.

If a VSD requires unique return codes for certain conditions, it can use return codes starting at VSDERR_BASE.

Remarks
If a VSD requires unique return codes for certain conditions, it can use return codes starting at VSDERR_BASE.

VSD_CLOSE
This command closes the device. VSD_CLOSE is a required command and must be implemented by all VSD writers.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters

 * hvsd (HVSD):Handle to the VSD to be closed.
 * ulFunc (ULONG):Set to VSD_CLOSE.
 * ulFlags (ULONG):No flags used for this command.
 * pRequest (PVOID):Not used for this command.

Return Value

 * rc (ULONG):Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_CANNOT_CLOSE
 * VSD is unable to close the device.


 * VSDERR_HARDWARE
 * A hardware error occurred.

Remarks
The hvsd handle is no longer valid after this command is issued.

Example Code
The following code illustrates how to close a VSD.

VSD_DDCMD
Stream handlers can communicate to their attached devices using the VSD_ DDCMD call. The DDCMD interface is the primary method of moving data to and from devices in OS/2 multimedia. See the OS/2 Multimedia Programming Reference for more detailed information on stream handler command (SHC) messages.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters

 * hvsd (HVSD):Handle to a VSD.
 * ulFunc (ULONG):Set to VSD_DDCMD.
 * ulFlags (ULONG):The following flags (subcommands) are defined for this command:
 * DDCMD_CONTROL :This subcommand of VSD_DDCMD performs a device-specific command. pRequest is a pointer to the DDCMDCONTROL structure.
 * DDCMD_DEREG_STREAM :This subcommand of VSD_DDCMD deregisters a stream instance with the device driver. pRequest is a pointer to DDCMDDEREGISTER structure.
 * DDCMD_READ :This subcommand of VSD_DDCMD is used by a stream handler to give an empty buffer to the VSD (for example, during a record operation). When the buffer has been filled, the VSD is responsible for communicating to the caller that the buffer has been filled. The VSD should pass a MSG_REPORTINT structure to the pSHDEntryPoint in DDCMDREGISTER to inform the caller.
 * pRequest is a pointer to DDCMDREADWRITE structure.


 * DDCMD_REG_STREAM :This subcommand of VSD_DDCMD registers a stream instance with the device driver. pRequest is a pointer to DDCMDREGISTER structure.


 * DDCMD_SETUP :This subcommand of VSD_DDCMD performs device-specific stream instance setup. pRequest is a pointer to DDCMDSETUP structure.


 * DDCMD_STATUS :This VSD subcommand requests streaming status from a device. Typically, it is called to request the current stream time. pRequest is a pointer to DDCMDSTATUS structure.


 * DDCMD_WRITE :This VSD subcommand is used by a stream handler to give a full buffer to the VSD (for example, during a playback operation). When the buffer has been consumed, the VSD is responsible for communicating to the caller that the buffer has been used. The VSD should pass a MSG_REPORTINT structure to the pSHDEntryPoint in DDCMDREGISTER to inform the caller.


 * pRequest is a pointer to DDCMDREADWRITE structure.


 * pRequest (PVOID):The value of pRequest varies according to the ulFlags value. See each particular ulFlags value for the definition of pRequest.

Return Value

 * rc (ULONG):Possible error codes vary according to the value of ulFlags.

Remarks
A user-level 32-bit buffer pointer is available in the pProcessLin field of the DDCMDREADWRITE. VSDs should use this pointer if they want to operate on the data while they are not in protect mode. The pBuffer field of the DDCMDREADWRITE contains a pointer whose address type was specified by the VSD on DDCMD_REG_STREAM. When the application returns a buffer, it must return the buffer specified by pBuffer and not by pProcessLin.

VSD_GETDEVCAPS
This command queries the device capabilities. These values should be constants that describe the device and driver characteristics. In general, the flags indicate what set of commands are supported. VSD_GETDEVCAPS is a required command and must be implemented by all VSD writers.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters

 * hvsd (HVSD):Handle to a VSD.
 * ulFunc (ULONG):Set to VSD_GETDEVCAPS.
 * ulFlags (ULONG):No flags used for this command.
 * pRequest (PVSD_GETDEVCAPS_PARMS):Pointer to the VSD_GETDEVCAPS_PARMS data structure.

Return Value

 * rc (ULONG):Error code indicating success or the type of failure:
 * VSDERR_REQUEST_BUF_TOO_SMALL
 * The ulLength in the request packet is too small.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.


 * VSDERR_HARDWARE
 * A hardware error occurred.

Remarks
This command requires the device to be opened. A device might have several types of device units, so this command must know which instance is involved. Once the device is opened, the device capabilities should be constant.

Each element in the bSupports[DC_MAX_DEVCAP] array of the VSD_GETDEVCAPS_ PARMS structure is a boolean value that indicates if the capability is supported. TRUE indicates that it is supported. FALSE indicates that it is not supported.

Example Code
The following code illustrates how to determine device capabilities for a VSD. HVSD                  hvsd; VSD_GETDEVCAPS_PARMS  vsdDevCaps;

rc = pInstance->pfnAUDIOIF( hvsd,                             VSD_GETDEVCAPS                              0,                              (PVOID) &vsdDevCaps );

if (!rc) {   /* If the VSD doesn't support volume  */

if( !vsdDevCaps.bSupports[ DC_HASVOLUME] ) {      return ( rc ); }

VSD_ESCAPE
This optional command sends a buffer to the driver.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_ESCAPE.

ulFlags (ULONG) No flags used for this command.

pRequest (PVSD_ESCAPE_PARMS) A pointer to the VSD_ESCAPE_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

VSD_INSERTSETTINGSPAGE
This command enables a VSD to insert device-specific settings pages into the system configuration application.

Parameters
hvsd (HVSD) Handle to a VSD instance.

ulFunc (ULONG) Set to VSD_INSERTSETTINGSPAGE.

ulFlags (ULONG) No flags used for this command.

pRequest (PMCI_DEVICESETTINGS_PARMS) Pointer to the MCI_DEVICESETTINGS_PARMS data structure.

Return Value
hwndRC (HWND) The return code contains the handle to a settings page or zero if no page is inserted.

VSD_OPEN
This command opens the device driver and returns a VSD handle or (HVSD). It should not allocate resources on the device (resource usage should be performed on the VSD restore).

VSD_OPEN is a required command and must be implemented by all VSD writers.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Not used.

ulFunc (ULONG) Set to VSD_OPEN.

ulFlags (ULONG) No flags used for this command.

pRequest (PVSD_OPEN_PARMS) Pointer to the VSD_OPEN_PARMS data structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * Command completed successfully.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.


 * VSDERR_NO_DEVICE_DRIVER
 * VSD is not connected to a device driver.


 * VSDERR_DEVICE_REJECTED
 * Device driver rejected the request.


 * VSDERR_HARDWARE
 * A hardware error occurred.


 * VSDERR_INVALID_BUFF
 * pRequest is not valid.

Remarks
The installation name of the media control driver (MCD) is passed in so that the VSD can query device-specific parameters from the INI file.

For an audio VSD, the pDevInfo pointer points to a VSD_AUDIOOPEN_PARMS structure. This structure contains enough information to initialize the audio device. The VSD is responsible for filling in the ulDataSubType field of the VSD_AUDIOOPEN_PARMS structure with a valid data subtype.

Example Code
The following code illustrates how to open an audio VSD. VSD_OPEN_PARMS       vsdOpenParms; VSD_AUDIOOPEN_PARMS  vsdData;

vsdData.ulLength = sizeof(VSD_AUDIOOPEN_PARMS); vsdData.ulFlags = 0; vsdData.ulSamplingRate      = pInstance->lSRate; vsdData.ulBitsPerSample     = pInstance->lBitsPerSRate; vsdData.ulChannels          = pInstance->sChannels; vsdData.ulDataType          = pInstance->sMode; vsdData.ulDeviceID          = pInstance->ulDeviceID; vsdData.ulOperation         = pInstance->ulOperation; vsdOpenParms.pDevInfo = (PVOID)&vsdData;

vsdOpenParms.ulLength = sizeof(VSD_OPEN_PARMS); memmove(&vsdOpenParms.szPDDName,            pInstance->szDeviceName,             strlen(pInstance->szDeviceName)); /* Open the audio VSD */ rc = pInstance->pfnAUDIOIF(0,                               VSD_OPEN,                                0L                                (PVOID)&vsdOpenParms); if (!rc) }       pInstance->hvsd = vsdOpenParms.hvsd; {

VSD_QUERY
This command allows an application to query the status of the VSD.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) The following flags can be used with VSD_QUERY:
 * VSD_QUERYAUDIOATTRIBUTES See VSD_QUERYAUDIOATTRIBUTES.
 * VSD_QUERYCONNECTOR See VSD_QUERYCONNECTOR.
 * VSD_QUERYDATATYPE See VSD_QUERYDATATYPE.
 * VSD_QUERYMONITOR See VSD_QUERYMONITOR.
 * VSD_QUERYVOLUME See VSD_QUERYVOLUME.
 * VSD_QUERYMIXCONNECTIONS See VSD_QUERYMIXCONNECTIONS.
 * VSD_QUERYMIXCONTROL See VSD_QUERYMIXCONTROL.
 * VSD_QUERYMIXLINE See VSD_QUERYMIXLINE.

pRequest (PVOID) Pointer varies according to ulFlags.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * Command completed successfully.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

Remarks
This command uses flags to indicate what information is queried.

VSD_QUERYAUDIOATTRIBUTES
This subcommand of the VSD_QUERY command queries the current audio settings and capabilities. A valid length must be placed in the ulLength field of the VSD_AUDIOATTRIBUTES_PARMS structure and the audio setting (such as treble, bass, and so on) must be placed in the ulFlags field of the VSD_ AUDIOATTRIBUTES_PARMS structure.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYAUDIOATTRIBUTES.

pRequest (PVSD_AUDIOATTRIBUTES_PARMS) Pointer to the VSD_AUDIOATTRIBUTES_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

Remarks
All values are returned in the ulValue field and can range from 0 - 100.

Example Code
The following code illustrates how to query audio attribute information from the VSD. HVSD                       hvsd; VSD_AUDIOATTRIBUTES_PARMS  vsdAttr;

/* Prime the structure with necessary values */ vsdAttr.ulLength = sizeof (VSD_AUDIOATTRIBUTES_PARMS); vsdAttr.ulFlags = VSD_BASS;

/*-    * Ask the VSD to either set or query an audio * attribute. The caller determines whether * to set or query via the command variable. *-*/

rc = pInstance->pfnAUDIOIF(hvsd,                               VSD_QUERY,                                VSD_QUERYAUDIOATTRIBUTES,                                (PVOID)&vsdAttr);

/* If Bass value is too high then...*/ if (!rc) {      if (vsdAttr.ulValue > 70) {      }

VSD_QUERYCONNECTOR
This subcommand of the VSD_QUERY command queries the state of the connector. (A connector can be a hardware or software connection on the device the VSD is controlling.) If the connector is enabled, the fEnabled field of the VSD_CONNECTOR_PARMS structure will contain MCI_TRUE, otherwise it will contain MCI_FALSE. For further information regarding connectors, refer to the MCI connector command in the OS/2 Multimedia Programming Reference. Valid connectors can be found in MCIOS2.H.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYCONNECTOR.

pRequest (PVSD_CONNECTOR_PARMS) A pointer to the VSD_CONNECTOR_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_UNSUPPORTED_CONN_TYPE
 * Connector type not supported.


 * VSDERR_INVALID_CONNECTOR_TYPE
 * Invalid connector type.


 * VSDERR_INVALID_CONNECTOR_INDEX
 * Invalid connector index.


 * VSDERR_CANNOT_MODIFY_CONNECTOR
 * Cannot enable or disable this connector.


 * VSDERR_INVALID_CONNECTOR
 * Invalid connector.


 * VSDERR_UNSUPPORTED_CONNECTOR
 * Unsupported connector.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

Example Code
The following code illustrates how to query the state of the connector. HVSD                  hvsd; VSD_CONNECTOR_PARMS   vsdConn;

vsdConn.ulConn_Type = pConnector->ulConnectorType; vsdConn.ulIndex = pConnector->ulConnectorIndex;

lError = pInstance->pfnNewVSD(hvsd,                                 VSD_QUERY,                                  VSD_QUERYCONNECTOR,                                  (PVOID)&vsdConn);

prConnector->ulReturn = vsdConn.fEnabled;

VSD_QUERYDATATYPE
This subcommand of the VSD_QUERY command queries if a particular set of data types are supported. The ulSamplingRate, ulBitsPerSample, ulChannels, and ulDataType will be filled in on input. The ulDataSubType is filled in by the VSD on output. If the current mode is not supported, the VSD should fill in the ulSamplingRate, ulBitsPerSample, and ulChannels with the closest that it supports.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYDATATYPE.

pRequest (PVSD_AUDIODATATYPE_PARMS) Pointer to the VSD_AUDIODATATYPE_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

Remarks
This command is typically sent by applications which need to determine if the VSD supports a particular datatype.

Example Code
The following code illustrates the use of VSD_QUERYDATATYPE: HVSD                      hvsd; VSD_AUDIODATATYPE_PARMS   AudioCaps;

/*---  * Tell the VSD that we want to enable a   * connector. *---*/  rc =  pInstance->pfnNewVSD( hvsd,                               VSD_QUERY,                               VSD_QUERYDATATYPE,                               (PVOID ) &AudioCaps );

if ( rc ) {       rc = MCIERR_INVALID_CONNECTION ; return (rc); }  else {     rc = MCIERR_SUCCESS; }

return ( rc );

} /* TestConnection */

VSD_QUERYMIXCONNECTIONS
This subcommand of the VSD_QUERY command queries the output that a particular VSD line (or connector) is routed to. For further information about VSD mixer support and functions, see Audio Sample for Vendor-Specific Drivers and Mixer IOCtl Functions Introduction

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYMIXCONNECTIONS.

pRequest (PLINECONNECTIONS) A pointer to the LINECONNECTIONS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.


 * VSDERR_INVALID_SOURCE
 * Invalid source.


 * VSDERR_INVALID_SINK
 * Invalid sink.


 * VSDERR_INVALID_CONNECTION
 * Invalid connection.

Remarks
The ulConnections field of the LINECONNECTIONS structure returns the particular output that a line is routed to. The ulLine field of the LINECONNECTIONS structure must contain a valid line on input. For more information on the values for ulLine and ulConnections, see the LINECONNECTIONS structure.

Example Code
The following code illustrates how to query the output that a particular line is routed to. HVSD             hvsd; LINECONNECTIONS  LineCon;

/* Find out the setting for the synth. */

LineCon.ulLine = SOURCE_SYNTHESIZER;

LineCon.ulLength = sizeof(MIXERLINEINFO); /* Ask VSD for the capabilities of this line. */

rc = pInstance->(hvsd,                  VSD_QUERY,                   VSD_QUERYMIXCONNECTIONS,                   (PVOID)&LineCon);

/* Are we connected to the amp or record outputs... */

if (LineCon.ulConnection & (SINK_SPEAKERS)) {    pMixParms->ulReturn = MCI_OUTPUT_AMP; } else {    pMixParms->ulReturn = MCI_OUTPUT_DIGITALAUDIO; }

VSD_QUERYMIXCONTROL
This subcommand of the VSD_QUERY command queries the audio attributes for an audio VSD connector (for example, the treble setting on a microphone connector). For further information about VSD mixer support and functions, see Audio Sample for Vendor-Specific Drivers and Mixer IOCtl Functions Introduction

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYMIXCONTROL.

pRequest (PMIXERCONTROL) A pointer to the MIXERCONTROL structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.


 * VSDERR_INVALID_SOURCE
 * Invalid source.


 * VSDERR_INVALID_SINK
 * Invalid sink.


 * VSDERR_INVALID_CONNECTION
 * Invalid connection.

Remarks
The ulLine field of the MIXERCONTROL structure must be filled in with one of the VSD sources/sinks in the low-order byte of the low word.

The ulControl field of the MIXERCONTROL structure must be filled in with the desired setting. For stereo controls, the high-order word of this field contains the left channel setting and the low-order word contains the right channel setting. A value of 0xFFFF represents full intensity and a value of 0x0000 is full cutout.

Example Code
The following code illustrates how to query the settings of audio attributes for a particular connector. HVSD          hvsd; MIXERCONTROL  MixerControl; USHORT        usBass;

/* Find out the setting for the synth. */

MixerControl.ulLine = SOURCE_SYNTHESIZER;

/* Ask VSD what is the current setting of the connector. */

MixerControl.ulControl = MIX_BASS; rc = pInstance->(hvsd,                  VSD_QUERY,                   VSD_QUERYMIXCONTROL,                   (PVOID)&MixerControl);

usBass = (MixControl.ulSetting)

}

VSD_QUERYMIXLINE
This subcommand of the VSD_QUERY command queries the audio attributes that are supported for the given VSD connector. For further information about VSD mixer support and functions, see Audio Sample for Vendor-Specific Drivers and Mixer IOCtl Functions Introduction

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYMIXLINE.

pRequest (PMIXERLINEINFO) A pointer to the MIXERLINEINFO structure. The ulSupport field will be filled by the VSD with the supported setting or settings if the line supports multiple settings. The ulLine field must be filled in by the caller.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_INVALID_SOURCE
 * Invalid source.


 * VSDERR_INVALID_SINK
 * Invalid sink.


 * VSDERR_INVALID_CONNECTION
 * Invalid connection.

Example Code
The following code illustrates how to query the supported audio attributes from a mixer connector. HVSD              hvsd; MIXERLINEINFO     mixerinfo; mixerinfo.ulLine = SYNTHESIZER_INPUT; mixerinfo.ulLength = sizeof(MIXERLINEINFO); rc = pInstance->pfnAUDIOIF( hsvd,                                 VSD_QUERY,                                  VSD_QUERYMIXLINE,                                  (PVOID) &mixerinfo);

if(!rc) if(mixerinfo.ulSupport & MIX_VOLUME) {         /* process volume */ }

} /* If no errors */

VSD_QUERYMONITOR
This subcommand of the VSD_QUERY command queries the device to determine if audio monitoring is enabled. The VSD returns TRUE if the monitor is enabled and FALSE if it is disabled.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD instance.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYMONITOR.

pRequest (PULONG) Output.

Return Value
rc (ULONG) VSD returns TRUE if the monitor is enabled and FALSE if it is disabled.

Example Code
The following code illustrates how to query the state of monitoring. rc = pInstance->pfnAUDIOIF((HVSD)pInstance->hvsd,                          VSD_QUERY,                           VSD_QUERYMONITOR,                           (PVOID)&pStat->ulReturn);

VSD_QUERYSTATUSLEVEL
This subcommand of the VSD_QUERY command queries the status of the audio input level (percentage). This command is optional.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYSTATUSLEVEL.

pRequest (PULONG) Current level of device.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.

VSD_QUERYVOLUME
This subcommand of the VSD_QUERY command queries the volume level. The volume is returned as a percentage between 0% and 100%

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_QUERY.

ulFlags (ULONG) Set to VSD_QUERYVOLUME.

pRequest (PVSD_VOLUME_PARMS) Pointer to the VSD_VOLUME_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful. field.

Remarks
On return, the VSD will fill in the ulVolume field of the VSD_VOLUME_PARMS structure.

Example Code
The following code illustrates how to query audio volume from the VSD. VSD_VOLUME_PARMS  vsdVol; ULONG             ulVol; vsdVol.ulLength = sizeof(VSD_VOLUME_PARMS); vsdVol.ulFlags = ulFlags;

/*-- *  Ask the VSD to query audio volume. *--*/

rc = pInstance->pfnAUDIOIF((HVSD)pInstance->hvsd,                          VSD_QUERY,                           VSD_QUERYVOLUME,                           (PVOID)&vsdVol); ulVol = vsdvol.ulVolume;

VSD_RESOURCE
This command can be issued only when the device is opened and is used for resource management.

VSD_RESOURCE is a required command and must be implemented by all VSD writers.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_RESOURCE.

ulFlags (ULONG) No flags used for this command.

pRequest (PVSD_RESOURCE_PARMS) Pointer to the VSD_RESOURCE_PARMS data structure.

The driver is responsible for filling in the ulResUnits and ulClass fields. The caller is responsible for filling in the ulDataType field.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * Command completed successfully.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters is missing.

Remarks
When an audio device driver is installed in MMPM/2, the installation routines place the following three keywords in the MMPM2.INI file: Because MMPM/2 allows many applications to simultaneously open the audio card, it uses these keywords to determine which applications can simultaneously use the audio device. All of the numbers are arbitrary and are defined on a device-by-device basis. However, device driver writers should use the numbering scheme defined below:
 * RESOURCEUNITS=
 * RESOURCECLASS=
 * VALIDCOMBINATIONS=

The keyword RESOURCECLASSES indicates the different resource types available on the audio device. ''The first parameter is the number of classes and it is followed by a listing of classes. A vendor should provide a class for each data type that they support''. For instance, if the XYZ audio card can only play PCM files, it would only have one resource class - the PCM class. However, if the ABC audio card can play PCM, MIDI, and ADPCM, then it would have three classes. The VSD should fill in the ulClass field with the class that is appropriate for this mode.

The keyword RESOURCEUNITS indicates the maximum number of instances that can be active on the card at any particular time. For example, if the XYZ card mentioned above had the ability to play three PCM files at the same time, the RESOURCEUNITS for this card would be three. In contrast, the ABC card can only play one PCM file and one MIDI file at any one time. Therefore, its resource units should be two. The VSD should fill in the ulResUnits field with the correct number of resources for the current mode (typically, one).

Example Code
The following code illustrates how to determine the number of resources consumed for a particular mode on an audio VSD. HVSD  hvsd; rc = pInstance->pfnAUDIOIF( hvsd,                             VSD_RESOURCE,                              0L,                              (PVOID)&vsdResourceParms );

pInstance->ulResourcesUsed = vsdResourceParms.ulResUnits; pInstance->ulClass = vsdResourceParms.ulClass;

VSD_RESTORE
This command restores the current state of the device. VSD_RESTORE is a required function and must be implemented by all VSD writers.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_RESTORE.

ulFlags (ULONG) No flags used for this command.

pRequest (PVOID) Not used with this command.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command completed successfully.

Remarks
MMPM/2 supports the concept of suspending and resuming the state of a device at any point in time. Unlike other environments, multiple applications can simultaneously have a device open and the Media Device Manager will cooperate with the VSD in order to manage the device. The VSD is responsible for saving and restoring the actual hardware device. For further information, see the OS/2 Multimedia Programming Reference (MCI_ RESTORE).

Example Code
The following code illustrates how to activate an audio VSD using VSD_RESTORE. ULONG  rc; HVSD   hvsd;

rc = pInstance->pfnAUDIOIF( hvsd,                                  VSD_RESTORE,                                   0L,                                   0 ); return(rc)

VSD_SAVE
This command saves the current state of the device. VSD_SAVE is a required function and must be implemented by all VSD writers. This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SAVE.

ulFlags (ULONG) No flags used for this command.

pRequest (PVOID) Not used with this command.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.

Remarks
MMPM/2 supports the concept of suspending and resuming the state of a device at any point in time. Unlike other environments, multiple applications can simultaneously have a device open and the Media Device Manager will cooperate with the VSD in order to manage the device. The VSD is responsible for saving and restoring the actual hardware device. For further information, see the OS/2 Multimedia Programming Reference (MCIDRV_ SAVE).

Example Code
The following code illustrates how to deactivate an audio VSD using VSD_SAVE. ULONG   rc; HVSD   hvsd; rc = pInstance->pfnAUDIOIF( hvsd,                            VSD_SAVE,                             0L,                             0 ); return(rc);

VSD_SET
This command allows an application to modify the settings of the VSD.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) The following flags can be used with VSD_SET.
 * VSD_SETAUDIOATTRIBUTES
 * See VSD_SETAUDIOATTRIBUTES


 * VSD_SETCONNECTOR
 * See VSD_SETCONNECTOR


 * VSD_SETDATATYPE
 * See VSD_SETDATATYPE


 * VSD_SETMIXCONNECTIONS
 * See VSD_SETMIXCONNECTIONS


 * VSD_SETMIXCONTROL
 * See VSD_SETMIXCONTROL


 * VSD_SETMONITOR
 * See VSD_SETMONITOR


 * VSD_SETVOLUME
 * See VSD_SETVOLUME

pRequest (PVOID) Pointer value varies according to the value of ulFlags.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_INVALID_HVSD
 * The hvsd(VSD handle) is not valid. Verify that the hvsdmatches the one provided on the VSD_OPEN.

Remarks
This messages uses flags to specify what to set on the adapter.

VSD_SETAUDIOATTRIBUTES
This subcommand of the VSD_SET command sets the audio attribute settings. A valid length must be placed in the ulLength field of the VSD_ AUDIOATTRIBUTES_PARMS structure. The audio setting to modify (such as treble, bass, and so on) must be placed in the ulFlags field of the VSD_ AUDIOATTRIBUTES_PARMS structure with the actual corresponding setting in the ulValue field. The value should be between 0 and 100. The ulDelay indicates the length of time over which this effect should take place.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETAUDIOATTRIBUTES.

pRequest (PVSD_AUDIOATTRIBUTES_PARMS) Pointer to the VSD_AUDIOATTRIBUTES_PARMS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.

Example Code
The following code illustrates how to set audio attribute information. VSD_AUDIOATTRIBUTES_PARMS  vsdAttr;

/* Prime the structure with necessary values */ vsdAttr.ulLength = sizeof (VSD_AUDIOATTRIBUTES_PARMS); vsdAttr.ulFlags = VSD_BASS; vsdAttr.ulValue = 100;

/*-    * Ask the VSD to either set or query an audio * attribute. The caller determines whether * to set or query via the command variable. *-*/

rc = pInstance->pfnAUDIOIF((HVSD)pInstance->hvsd,                               VSD_SET,                                VSD_SETAUDIOATTRIBUTES,                                (PVOID)&vsdAttr);

VSD_SETCONNECTOR
This subcommand of the VSD_SET command enables or disables a connector. (A connector can be a hardware or software connection on the device the VSD is controlling.) Note that enabling a connector can by default, disable another connector. For further information regarding connectors, refer to the MCI_CONNECTOR command in the OS/2 Multimedia Programming Reference. Additional connectors can be found in MCIOS2.H.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETCONNECTOR.

pRequest (PVSD_CONNECTOR_PARMS) A pointer to the VSD_CONNECTOR_PARMS structure.

The status of the connector, enable (VSD_ENABLE) or disable (VSD_DISABLE) must be indicated in the fEnabled field. A valid connector must be placed in the ulConn_Type field and a valid index in the ulIndex field.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_UNSUPPORTED_CONNECTOR
 * Connector setting is not supported.


 * VSDERR_INVALID_CONNECTOR
 * Connector setting is invalid.

Example Code
The following code illustrates how to set the state of the connector. HVSD                  hvsd; VSD_CONNECTOR_PARMS   vsdConn;

vsdConn.ulConn_Type = pConnector->ulConnectorType; vsdConn.ulIndex = pConnector->ulConnectorIndex; vsdConn.fEnabled = VSD_DISABLE;

/*-- * Tell the VSD that we want to disable a connector. *--*/ lError = pInstance->pfnNewVSD(hvsd,                                VSD_SET,                                VSD_SETCONNECTOR,                                (PVOID)&vsdConn);

VSD_SETDATATYPE
This subcommand of the VSD_SET command sets the current data type that the device is dealing with.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETDATATYPE.

pRequest (PVSD_AUDIODATATYPE_PARMS) Input. Pointer to a VSD_AUDIODATATYPE_PARMS structure.


 * Note: Every field in the VSD_AUDIODATATYPE_PARMS structure contains a numeric value except for ulOperation. This field contains either VSD_ PRODUCE for recording or VSD_CONSUME for playback. The VSD is responsible for filling in the ulBlockAlignment, ulDataSubType, and ulAverageBytesPerSec fields in the VSD_AUDIODATATYPE_PARMS structure.

The ulFlags field of the VSD_AUDIODATATYPE_PARMS structure contains a flag for each field in the structure that can be set. Every field has a flag except for the ulOperation field. The ulOperation field is valid for every call.

The VSD_AUDIODATATYPE_PARMS structure must contain at least one of the following flags:
 * VSD_MODE
 * VSD_CHANNELS
 * VSD_SAMPLESPERSEC
 * VSD_OPERATION
 * VSD_BITSPERSAMPLE

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.

Example Code
The following code illustrates how to set the data type, sampling rate, channels, and bits per sample for an audio VSD. HVSD                    hvsd; VSD_AUDIODATATYPE_PARMS AudioDatatype; PMMAUDIOHEADER          pmmaudioheader; AudioDatatype.ulDataType = pmmaudioheader->mmXWAVHeader.WAVEHeader.usFormatTag; AudioDatatype.ulBitsPerSample = pmmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample; AudioDatatype.ulSamplingRate = pmmaudioheader->mmXWAVHeader.WAVEHeader.usSamplesPerSec; AudioDatatype.ulChannels = pmmaudioheader->mmXWAVHeader.WAVEHeader.usChannels; AudioDatatype.ulOperation = VSD_PLAY; AudioDatatype.ulFlags = VSD_MODE|VSD_CHANNELS|VSD_SAMPLESPERSEC| VSD_OPERATION|VSD_BITSPERSAMPLE;

rc = pInstance->pfnNewVSD(hvsd,                            VSD_SET,                             VSD_SETDATATYPE,                    (PVOID)&AudioDatatype); if(rc) {    return(rc) }

VSD_SETMIXCONNECTIONS
This subcommand of the VSD_SET command routes the audio output of a connector to a particular output circuitry (that is, pass thru, internal mixer circuitry, and so on). For further information about VSD mixer support and functions, see Audio Sample for Vendor-Specific Drivers and Mixer IOCtl Functions Introduction

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETMIXCONNECTIONS.

pRequest (PLINECONNECTIONS) A pointer to the LINECONNECTIONS structure.

The caller must fill in the ulConnections and the ulLine fields of the LINECONNECTIONS structure.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_INVALID_SOURCE
 * Invalid source.


 * VSDERR_INVALID_SINK
 * Invalid sink.


 * VSDERR_INVALID_CONNECTION
 * Invalid connection.

Example Code
The following code illustrates how to route the output of a connector to the internal mixer circuitry. LINECONNECTIONS  mixinfo;

mixinfo.ulLine = SOURCE_SYNTHESIZER; mixinfo.ulConnection = SINK_SPEAKER; rc = pInstance->((HVSD)pInstance->hvsd,                  VSD_SET,                   VSD_SETMIXCONNECTIONS,                   (PVOID)&mixinfo);

return(rc);

VSD_SETMIXCONTROL
This subcommand of the VSD_SET command enables an application to set the current state of a particular line. For further information about VSD mixer support and functions, see Audio Sample for Vendor-Specific Drivers and Mixer IOCtl Functions Introduction

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETMIXCONTROL.

pRequest (PMIXERCONTROL) A pointer to the MIXERCONTROL structure.

The ulControl field of the MIXERCONTROL structure must be filled in with the desired setting. For stereo controls, the high-order word of this field contains the left channel setting and the low-order word contains the right channel setting. A value of 0xFFFF represents full intensity and a value of 0x0000 is full cutout. The ulLine field must also be filled in.

Return Value
rc (ULONG) Error code indicating success or the type of failure:
 * VSDERR_MISSING_PARAMETER
 * One or more parameters are missing.


 * VSDERR_INVALID_SOURCE
 * Invalid source.


 * VSDERR_INVALID_SINK
 * Invalid sink.


 * VSDERR_INVALID_CONNECTION
 * Invalid connection.

Example Code
The following code illustrates how to query the settings of an audio attributes for a particular connector. MIXERCONTROL  MixerControl; USHORT        usBass;

MixerControl.ulControl = MIX_SUPPORT_VOLUME; MixerControl.ulLine = SINK_LINE_OUT; MixerControl.ulSetting = 100;

lError = pInstance->((HVSD)pInstance->hvsd,                     VSD_SET,                      VSD_SETMIXCONTROL,                      (PVOID)&MixerControl);

return(lError);

VSD_SETMONITOR
This subcommand of the VSD_SET command enables (MCI_TRUE) or disables (MCI_ FALSE) the audio monitor feature of the device.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETMONITOR.

pRequest (PULONG) Input. Set to MCI_TRUE or MCI_FALSE.

Return Value
rc (ULONG) Error code indicating success.
 * VSDERR_SUCCESS
 * The command was successful.

Example Code
The following code illustrates how to set the state of the VSD monitor. ULONG   ulSetOn;

ulSetOn = MCI_TRUE;

/* Tell the VSD to change monitor status */

lError = prInstance->pfnAUDIOIF((HVSD)prInstance->pMix->hvsd                          VSD_SET,                           VSD_SETMONITOR,                           (PVOID)lSetOn);

VSD_SETVOLUME
This subcommand of the VSD_SET command sets the volume level as a percentage (0 - 100). If the value is not one of the supported volume levels, it is rounded up to the nearest supported level. The ulFlags field indicates which fields are to be used.

This command is sent using VSDEntry as follows: VSDEntry(hvsd, ulFunc, ulFlags, pRequest)

Parameters
hvsd (HVSD) Handle to a VSD.

ulFunc (ULONG) Set to VSD_SET.

ulFlags (ULONG) Set to VSD_SETVOLUME.

pRequest (PVSD_VOLUME_PARMS) Pointer to the VSD_VOLUME_PARMS structure.

The caller must fill in the ulVolume field if VSD_VOLUME is specified. The caller must fill in the ulMasterAudio field if VSD_MASTERVOLUME is specified. The caller must fill in the fMute field with a boolean if VSD_ MUTE is specified. TRUE mutes the device; FALSE unmutes the device.

Return Value
rc (ULONG) Error codes indicating success or the type of failure:
 * VSDERR_SUCCESS
 * The command was successful.


 * VSDERR_VOL_OUT_OF_RANGE
 * Invalid volume level.

Example Code
The following code illustrates how to set the volume on an audio VSD. VSD_VOLUME_PARMS  vsdVol; vsdVol.ulVolume = pInstance->ulVolume; vsdVol.ulMasterAudio = pInstance->ulMasterVolume; vsdVol.fMute = pInstance->fMute; vsdVol.ulVectoredVolume = pInstance->ulTime; vsdVol.ulFlags = VSD_VOLUME | VSD_MASTERVOLUME;

lError = prInstance->pfnAUDIOIF((HVSD)prInstance->pMix->hvsd                          VSD_SET,                           VSD_SETVOLUME,                           (PVOID)&vsdVol);