source: cmedia/trunk/Vsd/AudioIF/audioif.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: 18.3 KB
Line 
1/************************* START OF SPECIinCATIONS ***
2*
3* SOURCE FILE NAME: AUDIOIF.C
4*
5* DESCRIPTIVE NAME: Ring 3 Amp/Mixer AUDIO Interface Driver
6*
7* COPYRIGHT: IBM Confidential
8* Copyright (c) IBM Corporation 1991
9* All Rights Reserved
10*
11* STATUS: OS/2 Release 2.0
12*
13* FUNCTION: This source module contains the ring 3 (DLL) entry point for
14* MCD Amp/Mixer calls from the Amp/Mixer or Audio Stream Handler.
15* The Mixer MCI driver will call the VSD to setup for the correct
16* mode and manipulate audio attributes. The Audio Stream Handler
17* will pass data buffers to/from the audio device.
18*
19* Currently, there is only one entry point for a new VSD. This
20* VSD contains two for backwards compatibility with older
21* apps that talked to a private VSD interface.
22*
23*
24* Architecture :
25* Logical Mixer Device
26* ------------------------------------------------
27* | AMPMXMCD.DLL | VSD |
28* | (Device | (Device Dependent) |
29* | Independent) <---> |
30* | | |
31* |-------------------|---------------------------|
32* /\
33* |
34* | Buffers
35* |
36* \/
37* ----------- Buffers -----------------------
38* | SSM | <---------> | Audio Stream Handler |
39* ---------- -----------------------
40*
41*
42*
43
44*
45* NOTES:
46* DEPENDENCIES: This implementation of the VSD requires
47* an AUDIODD device driver. OEM implementations
48* do not.
49* RESTRICTIONS: Runs at user level.
50*
51* ENTRY POINT:
52* AUDIOIFDriverEntry
53*
54* EXTERNAL REFERENCES: Sends IOCTL request to ACPA audio board
55*
56* Change History:
57* DATE DEVELOPER CHANGE DESCRIPTION
58* 12/07/92 Linden deCarmo File created
59* 05/24/94 Linden deCarmo Cleaned up comments
60* 06/15/94 Linden deCarmo Cleaned up comments again.
61* 06/15/94 Linden deCarmo Removed AUDIOIF Device name
62* 06/15/94 Linden deCarmo Removed usMasterVol-not used.
63* 06/15/94 Linden deCarmo Fixed DLLInitTerm to create/open
64* global semaphore.
65* 06/19/94 Linden deCarmo Removed GetProdInfo--functionality in mixer.
66* 06/19/94 Linden deCarmo Cleaned DLLInit comments.
67* 06/29/95 Linden deCarmo Cleanup Hardware mixer support (15552).
68************************** END OF SPECIFICATIONS **************************/
69
70#define INCL_NOPMAPI
71#define INCL_DOS
72#define INCL_ERRORS
73#define INCL_AUDIO_VSD
74
75#include <os2.h>
76#include <os2me.h>
77#include <mcd.h>
78#include <audio.h>
79#include <stdio.h>
80#include <string.h>
81#include <hhpheap.h>
82#include <checkmem.h>
83
84#include <vsdcmds.h>
85#include <vsdaud.h>
86#include <os2mixer.h>
87#include <mmdsload.h> // MM_DosLoadModule @LP01
88
89
90#define AUDIOIF_MULTIPLIER 0x147AE14 // 0x7FFFFFFF / 100
91#define AUDIOIF_DIVISOR 0x147 // 0x7fff / 100 -- get one word
92#define NOT_INITIALIZED -1
93
94#define FAILURE 0L
95#define SUCCESS 1L
96#define VSD_SEM_NAME "\\SEM32\\AUDIOIF"
97
98
99
100/************************ START OF SPECIFICATIONS **************************
101*
102* SUBROUTINE NAME: VSDEntry
103*
104* FUNCTION: Ring 3 entry point for AUDIOIF calls from Amp/Mixer
105*
106* INPUT: HVSD hvsd Handle to the VSD
107* ULONG ulFunc Function to operate (i.e. VSD_OPEN, VSD_SET etc.)
108* ULONG ulFlags Flags to manipulate function
109* PVOID pRequest Pointer to function specific parameter.
110*
111* OUTPUT: returns VSDERR_SUCCESS if successful, otherwise it returns an
112* MCI error code.
113*
114* OS/2 CALLS: None
115*
116* C CALLS: None
117*
118* INTERNAL CALLS:
119*
120*************************** END OF SPECIFICATIONS *************************/
121
122ULONG APIENTRY MM_VSDEntry( HVSD hvsd,
123 ULONG ulFunc,
124 ULONG ulFlags,
125 PVOID pRequest )
126
127 {
128 LONG lError = VSDERR_SUCCESS;
129#ifdef PERFORMANCE_TRACE
130// ULONG ulTime = 0;
131// CHAR LoadError[100];
132// CHAR DebugBuf[256];
133// PerfStartTime();
134#endif
135
136 switch( ulFunc )
137 {
138
139 /**************************************
140 * Required functions for all VSD's.
141 **************************************/
142 /********************************************
143 * The first call a VSD will receive is an OPEN
144 *********************************************/
145
146 case VSD_OPEN :
147
148 lError = VSDOpen( ( PVSD_OPEN_PARMS ) pRequest );
149 break;
150
151 case VSD_DEVUNITS :
152 lError = VSDDevUnits( ( PVSD_INSTANCE ) hvsd, ( PVSD_DEVUNITS_PARMS )pRequest );
153 break;
154
155 case VSD_RESOURCE :
156 lError = VSDResource( ( PVSD_INSTANCE ) hvsd, ( PVSD_RESOURCE_PARMS ) pRequest );
157 break;
158
159
160 case VSD_RESTORE:
161
162#ifdef INCL_MM_WPOS
163 lError = VSDRestore( ( PVSD_INSTANCE ) hvsd, ( PVSD_RESTORE_PARMS ) pRequest );
164#else
165 lError = VSDRestore( ( PVSD_INSTANCE ) hvsd);
166
167#endif
168 break;
169
170 case VSD_SAVE:
171 lError = VSDSave( ( PVSD_INSTANCE ) hvsd );
172 break;
173
174 case VSD_CLOSE:
175 lError = VSDClose( ( PVSD_INSTANCE ) hvsd );
176 break;
177
178 case VSD_GETDEVCAPS:
179 lError = VSDCaps( ( PVSD_INSTANCE ) hvsd, ulFlags, ( PVSD_GETDEVCAPS_PARMS )pRequest );
180 break;
181
182 case VSD_QUERY :
183 lError = VsdQuery( ( PVSD_INSTANCE ) hvsd, ulFlags, pRequest);
184 break;
185
186 /**************************************
187 * Basic commands
188 **************************************/
189
190 case VSD_SET:
191
192 lError = VSDSetCommand( ( PVSD_INSTANCE ) hvsd, ulFlags, pRequest );
193 break;
194
195
196 /**************************************
197 * Other commands
198 **************************************/
199
200 // Merge of DDCMD.DLL with VSD.
201 case VSD_DDCMD:
202 lError = vsdDDCMDEntryPoint (pRequest);
203
204 break;
205
206 case VSD_ESCAPE:
207
208// case VSD_CREATE_MIX :
209 case VSD_EVENTS :
210
211 /* Unsupported commands */
212
213
214 case VSD_CAPTUREIMAGE :
215 case VSD_EJECT :
216 case VSD_FREEZE :
217 case VSD_INSERTSETTINGSPAGE :
218 case VSD_LOAD :
219 case VSD_PARK :
220 case VSD_RESET :
221 case VSD_RESTOREIMAGE :
222 case VSD_SEEK :
223 case VSD_STEP :
224
225 /*----------------------------------------------------
226 * Audio VSDs DO NOT have to support getProdInfo (unless
227 * they want to). No portion of MMPM2 will call the VSD
228 * requesting this info (remember, this is true only for
229 * audio). This information is obtained by the mixer
230 * via an MCI_SYSINFO call since each driver must place
231 * the information in the ini file when it is installed.
232 *---------------------------------------------------*/
233 case VSD_GETPRODINFO :
234
235 lError = VSDERR_UNSUPPORTED_FUNCTION;
236 break;
237
238 /*---------------------------------------------------------*
239 * Unknown message received
240 *---------------------------------------------------------*/
241
242 default:
243 lError = VSDERR_UNRECOGNIZED_COMMAND;
244
245 break;
246 }
247
248#ifdef PERFORMANCE_TRACE
249// ulTime = PerfGetTime();
250// strcpy(DebugBuf, "VSD Entry message : ");
251// _ltoa((ULONG)ulFunc, LoadError, 10);
252// strcat(DebugBuf, LoadError);
253// strcat(DebugBuf, " time in microseconds: ");
254// _ltoa((ULONG)ulTime, LoadError, 10);
255// strcat(DebugBuf, LoadError);
256//
257// console_printf(DebugBuf );
258#endif
259
260 return(lError);
261
262
263} /* VSDEntry */
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281/************************ START OF SPECIFICATIONS **************************
282*
283* SUBROUTINE NAME: MCI_Error()
284*
285* FUNCTION: Returns MCI equivalent of an OS/2 error code.
286*
287* INPUT: lError - OS/2 error code
288*
289* OUTPUT: Returns MCI equivalent of an OS/2 error code.
290*
291* OS/2 CALLS: None
292*
293* C CALLS: None
294*
295*************************** END OF SPECIFICATIONS *************************/
296
297LONG MCI_Error(ULONG lError)
298 {
299 ULONG lMCIError;
300
301 switch(lError)
302 {
303 case NO_ERROR:
304 lMCIError = VSDERR_SUCCESS;
305 break;
306
307 case ERROR_FILE_NOT_FOUND:
308 lMCIError = VSDERR_FILE_NOT_FOUND;
309 break;
310
311 case ERROR_PROC_NOT_FOUND:
312 lMCIError = VSDERR_DRIVER_PROC_NOT_FOUND;
313 break;
314
315 case ERROR_INTERRUPT:
316 case ERROR_INVALID_HANDLE:
317 case ERROR_INVALID_ADDRESS:
318 case ERROR_ACCESS_DENIED:
319 lMCIError = VSDERR_INTERNAL;
320 break;
321
322 case ERROR_NOT_ENOUGH_MEMORY:
323 lMCIError = VSDERR_OUT_OF_MEMORY;
324 break;
325 case ERROR_OPEN_FAILED:
326 case 65280 :
327 case 65536 :
328 lMCIError = VSDERR_HARDWARE;
329 break;
330
331 default:
332 lMCIError = VSDERR_HARDWARE;
333 break;
334 }
335
336 return(lMCIError);
337 }
338
339
340/************************ START OF SPECIFICATIONS **************************
341*
342* SUBROUTINE NAME: AUDIOIFInit()
343*
344* FUNCTION: Initializes global semaphore. If VSD needs to initialize global
345* variables, allocate heaps, or perform functions
346* which need to be done once per process, it should be done here.
347*
348* INPUT: None
349*
350* OUTPUT: Returns 1 if successful, 0 otherwise.
351*
352* OS/2 CALLS: DosCreateMutexSem()
353*
354*************************** END OF SPECIFICATIONS *************************/
355//#pragma linkage (_DLL_InitTerm, system)
356
357ULONG APIENTRY _VSD_InitTerm (ULONG hModhandle, ULONG Flag);
358ULONG APIENTRY _VSD_InitTerm (ULONG hModhandle, ULONG Flag)
359
360
361 {
362 extern ULONG ulNumUsersVSD;
363 extern HMTX hmtxProcessSemVSD;
364 extern PDRIVER_LINECAPS pdriverLineCaps;
365 extern HHUGEHEAP hhpHeapVSD;
366 extern PDRIVER_LINECAPS pdriverLineCapsRoot; //@LP18173
367 extern ULONG ulInputDevice; //@LP18173
368 extern ULONG ulOutputDevice; //@LP18173
369 ULONG rc;
370
371 /*********************************************************
372 * Termination
373 *********************************************************/
374 if ( Flag )
375 {
376 /*****************************************
377 * Cleanup semaphore and user count
378 ******************************************/
379 rc = DosRequestMutexSem ( hmtxProcessSemVSD, SEM_INDEFINITE_WAIT);
380
381
382
383 ulNumUsersVSD--;
384
385 // remove device specific information
386#ifdef INCL_MM_WPOS
387 RemoveDevicePorts( );
388#endif
389
390 // 15552 changes
391 /*********************************************
392 * If there are no more dll's alive, destroy the
393 * heap.
394 **********************************************/
395 if (!ulNumUsersVSD)
396 {
397 RemoveDeviceCaps( );
398 HhpDestroyHeap ( hhpHeapVSD); /* Destroy the heap */
399 hhpHeapVSD=0;
400
401 }
402 else
403 {
404 /*********************************************
405 * If not the last dll, then release access to heap
406 **********************************************/
407 HhpReleaseHeap ( hhpHeapVSD, HhpGetPID()); /* Release access */
408 }
409 // 15552 changes
410 DosReleaseMutexSem (hmtxProcessSemVSD);
411 DosCloseMutexSem (hmtxProcessSemVSD);
412
413 return (SUCCESS);
414 }
415
416 /*********************************************************
417 * Initialization
418 *********************************************************/
419 /*********************************************************
420 * Create the Global Mutex Sem if this is the first process
421 *********************************************************/
422 rc = DosCreateMutexSem ( VSD_SEM_NAME, &hmtxProcessSemVSD, 0L, FALSE);
423 if (rc == ERROR_DUPLICATE_NAME)
424 {
425 rc = MCIERR_SUCCESS;
426 /***************************************************
427 * Open The Mutex Semaphore for subsequent processes
428 ****************************************************/
429 rc = DosOpenMutexSem (VSD_SEM_NAME, (PHMTX) &hmtxProcessSemVSD);
430 }
431 if ( rc )
432 return (FAILURE);
433
434 /****************************************
435 * Acquire The Mutex Semaphore
436 *****************************************/
437 rc = DosRequestMutexSem ( hmtxProcessSemVSD, SEM_INDEFINITE_WAIT);
438 if (rc)
439 {
440 DosCloseMutexSem (hmtxProcessSemVSD);
441 return (FAILURE);
442 }
443
444
445 /****************************************
446 * Create the heap
447 *****************************************/
448 // 15552 changes
449 if (!ulNumUsersVSD && !hhpHeapVSD) /* First Proc Creates Heap */
450 {
451 hhpHeapVSD = HhpCreateHeap ( (ULONG)HEAP_SIZE, HH_SHARED);
452 if ( hhpHeapVSD == NULL)
453 {
454 DosReleaseMutexSem (hmtxProcessSemVSD);
455 DosCloseMutexSem (hmtxProcessSemVSD);
456 return (0L);
457 }
458
459 //@LP18173 - Reinitialize shared data for first time
460 pdriverLineCapsRoot = NULL ;
461 ulInputDevice = 0;
462 ulOutputDevice = 0;
463 }
464 else
465 {
466 /************************************
467 * Provide Shared Access to heap
468 ************************************/
469 rc = HhpAccessHeap (hhpHeapVSD, HhpGetPID() );
470 if ( rc )
471 {
472 DosReleaseMutexSem (hmtxProcessSemVSD);
473 DosCloseMutexSem (hmtxProcessSemVSD);
474 return (0L);
475 }
476 }
477 // 15552 changes
478
479 ulNumUsersVSD++;
480
481 /******************************************
482 * Release The Mutex Semaphore
483 *******************************************/
484 rc = DosReleaseMutexSem (hmtxProcessSemVSD);
485 if (rc)
486 {
487 if (ulNumUsersVSD)
488 DosCloseMutexSem (hmtxProcessSemVSD);
489 return (FAILURE);
490 }
491
492 return (SUCCESS);
493
494
495 } /* _DLL_InitTerm */
496
497
498/************************** START OF SPECIFICATIONS ************************
499* *
500* SUBROUTINE NAME: FindDeviceCaps *
501* *
502* DESCRIPTIVE NAME: Returns if the capabilities of a given device are *
503* stored in global memory. *
504* *
505*************************** END OF SPECIFICATIONS **************************/
506void FindDeviceCaps( PVSD_INSTANCE pInstance,
507 PDRIVER_LINECAPS *pdriverLineCaps)
508
509{
510 extern HMTX hmtxProcessSemVSD;
511 extern HHUGEHEAP hhpHeapVSD;
512
513 extern DRIVER_LINECAPS *pdriverLineCapsRoot;
514 DRIVER_LINECAPS *pTemp = pdriverLineCapsRoot;
515
516 // search through our list of global capabilities and find
517 // the requested device.
518 while (pTemp )
519 {
520 if ( !strcmp( pTemp->szDeviceName,
521 pInstance->szDeviceName ) )
522 {
523 break;
524 }
525 pTemp = pTemp->pNext;
526
527 } /* endwhile */
528 // return the device we found (if any)
529 *pdriverLineCaps = pTemp;
530 return;
531
532} // FindDeviceCaps
533
534
535/************************** START OF SPECIFICATIONS ************************
536* *
537* SUBROUTINE NAME: AddDeviceCaps *
538* *
539* DESCRIPTIVE NAME: Adds the capabililities of a given device to global *
540* memory for use by other instances/process *
541*
542* Prevents each process from having to query the same *
543* info.
544* *
545*************************** END OF SPECIFICATIONS **************************/
546ULONG AddDeviceCaps( PVSD_INSTANCE pInstance,
547 PDRIVER_LINECAPS *pdriverLineCaps)
548
549{
550
551 extern DRIVER_LINECAPS *pdriverLineCapsRoot;
552 extern HMTX hmtxProcessSemVSD;
553 extern HHUGEHEAP hhpHeapVSD;
554 ULONG rc;
555 DRIVER_LINECAPS *pTemp;
556
557 // allocate the memory
558 pTemp = HhpAllocMem( hhpHeapVSD, sizeof ( DRIVER_LINECAPS ) );
559
560 if ( !pTemp )
561 {
562 return ( MCIERR_OUT_OF_MEMORY );
563 }
564
565 rc = DosRequestMutexSem ( hmtxProcessSemVSD, SEM_INDEFINITE_WAIT);
566 strcpy( pTemp->szDeviceName, pInstance->szDeviceName );
567 pTemp->pNext = pdriverLineCapsRoot;
568 pdriverLineCapsRoot = pTemp;
569 DosReleaseMutexSem (hmtxProcessSemVSD);
570
571 // return the device we found (if any)
572 *pdriverLineCaps = pTemp;
573
574 return ( MCIERR_SUCCESS );
575
576} // FindDeviceCaps
577
578
579/************************** START OF SPECIFICATIONS ************************
580* *
581* SUBROUTINE NAME: RemoveDeviceCaps *
582* *
583* DESCRIPTIVE NAME: Removes linked list of global capabilities. Only *
584* called when last process is terminating. *
585* *
586*************************** END OF SPECIFICATIONS **************************/
587void RemoveDeviceCaps( void )
588
589{
590
591 extern DRIVER_LINECAPS *pdriverLineCapsRoot;
592 extern HHUGEHEAP hhpHeapVSD;
593 DRIVER_LINECAPS *pTemp;
594
595 // allocate the memory
596 pTemp = pdriverLineCapsRoot;
597
598 while ( pdriverLineCapsRoot )
599 {
600 pTemp = pdriverLineCapsRoot->pNext;
601 HhpFreeMem(hhpHeapVSD, ( PVOID) pdriverLineCapsRoot );
602
603 // advance to next routine
604
605 pdriverLineCapsRoot = pTemp;
606 }
607
608 return;
609
610} // FindDeviceCaps
611
612
613
614
Note: See TracBrowser for help on using the repository browser.