source: cmedia/trunk/Vsd/AudioIF/vsdset.c@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 45.0 KB
Line 
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
90LONG 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 **************************/
1154BOOL 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}
Note: See TracBrowser for help on using the repository browser.