WAVE_INFO

typedef struct _WAVE_INFO {
    ULONG                   Key;
#define WAVE_INFO_KEY       (*(ULONG *)"Wave")
    PDEVICE_OBJECT          DeviceObject;
    SOUND_DMA_BUFFER        DMABuf;
    SOUND_DOUBLE_BUFFER     DoubleBuffer;
    SOUND_BUFFER_QUEUE      BufferQueue;
    ULONG                   SamplesPerSec;
    UCHAR                   BitsPerSample;
    UCHAR                   Channels;
    BOOLEAN                 FormatChanged;
    PWAVEFORMATEX           WaveFormat;
    BOOLEAN                 LowPrioritySaved;
    PFILE_OBJECT            LowPriorityHandle;
    PLOCAL_DEVICE_INFO      LowPriorityDevice;
    struct {
        SOUND_BUFFER_QUEUE      BufferQueue;
        ULONG                   SamplesPerSec;
        UCHAR                   BitsPerSample;
        UCHAR                   Channels;
        PWAVEFORMATEX           WaveFormat;
        ULONG                   State;
    } LowPriorityModeSave;
    PVOID                   MRB[2];
    KEVENT                  DmaSetupEvent;
    KEVENT                  DpcEvent;
    KEVENT                  TimerDpcEvent;
    KSPIN_LOCK              DeviceSpinLock;
#if DBG
    BOOLEAN                 LockHeld;
#endif
    PKINTERRUPT             Interrupt;
    BOOLEAN                 Direction;
    UCHAR                   DMAType;
    UCHAR                   InterruptHalf;
    volatile BOOLEAN        DMABusy;
    volatile BOOLEAN        DpcQueued;
    ULONG                   Overrun;
    PVOID                   HwContext;
    WORK_QUEUE_ITEM         WaveStopWorkItem;
    KEVENT                  WaveReallyComplete;
    PSOUND_QUERY_FORMAT_ROUTINE QueryFormat;
    PWAVE_INTERFACE_ROUTINE
                            HwSetupDMA,
                            HwStopDMA,
                            HwSetWaveFormat;
    KDPC                    TimerDpc;
    KTIMER                  DeviceCheckTimer;
    BOOLEAN                 GotWaveDpc;
    BOOLEAN                 DeviceBad;
    BOOLEAN                 TimerActive;
    UCHAR                   FailureCount;
} WAVE_INFO, *PWAVE_INFO;
 

The WAVE_INFO structure contains wave device context information.

Members
Key
Internal only, for debugging. Should be “Wave”.
DeviceObject
Pointer to a DEVICE_OBJECT structure.
DMABuf
Structure describing a DMA buffer. Structure type is SOUND_DMA_BUFFER. Call SoundGetCommonBuffer to fill in this structure.
DoubleBuffer
Internal only. This is an internal structure containing additional information about the DMA buffer. The structure contains a pointer to the buffer described by the DMABuf member. The structure type is SOUND_DOUBLE_BUFFER.
BufferQueue
Internal only. For queuing device requests.
SamplesPerSec
Current samples per second.
BitsPerSample
Current bits per sample, per channel.
Channels
Current number of channels.
FormatChanged
Format has changed. Tested by HwSetWaveFormat function.
WaveFormat
Format for non-PCM formats.

LowPrioritySaved

LowPriorityHandle

LowPriorityDevice

LowPriorityModeSave
These four members are used by soundlib.lib for management of low priority mode, which allows a wave input device to nominate itself as pre-emptible if its dispatch routine receives IOCTL_WAVE_SET_LOW_PRIORITY. Only one user can be in low priority mode at a time.
MRB
Internal only. Contains adapter information.
DmaSetupEvent
Internal only. Stores event to wait on during channel allocation.
DpcEvent
Internal only. Used for synchronization with DPC termination.
TimerDpcEvent
Internal only. Used to track rogue devices.
DeviceSpinLock
Internal only. Used for DPC synchronization.
LockHeld
Internal only. Used for debugging.
Interrupt
Pointer to an interrupt object. Should be obtained from a call to SoundConnectInterrupt.
Direction
Set by soundlib.lib. Set to TRUE for output, FALSE for input.
DMAType
Type of DMA. One of the following enumerated values:
enum {
    SoundNoDMA,
    SoundAutoInitDMA,             // Use auto-initialize
    SoundReprogramOnInterruptDMA, // Reprogram on interrupt
    Sound2ChannelDMA              // Keep 2 channels going
};

Sound2ChannelDMA is not currently supported in soundlib.lib. It is intended for a device whose hardware uses two DMA channels and alternates between them to achieve continuous sound.

InterruptHalf
Internal only. Reserved for use when the DMAType member’s value is SoundReprogramOnInterruptDMA.
DMABusy
Set by soundlib.lib if DMA is in progress.
DpcQueued
Used for detecting an overrun condition. The ISR should test DpcQueued. If clear, the ISR can call IoRequestDpc. If set, an overrun has occurred and the ISR should set Overrun (see below) instead of calling IoRequestDpc.
Overrun
Set by the driver’s ISR if overrun occurs.
HwContext
Pointer to a driver-defined structure containing device-specific hardware information. Typically used by functions pointed by the HwSetupDMA, HwStopDMA, and HwSetWaveFormat members.
WaveStopWorkItem
Internal only. Structure used for calls to ExInitializeWorkItem and ExQueueWorkItem, when soundlib.lib is using system worker threads.
WaveReallyComplete
Internal only. Set by system worker thread after HwStopDMA has returned.
QueryFormat
Pointer to a driver-supplied function called when the driver receives IOCTL_WAVE_SET_FORMAT or IOCTL_WAVE_QUERY_FORMAT message. The function type is SOUND_QUERY_FORMAT_ROUTINE.
HwSetupDMA
Pointer to a driver-supplied function that programs the hardware to start a DMA transfer. Function type is WAVE_INTERFACE_ROUTINE.

The function is called after soundlib.lib has set up map registers by calling IoMapTransfer. For more information, see \src\mmedia\soundlib\wave.c.

HwStopDMA
Points to a driver-supplied function that sends commands to the hardware to stop DMA transfers. The function type is WAVE_INTERFACE_ROUTINE.

The function is called just before soundlib.lib calls IoFlushAdapterBuffers. For more information, see \src\mmedia\soundlib\wave.c.

Note:  HwStopDMA must not acquire the device exclusion mutex that soundlib.lib uses to synchronize device access. Code in soundlib.lib waits for a transfer to complete before starting a new one, and this wait occurs inside a request to the device, when the mutex is owned by the waiting thread. This means that HwStopDMA can require extra synchronization code, even though no further hardware calls to the current device can occur until the current transfer is complete.

HwSetWaveFormat
Points to a driver-supplied function that sends commands to the hardware to set the wave format. The function type is WAVE_INTERFACE_ROUTINE.

The function is called just before soundlib.lib starts each DMA transfer. For more information, see \src\mmedia\soundlib\wave.c.

TimerDpc
Internal only. Structure used by soundlib.lib for calls to KeInitializeDpc.
DeviceCheckTimer
Internal only. Structure used by soundlib.lib for calls to KeInitializeTimer.
GotWaveDpc
Internal only. Indicates the device is active.
DeviceBad
Internal only. Set if the device doesn’t send interrupts.
TimerActive
Internal only. Indicates the device is active.
FailureCount
Internal only. Contains count of failed I/O attempts. If the count reaches 30, BadDevice is set.
Comments

One WAVE_INFO structure must be defined for each waveform device (input or output) that can be in operation simultaneously. WAVE_INFO is defined in wave.h.

Allocate a WAVE_INFO structure from the nonpaged memory pool by calling ExAllocatePool, and then zero it by calling RtlZeroMemory. To initialize a WAVE_INFO structure, assign values to the HwSetupDMA, HwStopDMA, and HwSetWaveFormat members and then call SoundInitializeWaveInfo.

To create a waveform device object, call SoundCreateDevice and specify a WAVE_INFO structure pointer for the DeviceSpecificData parameter.