source: sbliveos2/trunk/drv16/ioctl.cpp@ 147

Last change on this file since 147 was 147, checked in by sandervl, 25 years ago

Fixed wave volume, recording gain + wave recording

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/* $Id: ioctl.cpp 147 2000-04-24 19:45:21Z sandervl $ */
2
3/* SCCSID = %W% %E% */
4/****************************************************************************
5 * *
6 * Copyright (c) IBM Corporation 1994 - 1997. *
7 * *
8 * The following IBM OS/2 source code is provided to you solely for the *
9 * the purpose of assisting you in your development of OS/2 device drivers. *
10 * You may use this code in accordance with the IBM License Agreement *
11 * provided in the IBM Device Driver Source Kit for OS/2. *
12 * *
13 ****************************************************************************/
14/**@internal %W%
15 * @notes
16 * the functions that implement all the IOCTLs (command 10x) received by
17 * the device driver via the strategy entry.
18 * @version %I%
19 * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit,
20 * <stack context>.
21 * @history
22 *
23 */
24#define INCL_NOPMAPI
25#include <os2.h>
26#include <audio.h>
27
28#include "strategy.h"
29#include "audiohw.hpp"
30#include "mpu401.hpp"
31#include "wavehw.hpp"
32#include "wavestrm.hpp"
33#include "midistrm.hpp"
34
35#include <include.h>
36#include <sbvsd.h>
37#include <dbgos2.h>
38#include <devhelp.h>
39#include <ossidc.h>
40#include <ioctl90.h>
41#include <parse.h>
42#include "ioctl.h"
43
44//Map of possible 256 supported ioctls (IOCTl 90 mixer api)
45char SBLiveIOCTLMap[256] = {0};
46MIXSTRUCT MixerSettings[16] = {0};
47
48//override flags for rec src & gain mixer commands
49BOOL fRecSrcIOCTL90 = FALSE;
50BOOL fRecGainIOCTL90 = FALSE;
51
52/**@internal
53 * @param PREQPACKET pointer to the strategy request packet
54 * @return None But the Status in the request packet is updated on error
55 * @notes
56 * The Audio Init Ioctl only 2 things happen in here :
57 * 1. We call CheckForStream to make sure there is not already a stream
58 * registered with the same sysfilenumber. If we get a good rc from that
59 * 2: we look at sMode in the MCI_AUDIO_INIT to determine the type of stream
60 * to init and call the approprate stream constructor.
61 *
62 */
63void IoctlAudioInit(PREQPACKET prp, USHORT LDev)
64{
65 LPMCI_AUDIO_INIT p = (LPMCI_AUDIO_INIT)prp->s.ioctl.pvData;
66 PAUDIOHW pHWobj;
67 PSTREAM pstream;
68 ULONG HardwareType;
69
70 // if this is an IDLE or De-Init request
71 // fetch the stream object based on the sysfilenum and turn on the
72 // stream idle bit in the stream state then write the sysfilenum
73 // into the request packet, set rc = 0 and return
74 if (p->sMode == IDLE) {
75 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
76 if (pstream)
77 pstream->ulStreamState |= STREAM_IDLE;
78 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
79 p->sReturnCode = 0;
80 return;
81 }
82 // call FindStream_fromFile to see if there is already a stream
83 // for this sysfilenum. if there is then see if the idle bit is on,
84 // if the idle bit is on, reset it, then write the sysfilenum
85 // into the request packet, set rc = 0 and return
86 // MMPM sends idle down to a stream that is "losing" the hardware but
87 // should not go away. It usually is associated with an app losing
88 // focus. If the idle bit is not the stream is either not registered or
89 // is being "re-initted" in another mode or with different file
90 // attributes. "Re-initting" a stream is a total hack on the part
91 // of MMPM they should de-register the stream and then init a new
92 // stream but they don't . If anyone ever writes a VSD that behaves
93 // "correctly" then this code can be deleted.
94 // Either way delete the stream and build a new one with
95 // this request packet.
96 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
97 if (pstream) {
98 if (pstream->ulStreamState & STREAM_IDLE) {
99 pstream->ulStreamState &= STREAM_NOT_IDLE;
100 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
101 p->sReturnCode = 0;
102 return;
103 }
104 else {
105 delete pstream;
106 }
107 }
108
109 // get the hardware type
110 // return with bad status if the harware type is invalid/unsupported
111 HardwareType = GetHardwareType(p->sMode, (USHORT)p->ulOperation, LDev);
112 if (HardwareType == AUDIOHW_INVALID_DEVICE) {
113 p->sReturnCode = INVALID_REQUEST;
114 prp->usStatus |= RPERR;
115 return;
116 }
117 // make sure we have a Hardware object that can handle this
118 // data type and operation..
119 pHWobj = GetHardwareDevice(HardwareType);
120 if (pHWobj == NULL) {
121 p->sReturnCode = INVALID_REQUEST;
122 prp->usStatus |= RPERR;
123 return;
124 }
125
126 p->ulFlags = 0; /* Zero the Flags */
127 switch (HardwareType) {
128 case AUDIOHW_WAVE_PLAY:
129 case AUDIOHW_WAVE_CAPTURE:
130 pstream = new WAVESTREAM(HardwareType,p,prp->s.ioctl.usSysFileNum);
131 break;
132#if 0
133 case AUDIOHW_MPU401_PLAY:
134 pstream = new MIDISTREAM(HardwareType, prp->s.ioctl.usSysFileNum);
135 break;
136#endif
137 default:
138 p->sReturnCode = INVALID_REQUEST;
139 prp->usStatus |= RPERR;
140 return;
141 } /* endswitch */
142
143 p->ulFlags |= VOLUME; /* volume control is supported */
144 p->ulFlags |= INPUT; /* Input select is supported */
145 p->ulFlags |= OUTPUT; /* Output select is supported */
146 p->ulFlags |= MONITOR; /* Record Monitor is supported */
147 p->sDeviceID = SB_LIVE; /* Reported in VSD dll */
148 pstream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
149 p->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
150 p->sReturnCode = 0;
151 dprintf(("IoctlAudioInit: file nr: %lx", pstream->ulSysFileNum));
152}
153
154
155/**@internal
156 * @param PREQPACKET pointer to the strategy request packet
157 * @return None But the Status in the request packet is updated on error
158 * @notes
159 */
160void IoctlAudioCapability(PREQPACKET prp, USHORT LDev)
161{
162 PAUDIOHW pHWobj;
163 PAUDIO_CAPS p = (PAUDIO_CAPS)prp->s.ioctl.pvData;
164 ULONG ulDevicetype;
165
166 // get the hardware device type based on the datatype and operation
167 ulDevicetype = GetHardwareType((USHORT)p->ulDataType,(USHORT)p->ulOperation,LDev);
168
169 // Tell the caller we support this IOCTL
170 p->ulCapability = SUPPORT_CAP;
171
172 // get the pointer to the hardware object
173 // call DevCaps
174 // bailout if no hardware object is returned..
175 pHWobj = GetHardwareDevice(ulDevicetype);
176 if (pHWobj) {
177 pHWobj->DevCaps(p);
178 if (p->ulSupport != SUPPORT_SUCCESS) {
179 prp->usStatus |= RPERR;
180 }
181 }
182 else {
183 p->ulSupport = UNSUPPORTED_DATATYPE;
184 prp->usStatus |= RPERR;
185 }
186}
187
188/**@internal IoctlAudioControl
189 * @param PREQPACKET pointer to the strategy request packet
190 * @return None But the Status in the request packet is updated on error
191 * @notes
192 * if it's AUDIO_CHANGE, just report success, otherwise report failure
193 * this is because we don't support volume, balance, multiple in/out devices,
194 * etc. Also, START, STOP, RESUME, and PAUSE are redundant, so we don't
195 * support those either.
196 */
197void IoctlAudioControl(PREQPACKET prp)
198{
199 LPMCI_AUDIO_CONTROL p = (LPMCI_AUDIO_CONTROL) prp->s.ioctl.pvData;
200 LPMCI_AUDIO_CHANGE pAudChange;
201 LPMCI_TRACK_INFO pMasterVol;
202 PSTREAM pStream;
203 ULONG volume;
204
205 if (p->usIOCtlRequest != AUDIO_CHANGE) {
206 p->sReturnCode = INVALID_REQUEST;
207 prp->usStatus |= RPERR | RPBADCMD;
208 return;
209 }
210 p->sReturnCode=0;
211
212 pAudChange = (LPMCI_AUDIO_CHANGE)p->pbRequestInfo;
213
214 if(DevHelp_VerifyAccess(SELECTOROF(pAudChange), sizeof(MCI_AUDIO_CHANGE), OFFSETOF(pAudChange), VERIFY_READONLY))
215 {
216 dprintf(("Invalid MCI_AUDIO_CHANGE pointer %lx!!", (ULONG)pAudChange));
217 p->sReturnCode = INVALID_REQUEST;
218 prp->usStatus |= RPERR | RPBADCMD;
219 return;
220 }
221 pMasterVol = (LPMCI_TRACK_INFO)pAudChange->pvDevInfo;
222 if(DevHelp_VerifyAccess(SELECTOROF(pMasterVol), sizeof(MCI_TRACK_INFO), OFFSETOF(pMasterVol), VERIFY_READONLY))
223 {
224 dprintf(("Invalid MCI_TRACK_INFO pointer %lx!!", (ULONG)pMasterVol));
225 p->sReturnCode = INVALID_REQUEST;
226 prp->usStatus |= RPERR | RPBADCMD;
227 return;
228 }
229
230 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
231 if(pStream == NULL) {
232 dprintf(("IoctlAudioControl stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
233 DebugInt3();
234 return;
235 }
236 if(pAudChange->lBalance != AUDIO_IGNORE)
237 pStream->SetBalance(pAudChange->lBalance);
238
239 if(pAudChange->lVolume != AUDIO_IGNORE) {
240 // stream volume ranges from 0 to 0x7FFFFFFF (linear)
241 volume = pAudChange->lVolume >> 16UL;
242 volume = (volume*100UL)/0x7FFFUL;
243 dprintf(("Set stream volume of %x to %d", prp->s.ioctl.usSysFileNum, volume));
244 pStream->SetVolume(MAKE_VOLUME_LR(volume, volume));
245 }
246
247 if(pMasterVol && pMasterVol->usMasterVolume != AUDIO_IGNORE) {
248 // master volume ranges from 0 to 0x7FFF (linear)
249 volume = pMasterVol->usMasterVolume;
250 volume = (volume*100UL)/0x7FFFUL;
251 if(volume > 100) {
252 volume = 100;
253 }
254 dprintf(("Set mastervolume to %d", volume));
255 pStream->SetMasterVol(MAKE_VOLUME_LR(volume, volume));
256 }
257 if(!fRecSrcIOCTL90) {
258 for(int i=0;i<8;i++)
259 {
260 switch(pAudChange->rInputList[0].ulDevType) {
261 case NULL_INPUT:
262 break; //continue;
263 case STEREO_LINE_INPUT:
264 case LEFT_LINE_INPUT:
265 case RIGHT_LINE_INPUT:
266 pStream->SetInputSrc(MIX_RECSRC_LINE);
267 break;
268
269 case MIC_INPUT:
270 case BOOSTED_MIC_INPUT:
271 pStream->SetInputSrc(MIX_RECSRC_MIC);
272 break;
273
274 case PHONE_LINE_INPUT:
275 case HANDSET_INPUT:
276 case SYNTH_INPUT:
277 case DIGITAL_PHONE_LINE_INPUT:
278 case DIGITAL_HANDSET_INPUT:
279 case MIDI_IN_PORT:
280// case LOOPBACK:
281 pStream->SetInputSrc(MIX_RECSRC_MIXER);
282 break;
283 }
284 }
285 }
286 if(!fRecGainIOCTL90 && pAudChange->lGain != AUDIO_IGNORE) {
287 // input ranges from 0 to 0x7FFFFFFF (linear)
288 volume = pAudChange->lGain >> 16UL;
289 volume = (volume*100UL)/0x7FFFUL;
290 if(volume > 100) {
291 volume = 100;
292 }
293 dprintf(("Set input gain of %x to %d", prp->s.ioctl.usSysFileNum, volume));
294 pStream->SetInputGain(MAKE_VOLUME_LR(volume, volume));
295 }
296}
297//******************************************************************************
298//******************************************************************************
299void IoctlMixer(PREQPACKET prp)
300{
301 MIXSTRUCT FAR *pMixStruct = (MIXSTRUCT FAR *)prp->s.ioctl.pvData;
302 ULONG FAR *pIoctlData = (ULONG FAR *)prp->s.ioctl.pvData;
303 CHAR FAR *pIoctlMap = (CHAR FAR *)prp->s.ioctl.pvData; //getapimap
304 USHORT VolumeL, VolumeR;
305
306 if((prp->s.ioctl.bCode & 0xF0) == 0x40)
307 {
308 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READWRITE))
309 {
310 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
311 prp->usStatus |= RPERR | RPBADCMD;
312 return;
313 }
314 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL = pMixStruct->VolumeL;
315 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR = pMixStruct->VolumeR;
316 MixerSettings[prp->s.ioctl.bCode & 0xF].Mute = pMixStruct->Mute;
317 VolumeL = (USHORT)pMixStruct->VolumeL;
318 VolumeR = (USHORT)pMixStruct->VolumeR;
319 if(prp->s.ioctl.bCode != BASSTREBLESET) {
320 if(pMixStruct->Mute == 1)
321 VolumeL = VolumeR = 0;
322 }
323 }
324 else
325 if((prp->s.ioctl.bCode & 0xF0) == 0x60)
326 {
327 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READONLY))
328 {
329 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
330 prp->usStatus |= RPERR | RPBADCMD;
331 return;
332 }
333 }
334
335 switch(prp->s.ioctl.bCode) {
336 case MICSET:
337 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMICVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
338 break;
339 case LINESET:
340 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETLINEINVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
341 break;
342 case CDSET:
343 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETCDVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
344 break;
345 case VIDEOSET:
346 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETVIDEOVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
347 break;
348 case AUXSET:
349 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETAUXVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
350 break;
351
352 case BASSTREBLESET:
353 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETBASS, MAKE_VOLUME_LR(VolumeL, VolumeL));
354 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETTREBLE, MAKE_VOLUME_LR(VolumeR, VolumeR));
355 break;
356#if 0
357 case STREAMVOLSET:
358 //release stream volume override?
359 if(pMixStruct->Mute == 2) {
360 fStreamVolIOCTL90 = FALSE;
361 break;
362 }
363 fStreamVolIOCTL90 = TRUE;
364 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMASTERVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
365 break;
366#endif
367
368 case RECORDSRCSET:
369 {
370 int recsrc;
371
372 //release recording source override?
373 if(pMixStruct->Mute == 2) {
374 fRecSrcIOCTL90 = FALSE;
375 break;
376 }
377 fRecSrcIOCTL90 = TRUE;
378 switch(pMixStruct->VolumeL) {
379 case I90SRC_MIC:
380 recsrc = MIX_RECSRC_MIC;
381 break;
382 case I90SRC_CD:
383 recsrc = MIX_RECSRC_CD;
384 break;
385 case I90SRC_VIDEO:
386 recsrc = MIX_RECSRC_VIDEO;
387 break;
388 case I90SRC_LINE:
389 recsrc = MIX_RECSRC_LINE;
390 break;
391 case I90SRC_AUX:
392 recsrc = MIX_RECSRC_AUX;
393 break;
394// case I90SRC_RES5:
395// case I90SRC_RES6:
396// case I90SRC_PHONE:
397 default:
398 break;
399 }
400 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTSRC, recsrc);
401 break;
402 }
403 case RECORDGAINSET:
404 //release recording gain override?
405 if(pMixStruct->Mute == 2) {
406 fRecGainIOCTL90 = FALSE;
407 break;
408 }
409 fRecGainIOCTL90 = TRUE;
410 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTGAIN, MAKE_VOLUME_LR(VolumeL, VolumeR));
411 break;
412
413 case MICQUERY:
414 case LINEQUERY:
415 case AUXQUERY:
416 case CDQUERY:
417 case VIDEOQUERY:
418 case RECORDSRCQUERY:
419 case RECORDGAINQUERY:
420 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
421 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
422 pMixStruct->Mute = MixerSettings[prp->s.ioctl.bCode & 0xF].Mute;
423 break;
424
425 case BASSTREBLEQUERY:
426 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
427 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
428 pMixStruct->Mute = 3; //bass & treble
429 break;
430
431 case APILEVELQUERY:
432 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlData), sizeof(ULONG), OFFSETOF(pIoctlData), VERIFY_READWRITE))
433 {
434 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pIoctlData));
435 prp->usStatus |= RPERR | RPBADCMD;
436 return;
437 }
438 *pIoctlData = 2;
439 break;
440
441 case GETAPIMAP:
442 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlMap), sizeof(SBLiveIOCTLMap), OFFSETOF(pIoctlMap), VERIFY_READWRITE))
443 {
444 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
445 prp->usStatus |= RPERR | RPBADCMD;
446 return;
447 }
448 _fmemcpy(pIoctlMap, SBLiveIOCTLMap, sizeof(SBLiveIOCTLMap));
449 break;
450// case STREAMVOLQUERY:
451// case MONOINSET:
452// case PHONESET:
453// case THREEDSET:
454// case MONOINQUERY:
455// case PHONEQUERY:
456// case THREEDQUERY:
457// case CALLBACKREG:
458// case MSGBUF:
459 default:
460 prp->usStatus |= RPERR | RPBADCMD;
461 return;
462 }
463}
464//******************************************************************************
465//******************************************************************************
466void MixerInit()
467{
468 REQPACKET rp;
469 MIXSTRUCT mixinfo;
470
471 SBLiveIOCTLMap[MICSET] = 1;
472 SBLiveIOCTLMap[MICQUERY] = 1;
473 SBLiveIOCTLMap[LINESET] = 1;
474 SBLiveIOCTLMap[LINEQUERY] = 1;
475 SBLiveIOCTLMap[CDSET] = 1;
476 SBLiveIOCTLMap[CDQUERY] = 1;
477 SBLiveIOCTLMap[VIDEOSET] = 1;
478 SBLiveIOCTLMap[VIDEOQUERY] = 1;
479 SBLiveIOCTLMap[AUXSET] = 1;
480 SBLiveIOCTLMap[AUXQUERY] = 1;
481 SBLiveIOCTLMap[BASSTREBLESET] = 1;
482 SBLiveIOCTLMap[BASSTREBLEQUERY] = 1;
483//// SBLiveIOCTLMap[STREAMVOLSET] = 1;
484//// SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
485 SBLiveIOCTLMap[RECORDSRCSET] = 1;
486 SBLiveIOCTLMap[RECORDSRCQUERY] = 1;
487 SBLiveIOCTLMap[RECORDGAINSET] = 1;
488 SBLiveIOCTLMap[RECORDGAINQUERY] = 1;
489 SBLiveIOCTLMap[APILEVELQUERY] = 1;
490 SBLiveIOCTLMap[GETAPIMAP] = 1;
491// SBLiveIOCTLMap[CALLBACKREG] = 1;
492
493 //Set mic
494 rp.s.ioctl.bCode = MICSET;
495 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
496 mixinfo.Mute = fMicMute;
497 mixinfo.VolumeR = mixinfo.VolumeL = 60;
498 IoctlMixer(&rp);
499
500 //Set line
501 rp.s.ioctl.bCode = LINESET;
502 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
503 mixinfo.Mute = fLineMute;
504 mixinfo.VolumeR = mixinfo.VolumeL = 80;
505 IoctlMixer(&rp);
506
507 //Set CD
508 rp.s.ioctl.bCode = CDSET;
509 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
510 mixinfo.Mute = fCDMute;
511 mixinfo.VolumeR = mixinfo.VolumeL = 80;
512 IoctlMixer(&rp);
513
514 //Set bass/treble
515 rp.s.ioctl.bCode = BASSTREBLESET;
516 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
517 mixinfo.Mute = 3;
518 mixinfo.VolumeR = mixinfo.VolumeL = 50;
519 IoctlMixer(&rp);
520
521 //Set recording source to line in
522 rp.s.ioctl.bCode = RECORDSRCSET;
523 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
524 mixinfo.Mute = 0;
525 mixinfo.VolumeL = I90SRC_LINE;
526 IoctlMixer(&rp);
527
528 //Release recording source override
529 rp.s.ioctl.bCode = RECORDSRCSET;
530 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
531 mixinfo.Mute = 2;
532 mixinfo.VolumeL = I90SRC_LINE;
533 IoctlMixer(&rp);
534
535 //Set master volume
536 rp.s.ioctl.bCode = STREAMVOLSET;
537 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
538 mixinfo.Mute = 0;
539 mixinfo.VolumeR = mixinfo.VolumeL = 90;
540 IoctlMixer(&rp);
541
542 //Release master volume override
543 rp.s.ioctl.bCode = STREAMVOLSET;
544 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
545 mixinfo.Mute = 2;
546 mixinfo.VolumeR = mixinfo.VolumeL = 90;
547 IoctlMixer(&rp);
548}
549//******************************************************************************
550//******************************************************************************
551/**@internal
552 * @param PREQPACKET pointer to the strategy request packet
553 * @return None But the Status in the request packet is updated on error
554 * @notes
555 * StrategyIoctl is called from the strategy entry point to process IOCTL
556 * requests. only catagory 80x requests will be processed.
557 */
558/* extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
559*
560*
561*
562*/
563extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
564{
565 if(prp->s.ioctl.bCategory == 0x90) {
566 IoctlMixer(prp);
567 return;
568 }
569 if(prp->s.ioctl.bCategory != AUDIO_IOCTL_CAT) {
570 prp->usStatus |= RPERR | RPBADCMD;
571 return;
572 }
573
574 switch (prp->s.ioctl.bCode) {
575 case AUDIO_INIT:
576 IoctlAudioInit(prp, LDev);
577 break;
578 case AUDIO_CONTROL:
579 IoctlAudioControl(prp);
580 break;
581 case AUDIO_CAPABILITY:
582 IoctlAudioCapability(prp, LDev);
583 break;
584 default:
585 prp->usStatus |= RPERR | RPBADCMD;
586 break;
587 }
588 return;
589}
Note: See TracBrowser for help on using the repository browser.