Annotation of ntddk/src/mmedia/soundlib/volume.c, revision 1.1.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.