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

Last change on this file since 302 was 205, checked in by stevenhl, 18 years ago

Make warnings away - SHL
Use drv16/midi_idc.h only - SHL
Add interrupts 16-23 - MF

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