Annotation of ntddk/src/mmedia/soundlib/volume.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1992  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     volume.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains code for set and get volume IOCTLs
        !            12: 
        !            13: Author:
        !            14: 
        !            15:     Robin Speed (RobinSp) 21-Oct-1992
        !            16: 
        !            17: Environment:
        !            18: 
        !            19:     Kernel mode
        !            20: 
        !            21: Revision History:
        !            22: 
        !            23: --*/
        !            24: 
        !            25: #include <string.h>
        !            26: #include <soundlib.h>          // Definition of what's in here
        !            27: 
        !            28: //
        !            29: // Internal routines
        !            30: //
        !            31: 
        !            32: VOID
        !            33: SoundVolumeNotify(
        !            34:     IN OUT PLOCAL_DEVICE_INFO pLDI
        !            35: );
        !            36: 
        !            37: //
        !            38: // Return the current volume setting.  If the card doesn't support
        !            39: // volume setting return maximum volume (FFFFFFFF)
        !            40: //
        !            41: 
        !            42: NTSTATUS
        !            43: SoundIoctlGetVolume(
        !            44:     IN     PLOCAL_DEVICE_INFO pLDI,
        !            45:     IN     PIRP pIrp,
        !            46:     IN     PIO_STACK_LOCATION IrpStack
        !            47: )
        !            48: {
        !            49:     PWAVE_DD_VOLUME pVol;
        !            50: 
        !            51:     if (pLDI->CreationFlags & SOUND_CREATION_NO_VOLUME) {
        !            52:         return STATUS_NOT_SUPPORTED;
        !            53:     }
        !            54: 
        !            55:     if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(WAVE_DD_VOLUME)) {
        !            56:         dprintf1(("Supplied buffer to small for requested data"));
        !            57:         return STATUS_BUFFER_TOO_SMALL;
        !            58:     }
        !            59: 
        !            60: 
        !            61:     //
        !            62:     // say how much we're sending back
        !            63:     //
        !            64: 
        !            65:     pIrp->IoStatus.Information = sizeof(WAVE_DD_VOLUME);
        !            66: 
        !            67:     //
        !            68:     // cast the buffer address to the pointer type we want
        !            69:     //
        !            70: 
        !            71:     pVol = (PWAVE_DD_VOLUME)pIrp->AssociatedIrp.SystemBuffer;
        !            72: 
        !            73:     //
        !            74:     // fill in the info
        !            75:     //
        !            76: 
        !            77:     *pVol = pLDI->Volume;
        !            78: 
        !            79:     return STATUS_SUCCESS;
        !            80: }
        !            81: //
        !            82: // Set the volume
        !            83: //
        !            84: 
        !            85: NTSTATUS
        !            86: SoundIoctlSetVolume(
        !            87:     IN     PLOCAL_DEVICE_INFO pLDI,
        !            88:     IN     PIRP pIrp,
        !            89:     IN     PIO_STACK_LOCATION IrpStack
        !            90: )
        !            91: {
        !            92:     PWAVE_DD_VOLUME pVol;
        !            93: 
        !            94:     //
        !            95:     // See if volume setting is supported
        !            96:     //
        !            97: 
        !            98:     if (pLDI->CreationFlags & SOUND_CREATION_NO_VOLUME) {
        !            99:         return STATUS_NOT_SUPPORTED;
        !           100:     }
        !           101: 
        !           102:     if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WAVE_DD_VOLUME)) {
        !           103:         dprintf1(("Supplied buffer to small for requested data"));
        !           104:         return STATUS_BUFFER_TOO_SMALL;
        !           105:     }
        !           106: 
        !           107:     //
        !           108:     // cast the buffer address to the pointer type we want
        !           109:     //
        !           110: 
        !           111:     pVol = (PWAVE_DD_VOLUME)pIrp->AssociatedIrp.SystemBuffer;
        !           112: 
        !           113:     //
        !           114:     // If the device is 'open' or aux (which is not explicitly opened to
        !           115:     // play) and the volume has changed then actually set the volume.
        !           116:     //
        !           117: 
        !           118:     if (// (pLDI->DeviceType == AUX_DEVICE || *pLDI->DeviceBusy) &&
        !           119:         (pLDI->Volume.Left != pVol->Left ||
        !           120:          pLDI->Volume.Right != pVol->Right)) {
        !           121: 
        !           122:         //
        !           123:         // Set the volume in the device
        !           124:         //
        !           125: 
        !           126:         pLDI->Volume = *pVol;
        !           127: 
        !           128:         //
        !           129:         // say how much we're sending back
        !           130:         //
        !           131: 
        !           132:         pIrp->IoStatus.Information = sizeof(WAVE_DD_VOLUME);
        !           133: 
        !           134:         //
        !           135:         // Not all devices have volume setting routines.  The 'real'
        !           136:         // device may in fact be sitting in user mode waiting for a
        !           137:         // volume change to complete
        !           138:         //
        !           139: 
        !           140:         (*pLDI->DeviceInit->HwSetVolume)(pLDI);
        !           141: 
        !           142: #ifdef VOLUME_NOTIFY
        !           143:         //
        !           144:         // Tell anyone who's waiting for it to change
        !           145:         //
        !           146: 
        !           147:         SoundVolumeNotify(pLDI);
        !           148: #endif // VOLUME_NOTIFY
        !           149: 
        !           150:         pLDI->VolumeChanged = TRUE;
        !           151:     }
        !           152: 
        !           153:     return STATUS_SUCCESS;
        !           154: }
        !           155: 
        !           156: #ifdef VOLUME_NOTIFY
        !           157: 
        !           158: 
        !           159: NTSTATUS
        !           160: SoundIoctlGetChangedVolume(
        !           161:     IN OUT PLOCAL_DEVICE_INFO pLDI,
        !           162:     IN     PIRP pIrp,
        !           163:     IN     PIO_STACK_LOCATION IrpStack
        !           164: )
        !           165: /*++
        !           166: 
        !           167: Routine Description:
        !           168: 
        !           169:     Checks the parameters and limits waiters (arbitrarily) to 8.
        !           170:     Tests if the current volume is the same as that passed in.  If
        !           171:     not then return the new volume immediately.  If the volume has
        !           172:     not changed then put the Irp in the waiting list.
        !           173: 
        !           174: Arguments:
        !           175: 
        !           176:     pLDI - Local device info
        !           177:     pIrp - Pointer to IO request packet
        !           178:     IrpStack - stack location info
        !           179: 
        !           180: Return Value:
        !           181: 
        !           182:     STATUS_BUFFER_TOO_SMALL - sizes passed in too small
        !           183:     STATUS_INSUFFICIENT_RESOURCES - if too many people are trying to wait
        !           184:     STATUS_SUCCESS - if volume has changed
        !           185:     STATUS_PENDING - if volume was same as before.
        !           186: 
        !           187: --*/
        !           188: {
        !           189:     PWAVE_DD_VOLUME pVol;
        !           190:     pVol = (PWAVE_DD_VOLUME)pIrp->AssociatedIrp.SystemBuffer;
        !           191: 
        !           192:     //
        !           193:     // Check input parameters
        !           194:     //
        !           195: 
        !           196:     if (pLDI->CreationFlags & SOUND_CREATION_NO_VOLUME) {
        !           197:         return STATUS_NOT_SUPPORTED;
        !           198:     }
        !           199: 
        !           200:     if (IrpStack->Parameters.DeviceIoControl.InputBufferLength <
        !           201:             sizeof(AUX_DD_VOLUME) ||
        !           202:         IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
        !           203:             sizeof(AUX_DD_VOLUME)) {
        !           204:         return STATUS_BUFFER_TOO_SMALL;
        !           205:     }
        !           206: 
        !           207:     //
        !           208:     // See if we can complete it now - ie if the device is 'playing'
        !           209:     // and the volume set is not what was passed in.
        !           210:     //
        !           211: 
        !           212:     if (// (pLDI->DeviceType == AUX_DEVICE || *pLDI->DeviceBusy) &&
        !           213:         (pVol->Left != pLDI->Volume.Left || pVol->Right != pLDI->Volume.Right))
        !           214:     {
        !           215:         *pVol = pLDI->Volume;
        !           216: 
        !           217:         pIrp->IoStatus.Information = sizeof(*pVol);
        !           218: 
        !           219:         return STATUS_SUCCESS;
        !           220:     } else {
        !           221: 
        !           222:         IoMarkIrpPending(pIrp);
        !           223:         pIrp->IoStatus.Status = STATUS_PENDING;
        !           224: 
        !           225:         SoundAddIrpToCancellableQ(&pLDI->VolumeQueue, pIrp, FALSE);
        !           226: 
        !           227:         return STATUS_PENDING;
        !           228:     }
        !           229: 
        !           230: }
        !           231: 
        !           232: 
        !           233: VOID
        !           234: SoundVolumeNotify(
        !           235:     IN OUT PLOCAL_DEVICE_INFO pLDI
        !           236: )
        !           237: /*++
        !           238: 
        !           239: Routine Description:
        !           240: 
        !           241:     Notify all waiters on this device that the volume has changed.
        !           242:     This involves just copying the data into their Irps and
        !           243:     completing them.
        !           244: 
        !           245: Arguments:
        !           246: 
        !           247:     pLDI - Local device info
        !           248: 
        !           249: Return Value:
        !           250: 
        !           251:     None
        !           252: 
        !           253: --*/
        !           254: {
        !           255:     PLIST_ENTRY ListHead;
        !           256:     ListHead = &pLDI->VolumeQueue;
        !           257: 
        !           258:     //
        !           259:     // Remove all the queue entries, completing all
        !           260:     // the Irps represented by the entries
        !           261:     //
        !           262: 
        !           263:     for (;;) {
        !           264:         PIRP pIrp;
        !           265: 
        !           266:         pIrp = SoundRemoveFromCancellableQ(ListHead);
        !           267: 
        !           268:         if (pIrp == NULL) {
        !           269:             break;
        !           270:         }
        !           271:         *((PWAVE_DD_VOLUME)pIrp->AssociatedIrp.SystemBuffer) =
        !           272:             pLDI->Volume;
        !           273: 
        !           274:         pIrp->IoStatus.Status = STATUS_SUCCESS;
        !           275:         pIrp->IoStatus.Information = sizeof(WAVE_DD_VOLUME);
        !           276: 
        !           277:         //
        !           278:         // Bump priority here because the application may still be trying
        !           279:         // to be real-time
        !           280:         //
        !           281:         IoCompleteRequest(pIrp, IO_SOUND_INCREMENT);
        !           282:     }
        !           283: }
        !           284: 
        !           285: 
        !           286: #endif // VOLUME_NOTIFY
        !           287: 
        !           288: //
        !           289: // Default hardware volume setting routine - does nothing
        !           290: //
        !           291: 
        !           292: VOID
        !           293: SoundNoVolume(
        !           294:     PLOCAL_DEVICE_INFO pLDI
        !           295: )
        !           296: {
        !           297:    return;
        !           298: }
        !           299: 
        !           300: VOID
        !           301: SoundSaveDeviceVolume(
        !           302:     PLOCAL_DEVICE_INFO pLDI,
        !           303:     PWSTR KeyName
        !           304: )
        !           305: {
        !           306:     if (pLDI->VolumeChanged) {
        !           307: 
        !           308:         dprintf3(("Saving volume setting for device type %4.4s : %8X, %8X",
        !           309:                  &pLDI->Key, pLDI->Volume.Left, pLDI->Volume.Right));
        !           310: 
        !           311:         SoundWriteRegistryDWORD(KeyName,
        !           312:                                 pLDI->DeviceInit->LeftVolumeName,
        !           313:                                 pLDI->Volume.Left);
        !           314:         SoundWriteRegistryDWORD(KeyName,
        !           315:                                 pLDI->DeviceInit->RightVolumeName,
        !           316:                                 pLDI->Volume.Right);
        !           317:         pLDI->VolumeChanged = FALSE;
        !           318:     }
        !           319: }
        !           320: 
        !           321: 
        !           322: #if 0
        !           323: //
        !           324: // Pitch is always 1.0 as the card does not support pitch shift
        !           325: //
        !           326: 
        !           327: NTSTATUS SoundIoctlGetPitch(PLOCAL_DEVICE_INFO pLDI, PIRP pIrp, PIO_STACK_LOCATION IrpStack)
        !           328: {
        !           329:     PWAVE_DD_PITCH pPitch;
        !           330: 
        !           331:     if (pLDI->DeviceType != WAVE_OUT) {
        !           332:         return STATUS_INVALID_PARAMETER;
        !           333:     }
        !           334: 
        !           335:     if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(WAVE_DD_PITCH)) {
        !           336:         dprintf1(("Supplied buffer to small for requested data"));
        !           337:         return STATUS_BUFFER_TOO_SMALL;
        !           338:     }
        !           339: 
        !           340:     //
        !           341:     // say how much we're sending back
        !           342:     //
        !           343: 
        !           344:     pIrp->IoStatus.Information = sizeof(WAVE_DD_PITCH);
        !           345: 
        !           346:     //
        !           347:     // cast the buffer address to the pointer type we want
        !           348:     //
        !           349: 
        !           350:     pPitch = (PWAVE_DD_PITCH)pIrp->AssociatedIrp.SystemBuffer;
        !           351: 
        !           352:     //
        !           353:     // fill in the info
        !           354:     //
        !           355: 
        !           356:     pPitch->Pitch = 0x10000;
        !           357: 
        !           358:     return STATUS_SUCCESS;
        !           359: }
        !           360: 
        !           361: //
        !           362: // Playback rate is always 1.0 as the card does not support rate shift
        !           363: //
        !           364: 
        !           365: NTSTATUS SoundIoctlGetPlaybackRate(PLOCAL_DEVICE_INFO pLDI, PIRP pIrp, PIO_STACK_LOCATION IrpStack)
        !           366: {
        !           367:     PWAVE_DD_PLAYBACK_RATE pPlaybackRate;
        !           368: 
        !           369:     if (pLDI->DeviceType != WAVE_OUT) {
        !           370:         return STATUS_INVALID_PARAMETER;
        !           371:     }
        !           372: 
        !           373:     if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(WAVE_DD_PLAYBACK_RATE)) {
        !           374:         dprintf1(("Supplied buffer to small for requested data"));
        !           375:         return STATUS_BUFFER_TOO_SMALL;
        !           376:     }
        !           377: 
        !           378:     //
        !           379:     // say how much we're sending back
        !           380:     //
        !           381: 
        !           382:     pIrp->IoStatus.Information = sizeof(WAVE_DD_PLAYBACK_RATE);
        !           383: 
        !           384:     //
        !           385:     // cast the buffer address to the pointer type we want
        !           386:     //
        !           387: 
        !           388:     pPlaybackRate = (PWAVE_DD_PLAYBACK_RATE)pIrp->AssociatedIrp.SystemBuffer;
        !           389: 
        !           390:     //
        !           391:     // fill in the info
        !           392:     //
        !           393: 
        !           394:     pPlaybackRate->Rate = 0x10000;
        !           395: 
        !           396:     return STATUS_SUCCESS;
        !           397: }
        !           398: 
        !           399: #endif
        !           400: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.