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

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

update for new direct audio interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/* $Id: ioctl.cpp 166 2001-03-22 18:13:01Z 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 PSTREAM pStream;
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
318 if(DevHelp_VerifyAccess(SELECTOROF(pInit), sizeof(MCI_AUDIO_INIT), OFFSETOF(pInit), VERIFY_READWRITE))
319 {
320 dprintf(("Invalid MCI_AUDIO_INIT pointer %lx!!", (ULONG)pInit));
321 prp->usStatus |= RPERR | RPBADCMD;
322 return;
323 }
324
325 audioCaps.ulLength = sizeof(MCI_AUDIO_CAPS);
326 audioCaps.ulSamplingRate = pInit->lSRate;
327 audioCaps.ulChannels = pInit->sChannels;
328 audioCaps.ulBitsPerSample = pInit->lBitsPerSRate;
329 audioCaps.ulDataType = pInit->sMode;
330 audioCaps.ulOperation = OPERATION_PLAY;
331
332 // get the pointer to the hardware object
333 // call DevCaps
334 // bailout if no hardware object is returned..
335 pHWobj = GetHardwareDevice(AUDIOHW_WAVE_PLAY);
336 if (pHWobj)
337 {
338 pHWobj->DevCaps(&audioCaps);
339 if (audioCaps.ulSupport != SUPPORT_SUCCESS) {
340 dprintf(("IoctlDirectAudio: DevCaps failed"));
341 pInit->sReturnCode = INVALID_REQUEST;
342 prp->usStatus |= RPERR;
343 return;
344 }
345 }
346 else {
347 pInit->sReturnCode = INVALID_REQUEST;
348 prp->usStatus |= RPERR;
349 return;
350 }
351
352 pStream = new DWAVESTREAM(AUDIOHW_WAVE_PLAY, pInit, prp->s.ioctl.usSysFileNum);
353 if(pStream == NULL) {
354 DebugInt3();
355 pInit->sReturnCode = INVALID_REQUEST;
356 prp->usStatus |= RPERR;
357 return;
358 }
359
360 pInit->ulFlags |= VOLUME; /* volume control is supported */
361 pInit->ulFlags |= INPUT; /* Input select is supported */
362 pInit->ulFlags |= OUTPUT; /* Output select is supported */
363 pInit->ulFlags |= MONITOR; /* Record Monitor is supported */
364 pInit->sDeviceID = SB_LIVE; /* Reported in VSD dll */
365 pStream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
366 pInit->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
367 pInit->sReturnCode = 0;
368
369 return;
370 }
371 else
372 if(prp->s.ioctl.bCode == DAUDIO_QUERYFORMAT)
373 {
374 LPMCI_AUDIO_INIT pInit = (LPMCI_AUDIO_INIT) prp->s.ioctl.pvData;
375 PAUDIOHW pHWobj;
376 MCI_AUDIO_CAPS audioCaps;
377
378 if(DevHelp_VerifyAccess(SELECTOROF(pInit), sizeof(MCI_AUDIO_INIT), OFFSETOF(pInit), VERIFY_READWRITE))
379 {
380 dprintf(("Invalid MCI_AUDIO_INIT pointer %lx!!", (ULONG)pInit));
381 prp->usStatus |= RPERR | RPBADCMD;
382 return;
383 }
384
385 audioCaps.ulLength = sizeof(MCI_AUDIO_CAPS);
386 audioCaps.ulSamplingRate = pInit->lSRate;
387 audioCaps.ulChannels = pInit->sChannels;
388 audioCaps.ulBitsPerSample = pInit->lBitsPerSRate;
389 audioCaps.ulDataType = pInit->sMode;
390 audioCaps.ulOperation = OPERATION_PLAY;
391
392 // get the pointer to the hardware object
393 // call DevCaps
394 // bailout if no hardware object is returned..
395 pHWobj = GetHardwareDevice(AUDIOHW_WAVE_PLAY);
396 if (pHWobj)
397 {
398 pHWobj->DevCaps(&audioCaps);
399 if (audioCaps.ulSupport != SUPPORT_SUCCESS) {
400 dprintf(("IoctlDirectAudio: DevCaps failed"));
401 prp->usStatus |= RPERR;
402 pInit->sReturnCode = INVALID_REQUEST;
403 return;
404 }
405 pInit->sReturnCode = 0;
406 return;
407 }
408 else {
409 pInit->sReturnCode = INVALID_REQUEST;
410 prp->usStatus |= RPERR;
411 return;
412 }
413 }
414
415 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
416 if(pStream == NULL) {
417 dprintf(("IoctlDirectAudio stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
418 DebugInt3();
419 prp->usStatus |= RPERR | RPBADCMD;
420 return;
421 }
422
423 LPDAUDIO_CMD pDAudioCmd = (LPDAUDIO_CMD) prp->s.ioctl.pvData;
424 ULONG rc = 0;
425
426 if(DevHelp_VerifyAccess(SELECTOROF(pDAudioCmd), sizeof(DAUDIO_CMD), OFFSETOF(pDAudioCmd), VERIFY_READWRITE))
427 {
428 dprintf(("Invalid DAUDIO_CMD pointer %lx!!", (ULONG)pDAudioCmd));
429 prp->usStatus |= RPERR | RPBADCMD;
430 return;
431 }
432
433 switch(prp->s.ioctl.bCode)
434 {
435 case DAUDIO_CLOSE:
436 delete pStream;
437 break;
438
439 case DAUDIO_SETVOLUME:
440 pStream->SetVolume(pDAudioCmd->Vol.Volume);
441 break;
442
443 case DAUDIO_GETVOLUME:
444 pDAudioCmd->Vol.Volume = pStream->GetVolume();
445 break;
446
447 case DAUDIO_START:
448 rc = pStream->StartStream();
449 break;
450
451 case DAUDIO_STOP:
452 {
453 CONTROL_PARM cParm;
454 rc = pStream->StopStream(&cParm);
455 break;
456 }
457
458 case DAUDIO_PAUSE:
459 {
460 CONTROL_PARM cParm;
461 rc = pStream->PauseStream(&cParm);
462 break;
463 }
464
465 case DAUDIO_RESUME:
466 rc = pStream->ResumeStream();
467 break;
468
469 case DAUDIO_GETPOS:
470 pDAudioCmd->Pos.ulCurrentPos = pStream->GetCurrentPos();
471 break;
472
473 case DAUDIO_ADDBUFFER:
474 {
475 rc = pStream->Write((PSTREAMBUF)pDAudioCmd->Buffer.lpBuffer, pDAudioCmd->Buffer.ulBufferLength);
476 break;
477 }
478
479 case DAUDIO_REGISTER_THREAD:
480 {
481 DDCMDREGISTER reg;
482
483 if(DevHelp_OpenEventSem(pDAudioCmd->Thread.hSemaphore) != 0) {
484 dprintf(("DevHlp_OpenEventSem %lx failed!", pDAudioCmd->Thread.hSemaphore));
485 prp->usStatus |= RPERR | RPBADCMD;
486 return;
487 }
488
489 reg.ulFunction = DDCMD_REG_STREAM;
490 reg.hStream = pDAudioCmd->Thread.hSemaphore;
491 reg.ulSysFileNum = prp->s.ioctl.usSysFileNum;
492 reg.pSHDEntryPoint = NULL;
493 rc = pStream->Register(&reg);
494 break;
495 }
496
497 case DAUDIO_DEREGISTER_THREAD:
498 {
499 pStream->DeRegister();
500
501 if(DevHelp_CloseEventSem(pDAudioCmd->Thread.hSemaphore) != 0) {
502 dprintf(("DevHlp_CloseEventSemaphore %lx failed!", pDAudioCmd->Thread.hSemaphore));
503 prp->usStatus |= RPERR | RPBADCMD;
504 return;
505 }
506 break;
507 }
508
509 }
510
511 if(rc) {
512 prp->usStatus |= RPERR | RPBADCMD;
513 return;
514 }
515 return;
516}
517//******************************************************************************
518//******************************************************************************
519void IoctlMixer(PREQPACKET prp)
520{
521 MIXSTRUCT FAR *pMixStruct = (MIXSTRUCT FAR *)prp->s.ioctl.pvData;
522 ULONG FAR *pIoctlData = (ULONG FAR *)prp->s.ioctl.pvData;
523 CHAR FAR *pIoctlMap = (CHAR FAR *)prp->s.ioctl.pvData; //getapimap
524 USHORT VolumeL, VolumeR;
525
526 if((prp->s.ioctl.bCode & 0xF0) == 0x40)
527 {
528 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READWRITE))
529 {
530 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
531 prp->usStatus |= RPERR | RPBADCMD;
532 return;
533 }
534 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL = pMixStruct->VolumeL;
535 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR = pMixStruct->VolumeR;
536 MixerSettings[prp->s.ioctl.bCode & 0xF].Mute = pMixStruct->Mute;
537 VolumeL = (USHORT)pMixStruct->VolumeL;
538 VolumeR = (USHORT)pMixStruct->VolumeR;
539 if(prp->s.ioctl.bCode != BASSTREBLESET) {
540 if(pMixStruct->Mute == 1)
541 VolumeL = VolumeR = 0;
542 }
543 }
544 else
545 if((prp->s.ioctl.bCode & 0xF0) == 0x60)
546 {
547 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READONLY))
548 {
549 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
550 prp->usStatus |= RPERR | RPBADCMD;
551 return;
552 }
553 }
554
555 switch(prp->s.ioctl.bCode) {
556 case MICSET:
557 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMICVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
558 break;
559 case LINESET:
560 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETLINEINVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
561 break;
562 case CDSET:
563 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETCDVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
564 break;
565 case VIDEOSET:
566 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETVIDEOVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
567 break;
568 case AUXSET:
569 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETAUXVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
570 break;
571
572 case BASSTREBLESET:
573 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETBASS, MAKE_VOLUME_LR(VolumeL, VolumeL));
574 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETTREBLE, MAKE_VOLUME_LR(VolumeR, VolumeR));
575 break;
576#if 0
577 case STREAMVOLSET:
578 //release stream volume override?
579 if(pMixStruct->Mute == 2) {
580 fStreamVolIOCTL90 = FALSE;
581 break;
582 }
583 fStreamVolIOCTL90 = TRUE;
584 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMASTERVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
585 break;
586#endif
587
588 case RECORDSRCSET:
589 {
590 int recsrc = MIX_RECSRC_LINE;
591
592 //release recording source override?
593 if(pMixStruct->Mute == 2) {
594 fRecSrcIOCTL90 = FALSE;
595 break;
596 }
597 fRecSrcIOCTL90 = TRUE;
598 switch(pMixStruct->VolumeL) {
599 case I90SRC_MIC:
600 recsrc = MIX_RECSRC_MIC;
601 break;
602 case I90SRC_CD:
603 recsrc = MIX_RECSRC_CD;
604 break;
605 case I90SRC_VIDEO:
606 recsrc = MIX_RECSRC_VIDEO;
607 break;
608 case I90SRC_LINE:
609 recsrc = MIX_RECSRC_LINE;
610 break;
611 case I90SRC_AUX:
612 recsrc = MIX_RECSRC_AUX;
613 break;
614 // case I90SRC_RES5:
615 // case I90SRC_RES6:
616 // case I90SRC_PHONE:
617 default:
618 break;
619 }
620 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTSRC, recsrc);
621 break;
622 }
623 case RECORDGAINSET:
624 //release recording gain override?
625 if(pMixStruct->Mute == 2) {
626 fRecGainIOCTL90 = FALSE;
627 break;
628 }
629 fRecGainIOCTL90 = TRUE;
630 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTGAIN, MAKE_VOLUME_LR(VolumeL, VolumeL));
631 break;
632
633 case MICQUERY:
634 case LINEQUERY:
635 case AUXQUERY:
636 case CDQUERY:
637 case VIDEOQUERY:
638 case RECORDSRCQUERY:
639 case RECORDGAINQUERY:
640 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
641 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
642 pMixStruct->Mute = MixerSettings[prp->s.ioctl.bCode & 0xF].Mute;
643 break;
644
645 case BASSTREBLEQUERY:
646 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
647 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
648 pMixStruct->Mute = 3; //bass & treble
649 break;
650
651 case APILEVELQUERY:
652 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlData), sizeof(ULONG), OFFSETOF(pIoctlData), VERIFY_READWRITE))
653 {
654 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pIoctlData));
655 prp->usStatus |= RPERR | RPBADCMD;
656 return;
657 }
658 *pIoctlData = 2;
659 break;
660
661 case GETAPIMAP:
662 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlMap), sizeof(SBLiveIOCTLMap), OFFSETOF(pIoctlMap), VERIFY_READWRITE))
663 {
664 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
665 prp->usStatus |= RPERR | RPBADCMD;
666 return;
667 }
668 _fmemcpy(pIoctlMap, SBLiveIOCTLMap, sizeof(SBLiveIOCTLMap));
669 break;
670// case STREAMVOLQUERY:
671// case MONOINSET:
672// case PHONESET:
673// case THREEDSET:
674// case MONOINQUERY:
675// case PHONEQUERY:
676// case THREEDQUERY:
677// case CALLBACKREG:
678// case MSGBUF:
679 default:
680 prp->usStatus |= RPERR | RPBADCMD;
681 return;
682 }
683}
684//******************************************************************************
685//******************************************************************************
686void MixerInit()
687{
688 REQPACKET rp;
689 MIXSTRUCT mixinfo;
690
691 SBLiveIOCTLMap[MICSET] = 1;
692 SBLiveIOCTLMap[MICQUERY] = 1;
693 SBLiveIOCTLMap[LINESET] = 1;
694 SBLiveIOCTLMap[LINEQUERY] = 1;
695 SBLiveIOCTLMap[CDSET] = 1;
696 SBLiveIOCTLMap[CDQUERY] = 1;
697 SBLiveIOCTLMap[VIDEOSET] = 1;
698 SBLiveIOCTLMap[VIDEOQUERY] = 1;
699 SBLiveIOCTLMap[AUXSET] = 1;
700 SBLiveIOCTLMap[AUXQUERY] = 1;
701 SBLiveIOCTLMap[BASSTREBLESET] = 1;
702 SBLiveIOCTLMap[BASSTREBLEQUERY] = 1;
703//// SBLiveIOCTLMap[STREAMVOLSET] = 1;
704//// SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
705 SBLiveIOCTLMap[RECORDSRCSET] = 1;
706 SBLiveIOCTLMap[RECORDSRCQUERY] = 1;
707 SBLiveIOCTLMap[RECORDGAINSET] = 1;
708 SBLiveIOCTLMap[RECORDGAINQUERY] = 1;
709 SBLiveIOCTLMap[APILEVELQUERY] = 1;
710 SBLiveIOCTLMap[GETAPIMAP] = 1;
711// SBLiveIOCTLMap[CALLBACKREG] = 1;
712
713 //Set mic
714 rp.s.ioctl.bCode = MICSET;
715 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
716 mixinfo.Mute = fMicMute;
717 mixinfo.VolumeR = mixinfo.VolumeL = 60;
718 IoctlMixer(&rp);
719
720 //Set line
721 rp.s.ioctl.bCode = LINESET;
722 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
723 mixinfo.Mute = fLineMute;
724 mixinfo.VolumeR = mixinfo.VolumeL = 80;
725 IoctlMixer(&rp);
726
727 //Set CD
728 rp.s.ioctl.bCode = CDSET;
729 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
730 mixinfo.Mute = fCDMute;
731 mixinfo.VolumeR = mixinfo.VolumeL = 80;
732 IoctlMixer(&rp);
733
734 //Set bass/treble
735 rp.s.ioctl.bCode = BASSTREBLESET;
736 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
737 mixinfo.Mute = 3;
738 mixinfo.VolumeR = mixinfo.VolumeL = 50;
739 IoctlMixer(&rp);
740
741 //Set recording source to line in
742 rp.s.ioctl.bCode = RECORDSRCSET;
743 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
744 mixinfo.Mute = 0;
745 mixinfo.VolumeL = I90SRC_LINE;
746 IoctlMixer(&rp);
747
748 //Release recording source override
749 rp.s.ioctl.bCode = RECORDSRCSET;
750 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
751 mixinfo.Mute = 2;
752 mixinfo.VolumeL = I90SRC_LINE;
753 IoctlMixer(&rp);
754
755 //Set master volume
756 rp.s.ioctl.bCode = STREAMVOLSET;
757 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
758 mixinfo.Mute = 0;
759 mixinfo.VolumeR = mixinfo.VolumeL = 90;
760 IoctlMixer(&rp);
761
762 //Release master volume override
763 rp.s.ioctl.bCode = STREAMVOLSET;
764 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
765 mixinfo.Mute = 2;
766 mixinfo.VolumeR = mixinfo.VolumeL = 90;
767 IoctlMixer(&rp);
768}
769//******************************************************************************
770//******************************************************************************
771/**@internal
772 * @param PREQPACKET pointer to the strategy request packet
773 * @return None But the Status in the request packet is updated on error
774 * @notes
775 * StrategyIoctl is called from the strategy entry point to process IOCTL
776 * requests. only catagory 80x requests will be processed.
777 */
778/* extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
779*
780*
781*
782*/
783extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
784{
785 if(prp->s.ioctl.bCategory == DAUDIO_IOCTL_CAT) {
786 IoctlDirectAudio(prp);
787 return;
788 }
789
790 if(prp->s.ioctl.bCategory == 0x90) {
791 IoctlMixer(prp);
792 return;
793 }
794 if(prp->s.ioctl.bCategory != AUDIO_IOCTL_CAT) {
795 prp->usStatus |= RPERR | RPBADCMD;
796 return;
797 }
798
799 switch (prp->s.ioctl.bCode)
800 {
801 case AUDIO_INIT:
802 IoctlAudioInit(prp, LDev);
803 break;
804 case AUDIO_CONTROL:
805 IoctlAudioControl(prp);
806 break;
807 case AUDIO_CAPABILITY:
808 IoctlAudioCapability(prp, LDev);
809 break;
810 default:
811 prp->usStatus |= RPERR | RPBADCMD;
812 break;
813 }
814 return;
815}
Note: See TracBrowser for help on using the repository browser.