[142] | 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>
|
---|
[166] | 26 | #include <os2me.h>
|
---|
[142] | 27 | #include <audio.h>
|
---|
| 28 |
|
---|
| 29 | #include "strategy.h"
|
---|
| 30 | #include "audiohw.hpp"
|
---|
| 31 | #include "mpu401.hpp"
|
---|
| 32 | #include "wavehw.hpp"
|
---|
[166] | 33 | #include "dwavestrm.hpp"
|
---|
[142] | 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 |
|
---|
[166] | 45 | #include <daudio.h>
|
---|
| 46 |
|
---|
[142] | 47 | //Map of possible 256 supported ioctls (IOCTl 90 mixer api)
|
---|
| 48 | char SBLiveIOCTLMap[256] = {0};
|
---|
| 49 | MIXSTRUCT MixerSettings[16] = {0};
|
---|
| 50 |
|
---|
| 51 | //override flags for rec src & gain mixer commands
|
---|
| 52 | BOOL fRecSrcIOCTL90 = FALSE;
|
---|
| 53 | BOOL fRecGainIOCTL90 = FALSE;
|
---|
| 54 |
|
---|
[178] | 55 | int numFreeStreams = SBLIVECAPS_MAXSTREAMS;
|
---|
| 56 |
|
---|
[142] | 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 | */
|
---|
| 68 | void 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 {
|
---|
[188] | 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;
|
---|
[142] | 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:
|
---|
[147] | 150 | pstream = new MIDISTREAM(HardwareType, prp->s.ioctl.usSysFileNum);
|
---|
[142] | 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 | */
|
---|
| 176 | void 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 | */
|
---|
| 213 | void 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;
|
---|
[147] | 219 | ULONG volume;
|
---|
[148] | 220 | ULONG addr;
|
---|
[142] | 221 |
|
---|
| 222 | if (p->usIOCtlRequest != AUDIO_CHANGE) {
|
---|
[178] | 223 | p->sReturnCode = INVALID_REQUEST;
|
---|
| 224 | prp->usStatus |= RPERR | RPBADCMD;
|
---|
| 225 | return;
|
---|
[142] | 226 | }
|
---|
| 227 | p->sReturnCode=0;
|
---|
| 228 |
|
---|
| 229 | pAudChange = (LPMCI_AUDIO_CHANGE)p->pbRequestInfo;
|
---|
[148] | 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) {
|
---|
[178] | 235 | dprintf(("Invalid MCI_AUDIO_CHANGE pointer %lx!!", (ULONG)pAudChange));
|
---|
| 236 | p->sReturnCode = INVALID_REQUEST;
|
---|
| 237 | prp->usStatus |= RPERR | RPBADCMD;
|
---|
| 238 | return;
|
---|
[142] | 239 | }
|
---|
| 240 | pMasterVol = (LPMCI_TRACK_INFO)pAudChange->pvDevInfo;
|
---|
[148] | 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) {
|
---|
[178] | 246 | dprintf(("Invalid MCI_TRACK_INFO pointer %lx!!", (ULONG)pMasterVol));
|
---|
| 247 | p->sReturnCode = INVALID_REQUEST;
|
---|
| 248 | prp->usStatus |= RPERR | RPBADCMD;
|
---|
| 249 | return;
|
---|
[142] | 250 | }
|
---|
| 251 |
|
---|
| 252 | pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
|
---|
| 253 | if(pStream == NULL) {
|
---|
[178] | 254 | dprintf(("IoctlAudioControl stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
|
---|
| 255 | DebugInt3();
|
---|
| 256 | return;
|
---|
[142] | 257 | }
|
---|
| 258 | if(pAudChange->lBalance != AUDIO_IGNORE)
|
---|
[178] | 259 | pStream->SetProperty(PROPERTY_BALANCE, pAudChange->lBalance);
|
---|
[142] | 260 |
|
---|
[147] | 261 | if(pAudChange->lVolume != AUDIO_IGNORE) {
|
---|
[178] | 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));
|
---|
[147] | 267 | }
|
---|
[166] | 268 |
|
---|
[142] | 269 | if(pMasterVol && pMasterVol->usMasterVolume != AUDIO_IGNORE) {
|
---|
[178] | 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));
|
---|
[142] | 278 | }
|
---|
[147] | 279 | if(!fRecSrcIOCTL90) {
|
---|
[166] | 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:
|
---|
[178] | 288 | pStream->SetProperty(PROPERTY_INPUTSRC, MIX_RECSRC_LINE);
|
---|
[166] | 289 | break;
|
---|
| 290 |
|
---|
| 291 | case MIC_INPUT:
|
---|
| 292 | case BOOSTED_MIC_INPUT:
|
---|
[178] | 293 | pStream->SetProperty(PROPERTY_INPUTSRC, MIX_RECSRC_MIC);
|
---|
[166] | 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:
|
---|
[178] | 303 | pStream->SetProperty(PROPERTY_INPUTSRC, MIX_RECSRC_MIXER);
|
---|
[166] | 304 | break;
|
---|
| 305 | }
|
---|
| 306 | }
|
---|
[142] | 307 | }
|
---|
[147] | 308 | if(!fRecGainIOCTL90 && pAudChange->lGain != AUDIO_IGNORE) {
|
---|
[178] | 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));
|
---|
[147] | 317 | }
|
---|
[142] | 318 | }
|
---|
| 319 | //******************************************************************************
|
---|
| 320 | //******************************************************************************
|
---|
[166] | 321 | void 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;
|
---|
[167] | 328 | PDWAVESTREAM pStream;
|
---|
[166] | 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 |
|
---|
[167] | 372 | if(!pStream->IsEverythingOk()) {
|
---|
| 373 | delete pStream;
|
---|
| 374 | DebugInt3();
|
---|
| 375 | pInit->sReturnCode = INVALID_REQUEST;
|
---|
| 376 | prp->usStatus |= RPERR;
|
---|
| 377 | return;
|
---|
| 378 | }
|
---|
[166] | 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 | }
|
---|
[178] | 433 | else
|
---|
| 434 | if(prp->s.ioctl.bCode == DAUDIO_QUERYCAPS)
|
---|
| 435 | {
|
---|
| 436 | LPDAUDIO_CAPS lpCaps = (LPDAUDIO_CAPS) prp->s.ioctl.pvData;
|
---|
| 437 | PWAVEAUDIO pHWobj;
|
---|
[166] | 438 |
|
---|
[178] | 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 | }
|
---|
[167] | 463 | PSTREAM pStream;
|
---|
| 464 |
|
---|
[166] | 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:
|
---|
[172] | 490 | {
|
---|
[178] | 491 | pStream->SetProperty(PROPERTY_VOLUME, MAKE_VOLUME_LR(pDAudioCmd->Vol.VolumeL, pDAudioCmd->Vol.VolumeR));
|
---|
[166] | 492 | break;
|
---|
[172] | 493 | }
|
---|
[166] | 494 |
|
---|
| 495 | case DAUDIO_GETVOLUME:
|
---|
[178] | 496 | pDAudioCmd->Vol.VolumeL = GET_VOLUME_L(pStream->GetProperty(PROPERTY_VOLUME));
|
---|
| 497 | pDAudioCmd->Vol.VolumeR = GET_VOLUME_R(pStream->GetProperty(PROPERTY_VOLUME));
|
---|
[166] | 498 | break;
|
---|
| 499 |
|
---|
| 500 | case DAUDIO_START:
|
---|
[178] | 501 | if(numFreeStreams > 0) {
|
---|
| 502 | rc = pStream->StartStream();
|
---|
| 503 | if(!rc) numFreeStreams--;
|
---|
| 504 | }
|
---|
| 505 | else rc = 1; //fail
|
---|
| 506 |
|
---|
[166] | 507 | break;
|
---|
| 508 |
|
---|
| 509 | case DAUDIO_STOP:
|
---|
| 510 | {
|
---|
| 511 | CONTROL_PARM cParm;
|
---|
[178] | 512 | int fActive = pStream->isActive();
|
---|
| 513 |
|
---|
[166] | 514 | rc = pStream->StopStream(&cParm);
|
---|
[178] | 515 | if(!rc && fActive) numFreeStreams++;
|
---|
[166] | 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();
|
---|
[178] | 532 | pDAudioCmd->Pos.ulWritePos = pStream->GetCurrentWritePos();
|
---|
[166] | 533 | break;
|
---|
| 534 |
|
---|
| 535 | case DAUDIO_ADDBUFFER:
|
---|
| 536 | {
|
---|
| 537 | rc = pStream->Write((PSTREAMBUF)pDAudioCmd->Buffer.lpBuffer, pDAudioCmd->Buffer.ulBufferLength);
|
---|
| 538 | break;
|
---|
| 539 | }
|
---|
| 540 |
|
---|
[178] | 541 | case DAUDIO_SETPROPERTY:
|
---|
| 542 | {
|
---|
[205] | 543 | rc = pStream->SetProperty((INT)pDAudioCmd->SetProperty.type, pDAudioCmd->SetProperty.value);
|
---|
[186] | 544 | break;
|
---|
[178] | 545 | }
|
---|
| 546 |
|
---|
[166] | 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(®);
|
---|
| 556 | break;
|
---|
| 557 | }
|
---|
| 558 |
|
---|
| 559 | case DAUDIO_DEREGISTER_THREAD:
|
---|
| 560 | {
|
---|
| 561 | pStream->DeRegister();
|
---|
| 562 | break;
|
---|
| 563 | }
|
---|
| 564 |
|
---|
[178] | 565 | case DAUDIO_QUERYVERSION:
|
---|
| 566 | pDAudioCmd->Version.ulVersion = DAUDIO_VERSION;
|
---|
| 567 | break;
|
---|
[166] | 568 | }
|
---|
| 569 |
|
---|
| 570 | if(rc) {
|
---|
| 571 | prp->usStatus |= RPERR | RPBADCMD;
|
---|
| 572 | return;
|
---|
| 573 | }
|
---|
| 574 | return;
|
---|
| 575 | }
|
---|
| 576 | //******************************************************************************
|
---|
| 577 | //******************************************************************************
|
---|
[142] | 578 | void 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 |
|
---|
[166] | 585 | if((prp->s.ioctl.bCode & 0xF0) == 0x40)
|
---|
[142] | 586 | {
|
---|
[166] | 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 | }
|
---|
[142] | 602 | }
|
---|
| 603 | else
|
---|
[166] | 604 | if((prp->s.ioctl.bCode & 0xF0) == 0x60)
|
---|
[142] | 605 | {
|
---|
[166] | 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 | }
|
---|
[142] | 612 | }
|
---|
| 613 |
|
---|
[166] | 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;
|
---|
[142] | 630 |
|
---|
[166] | 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;
|
---|
[191] | 635 |
|
---|
[166] | 636 | case STREAMVOLSET:
|
---|
[191] | 637 | OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETPCMVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
|
---|
[166] | 638 | break;
|
---|
[142] | 639 |
|
---|
[166] | 640 | case RECORDSRCSET:
|
---|
| 641 | {
|
---|
| 642 | int recsrc = MIX_RECSRC_LINE;
|
---|
[142] | 643 |
|
---|
[166] | 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;
|
---|
[142] | 684 |
|
---|
[166] | 685 | case MICQUERY:
|
---|
| 686 | case LINEQUERY:
|
---|
| 687 | case AUXQUERY:
|
---|
| 688 | case CDQUERY:
|
---|
| 689 | case VIDEOQUERY:
|
---|
| 690 | case RECORDSRCQUERY:
|
---|
| 691 | case RECORDGAINQUERY:
|
---|
[191] | 692 | case STREAMVOLQUERY:
|
---|
[166] | 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;
|
---|
[142] | 697 |
|
---|
[166] | 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;
|
---|
[142] | 703 |
|
---|
[166] | 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;
|
---|
[142] | 713 |
|
---|
[166] | 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;
|
---|
[191] | 723 |
|
---|
[142] | 724 | // case MONOINSET:
|
---|
| 725 | // case PHONESET:
|
---|
| 726 | // case THREEDSET:
|
---|
| 727 | // case MONOINQUERY:
|
---|
| 728 | // case PHONEQUERY:
|
---|
| 729 | // case THREEDQUERY:
|
---|
| 730 | // case CALLBACKREG:
|
---|
| 731 | // case MSGBUF:
|
---|
[166] | 732 | default:
|
---|
| 733 | prp->usStatus |= RPERR | RPBADCMD;
|
---|
| 734 | return;
|
---|
| 735 | }
|
---|
[142] | 736 | }
|
---|
| 737 | //******************************************************************************
|
---|
| 738 | //******************************************************************************
|
---|
| 739 | void MixerInit()
|
---|
| 740 | {
|
---|
| 741 | REQPACKET rp;
|
---|
| 742 | MIXSTRUCT mixinfo;
|
---|
| 743 |
|
---|
[166] | 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;
|
---|
[191] | 756 | SBLiveIOCTLMap[STREAMVOLSET] = 1;
|
---|
| 757 | SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
|
---|
[166] | 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;
|
---|
[142] | 765 |
|
---|
[166] | 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);
|
---|
[142] | 772 |
|
---|
[166] | 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);
|
---|
[142] | 779 |
|
---|
[166] | 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);
|
---|
[142] | 786 |
|
---|
[191] | 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
|
---|
[166] | 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);
|
---|
[142] | 800 |
|
---|
[166] | 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);
|
---|
[142] | 807 |
|
---|
[166] | 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);
|
---|
[142] | 814 |
|
---|
[191] | 815 | //Set PCM volume
|
---|
[166] | 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);
|
---|
[142] | 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 | */
|
---|
| 836 | extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
|
---|
| 837 | {
|
---|
[166] | 838 | if(prp->s.ioctl.bCategory == DAUDIO_IOCTL_CAT) {
|
---|
| 839 | IoctlDirectAudio(prp);
|
---|
| 840 | return;
|
---|
| 841 | }
|
---|
[142] | 842 |
|
---|
[166] | 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;
|
---|
[142] | 868 | }
|
---|