| 1 | /************************* START OF SPECIFICATIONS ***
|
|---|
| 2 | *
|
|---|
| 3 | * SOURCE FILE NAME: VSDSET.C
|
|---|
| 4 | *
|
|---|
| 5 | * DESCRIPTIVE NAME: Allows setting of audio attributes via VSD
|
|---|
| 6 | *
|
|---|
| 7 | * COPYRIGHT: IBM Confidential
|
|---|
| 8 | * Copyright (c) IBM Corporation 1991, 1993
|
|---|
| 9 | * All Rights Reserved
|
|---|
| 10 | *
|
|---|
| 11 | * FUNCTION: This source file processes VSD_SET requests.
|
|---|
| 12 | *
|
|---|
| 13 | *
|
|---|
| 14 | * NOTES: This source file illustrates the handling of the following flags:
|
|---|
| 15 | * 1. VSD_SETVOLUME (Changing instance and master volume ).
|
|---|
| 16 | * 2. VSD_SETCONNECTOR (enable/disable connectors
|
|---|
| 17 | * 4. VSD_SETMIXCONNECTIONS ( change the setting of a particular mixer
|
|---|
| 18 | * connector setting like treble, bass etc.)
|
|---|
| 19 | * 5. VSD_SETAUDIOATTRIBUTES (change audio attributes like treble bass).
|
|---|
| 20 | * 6. VSD_SETMONITOR (enable - disable monitoring ).
|
|---|
| 21 | * 7. VSD_SETDATATYPE (changing digital audio attributes -- channels etc.).
|
|---|
| 22 | * 8. VSD_SETMIXCONTROL (modify the settings of the mixer device ).
|
|---|
| 23 | *
|
|---|
| 24 | * Also calling the mixer interface.
|
|---|
| 25 | *
|
|---|
| 26 | * Change History:
|
|---|
| 27 | * DATE DEVELOPER CHANGE DESCRIPTION
|
|---|
| 28 | * 07/21/93 Linden deCarmo File created
|
|---|
| 29 | * 06/14/94 Linden deCarmo Updated query to enabled the right
|
|---|
| 30 | * connectors via input/output dev variable
|
|---|
| 31 | * 06/15/94 Linden deCarmo Removed VSDSet call to vsdioctl.c for consistency.
|
|---|
| 32 | * 06/19/94 Linden deCarmo Improved comments in general
|
|---|
| 33 | * 06/19/94 Linden deCarmo Greatly improved connector documentation
|
|---|
| 34 | * 07/13/94 Linden deCarmo Fixed audio attribute problems.
|
|---|
| 35 | * 06/29/95 Linden deCarmo Cleanup Hardware mixer support (15552).
|
|---|
| 36 | * 08/29/95 Paul Rogers Arrange processing in SETVOLUME to acct for presence
|
|---|
| 37 | * or absence of mixer (16914) @PR1
|
|---|
| 38 | *
|
|---|
| 39 | ************************** END OF SPECIFICATIONS **************************/
|
|---|
| 40 |
|
|---|
| 41 | #define INCL_NOPMAPI
|
|---|
| 42 | #define INCL_DOS
|
|---|
| 43 | #define INCL_ERRORS
|
|---|
| 44 |
|
|---|
| 45 | #define INCL_AUDIO_VSD
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 | #include <os2.h>
|
|---|
| 49 | #include <os2me.h>
|
|---|
| 50 | #include <mcd.h>
|
|---|
| 51 | #include <audio.h>
|
|---|
| 52 | #include <stdio.h>
|
|---|
| 53 | #include <string.h>
|
|---|
| 54 | #include <hhpheap.h>
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 | #include <vsdcmds.h>
|
|---|
| 58 | #include <vsdaud.h>
|
|---|
| 59 | #include <os2mixer.h>
|
|---|
| 60 | #include <vsdmix.h>
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 | /************************ START OF SPECIFICATIONS **************************
|
|---|
| 70 | *
|
|---|
| 71 | * SUBROUTINE NAME: VSDSet
|
|---|
| 72 | *
|
|---|
| 73 | * FUNCTION: Sets audio attributes (Sample rate, bits per sample, etc)
|
|---|
| 74 | *
|
|---|
| 75 | * INPUT: pInstance - pointer to VSD Instance structure
|
|---|
| 76 | * ulFlags - flags used in set operation
|
|---|
| 77 | *
|
|---|
| 78 | * OUTPUT: returns VSDERR_SUCCESS if successful, otherwise it returns an
|
|---|
| 79 | * MCI error code.
|
|---|
| 80 | *
|
|---|
| 81 | * OS/2 CALLS:
|
|---|
| 82 | *
|
|---|
| 83 | * C CALLS: None.
|
|---|
| 84 | *
|
|---|
| 85 | * INTERNAL CALLS: MCI_Error(), ModifyAudioAttributes()
|
|---|
| 86 |
|
|---|
| 87 | *
|
|---|
| 88 | *************************** END OF SPECIFICATIONS *************************/
|
|---|
| 89 |
|
|---|
| 90 | LONG VSDSetCommand( PVSD_INSTANCE pInstance,
|
|---|
| 91 | ULONG ulFlags,
|
|---|
| 92 | PVOID pRequest )
|
|---|
| 93 |
|
|---|
| 94 | {
|
|---|
| 95 | LONG lError = VSDERR_SUCCESS;
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 | // ULONG ulResourceDecrease;
|
|---|
| 99 | // ULONG ulResourceChangeNeeded = FALSE;
|
|---|
| 100 | ULONG ulOldResources = pInstance->ulResourcesUsed;
|
|---|
| 101 | // ULONG ulMatch;
|
|---|
| 102 | ULONG ulResourceChange = FALSE;
|
|---|
| 103 | ULONG ulOldClass = pInstance->ulClass;
|
|---|
| 104 | ULONG ulMicType;
|
|---|
| 105 | ULONG ulSpeakerType;
|
|---|
| 106 | ULONG ulSaveInputDev;
|
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 | VSD_INSTANCE TempAmp;
|
|---|
| 110 |
|
|---|
| 111 | MCIDRV_CHANGERESOURCE_PARMS mciChangeResource;
|
|---|
| 112 |
|
|---|
| 113 | PVSD_AUDIODATATYPE_PARMS pAudioSettings;
|
|---|
| 114 |
|
|---|
| 115 |
|
|---|
| 116 | switch ( ulFlags )
|
|---|
| 117 | {
|
|---|
| 118 |
|
|---|
| 119 | /*----------------------------------------------------------------
|
|---|
| 120 | * Set datatype allows the mixer (and only the mixer) to change
|
|---|
| 121 | * the mode that the VSD is in. The following flags can be
|
|---|
| 122 | * in the ulFlags field.
|
|---|
| 123 | * VSD_MODE Modify the datatype (i.e. PCM, mulaw etc.)
|
|---|
| 124 | * VSD_BITSPERSAMPLE Modify the BPS (i.e. 4, 8, 16 etc.)
|
|---|
| 125 | * VSD_CHANNELS Modify the number of channels.
|
|---|
| 126 | * VSD_SAMPLESPERSEC Modify the sampling rate (11K, 22k, 44k etc.)
|
|---|
| 127 | *
|
|---|
| 128 | * If the mode is not valid, one of the following errors should
|
|---|
| 129 | * be returned.
|
|---|
| 130 | *
|
|---|
| 131 | * VSDERR_UNSUPP_FORMAT_TAG
|
|---|
| 132 | * VSDERR_UNSUPP_BITSPERSAMPLE
|
|---|
| 133 | * VSDERR_UNSUPP_CHANNELS
|
|---|
| 134 | * VSDERR_UNSUPP_SAMPLESPERSEC
|
|---|
| 135 | * VSDERR_UNSUPP_FORMAT_MODE
|
|---|
| 136 | *---------------------------------------------------------------*/
|
|---|
| 137 | case VSD_SETDATATYPE:
|
|---|
| 138 | {
|
|---|
| 139 |
|
|---|
| 140 | pAudioSettings = (PVSD_AUDIODATATYPE_PARMS) pRequest;
|
|---|
| 141 |
|
|---|
| 142 | /* Temporarily copy the VSD instance and check the values */
|
|---|
| 143 |
|
|---|
| 144 | memmove (&TempAmp, pInstance, sizeof (VSD_INSTANCE));
|
|---|
| 145 | TempAmp.ulOperation = pAudioSettings->ulOperation;
|
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 | /*--------------------------------------------------
|
|---|
| 149 | * If the caller is changing the mode (ie PCM, MIDI)
|
|---|
| 150 | * then there are some checks we will have to perform.
|
|---|
| 151 | *--------------------------------------------------*/
|
|---|
| 152 |
|
|---|
| 153 | if (pAudioSettings->ulFlags & VSD_MODE)
|
|---|
| 154 |
|
|---|
| 155 | {
|
|---|
| 156 | TempAmp.sMode = ( SHORT ) pAudioSettings->ulDataType;
|
|---|
| 157 | TempAmp.ulDataType = pAudioSettings->ulDataType;
|
|---|
| 158 |
|
|---|
| 159 | /*-------------------------------------------
|
|---|
| 160 | * Mulaw and Alaw are all 8bit types. Force
|
|---|
| 161 | * the bitspersample to be 8.
|
|---|
| 162 | *-------------------------------------------*/
|
|---|
| 163 |
|
|---|
| 164 | if ( TempAmp.sMode == DATATYPE_MULAW ||
|
|---|
| 165 | TempAmp.sMode == DATATYPE_ALAW ||
|
|---|
| 166 | TempAmp.sMode == DATATYPE_RIFF_MULAW ||
|
|---|
| 167 | TempAmp.sMode == DATATYPE_RIFF_ALAW )
|
|---|
| 168 |
|
|---|
| 169 | {
|
|---|
| 170 | pAudioSettings->ulFlags |= VSD_BITSPERSAMPLE;
|
|---|
| 171 | pAudioSettings->ulBitsPerSample = 8;
|
|---|
| 172 |
|
|---|
| 173 | /*----------------------------------------------
|
|---|
| 174 | * Perform some mapping to deal with the fact that
|
|---|
| 175 | * Microsoft defined the same thing twice.
|
|---|
| 176 | *----------------------------------------------*/
|
|---|
| 177 |
|
|---|
| 178 | if ( TempAmp.sMode == DATATYPE_RIFF_MULAW )
|
|---|
| 179 | {
|
|---|
| 180 | pAudioSettings->ulDataType = DATATYPE_MULAW;
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | if ( TempAmp.sMode == DATATYPE_RIFF_ALAW )
|
|---|
| 184 | {
|
|---|
| 185 | pAudioSettings->ulDataType = DATATYPE_ALAW;
|
|---|
| 186 | }
|
|---|
| 187 |
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | /*-------------------------------------------
|
|---|
| 191 | * IBM_ADPCM by definition is a 4bit type.
|
|---|
| 192 | * compressed 16 bit.
|
|---|
| 193 | *-------------------------------------------*/
|
|---|
| 194 |
|
|---|
| 195 |
|
|---|
| 196 | if ( TempAmp.sMode == DATATYPE_ADPCM_AVC )
|
|---|
| 197 | {
|
|---|
| 198 | pAudioSettings->ulFlags |= MCI_WAVE_SET_BITSPERSAMPLE;
|
|---|
| 199 | pAudioSettings->ulBitsPerSample = 16;
|
|---|
| 200 | }
|
|---|
| 201 |
|
|---|
| 202 |
|
|---|
| 203 |
|
|---|
| 204 | }
|
|---|
| 205 |
|
|---|
| 206 | /* Store the requested values */
|
|---|
| 207 |
|
|---|
| 208 | if (pAudioSettings->ulFlags & VSD_BITSPERSAMPLE)
|
|---|
| 209 |
|
|---|
| 210 | {
|
|---|
| 211 | TempAmp.lBitsPerSRate = pAudioSettings->ulBitsPerSample;
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 | if (pAudioSettings->ulFlags & VSD_SAMPLESPERSEC)
|
|---|
| 215 |
|
|---|
| 216 | {
|
|---|
| 217 | TempAmp.lSRate = pAudioSettings->ulSamplingRate;
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | if (pAudioSettings->ulFlags & VSD_CHANNELS)
|
|---|
| 221 |
|
|---|
| 222 | {
|
|---|
| 223 | TempAmp.sChannels = pAudioSettings->ulChannels;
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | /******************************************************
|
|---|
| 227 | * When the VSD was loaded, it brought in a resource file
|
|---|
| 228 | * check the resource file if this particular device
|
|---|
| 229 | * supports the mode the caller requested.
|
|---|
| 230 | ******************************************************/
|
|---|
| 231 |
|
|---|
| 232 |
|
|---|
| 233 | lError = GetClassInformation( &TempAmp );
|
|---|
| 234 |
|
|---|
| 235 | /******************************************************
|
|---|
| 236 | * Fix for varied sample rates, if all flags come in
|
|---|
| 237 | * assume that sample rates are valid
|
|---|
| 238 | ******************************************************/
|
|---|
| 239 |
|
|---|
| 240 | if ( pAudioSettings->ulFlags != ( VSD_BITSPERSAMPLE |
|
|---|
| 241 | VSD_MODE |
|
|---|
| 242 | VSD_CHANNELS |
|
|---|
| 243 | VSD_SAMPLESPERSEC ) )
|
|---|
| 244 | {
|
|---|
| 245 |
|
|---|
| 246 | if ( lError )
|
|---|
| 247 | {
|
|---|
| 248 | pAudioSettings->ulDataType = TempAmp.sBestFitMode;
|
|---|
| 249 | pAudioSettings->ulBitsPerSample = TempAmp.ulBestFitBPS;
|
|---|
| 250 | pAudioSettings->ulChannels = TempAmp.ulBestFitChan;
|
|---|
| 251 | pAudioSettings->ulSamplingRate = TempAmp.ulBestFitRate;
|
|---|
| 252 |
|
|---|
| 253 | return (lError);
|
|---|
| 254 | }
|
|---|
| 255 |
|
|---|
| 256 | }
|
|---|
| 257 |
|
|---|
| 258 | else
|
|---|
| 259 | {
|
|---|
| 260 | /*--------------------------------------------------*
|
|---|
| 261 | * Since we will have to do a best fit on the file
|
|---|
| 262 | * all of the resource management stuff is messed
|
|---|
| 263 | * up. Set a variable to indicate that we will have
|
|---|
| 264 | * to inform MDM of a possible resource class/unit
|
|---|
| 265 | * change.
|
|---|
| 266 | *---------------------------------------------------*/
|
|---|
| 267 | if ( lError )
|
|---|
| 268 | {
|
|---|
| 269 | #ifndef INCL_MM_WPOS
|
|---|
| 270 | // 15552
|
|---|
| 271 | if ( pInstance->ulDeviceID == MACPA &&
|
|---|
| 272 | lError == VSDERR_UNSUPP_SAMPLESPERSEC )
|
|---|
| 273 | {
|
|---|
| 274 | lError = 0;
|
|---|
| 275 | MapModes( &TempAmp );
|
|---|
| 276 | }
|
|---|
| 277 | else
|
|---|
| 278 | #endif
|
|---|
| 279 | // 15552
|
|---|
| 280 | {
|
|---|
| 281 | pAudioSettings->ulDataType = TempAmp.sBestFitMode;
|
|---|
| 282 | pAudioSettings->ulBitsPerSample = TempAmp.ulBestFitBPS;
|
|---|
| 283 | pAudioSettings->ulChannels = TempAmp.ulBestFitChan;
|
|---|
| 284 | pAudioSettings->ulSamplingRate = TempAmp.ulBestFitRate;
|
|---|
| 285 | return ( lError );
|
|---|
| 286 |
|
|---|
| 287 | }
|
|---|
| 288 | } /* If we could not find this device */
|
|---|
| 289 |
|
|---|
| 290 | lError = 0;
|
|---|
| 291 | }
|
|---|
| 292 |
|
|---|
| 293 | /*********************************************************
|
|---|
| 294 | * Copy Temporary Instance Parameters into Actual Instance
|
|---|
| 295 | **********************************************************/
|
|---|
| 296 |
|
|---|
| 297 | memcpy ( pInstance, &TempAmp, sizeof (MCI_AMP_INSTANCE));
|
|---|
| 298 |
|
|---|
| 299 |
|
|---|
| 300 | /***********************************************************
|
|---|
| 301 | * For ACPA, block alignment is simply bits/per sample * channels
|
|---|
| 302 | * othercards may have a different algorithm
|
|---|
| 303 | **********************************************************/
|
|---|
| 304 |
|
|---|
| 305 | // pInstance->ulBlockAlignment = ( pInstance->lBitsPerSRate / 8 )
|
|---|
| 306 |
|
|---|
| 307 | // divisions are very, very expensive--do shift (1 cycle versus 36 on PPC
|
|---|
| 308 |
|
|---|
| 309 | pInstance->ulBlockAlignment = ( pInstance->lBitsPerSRate >> 3 )
|
|---|
| 310 | * pInstance->sChannels;
|
|---|
| 311 |
|
|---|
| 312 | // if ( ulOldResources > ( SHORT ) pInstance->ulResourcesUsed )
|
|---|
| 313 | // {
|
|---|
| 314 | // ulResourceDecrease = TRUE;
|
|---|
| 315 | // }
|
|---|
| 316 | // else
|
|---|
| 317 | // {
|
|---|
| 318 | // ulResourceDecrease = FALSE;
|
|---|
| 319 | // }
|
|---|
| 320 | if ( ulOldResources != pInstance->ulResourcesUsed ||
|
|---|
| 321 | ulOldClass != pInstance->ulClass )
|
|---|
| 322 | {
|
|---|
| 323 | ulResourceChange = TRUE;
|
|---|
| 324 | }
|
|---|
| 325 |
|
|---|
| 326 |
|
|---|
| 327 | mciChangeResource.pInstance = ( PVOID ) pInstance;
|
|---|
| 328 | mciChangeResource.usResourceUnits = ( USHORT ) pInstance->ulResourcesUsed;
|
|---|
| 329 | mciChangeResource.usResourceClass = ( USHORT ) pInstance->ulClass;
|
|---|
| 330 | mciChangeResource.usResourcePriority = 0;
|
|---|
| 331 |
|
|---|
| 332 | if ( ulResourceChange )
|
|---|
| 333 | {
|
|---|
| 334 |
|
|---|
| 335 | /*-------------------------------------------
|
|---|
| 336 | * Report to MDM the number of resource units
|
|---|
| 337 | * this new mode will consume.
|
|---|
| 338 | *------------------------------------------*/
|
|---|
| 339 |
|
|---|
| 340 | lError = mciSendCommand( pInstance->usDeviceID,
|
|---|
| 341 | MCIDRV_CHANGERESOURCE,
|
|---|
| 342 | MCI_WAIT,
|
|---|
| 343 | ( DWORD ) &mciChangeResource,
|
|---|
| 344 | 0 );
|
|---|
| 345 |
|
|---|
| 346 | if ( ( DWORD_LOWD( lError ) != VSDERR_SUCCESS ) )
|
|---|
| 347 | {
|
|---|
| 348 | /* Test tool does not pass in device id */
|
|---|
| 349 |
|
|---|
| 350 | if ( pInstance->usDeviceID )
|
|---|
| 351 | {
|
|---|
| 352 | pInstance->ulResourcesUsed = ulOldResources;
|
|---|
| 353 | return ( lError );
|
|---|
| 354 | }
|
|---|
| 355 | }
|
|---|
| 356 | }
|
|---|
| 357 |
|
|---|
| 358 | if ( !pInstance->ulActive )
|
|---|
| 359 | {
|
|---|
| 360 | /* Update the streaming subtype */
|
|---|
| 361 |
|
|---|
| 362 | pAudioSettings->ulDataSubType = pInstance->ulSubType;
|
|---|
| 363 |
|
|---|
| 364 | return ( VSDERR_SUCCESS );
|
|---|
| 365 | }
|
|---|
| 366 |
|
|---|
| 367 | // /* Check to see if a best fit was done */
|
|---|
| 368 | //
|
|---|
| 369 | // ulMatch = pInstance->ulMatch;
|
|---|
| 370 |
|
|---|
| 371 | /*----------------------------------------
|
|---|
| 372 | * Setup the card in the appropriate mode
|
|---|
| 373 | * i.e. PCM, MIDI etc.
|
|---|
| 374 | *---------------------------------------*/
|
|---|
| 375 |
|
|---|
| 376 | lError = DoIOCTLLoad( pInstance, pInstance->ulHardwareMode );
|
|---|
| 377 |
|
|---|
| 378 | if ( !lError )
|
|---|
| 379 | {
|
|---|
| 380 | if ( ulResourceChange )
|
|---|
| 381 | {
|
|---|
| 382 |
|
|---|
| 383 | /*----------------------------------------*
|
|---|
| 384 | * Place this code here since the DoIOCTL
|
|---|
| 385 | * May have done a best fit and changed
|
|---|
| 386 | * the resource class.
|
|---|
| 387 | *----------------------------------------*/
|
|---|
| 388 |
|
|---|
| 389 | mciChangeResource.usResourceUnits = ( USHORT ) pInstance->ulResourcesUsed;
|
|---|
| 390 | mciChangeResource.usResourceClass = ( USHORT ) pInstance->ulClass;
|
|---|
| 391 | mciChangeResource.usResourcePriority = 0;
|
|---|
| 392 |
|
|---|
| 393 | lError = mciSendCommand( pInstance->usDeviceID,
|
|---|
| 394 | MCIDRV_CHANGERESOURCE,
|
|---|
| 395 | MCI_WAIT,
|
|---|
| 396 | ( DWORD ) &mciChangeResource,
|
|---|
| 397 | 0 );
|
|---|
| 398 |
|
|---|
| 399 | if ( ( DWORD_LOWD( lError ) != VSDERR_SUCCESS ) )
|
|---|
| 400 | {
|
|---|
| 401 | /* Avoid problem for test tool */
|
|---|
| 402 |
|
|---|
| 403 | if ( pInstance->usDeviceID )
|
|---|
| 404 | {
|
|---|
| 405 | pInstance->ulResourcesUsed = ulOldResources;
|
|---|
| 406 | return ( lError );
|
|---|
| 407 | }
|
|---|
| 408 | }
|
|---|
| 409 | } /* If resource change */
|
|---|
| 410 | } /* if no errors after DOIOCTL */
|
|---|
| 411 |
|
|---|
| 412 | /*-----------------------------------------------------------------*
|
|---|
| 413 | * Call set driver to restore instance volume, balance, etc...
|
|---|
| 414 | *-----------------------------------------------------------------*/
|
|---|
| 415 |
|
|---|
| 416 | if ( !lError )
|
|---|
| 417 | {
|
|---|
| 418 | lError = ModifyAudioAttributes(pInstance, VSD_SET_ALL );
|
|---|
| 419 | }
|
|---|
| 420 |
|
|---|
| 421 | /*-----------------------------------------------------------------*
|
|---|
| 422 | * Return private informaiton to the IBM amp-mixer.
|
|---|
| 423 | * Used only by AUDIODD drivers.
|
|---|
| 424 | *-----------------------------------------------------------------*/
|
|---|
| 425 |
|
|---|
| 426 | pAudioSettings->ulReserved1 = pInstance->ulGlobalFile;
|
|---|
| 427 | pAudioSettings->ulDataSubType = pInstance->ulSubType;
|
|---|
| 428 |
|
|---|
| 429 | }
|
|---|
| 430 | break;
|
|---|
| 431 |
|
|---|
| 432 |
|
|---|
| 433 | case VSD_SETMONITOR:
|
|---|
| 434 | {
|
|---|
| 435 | // ULONG ulOldMon = pInstance->lMonitor; /* Holds the status of the
|
|---|
| 436 | // instance monitor */
|
|---|
| 437 | ULONG ulSetFlags = VSD_SET_ALL;
|
|---|
| 438 |
|
|---|
| 439 | /*----------------------------------------
|
|---|
| 440 | * Monitor requires that the paramter be
|
|---|
| 441 | * non-zero if on, 0 (FALSE) if not.
|
|---|
| 442 | *----------------------------------------*/
|
|---|
| 443 |
|
|---|
| 444 | if ( pRequest )
|
|---|
| 445 | {
|
|---|
| 446 | pInstance->lMonitor = TRUE;
|
|---|
| 447 | }
|
|---|
| 448 | else
|
|---|
| 449 | {
|
|---|
| 450 | pInstance->lMonitor = FALSE;
|
|---|
| 451 | }
|
|---|
| 452 | if ( pInstance->fHardwareMix )
|
|---|
| 453 | {
|
|---|
| 454 | ulSetFlags = VSD_SET_MONITOR;
|
|---|
| 455 | }
|
|---|
| 456 | /*-----------------------------------------------------
|
|---|
| 457 | * if we opened a real mixer (i.e no AUDIODD), then the
|
|---|
| 458 | * IOCTLs will not be necessary.
|
|---|
| 459 | *----------------------------------------------------*/
|
|---|
| 460 | lError = ModifyAudioAttributes(pInstance, ulSetFlags );
|
|---|
| 461 |
|
|---|
| 462 | } /* VSD_SET_MONITOR */
|
|---|
| 463 | break;
|
|---|
| 464 |
|
|---|
| 465 | case VSD_SETVOLUME :
|
|---|
| 466 | {
|
|---|
| 467 | PVSD_VOLUME_PARMS pVol;
|
|---|
| 468 | ULONG ulSetRequired = TRUE;
|
|---|
| 469 | // MIXERCONTROL MixerControl;
|
|---|
| 470 |
|
|---|
| 471 |
|
|---|
| 472 | pVol = ( PVSD_VOLUME_PARMS ) pRequest;
|
|---|
| 473 | ulFlags = VSD_SET_VOLUME;
|
|---|
| 474 |
|
|---|
| 475 | if ( pVol->ulFlags & VSD_VOLUME )
|
|---|
| 476 | {
|
|---|
| 477 | // See if we can avoid processing, if the mixer is present... @PR1
|
|---|
| 478 | //
|
|---|
| 479 | if ( pInstance->fHardwareMix )
|
|---|
| 480 | {
|
|---|
| 481 | if ( pInstance->lLeftVolume != pVol->ulVolume)
|
|---|
| 482 | {
|
|---|
| 483 | pInstance->lLeftVolume = pVol->ulVolume;
|
|---|
| 484 | }
|
|---|
| 485 | else
|
|---|
| 486 | {
|
|---|
| 487 | // the value hasn't changed--no point modifying the driver.
|
|---|
| 488 |
|
|---|
| 489 | ulSetRequired = FALSE;
|
|---|
| 490 | }
|
|---|
| 491 | } // End if the mixer if present @PR1
|
|---|
| 492 | else // No mixer present, just set the desired volume @PR1
|
|---|
| 493 | { //@PR1
|
|---|
| 494 | pInstance->lLeftVolume = pVol->ulVolume; //@PR1
|
|---|
| 495 | } //@PR1
|
|---|
| 496 | ulFlags = VSD_SET_VOLUME;
|
|---|
| 497 | pInstance->ulVSDFlags |= VSD_VOLUME_KNOWN;
|
|---|
| 498 | }
|
|---|
| 499 |
|
|---|
| 500 | if ( pVol->ulFlags & VSD_MASTERVOLUME )
|
|---|
| 501 | {
|
|---|
| 502 | pInstance->ulMasterVolume = pVol->ulMasterAudio;
|
|---|
| 503 | ulFlags = VSD_SET_MASTER;
|
|---|
| 504 | } /* Mastervolume flag is passed in */
|
|---|
| 505 |
|
|---|
| 506 | if ( pVol->ulFlags & VSD_MUTE )
|
|---|
| 507 | {
|
|---|
| 508 | if ( pInstance->fHardwareMix )
|
|---|
| 509 | {
|
|---|
| 510 | ulFlags = VSD_SET_MUTE;
|
|---|
| 511 | }
|
|---|
| 512 | else
|
|---|
| 513 | {
|
|---|
| 514 | ulFlags = VSD_SET_MUTE | VSD_SET_VOLUME;
|
|---|
| 515 | }
|
|---|
| 516 | pInstance->fMute = pVol->fMute;
|
|---|
| 517 | ulSetRequired = TRUE;
|
|---|
| 518 | } /* Mute flag is passed in */
|
|---|
| 519 |
|
|---|
| 520 | #ifdef PERFORMANCE_TRACE
|
|---|
| 521 | // console_printf("setting volume\n");
|
|---|
| 522 | #endif
|
|---|
| 523 |
|
|---|
| 524 | if ( ulSetRequired )
|
|---|
| 525 | {
|
|---|
| 526 | lError = ModifyAudioAttributes( pInstance, ulFlags );
|
|---|
| 527 | }
|
|---|
| 528 | }
|
|---|
| 529 | break;
|
|---|
| 530 | case VSD_SETAUDIOATTRIBUTES:
|
|---|
| 531 | {
|
|---|
| 532 | PVSD_AUDIOATTRIBUTES_PARMS pAudioAttr;
|
|---|
| 533 |
|
|---|
| 534 | pAudioAttr = ( PVSD_AUDIOATTRIBUTES_PARMS ) pRequest;
|
|---|
| 535 |
|
|---|
| 536 | if ( pAudioAttr->ulFlags == VSD_TREBLE )
|
|---|
| 537 | {
|
|---|
| 538 |
|
|---|
| 539 | pInstance->lTreble = pAudioAttr->ulValue;
|
|---|
| 540 | ulFlags = VSD_SET_TREBLE;
|
|---|
| 541 | }
|
|---|
| 542 |
|
|---|
| 543 | if ( pAudioAttr->ulFlags == VSD_BASS )
|
|---|
| 544 | {
|
|---|
| 545 | pInstance->lBass = pAudioAttr->ulValue;
|
|---|
| 546 | ulFlags = VSD_SET_BASS;
|
|---|
| 547 | }
|
|---|
| 548 |
|
|---|
| 549 | if ( pAudioAttr->ulFlags == VSD_PITCH )
|
|---|
| 550 | {
|
|---|
| 551 | pInstance->lPitch = pAudioAttr->ulValue;
|
|---|
| 552 | ulFlags = VSD_SET_PITCH;
|
|---|
| 553 | }
|
|---|
| 554 |
|
|---|
| 555 | if ( pAudioAttr->ulFlags == VSD_BALANCE )
|
|---|
| 556 | {
|
|---|
| 557 | pInstance->lBalance = pAudioAttr->ulValue;
|
|---|
| 558 |
|
|---|
| 559 | if ( pInstance->fHardwareMix )
|
|---|
| 560 | {
|
|---|
| 561 | ulFlags = VSD_SET_BALANCE;
|
|---|
| 562 | }
|
|---|
| 563 | else
|
|---|
| 564 | {
|
|---|
| 565 | ulFlags = VSD_SET_BALANCE | VSD_VOLUME;
|
|---|
| 566 | }
|
|---|
| 567 | }
|
|---|
| 568 |
|
|---|
| 569 | if ( pAudioAttr->ulFlags == VSD_GAIN )
|
|---|
| 570 | {
|
|---|
| 571 | pInstance->ulGainLevel = pAudioAttr->ulValue;
|
|---|
| 572 |
|
|---|
| 573 | if ( pInstance->fHardwareMix )
|
|---|
| 574 | {
|
|---|
| 575 | ulFlags = VSD_SET_GAIN;
|
|---|
| 576 | }
|
|---|
| 577 | else
|
|---|
| 578 | {
|
|---|
| 579 | ulFlags = VSD_SET_GAIN | VSD_VOLUME;
|
|---|
| 580 | }
|
|---|
| 581 | }
|
|---|
| 582 |
|
|---|
| 583 |
|
|---|
| 584 | lError = ModifyAudioAttributes(pInstance, ulFlags );
|
|---|
| 585 |
|
|---|
| 586 | } /* case set audio attributes */
|
|---|
| 587 |
|
|---|
| 588 | break;
|
|---|
| 589 | case VSD_SETMIXCONNECTIONS:
|
|---|
| 590 | if ( pInstance->fHardwareMix )
|
|---|
| 591 | {
|
|---|
| 592 | lError = mixSetConnections ( pInstance->hMix,
|
|---|
| 593 | ( PLINECONNECTIONS ) pRequest );
|
|---|
| 594 | }
|
|---|
| 595 | else
|
|---|
| 596 | {
|
|---|
| 597 | lError = VSDERR_UNSUPPORTED_COMMAND;
|
|---|
| 598 | }
|
|---|
| 599 | break;
|
|---|
| 600 | case VSD_SETMIXCONTROL:
|
|---|
| 601 | if ( pInstance->fHardwareMix )
|
|---|
| 602 | {
|
|---|
| 603 | // 16061
|
|---|
| 604 | if ( LineSupport( pInstance, ( PMIXERCONTROL ) pRequest ) )
|
|---|
| 605 | {
|
|---|
| 606 | lError = mixSetControl ( pInstance->hMix,
|
|---|
| 607 | ( PMIXERCONTROL ) pRequest );
|
|---|
| 608 |
|
|---|
| 609 | // this may change the volume value so we can't
|
|---|
| 610 | // cache volume requests.
|
|---|
| 611 |
|
|---|
| 612 | pInstance->ulVSDFlags &= ~VSD_VOLUME_KNOWN;
|
|---|
| 613 | }
|
|---|
| 614 | else
|
|---|
| 615 | {
|
|---|
| 616 | lError = MCIERR_UNSUPPORTED_ATTRIBUTE;
|
|---|
| 617 | }
|
|---|
| 618 | // 16061
|
|---|
| 619 | }
|
|---|
| 620 | else
|
|---|
| 621 | {
|
|---|
| 622 | lError = VSDERR_UNSUPPORTED_COMMAND;
|
|---|
| 623 | }
|
|---|
| 624 |
|
|---|
| 625 | break;
|
|---|
| 626 |
|
|---|
| 627 | case VSD_SETDISPLAY :
|
|---|
| 628 | case VSD_SETINPUTLEVEL :
|
|---|
| 629 | case VSD_SETDOOR :
|
|---|
| 630 | case VSD_SETCOMMSETTINGS :
|
|---|
| 631 | case VSD_SETRATE :
|
|---|
| 632 | case VSD_SETKEYLOCK :
|
|---|
| 633 | case VSD_SETCUE :
|
|---|
| 634 | case VSD_SETCOUNTER :
|
|---|
| 635 | case VSD_SETPOSITION :
|
|---|
| 636 | case VSD_SETDIRECTION :
|
|---|
| 637 | case VSD_SETVIEWPORTPOSITION:
|
|---|
| 638 | case VSD_SETVIEWPORT :
|
|---|
| 639 | case VSD_SETIMAGEFORMAT :
|
|---|
| 640 | lError = VSDERR_UNSUPPORTED_FLAG;
|
|---|
| 641 | break;
|
|---|
| 642 |
|
|---|
| 643 |
|
|---|
| 644 | /*--------------------------------------------------------------------------------
|
|---|
| 645 | * The IBM Amp-mixer device has the notion of logical connections. See below:
|
|---|
| 646 | *
|
|---|
| 647 | * Input Output
|
|---|
| 648 | * -------------------------------------
|
|---|
| 649 | * | |
|
|---|
| 650 | * Microphone - | |-Speakers (Internal and External)
|
|---|
| 651 | * Line In - | Mixer Device |-Headphones
|
|---|
| 652 | * Internal Audio - | |-
|
|---|
| 653 | * | |
|
|---|
| 654 | * Amp Stream - | |
|
|---|
| 655 | * | |
|
|---|
| 656 | * ------------------------------------
|
|---|
| 657 | *
|
|---|
| 658 | * However, the logical mixer device performs no checking on the type of connectors
|
|---|
| 659 | * so, vendors can easily add support for additional connectors. The logical mixer
|
|---|
| 660 | * device takes the request to enable, disable or query the connector and forwards
|
|---|
| 661 | * it directly to the VSD. The VSD should either perform the action or return
|
|---|
| 662 | * one of the following errors:
|
|---|
| 663 | *
|
|---|
| 664 | * VSDERR_UNSUPPORTED_CONN_TYPE
|
|---|
| 665 | * VSDERR_CANNOT_MODIFY_CONNECTOR
|
|---|
| 666 | * VSDERR_INVALID_CONNECTOR_TYPE
|
|---|
| 667 | *-------------------------------------------------------------------------------*/
|
|---|
| 668 |
|
|---|
| 669 |
|
|---|
| 670 | case VSD_SETCONNECTOR:
|
|---|
| 671 | {
|
|---|
| 672 | PVSD_CONNECTOR_PARMS pVsdCon;
|
|---|
| 673 | // 15552
|
|---|
| 674 | BOOL fSetRequired = FALSE;
|
|---|
| 675 | extern ULONG ulInputDevice;
|
|---|
| 676 | extern ULONG ulOutputDevice;
|
|---|
| 677 | extern HMTX hmtxProcessSemVSD;
|
|---|
| 678 | // 15552
|
|---|
| 679 |
|
|---|
| 680 | pVsdCon = ( PVSD_CONNECTOR_PARMS ) pRequest;
|
|---|
| 681 |
|
|---|
| 682 | if ( pVsdCon->ulConn_Type == MCI_HEADPHONES_CONNECTOR ||
|
|---|
| 683 | pVsdCon->ulConn_Type == MCI_VIDEO_IN_CONNECTOR ||
|
|---|
| 684 | pVsdCon->ulConn_Type == MCI_VIDEO_OUT_CONNECTOR ||
|
|---|
| 685 | pVsdCon->ulConn_Type == MCI_PHONE_SET_CONNECTOR ||
|
|---|
| 686 | pVsdCon->ulConn_Type == MCI_PHONE_LINE_CONNECTOR ||
|
|---|
| 687 | pVsdCon->ulConn_Type == MCI_UNIVERSAL_CONNECTOR ||
|
|---|
| 688 | pVsdCon->ulConn_Type == MCI_MIDI_STREAM_CONNECTOR ||
|
|---|
| 689 | pVsdCon->ulConn_Type == MCI_CD_STREAM_CONNECTOR ||
|
|---|
| 690 | pVsdCon->ulConn_Type == MCI_WAVE_STREAM_CONNECTOR )
|
|---|
| 691 | {
|
|---|
| 692 | return ( VSDERR_UNSUPPORTED_CONN_TYPE );
|
|---|
| 693 | }
|
|---|
| 694 |
|
|---|
| 695 | if ( lError = ValidateIndex( pVsdCon->ulConn_Type, pVsdCon->ulIndex ) )
|
|---|
| 696 | {
|
|---|
| 697 | return (lError );
|
|---|
| 698 | }
|
|---|
| 699 |
|
|---|
| 700 | if ( pVsdCon->ulConn_Type == MCI_AMP_STREAM_CONNECTOR )
|
|---|
| 701 | {
|
|---|
| 702 | return ( VSDERR_CANNOT_MODIFY_CONNECTOR );
|
|---|
| 703 | }
|
|---|
| 704 |
|
|---|
| 705 | /*--------------------------------------------------
|
|---|
| 706 | * Does the device support the new mixer IOCTL set?
|
|---|
| 707 | * If it does, then enabling the connectors will
|
|---|
| 708 | * utilze the new IOCTL set.
|
|---|
| 709 | *-------------------------------------------------*/
|
|---|
| 710 | if ( pInstance->fHardwareMix )
|
|---|
| 711 | {
|
|---|
| 712 | LINECONNECTIONS mixinfo;
|
|---|
| 713 |
|
|---|
| 714 | /* The MCI connectors map directly to mixer connectors */
|
|---|
| 715 |
|
|---|
| 716 | mixinfo.ulLine = pVsdCon->ulConn_Type;
|
|---|
| 717 | /*--------------------------------------------------
|
|---|
| 718 | * The instance variables, ulInputDev and ulOutputDev
|
|---|
| 719 | * contain a bitmap of the enabled connectors.
|
|---|
| 720 | * Update the state of the connectors due to the
|
|---|
| 721 | * request to enable/disable.
|
|---|
| 722 | *-------------------------------------------------*/
|
|---|
| 723 |
|
|---|
| 724 | if (( pVsdCon->fEnabled == VSD_ENABLE ) &&
|
|---|
| 725 | ( pVsdCon->ulConn_Type == MCI_LINE_IN_CONNECTOR ||
|
|---|
| 726 | pVsdCon->ulConn_Type == MCI_AUDIO_IN_CONNECTOR ||
|
|---|
| 727 | pVsdCon->ulConn_Type == MCI_INTERNAL_AUDIO_CONNECTOR ||
|
|---|
| 728 | pVsdCon->ulConn_Type == MCI_MICROPHONE_CONNECTOR ))
|
|---|
| 729 | {
|
|---|
| 730 | /*-------------------------------------------------
|
|---|
| 731 | * To enable a connector to the source, must first
|
|---|
| 732 | * disable previous connectors.
|
|---|
| 733 | *------------------------------------------------*/
|
|---|
| 734 | ulSaveInputDev = pInstance->ulInputDev;
|
|---|
| 735 | switch( pVsdCon->ulConn_Type )
|
|---|
| 736 | {
|
|---|
| 737 | case MCI_LINE_IN_CONNECTOR :
|
|---|
| 738 | case MCI_AUDIO_IN_CONNECTOR :
|
|---|
| 739 | pInstance->ulInputDev = SOURCE_LINE;
|
|---|
| 740 |
|
|---|
| 741 | break;
|
|---|
| 742 | case MCI_INTERNAL_AUDIO_CONNECTOR :
|
|---|
| 743 | pInstance->ulInputDev = SOURCE_INTERNAL_AUDIO;
|
|---|
| 744 |
|
|---|
| 745 | break;
|
|---|
| 746 | case MCI_MICROPHONE_CONNECTOR :
|
|---|
| 747 | pInstance->ulInputDev = SOURCE_MICROPHONE;
|
|---|
| 748 |
|
|---|
| 749 | break;
|
|---|
| 750 | default :
|
|---|
| 751 | return ( VSDERR_INVALID_CONNECTOR_TYPE );
|
|---|
| 752 | } /* switch the connector type */
|
|---|
| 753 |
|
|---|
| 754 |
|
|---|
| 755 | DosRequestMutexSem ( hmtxProcessSemVSD, SEM_INDEFINITE_WAIT);
|
|---|
| 756 |
|
|---|
| 757 | // 15552
|
|---|
| 758 | if ( pInstance->ulInputDev != ulInputDevice )
|
|---|
| 759 | {
|
|---|
| 760 | // is there a connection to remove????
|
|---|
| 761 |
|
|---|
| 762 | if (ulSaveInputDev)
|
|---|
| 763 | {
|
|---|
| 764 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 765 | mixinfo.ulLine = ulSaveInputDev;
|
|---|
| 766 | mixinfo.ulLength = sizeof ( LINECONNECTIONS );
|
|---|
| 767 |
|
|---|
| 768 | // don't want to update the global variable here
|
|---|
| 769 | // wait until set is complete and successful.
|
|---|
| 770 | fSetRequired = TRUE;
|
|---|
| 771 | lError = mixSetConnections ( pInstance->hMix,
|
|---|
| 772 | &mixinfo );
|
|---|
| 773 | }
|
|---|
| 774 |
|
|---|
| 775 | mixinfo.ulConnection = SINK_WAVE;
|
|---|
| 776 | mixinfo.ulLine = pInstance->ulInputDev;
|
|---|
| 777 | mixinfo.ulLength = sizeof ( LINECONNECTIONS );
|
|---|
| 778 |
|
|---|
| 779 |
|
|---|
| 780 | ulInputDevice = pInstance->ulInputDev;
|
|---|
| 781 | if (lError = mixSetConnections ( pInstance->hMix,
|
|---|
| 782 | &mixinfo ))
|
|---|
| 783 | {
|
|---|
| 784 | /*-------------------------------------------------
|
|---|
| 785 | * Error enabling new source connector, must back
|
|---|
| 786 | * out to orginal connectors.
|
|---|
| 787 | *------------------------------------------------*/
|
|---|
| 788 | pInstance->ulInputDev = ulSaveInputDev;
|
|---|
| 789 | mixinfo.ulConnection = pInstance->ulOutputDev;
|
|---|
| 790 | mixinfo.ulLine = pInstance->ulInputDev;
|
|---|
| 791 | mixinfo.ulLength = sizeof ( LINECONNECTIONS );
|
|---|
| 792 |
|
|---|
| 793 | mixSetConnections ( pInstance->hMix,
|
|---|
| 794 | &mixinfo );
|
|---|
| 795 | }
|
|---|
| 796 | } // if the global connection differs from the isntance
|
|---|
| 797 | DosReleaseMutexSem (hmtxProcessSemVSD);
|
|---|
| 798 | // 15552
|
|---|
| 799 |
|
|---|
| 800 | } // enabling an input connector
|
|---|
| 801 | else
|
|---|
| 802 | {
|
|---|
| 803 | // 15552
|
|---|
| 804 | DosRequestMutexSem ( hmtxProcessSemVSD, SEM_INDEFINITE_WAIT);
|
|---|
| 805 | // 15552
|
|---|
| 806 | if ( pVsdCon->fEnabled == VSD_DISABLE )
|
|---|
| 807 | {
|
|---|
| 808 | switch( pVsdCon->ulConn_Type )
|
|---|
| 809 | {
|
|---|
| 810 | case MCI_LINE_IN_CONNECTOR :
|
|---|
| 811 | case MCI_AUDIO_IN_CONNECTOR :
|
|---|
| 812 | pInstance->ulInputDev &= ~SOURCE_LINE;
|
|---|
| 813 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 814 | mixinfo.ulLine = SOURCE_LINE;
|
|---|
| 815 | if ( pInstance->ulInputDev != ulInputDevice )
|
|---|
| 816 | {
|
|---|
| 817 | ulInputDevice = pInstance->ulInputDev;
|
|---|
| 818 | fSetRequired = TRUE;
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 |
|
|---|
| 822 | break;
|
|---|
| 823 | case MCI_INTERNAL_AUDIO_CONNECTOR :
|
|---|
| 824 | pInstance->ulInputDev &= ~SOURCE_INTERNAL_AUDIO;
|
|---|
| 825 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 826 | mixinfo.ulLine = SOURCE_INTERNAL_AUDIO;
|
|---|
| 827 | if ( pInstance->ulInputDev != ulInputDevice )
|
|---|
| 828 | {
|
|---|
| 829 | ulInputDevice = pInstance->ulInputDev;
|
|---|
| 830 | fSetRequired = TRUE;
|
|---|
| 831 | }
|
|---|
| 832 |
|
|---|
| 833 | break;
|
|---|
| 834 | case MCI_MICROPHONE_CONNECTOR :
|
|---|
| 835 | pInstance->ulInputDev &= ~SOURCE_MICROPHONE;
|
|---|
| 836 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 837 | mixinfo.ulLine = SOURCE_MICROPHONE;
|
|---|
| 838 | if ( pInstance->ulInputDev != ulInputDevice )
|
|---|
| 839 | {
|
|---|
| 840 | ulInputDevice = pInstance->ulInputDev;
|
|---|
| 841 | fSetRequired = TRUE;
|
|---|
| 842 | }
|
|---|
| 843 |
|
|---|
| 844 | break;
|
|---|
| 845 | case MCI_LINE_OUT_CONNECTOR :
|
|---|
| 846 | case MCI_AUDIO_OUT_CONNECTOR :
|
|---|
| 847 | pInstance->ulOutputDev &= ~SINK_LINE_OUT;
|
|---|
| 848 | mixinfo.ulLine = SINK_LINE_OUT;
|
|---|
| 849 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 850 | // ensure that the global connections
|
|---|
| 851 | // have all the current instance values
|
|---|
| 852 |
|
|---|
| 853 | if ( !(OutputConnectionMatch(pInstance->ulOutputDev,FALSE)))
|
|---|
| 854 | {
|
|---|
| 855 | ulOutputDevice = pInstance->ulOutputDev;
|
|---|
| 856 | fSetRequired = TRUE;
|
|---|
| 857 | }
|
|---|
| 858 |
|
|---|
| 859 | break;
|
|---|
| 860 | case MCI_SPEAKERS_CONNECTOR :
|
|---|
| 861 | if ( pVsdCon->ulIndex == 1)
|
|---|
| 862 | {
|
|---|
| 863 | pInstance->ulOutputDev &= ~SINK_HEADPHONES;
|
|---|
| 864 | mixinfo.ulLine = SINK_HEADPHONES;
|
|---|
| 865 | }
|
|---|
| 866 | else
|
|---|
| 867 | {
|
|---|
| 868 | pInstance->ulOutputDev &= ~SINK_SPEAKER;
|
|---|
| 869 | mixinfo.ulLine = SINK_SPEAKER;
|
|---|
| 870 | }
|
|---|
| 871 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 872 | // ensure that the global connections
|
|---|
| 873 | // have all the current instance values
|
|---|
| 874 |
|
|---|
| 875 | if ( !(OutputConnectionMatch(pInstance->ulOutputDev,FALSE) ) )
|
|---|
| 876 | {
|
|---|
| 877 | ulOutputDevice = pInstance->ulOutputDev;
|
|---|
| 878 | fSetRequired = TRUE;
|
|---|
| 879 | }
|
|---|
| 880 | break;
|
|---|
| 881 |
|
|---|
| 882 | case MCI_HEADPHONES_CONNECTOR :
|
|---|
| 883 | pInstance->ulOutputDev &= ~SINK_HEADPHONES;
|
|---|
| 884 | mixinfo.ulConnection = SINK_NULL;
|
|---|
| 885 | mixinfo.ulLine = SINK_HEADPHONES;
|
|---|
| 886 | // ensure that the global connections
|
|---|
| 887 | // have all the current instance values
|
|---|
| 888 |
|
|---|
| 889 | if ( !(OutputConnectionMatch(pInstance->ulOutputDev,FALSE) ) )
|
|---|
| 890 | {
|
|---|
| 891 | ulOutputDevice = pInstance->ulOutputDev;
|
|---|
| 892 | fSetRequired = TRUE;
|
|---|
| 893 | }
|
|---|
| 894 | break;
|
|---|
| 895 | default :
|
|---|
| 896 | DosReleaseMutexSem (hmtxProcessSemVSD);
|
|---|
| 897 | return ( VSDERR_INVALID_CONNECTOR_TYPE );
|
|---|
| 898 | } /* switch the connector type */
|
|---|
| 899 | } // if disabling a connector
|
|---|
| 900 |
|
|---|
| 901 | else
|
|---|
| 902 | {
|
|---|
| 903 | // enabling a connector
|
|---|
| 904 | switch( pVsdCon->ulConn_Type )
|
|---|
| 905 | {
|
|---|
| 906 | case MCI_LINE_OUT_CONNECTOR :
|
|---|
| 907 | case MCI_AUDIO_OUT_CONNECTOR :
|
|---|
| 908 | pInstance->ulOutputDev |= SINK_LINE_OUT;
|
|---|
| 909 |
|
|---|
| 910 | break;
|
|---|
| 911 | case MCI_SPEAKERS_CONNECTOR :
|
|---|
| 912 | if ( pVsdCon->ulIndex == 1)
|
|---|
| 913 | pInstance->ulOutputDev |= SINK_HEADPHONES;
|
|---|
| 914 | else
|
|---|
| 915 | pInstance->ulOutputDev |= SINK_SPEAKER;
|
|---|
| 916 | break;
|
|---|
| 917 |
|
|---|
| 918 | case MCI_HEADPHONES_CONNECTOR :
|
|---|
| 919 | pInstance->ulOutputDev |= SINK_HEADPHONES;
|
|---|
| 920 | break;
|
|---|
| 921 | default :
|
|---|
| 922 | DosReleaseMutexSem (hmtxProcessSemVSD);
|
|---|
| 923 | return ( VSDERR_INVALID_CONNECTOR_TYPE );
|
|---|
| 924 | } /* switch the connector type */
|
|---|
| 925 |
|
|---|
| 926 | mixinfo.ulConnection = pInstance->ulOutputDev;
|
|---|
| 927 | /////////////////////////mixinfo.ulLine = pInstance->ulInputDev;
|
|---|
| 928 | mixinfo.ulLine = SOURCE_WAVE;
|
|---|
| 929 |
|
|---|
| 930 | // ensure that the global connections
|
|---|
| 931 | // have all the current instance values
|
|---|
| 932 |
|
|---|
| 933 | if ( !(OutputConnectionMatch(pInstance->ulOutputDev, TRUE ) ) )
|
|---|
| 934 | {
|
|---|
| 935 | ulOutputDevice = pInstance->ulOutputDev;
|
|---|
| 936 | fSetRequired = TRUE;
|
|---|
| 937 | }
|
|---|
| 938 |
|
|---|
| 939 | } /* if we should enable a connector */
|
|---|
| 940 |
|
|---|
| 941 | if ( fSetRequired )
|
|---|
| 942 | {
|
|---|
| 943 | mixinfo.ulLength = sizeof ( LINECONNECTIONS );
|
|---|
| 944 |
|
|---|
| 945 | /*-------------------------------
|
|---|
| 946 | * Enable/Disable the connector.
|
|---|
| 947 | *-------------------------------*/
|
|---|
| 948 |
|
|---|
| 949 | lError = mixSetConnections ( pInstance->hMix,
|
|---|
| 950 | &mixinfo );
|
|---|
| 951 | } // if a setting has changed from a global setting
|
|---|
| 952 | // then ensure that it is updated
|
|---|
| 953 |
|
|---|
| 954 | // 15552
|
|---|
| 955 | DosReleaseMutexSem (hmtxProcessSemVSD);
|
|---|
| 956 | // 15552
|
|---|
| 957 | } // else not touching an input connector
|
|---|
| 958 |
|
|---|
| 959 | } // new mixer interface supported
|
|---|
| 960 |
|
|---|
| 961 | else
|
|---|
| 962 | {
|
|---|
| 963 | // 15552
|
|---|
| 964 |
|
|---|
| 965 | #ifdef INCL_MM_OS2
|
|---|
| 966 | /* If the caller wishes to disable a connector */
|
|---|
| 967 |
|
|---|
| 968 | if ( pVsdCon->fEnabled == VSD_DISABLE)
|
|---|
| 969 | {
|
|---|
| 970 | switch( pVsdCon->ulConn_Type )
|
|---|
| 971 | {
|
|---|
| 972 | case MCI_LINE_IN_CONNECTOR:
|
|---|
| 973 | case MCI_AUDIO_IN_CONNECTOR :
|
|---|
| 974 | if ( StatusIOPort( STEREO_LINE_INPUT, pInstance, INPUT_PORT ) == MCI_TRUE )
|
|---|
| 975 | {
|
|---|
| 976 | lError = RemoveIOPort( STEREO_LINE_INPUT,
|
|---|
| 977 | pInstance,
|
|---|
| 978 | INPUT_PORT );
|
|---|
| 979 | }
|
|---|
| 980 |
|
|---|
| 981 | break;
|
|---|
| 982 |
|
|---|
| 983 | case MCI_MICROPHONE_CONNECTOR:
|
|---|
| 984 | if ( pInstance->ulGainLevel >= 70 )
|
|---|
| 985 | {
|
|---|
| 986 | ulMicType = BOOSTED_MIC_INPUT;
|
|---|
| 987 | }
|
|---|
| 988 | else
|
|---|
| 989 | {
|
|---|
| 990 | ulMicType = MIC_INPUT;
|
|---|
| 991 | }
|
|---|
| 992 | if ( StatusIOPort( ulMicType,
|
|---|
| 993 | pInstance,
|
|---|
| 994 | INPUT_PORT ) == MCI_TRUE )
|
|---|
| 995 | {
|
|---|
| 996 | lError = RemoveIOPort( ulMicType,
|
|---|
| 997 | pInstance,
|
|---|
| 998 | INPUT_PORT );
|
|---|
| 999 | }
|
|---|
| 1000 |
|
|---|
| 1001 | break;
|
|---|
| 1002 |
|
|---|
| 1003 | case MCI_LINE_OUT_CONNECTOR:
|
|---|
| 1004 | case MCI_AUDIO_OUT_CONNECTOR :
|
|---|
| 1005 | if ( StatusIOPort( STEREO_LINE_OUTPUT, pInstance, OUTPUT_PORT ) == MCI_TRUE )
|
|---|
| 1006 | {
|
|---|
| 1007 | lError = RemoveIOPort( STEREO_LINE_OUTPUT,
|
|---|
| 1008 | pInstance,
|
|---|
| 1009 | OUTPUT_PORT );
|
|---|
| 1010 | }
|
|---|
| 1011 |
|
|---|
| 1012 | break;
|
|---|
| 1013 |
|
|---|
| 1014 | case MCI_SPEAKERS_CONNECTOR:
|
|---|
| 1015 | if ( pVsdCon->ulIndex == 2 )
|
|---|
| 1016 | {
|
|---|
| 1017 | ulSpeakerType = SPEAKER_OUTPUT;
|
|---|
| 1018 | }
|
|---|
| 1019 | else
|
|---|
| 1020 | {
|
|---|
| 1021 | ulSpeakerType = HEADSET_OUTPUT;
|
|---|
| 1022 | }
|
|---|
| 1023 | if ( StatusIOPort( ulSpeakerType, pInstance, OUTPUT_PORT ) == MCI_TRUE )
|
|---|
| 1024 | {
|
|---|
| 1025 | lError = RemoveIOPort( ulSpeakerType,
|
|---|
| 1026 | pInstance,
|
|---|
| 1027 | OUTPUT_PORT );
|
|---|
| 1028 | }
|
|---|
| 1029 |
|
|---|
| 1030 | break;
|
|---|
| 1031 |
|
|---|
| 1032 |
|
|---|
| 1033 | case MCI_HEADPHONES_CONNECTOR:
|
|---|
| 1034 | case MCI_VIDEO_IN_CONNECTOR :
|
|---|
| 1035 | case MCI_VIDEO_OUT_CONNECTOR :
|
|---|
| 1036 | case MCI_PHONE_SET_CONNECTOR :
|
|---|
| 1037 | case MCI_PHONE_LINE_CONNECTOR :
|
|---|
| 1038 | case MCI_UNIVERSAL_CONNECTOR :
|
|---|
| 1039 |
|
|---|
| 1040 | lError = VSDERR_UNSUPPORTED_CONN_TYPE;
|
|---|
| 1041 | break;
|
|---|
| 1042 | default:
|
|---|
| 1043 | lError = VSDERR_INVALID_CONNECTOR_TYPE;
|
|---|
| 1044 | break;
|
|---|
| 1045 | } /* switch connector type */
|
|---|
| 1046 |
|
|---|
| 1047 | if ( pInstance->ulActive )
|
|---|
| 1048 | {
|
|---|
| 1049 | ModifyAudioAttributes(pInstance, VSD_SET_ALL );
|
|---|
| 1050 | }
|
|---|
| 1051 |
|
|---|
| 1052 | } /* if disabling a connector */
|
|---|
| 1053 |
|
|---|
| 1054 | else
|
|---|
| 1055 | {
|
|---|
| 1056 | /*-------------------------------------------------------------*
|
|---|
| 1057 | * Enable connector
|
|---|
| 1058 | *-------------------------------------------------------------*/
|
|---|
| 1059 |
|
|---|
| 1060 | switch( pVsdCon->ulConn_Type )
|
|---|
| 1061 | {
|
|---|
| 1062 | case MCI_LINE_IN_CONNECTOR :
|
|---|
| 1063 | case MCI_AUDIO_IN_CONNECTOR :
|
|---|
| 1064 | if (StatusIOPort( STEREO_LINE_INPUT, pInstance, INPUT_PORT ) != MCI_TRUE )
|
|---|
| 1065 | {
|
|---|
| 1066 | lError = AddIOPort( STEREO_LINE_INPUT,
|
|---|
| 1067 | pInstance,
|
|---|
| 1068 | INPUT_PORT );
|
|---|
| 1069 | }
|
|---|
| 1070 | break;
|
|---|
| 1071 |
|
|---|
| 1072 | case MCI_MICROPHONE_CONNECTOR:
|
|---|
| 1073 | if ( pInstance->ulGainLevel >= 70 )
|
|---|
| 1074 | {
|
|---|
| 1075 | ulMicType = BOOSTED_MIC_INPUT;
|
|---|
| 1076 | }
|
|---|
| 1077 | else
|
|---|
| 1078 | {
|
|---|
| 1079 | ulMicType = MIC_INPUT;
|
|---|
| 1080 | }
|
|---|
| 1081 | if ( StatusIOPort( ulMicType, pInstance, INPUT_PORT ) != MCI_TRUE )
|
|---|
| 1082 | {
|
|---|
| 1083 | lError = AddIOPort( ulMicType,
|
|---|
| 1084 | pInstance,
|
|---|
| 1085 | INPUT_PORT );
|
|---|
| 1086 | }
|
|---|
| 1087 | break;
|
|---|
| 1088 |
|
|---|
| 1089 | case MCI_LINE_OUT_CONNECTOR:
|
|---|
| 1090 | case MCI_AUDIO_OUT_CONNECTOR :
|
|---|
| 1091 | if (StatusIOPort( STEREO_LINE_OUTPUT, pInstance, OUTPUT_PORT ) != MCI_TRUE)
|
|---|
| 1092 | {
|
|---|
| 1093 | lError = AddIOPort( STEREO_LINE_OUTPUT,
|
|---|
| 1094 | pInstance,
|
|---|
| 1095 | OUTPUT_PORT );
|
|---|
| 1096 | }
|
|---|
| 1097 |
|
|---|
| 1098 | break;
|
|---|
| 1099 |
|
|---|
| 1100 | case MCI_SPEAKERS_CONNECTOR:
|
|---|
| 1101 | if ( pVsdCon->ulIndex == 2 )
|
|---|
| 1102 | {
|
|---|
| 1103 | ulSpeakerType = SPEAKER_OUTPUT;
|
|---|
| 1104 | }
|
|---|
| 1105 | else
|
|---|
| 1106 | {
|
|---|
| 1107 | ulSpeakerType = HEADSET_OUTPUT;
|
|---|
| 1108 | }
|
|---|
| 1109 |
|
|---|
| 1110 | if (StatusIOPort( ulSpeakerType, pInstance, OUTPUT_PORT ) != MCI_TRUE )
|
|---|
| 1111 | {
|
|---|
| 1112 | lError = AddIOPort( ulSpeakerType,
|
|---|
| 1113 | pInstance,
|
|---|
| 1114 | OUTPUT_PORT );
|
|---|
| 1115 | }
|
|---|
| 1116 | break;
|
|---|
| 1117 |
|
|---|
| 1118 | default:
|
|---|
| 1119 | lError = VSDERR_INVALID_CONNECTOR_TYPE;
|
|---|
| 1120 | break;
|
|---|
| 1121 | } /* switch connector type */
|
|---|
| 1122 |
|
|---|
| 1123 | /*-----------------------------------------------------
|
|---|
| 1124 | * if we opened a real mixer (i.e no AUDIODD), then the
|
|---|
| 1125 | * IOCTLs will not be necessary.
|
|---|
| 1126 | *----------------------------------------------------*/
|
|---|
| 1127 |
|
|---|
| 1128 | if ( pInstance->ulActive && !pInstance->fHardwareMix )
|
|---|
| 1129 | {
|
|---|
| 1130 | ModifyAudioAttributes(pInstance, VSD_SET_ALL );
|
|---|
| 1131 | }
|
|---|
| 1132 | } /* else enable a connector */
|
|---|
| 1133 | #endif
|
|---|
| 1134 | // 15552
|
|---|
| 1135 | } /* else no hardware mixing functions */
|
|---|
| 1136 |
|
|---|
| 1137 | } /* set connector case */
|
|---|
| 1138 | break;
|
|---|
| 1139 | } /* switch ulFlags */
|
|---|
| 1140 |
|
|---|
| 1141 | return(lError);
|
|---|
| 1142 |
|
|---|
| 1143 | } /* VsdSetCommand */
|
|---|
| 1144 |
|
|---|
| 1145 |
|
|---|
| 1146 | /************************** START OF SPECIFICATIONS ************************
|
|---|
| 1147 | * *
|
|---|
| 1148 | * SUBROUTINE NAME: RemoveDeviceCaps *
|
|---|
| 1149 | * *
|
|---|
| 1150 | * DESCRIPTIVE NAME: Removes linked list of global capabilities. Only *
|
|---|
| 1151 | * called when last process is terminating. *
|
|---|
| 1152 | * *
|
|---|
| 1153 | *************************** END OF SPECIFICATIONS **************************/
|
|---|
| 1154 | BOOL OutputConnectionMatch( ULONG ulInstanceOutput, BOOL fAdd )
|
|---|
| 1155 |
|
|---|
| 1156 | {
|
|---|
| 1157 | extern ULONG ulOutputDevice;
|
|---|
| 1158 |
|
|---|
| 1159 | if ( fAdd )
|
|---|
| 1160 | {
|
|---|
| 1161 | if ( ulInstanceOutput & SINK_LINE_OUT &&
|
|---|
| 1162 | !(ulOutputDevice & SINK_LINE_OUT))
|
|---|
| 1163 | {
|
|---|
| 1164 | return ( FALSE );
|
|---|
| 1165 | }
|
|---|
| 1166 |
|
|---|
| 1167 | if ( ulInstanceOutput & SINK_SPEAKER &&
|
|---|
| 1168 | !(ulOutputDevice & SINK_SPEAKER))
|
|---|
| 1169 | {
|
|---|
| 1170 | return ( FALSE );
|
|---|
| 1171 | }
|
|---|
| 1172 |
|
|---|
| 1173 | if ( ulInstanceOutput & SINK_HEADPHONES &&
|
|---|
| 1174 | !(ulOutputDevice & SINK_HEADPHONES))
|
|---|
| 1175 | {
|
|---|
| 1176 | return ( FALSE );
|
|---|
| 1177 | }
|
|---|
| 1178 | }
|
|---|
| 1179 | else
|
|---|
| 1180 | {
|
|---|
| 1181 | if ( (ulOutputDevice & SINK_LINE_OUT) &&
|
|---|
| 1182 | !(ulInstanceOutput & SINK_LINE_OUT))
|
|---|
| 1183 | {
|
|---|
| 1184 | return ( FALSE );
|
|---|
| 1185 | }
|
|---|
| 1186 |
|
|---|
| 1187 | if ( (ulOutputDevice & SINK_SPEAKER) &&
|
|---|
| 1188 | !(ulInstanceOutput & SINK_SPEAKER))
|
|---|
| 1189 | {
|
|---|
| 1190 | return ( FALSE );
|
|---|
| 1191 | }
|
|---|
| 1192 |
|
|---|
| 1193 | if ( (ulOutputDevice & SINK_HEADPHONES) &&
|
|---|
| 1194 | !(ulInstanceOutput & SINK_HEADPHONES))
|
|---|
| 1195 | {
|
|---|
| 1196 | return ( FALSE );
|
|---|
| 1197 | }
|
|---|
| 1198 | }
|
|---|
| 1199 |
|
|---|
| 1200 | return ( TRUE );
|
|---|
| 1201 | }
|
|---|