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

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

* empty log message *

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