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

Last change on this file since 167 was 167, checked in by sandervl, 24 years ago

update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.0 KB
Line 
1/* $Id: ioctl.cpp 167 2001-03-22 23:33:12Z 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 <os2me.h>
27#include <audio.h>
28
29#include "strategy.h"
30#include "audiohw.hpp"
31#include "mpu401.hpp"
32#include "wavehw.hpp"
33#include "dwavestrm.hpp"
34#include "midistrm.hpp"
35
36#include <include.h>
37#include <sbvsd.h>
38#include <dbgos2.h>
39#include <devhelp.h>
40#include <ossidc.h>
41#include <ioctl90.h>
42#include <parse.h>
43#include "ioctl.h"
44
45#include <daudio.h>
46
47//Map of possible 256 supported ioctls (IOCTl 90 mixer api)
48char SBLiveIOCTLMap[256] = {0};
49MIXSTRUCT MixerSettings[16] = {0};
50
51//override flags for rec src & gain mixer commands
52BOOL fRecSrcIOCTL90 = FALSE;
53BOOL fRecGainIOCTL90 = FALSE;
54
55/**@internal
56 * @param PREQPACKET pointer to the strategy request packet
57 * @return None But the Status in the request packet is updated on error
58 * @notes
59 * The Audio Init Ioctl only 2 things happen in here :
60 * 1. We call CheckForStream to make sure there is not already a stream
61 * registered with the same sysfilenumber. If we get a good rc from that
62 * 2: we look at sMode in the MCI_AUDIO_INIT to determine the type of stream
63 * to init and call the approprate stream constructor.
64 *
65 */
66void IoctlAudioInit(PREQPACKET prp, USHORT LDev)
67{
68 LPMCI_AUDIO_INIT p = (LPMCI_AUDIO_INIT)prp->s.ioctl.pvData;
69 PAUDIOHW pHWobj;
70 PSTREAM pstream;
71 ULONG HardwareType;
72
73 // if this is an IDLE or De-Init request
74 // fetch the stream object based on the sysfilenum and turn on the
75 // stream idle bit in the stream state then write the sysfilenum
76 // into the request packet, set rc = 0 and return
77 if (p->sMode == IDLE) {
78 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
79 if (pstream)
80 pstream->ulStreamState |= STREAM_IDLE;
81 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
82 p->sReturnCode = 0;
83 return;
84 }
85 // call FindStream_fromFile to see if there is already a stream
86 // for this sysfilenum. if there is then see if the idle bit is on,
87 // if the idle bit is on, reset it, then write the sysfilenum
88 // into the request packet, set rc = 0 and return
89 // MMPM sends idle down to a stream that is "losing" the hardware but
90 // should not go away. It usually is associated with an app losing
91 // focus. If the idle bit is not the stream is either not registered or
92 // is being "re-initted" in another mode or with different file
93 // attributes. "Re-initting" a stream is a total hack on the part
94 // of MMPM they should de-register the stream and then init a new
95 // stream but they don't . If anyone ever writes a VSD that behaves
96 // "correctly" then this code can be deleted.
97 // Either way delete the stream and build a new one with
98 // this request packet.
99 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
100 if (pstream) {
101 if (pstream->ulStreamState & STREAM_IDLE) {
102 pstream->ulStreamState &= STREAM_NOT_IDLE;
103 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
104 p->sReturnCode = 0;
105 return;
106 }
107 else {
108 delete pstream;
109 }
110 }
111
112 // get the hardware type
113 // return with bad status if the harware type is invalid/unsupported
114 HardwareType = GetHardwareType(p->sMode, (USHORT)p->ulOperation, LDev);
115 if (HardwareType == AUDIOHW_INVALID_DEVICE) {
116 p->sReturnCode = INVALID_REQUEST;
117 prp->usStatus |= RPERR;
118 return;
119 }
120 // make sure we have a Hardware object that can handle this
121 // data type and operation..
122 pHWobj = GetHardwareDevice(HardwareType);
123 if (pHWobj == NULL) {
124 p->sReturnCode = INVALID_REQUEST;
125 prp->usStatus |= RPERR;
126 return;
127 }
128
129 p->ulFlags = 0; /* Zero the Flags */
130 switch (HardwareType) {
131 case AUDIOHW_WAVE_PLAY:
132 case AUDIOHW_WAVE_CAPTURE:
133 pstream = new WAVESTREAM(HardwareType,p,prp->s.ioctl.usSysFileNum);
134 break;
135#if 0
136 case AUDIOHW_MPU401_PLAY:
137 pstream = new MIDISTREAM(HardwareType, prp->s.ioctl.usSysFileNum);
138 break;
139#endif
140 default:
141 p->sReturnCode = INVALID_REQUEST;
142 prp->usStatus |= RPERR;
143 return;
144 } /* endswitch */
145
146 p->ulFlags |= VOLUME; /* volume control is supported */
147 p->ulFlags |= INPUT; /* Input select is supported */
148 p->ulFlags |= OUTPUT; /* Output select is supported */
149 p->ulFlags |= MONITOR; /* Record Monitor is supported */
150 p->sDeviceID = SB_LIVE; /* Reported in VSD dll */
151 pstream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
152 p->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
153 p->sReturnCode = 0;
154 dprintf(("IoctlAudioInit: file nr: %lx", pstream->ulSysFileNum));
155}
156
157
158/**@internal
159 * @param PREQPACKET pointer to the strategy request packet
160 * @return None But the Status in the request packet is updated on error
161 * @notes
162 */
163void IoctlAudioCapability(PREQPACKET prp, USHORT LDev)
164{
165 PAUDIOHW pHWobj;
166 PAUDIO_CAPS p = (PAUDIO_CAPS)prp->s.ioctl.pvData;
167 ULONG ulDevicetype;
168
169 // get the hardware device type based on the datatype and operation
170 ulDevicetype = GetHardwareType((USHORT)p->ulDataType,(USHORT)p->ulOperation,LDev);
171
172 // Tell the caller we support this IOCTL
173 p->ulCapability = SUPPORT_CAP;
174
175 // get the pointer to the hardware object
176 // call DevCaps
177 // bailout if no hardware object is returned..
178 pHWobj = GetHardwareDevice(ulDevicetype);
179 if (pHWobj) {
180 pHWobj->DevCaps(p);
181 if (p->ulSupport != SUPPORT_SUCCESS) {
182 prp->usStatus |= RPERR;
183 }
184 }
185 else {
186 p->ulSupport = UNSUPPORTED_DATATYPE;
187 prp->usStatus |= RPERR;
188 }
189}
190
191/**@internal IoctlAudioControl
192 * @param PREQPACKET pointer to the strategy request packet
193 * @return None But the Status in the request packet is updated on error
194 * @notes
195 * if it's AUDIO_CHANGE, just report success, otherwise report failure
196 * this is because we don't support volume, balance, multiple in/out devices,
197 * etc. Also, START, STOP, RESUME, and PAUSE are redundant, so we don't
198 * support those either.
199 */
200void IoctlAudioControl(PREQPACKET prp)
201{
202 LPMCI_AUDIO_CONTROL p = (LPMCI_AUDIO_CONTROL) prp->s.ioctl.pvData;
203 LPMCI_AUDIO_CHANGE pAudChange;
204 LPMCI_TRACK_INFO pMasterVol;
205 PSTREAM pStream;
206 ULONG volume;
207 ULONG addr;
208
209 if (p->usIOCtlRequest != AUDIO_CHANGE) {
210 p->sReturnCode = INVALID_REQUEST;
211 prp->usStatus |= RPERR | RPBADCMD;
212 return;
213 }
214 p->sReturnCode=0;
215
216 pAudChange = (LPMCI_AUDIO_CHANGE)p->pbRequestInfo;
217
218 //Test for MMPM/2 bug (structure crosses selector boundary)
219 addr = OFFSETOF(pAudChange);
220 addr += sizeof(MCI_AUDIO_CHANGE);
221 if(addr >= 0x10000UL) {
222 dprintf(("Invalid MCI_AUDIO_CHANGE pointer %lx!!", (ULONG)pAudChange));
223 p->sReturnCode = INVALID_REQUEST;
224 prp->usStatus |= RPERR | RPBADCMD;
225 return;
226 }
227 pMasterVol = (LPMCI_TRACK_INFO)pAudChange->pvDevInfo;
228
229 //Test for MMPM/2 bug (structure crosses selector boundary)
230 addr = OFFSETOF(pMasterVol);
231 addr += sizeof(MCI_TRACK_INFO);
232 if(addr >= 0x10000UL) {
233 dprintf(("Invalid MCI_TRACK_INFO pointer %lx!!", (ULONG)pMasterVol));
234 p->sReturnCode = INVALID_REQUEST;
235 prp->usStatus |= RPERR | RPBADCMD;
236 return;
237 }
238
239 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
240 if(pStream == NULL) {
241 dprintf(("IoctlAudioControl stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
242 DebugInt3();
243 return;
244 }
245 if(pAudChange->lBalance != AUDIO_IGNORE)
246 pStream->SetBalance(pAudChange->lBalance);
247
248 if(pAudChange->lVolume != AUDIO_IGNORE) {
249 // stream volume ranges from 0 to 0x7FFFFFFF (linear)
250 volume = pAudChange->lVolume >> 16UL;
251 volume = (volume*100UL)/0x7FFFUL;
252 dprintf(("Set stream volume of %x to %d", prp->s.ioctl.usSysFileNum, volume));
253 pStream->SetVolume(MAKE_VOLUME_LR(volume, volume));
254 }
255
256 if(pMasterVol && pMasterVol->usMasterVolume != AUDIO_IGNORE) {
257 // master volume ranges from 0 to 0x7FFF (linear)
258 volume = pMasterVol->usMasterVolume;
259 volume = (volume*100UL)/0x7FFFUL;
260 if(volume > 100) {
261 volume = 100;
262 }
263 dprintf(("Set mastervolume to %d", volume));
264 pStream->SetMasterVol(MAKE_VOLUME_LR(volume, volume));
265 }
266 if(!fRecSrcIOCTL90) {
267 for(int i=0;i<8;i++)
268 {
269 switch(pAudChange->rInputList[0].ulDevType) {
270 case NULL_INPUT:
271 break; //continue;
272 case STEREO_LINE_INPUT:
273 case LEFT_LINE_INPUT:
274 case RIGHT_LINE_INPUT:
275 pStream->SetInputSrc(MIX_RECSRC_LINE);
276 break;
277
278 case MIC_INPUT:
279 case BOOSTED_MIC_INPUT:
280 pStream->SetInputSrc(MIX_RECSRC_MIC);
281 break;
282
283 case PHONE_LINE_INPUT:
284 case HANDSET_INPUT:
285 case SYNTH_INPUT:
286 case DIGITAL_PHONE_LINE_INPUT:
287 case DIGITAL_HANDSET_INPUT:
288 case MIDI_IN_PORT:
289// case LOOPBACK:
290 pStream->SetInputSrc(MIX_RECSRC_MIXER);
291 break;
292 }
293 }
294 }
295 if(!fRecGainIOCTL90 && pAudChange->lGain != AUDIO_IGNORE) {
296 // input ranges from 0 to 0x7FFFFFFF (linear)
297 volume = pAudChange->lGain >> 16UL;
298 volume = (volume*100UL)/0x7FFFUL;
299 if(volume > 100) {
300 volume = 100;
301 }
302 dprintf(("Set input gain of %x to %d", prp->s.ioctl.usSysFileNum, volume));
303 pStream->SetInputGain(MAKE_VOLUME_LR(volume, volume));
304 }
305}
306//******************************************************************************
307//******************************************************************************
308void IoctlDirectAudio(PREQPACKET prp)
309{
310 if(prp->s.ioctl.bCode == DAUDIO_OPEN)
311 {
312 LPMCI_AUDIO_INIT pInit = (LPMCI_AUDIO_INIT) prp->s.ioctl.pvData;
313 PAUDIOHW pHWobj;
314 MCI_AUDIO_CAPS audioCaps;
315 PDWAVESTREAM pStream;
316
317 if(DevHelp_VerifyAccess(SELECTOROF(pInit), sizeof(MCI_AUDIO_INIT), OFFSETOF(pInit), VERIFY_READWRITE))
318 {
319 dprintf(("Invalid MCI_AUDIO_INIT pointer %lx!!", (ULONG)pInit));
320 prp->usStatus |= RPERR | RPBADCMD;
321 return;
322 }
323
324 audioCaps.ulLength = sizeof(MCI_AUDIO_CAPS);
325 audioCaps.ulSamplingRate = pInit->lSRate;
326 audioCaps.ulChannels = pInit->sChannels;
327 audioCaps.ulBitsPerSample = pInit->lBitsPerSRate;
328 audioCaps.ulDataType = pInit->sMode;
329 audioCaps.ulOperation = OPERATION_PLAY;
330
331 // get the pointer to the hardware object
332 // call DevCaps
333 // bailout if no hardware object is returned..
334 pHWobj = GetHardwareDevice(AUDIOHW_WAVE_PLAY);
335 if (pHWobj)
336 {
337 pHWobj->DevCaps(&audioCaps);
338 if (audioCaps.ulSupport != SUPPORT_SUCCESS) {
339 dprintf(("IoctlDirectAudio: DevCaps failed"));
340 pInit->sReturnCode = INVALID_REQUEST;
341 prp->usStatus |= RPERR;
342 return;
343 }
344 }
345 else {
346 pInit->sReturnCode = INVALID_REQUEST;
347 prp->usStatus |= RPERR;
348 return;
349 }
350
351 pStream = new DWAVESTREAM(AUDIOHW_WAVE_PLAY, pInit, prp->s.ioctl.usSysFileNum);
352 if(pStream == NULL) {
353 DebugInt3();
354 pInit->sReturnCode = INVALID_REQUEST;
355 prp->usStatus |= RPERR;
356 return;
357 }
358
359 if(!pStream->IsEverythingOk()) {
360 delete pStream;
361 DebugInt3();
362 pInit->sReturnCode = INVALID_REQUEST;
363 prp->usStatus |= RPERR;
364 return;
365 }
366 pInit->ulFlags |= VOLUME; /* volume control is supported */
367 pInit->ulFlags |= INPUT; /* Input select is supported */
368 pInit->ulFlags |= OUTPUT; /* Output select is supported */
369 pInit->ulFlags |= MONITOR; /* Record Monitor is supported */
370 pInit->sDeviceID = SB_LIVE; /* Reported in VSD dll */
371 pStream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
372 pInit->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
373 pInit->sReturnCode = 0;
374
375 return;
376 }
377 else
378 if(prp->s.ioctl.bCode == DAUDIO_QUERYFORMAT)
379 {
380 LPMCI_AUDIO_INIT pInit = (LPMCI_AUDIO_INIT) prp->s.ioctl.pvData;
381 PAUDIOHW pHWobj;
382 MCI_AUDIO_CAPS audioCaps;
383
384 if(DevHelp_VerifyAccess(SELECTOROF(pInit), sizeof(MCI_AUDIO_INIT), OFFSETOF(pInit), VERIFY_READWRITE))
385 {
386 dprintf(("Invalid MCI_AUDIO_INIT pointer %lx!!", (ULONG)pInit));
387 prp->usStatus |= RPERR | RPBADCMD;
388 return;
389 }
390
391 audioCaps.ulLength = sizeof(MCI_AUDIO_CAPS);
392 audioCaps.ulSamplingRate = pInit->lSRate;
393 audioCaps.ulChannels = pInit->sChannels;
394 audioCaps.ulBitsPerSample = pInit->lBitsPerSRate;
395 audioCaps.ulDataType = pInit->sMode;
396 audioCaps.ulOperation = OPERATION_PLAY;
397
398 // get the pointer to the hardware object
399 // call DevCaps
400 // bailout if no hardware object is returned..
401 pHWobj = GetHardwareDevice(AUDIOHW_WAVE_PLAY);
402 if (pHWobj)
403 {
404 pHWobj->DevCaps(&audioCaps);
405 if (audioCaps.ulSupport != SUPPORT_SUCCESS) {
406 dprintf(("IoctlDirectAudio: DevCaps failed"));
407 prp->usStatus |= RPERR;
408 pInit->sReturnCode = INVALID_REQUEST;
409 return;
410 }
411 pInit->sReturnCode = 0;
412 return;
413 }
414 else {
415 pInit->sReturnCode = INVALID_REQUEST;
416 prp->usStatus |= RPERR;
417 return;
418 }
419 }
420
421 PSTREAM pStream;
422
423 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
424 if(pStream == NULL) {
425 dprintf(("IoctlDirectAudio stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
426 DebugInt3();
427 prp->usStatus |= RPERR | RPBADCMD;
428 return;
429 }
430
431 LPDAUDIO_CMD pDAudioCmd = (LPDAUDIO_CMD) prp->s.ioctl.pvData;
432 ULONG rc = 0;
433
434 if(DevHelp_VerifyAccess(SELECTOROF(pDAudioCmd), sizeof(DAUDIO_CMD), OFFSETOF(pDAudioCmd), VERIFY_READWRITE))
435 {
436 dprintf(("Invalid DAUDIO_CMD pointer %lx!!", (ULONG)pDAudioCmd));
437 prp->usStatus |= RPERR | RPBADCMD;
438 return;
439 }
440
441 switch(prp->s.ioctl.bCode)
442 {
443 case DAUDIO_CLOSE:
444 delete pStream;
445 break;
446
447 case DAUDIO_SETVOLUME:
448 pStream->SetVolume(pDAudioCmd->Vol.Volume);
449 break;
450
451 case DAUDIO_GETVOLUME:
452 pDAudioCmd->Vol.Volume = pStream->GetVolume();
453 break;
454
455 case DAUDIO_START:
456 rc = pStream->StartStream();
457 break;
458
459 case DAUDIO_STOP:
460 {
461 CONTROL_PARM cParm;
462 rc = pStream->StopStream(&cParm);
463 break;
464 }
465
466 case DAUDIO_PAUSE:
467 {
468 CONTROL_PARM cParm;
469 rc = pStream->PauseStream(&cParm);
470 break;
471 }
472
473 case DAUDIO_RESUME:
474 rc = pStream->ResumeStream();
475 break;
476
477 case DAUDIO_GETPOS:
478 pDAudioCmd->Pos.ulCurrentPos = pStream->GetCurrentPos();
479 break;
480
481 case DAUDIO_ADDBUFFER:
482 {
483 rc = pStream->Write((PSTREAMBUF)pDAudioCmd->Buffer.lpBuffer, pDAudioCmd->Buffer.ulBufferLength);
484 break;
485 }
486
487 case DAUDIO_REGISTER_THREAD:
488 {
489 DDCMDREGISTER reg;
490
491 reg.ulFunction = DDCMD_REG_STREAM;
492 reg.hStream = pDAudioCmd->Thread.hSemaphore;
493 reg.ulSysFileNum = prp->s.ioctl.usSysFileNum;
494 reg.pSHDEntryPoint = NULL;
495 rc = pStream->Register(&reg);
496 break;
497 }
498
499 case DAUDIO_DEREGISTER_THREAD:
500 {
501 pStream->DeRegister();
502 break;
503 }
504
505 }
506
507 if(rc) {
508 prp->usStatus |= RPERR | RPBADCMD;
509 return;
510 }
511 return;
512}
513//******************************************************************************
514//******************************************************************************
515void IoctlMixer(PREQPACKET prp)
516{
517 MIXSTRUCT FAR *pMixStruct = (MIXSTRUCT FAR *)prp->s.ioctl.pvData;
518 ULONG FAR *pIoctlData = (ULONG FAR *)prp->s.ioctl.pvData;
519 CHAR FAR *pIoctlMap = (CHAR FAR *)prp->s.ioctl.pvData; //getapimap
520 USHORT VolumeL, VolumeR;
521
522 if((prp->s.ioctl.bCode & 0xF0) == 0x40)
523 {
524 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READWRITE))
525 {
526 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
527 prp->usStatus |= RPERR | RPBADCMD;
528 return;
529 }
530 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL = pMixStruct->VolumeL;
531 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR = pMixStruct->VolumeR;
532 MixerSettings[prp->s.ioctl.bCode & 0xF].Mute = pMixStruct->Mute;
533 VolumeL = (USHORT)pMixStruct->VolumeL;
534 VolumeR = (USHORT)pMixStruct->VolumeR;
535 if(prp->s.ioctl.bCode != BASSTREBLESET) {
536 if(pMixStruct->Mute == 1)
537 VolumeL = VolumeR = 0;
538 }
539 }
540 else
541 if((prp->s.ioctl.bCode & 0xF0) == 0x60)
542 {
543 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READONLY))
544 {
545 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
546 prp->usStatus |= RPERR | RPBADCMD;
547 return;
548 }
549 }
550
551 switch(prp->s.ioctl.bCode) {
552 case MICSET:
553 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMICVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
554 break;
555 case LINESET:
556 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETLINEINVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
557 break;
558 case CDSET:
559 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETCDVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
560 break;
561 case VIDEOSET:
562 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETVIDEOVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
563 break;
564 case AUXSET:
565 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETAUXVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
566 break;
567
568 case BASSTREBLESET:
569 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETBASS, MAKE_VOLUME_LR(VolumeL, VolumeL));
570 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETTREBLE, MAKE_VOLUME_LR(VolumeR, VolumeR));
571 break;
572#if 0
573 case STREAMVOLSET:
574 //release stream volume override?
575 if(pMixStruct->Mute == 2) {
576 fStreamVolIOCTL90 = FALSE;
577 break;
578 }
579 fStreamVolIOCTL90 = TRUE;
580 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMASTERVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
581 break;
582#endif
583
584 case RECORDSRCSET:
585 {
586 int recsrc = MIX_RECSRC_LINE;
587
588 //release recording source override?
589 if(pMixStruct->Mute == 2) {
590 fRecSrcIOCTL90 = FALSE;
591 break;
592 }
593 fRecSrcIOCTL90 = TRUE;
594 switch(pMixStruct->VolumeL) {
595 case I90SRC_MIC:
596 recsrc = MIX_RECSRC_MIC;
597 break;
598 case I90SRC_CD:
599 recsrc = MIX_RECSRC_CD;
600 break;
601 case I90SRC_VIDEO:
602 recsrc = MIX_RECSRC_VIDEO;
603 break;
604 case I90SRC_LINE:
605 recsrc = MIX_RECSRC_LINE;
606 break;
607 case I90SRC_AUX:
608 recsrc = MIX_RECSRC_AUX;
609 break;
610 // case I90SRC_RES5:
611 // case I90SRC_RES6:
612 // case I90SRC_PHONE:
613 default:
614 break;
615 }
616 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTSRC, recsrc);
617 break;
618 }
619 case RECORDGAINSET:
620 //release recording gain override?
621 if(pMixStruct->Mute == 2) {
622 fRecGainIOCTL90 = FALSE;
623 break;
624 }
625 fRecGainIOCTL90 = TRUE;
626 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTGAIN, MAKE_VOLUME_LR(VolumeL, VolumeL));
627 break;
628
629 case MICQUERY:
630 case LINEQUERY:
631 case AUXQUERY:
632 case CDQUERY:
633 case VIDEOQUERY:
634 case RECORDSRCQUERY:
635 case RECORDGAINQUERY:
636 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
637 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
638 pMixStruct->Mute = MixerSettings[prp->s.ioctl.bCode & 0xF].Mute;
639 break;
640
641 case BASSTREBLEQUERY:
642 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
643 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
644 pMixStruct->Mute = 3; //bass & treble
645 break;
646
647 case APILEVELQUERY:
648 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlData), sizeof(ULONG), OFFSETOF(pIoctlData), VERIFY_READWRITE))
649 {
650 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pIoctlData));
651 prp->usStatus |= RPERR | RPBADCMD;
652 return;
653 }
654 *pIoctlData = 2;
655 break;
656
657 case GETAPIMAP:
658 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlMap), sizeof(SBLiveIOCTLMap), OFFSETOF(pIoctlMap), VERIFY_READWRITE))
659 {
660 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
661 prp->usStatus |= RPERR | RPBADCMD;
662 return;
663 }
664 _fmemcpy(pIoctlMap, SBLiveIOCTLMap, sizeof(SBLiveIOCTLMap));
665 break;
666// case STREAMVOLQUERY:
667// case MONOINSET:
668// case PHONESET:
669// case THREEDSET:
670// case MONOINQUERY:
671// case PHONEQUERY:
672// case THREEDQUERY:
673// case CALLBACKREG:
674// case MSGBUF:
675 default:
676 prp->usStatus |= RPERR | RPBADCMD;
677 return;
678 }
679}
680//******************************************************************************
681//******************************************************************************
682void MixerInit()
683{
684 REQPACKET rp;
685 MIXSTRUCT mixinfo;
686
687 SBLiveIOCTLMap[MICSET] = 1;
688 SBLiveIOCTLMap[MICQUERY] = 1;
689 SBLiveIOCTLMap[LINESET] = 1;
690 SBLiveIOCTLMap[LINEQUERY] = 1;
691 SBLiveIOCTLMap[CDSET] = 1;
692 SBLiveIOCTLMap[CDQUERY] = 1;
693 SBLiveIOCTLMap[VIDEOSET] = 1;
694 SBLiveIOCTLMap[VIDEOQUERY] = 1;
695 SBLiveIOCTLMap[AUXSET] = 1;
696 SBLiveIOCTLMap[AUXQUERY] = 1;
697 SBLiveIOCTLMap[BASSTREBLESET] = 1;
698 SBLiveIOCTLMap[BASSTREBLEQUERY] = 1;
699//// SBLiveIOCTLMap[STREAMVOLSET] = 1;
700//// SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
701 SBLiveIOCTLMap[RECORDSRCSET] = 1;
702 SBLiveIOCTLMap[RECORDSRCQUERY] = 1;
703 SBLiveIOCTLMap[RECORDGAINSET] = 1;
704 SBLiveIOCTLMap[RECORDGAINQUERY] = 1;
705 SBLiveIOCTLMap[APILEVELQUERY] = 1;
706 SBLiveIOCTLMap[GETAPIMAP] = 1;
707// SBLiveIOCTLMap[CALLBACKREG] = 1;
708
709 //Set mic
710 rp.s.ioctl.bCode = MICSET;
711 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
712 mixinfo.Mute = fMicMute;
713 mixinfo.VolumeR = mixinfo.VolumeL = 60;
714 IoctlMixer(&rp);
715
716 //Set line
717 rp.s.ioctl.bCode = LINESET;
718 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
719 mixinfo.Mute = fLineMute;
720 mixinfo.VolumeR = mixinfo.VolumeL = 80;
721 IoctlMixer(&rp);
722
723 //Set CD
724 rp.s.ioctl.bCode = CDSET;
725 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
726 mixinfo.Mute = fCDMute;
727 mixinfo.VolumeR = mixinfo.VolumeL = 80;
728 IoctlMixer(&rp);
729
730 //Set bass/treble
731 rp.s.ioctl.bCode = BASSTREBLESET;
732 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
733 mixinfo.Mute = 3;
734 mixinfo.VolumeR = mixinfo.VolumeL = 50;
735 IoctlMixer(&rp);
736
737 //Set recording source to line in
738 rp.s.ioctl.bCode = RECORDSRCSET;
739 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
740 mixinfo.Mute = 0;
741 mixinfo.VolumeL = I90SRC_LINE;
742 IoctlMixer(&rp);
743
744 //Release recording source override
745 rp.s.ioctl.bCode = RECORDSRCSET;
746 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
747 mixinfo.Mute = 2;
748 mixinfo.VolumeL = I90SRC_LINE;
749 IoctlMixer(&rp);
750
751 //Set master volume
752 rp.s.ioctl.bCode = STREAMVOLSET;
753 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
754 mixinfo.Mute = 0;
755 mixinfo.VolumeR = mixinfo.VolumeL = 90;
756 IoctlMixer(&rp);
757
758 //Release master volume override
759 rp.s.ioctl.bCode = STREAMVOLSET;
760 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
761 mixinfo.Mute = 2;
762 mixinfo.VolumeR = mixinfo.VolumeL = 90;
763 IoctlMixer(&rp);
764}
765//******************************************************************************
766//******************************************************************************
767/**@internal
768 * @param PREQPACKET pointer to the strategy request packet
769 * @return None But the Status in the request packet is updated on error
770 * @notes
771 * StrategyIoctl is called from the strategy entry point to process IOCTL
772 * requests. only catagory 80x requests will be processed.
773 */
774/* extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
775*
776*
777*
778*/
779extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
780{
781 if(prp->s.ioctl.bCategory == DAUDIO_IOCTL_CAT) {
782 IoctlDirectAudio(prp);
783 return;
784 }
785
786 if(prp->s.ioctl.bCategory == 0x90) {
787 IoctlMixer(prp);
788 return;
789 }
790 if(prp->s.ioctl.bCategory != AUDIO_IOCTL_CAT) {
791 prp->usStatus |= RPERR | RPBADCMD;
792 return;
793 }
794
795 switch (prp->s.ioctl.bCode)
796 {
797 case AUDIO_INIT:
798 IoctlAudioInit(prp, LDev);
799 break;
800 case AUDIO_CONTROL:
801 IoctlAudioControl(prp);
802 break;
803 case AUDIO_CAPABILITY:
804 IoctlAudioCapability(prp, LDev);
805 break;
806 default:
807 prp->usStatus |= RPERR | RPBADCMD;
808 break;
809 }
810 return;
811}
Note: See TracBrowser for help on using the repository browser.