2020-09-30 17:12:29 +02:00

1528 lines
50 KiB
Plaintext

SOUNDLIB reference
------------------
SOUNDLIB structures and types
-----------------------------
devices.h
SOUND_DISPATCH_ROUTINE
typedef NTSTATUS SOUND_DISPATCH_ROUTINE(struct _LOCAL_DEVICE_INFO *, PIRP, PIO_STACK_LOCATION);
This is a routine that processes requests for the device. Normally
SOUNDLIB code provides the actual entry point.
SOUND_HW_SET_VOLUME_ROUTINE
typedef VOID SOUND_HW_SET_VOLUME_ROUTINE(struct _LOCAL_DEVICE_INFO *);
Set the volume for a given device. For drivers with MIXER devices this
will normally be SoundNoVolume as the actual volume setting is handled
by the MIXER device code. In this case SoundSetVolumeControlId can
be used to relate a WAVE, MIDI or AUX device to a MIXER control Id.
SOUND_EXCLUDE_CODE
typedef enum {
SoundExcludeOpen,
SoundExcludeClose,
SoundExcludeEnter,
SoundExcludeLeave,
SoundExcludeQueryOpen
} SOUND_EXCLUDE_CODE;
SoundExcludeOpen The device is being opened
SoundExcludeClose The devices is being closed
SoundExcludeEnter A request for this device is starting
SoundExcludeLeave The request has finished
SoundExcludeQueryOpen Is the device open?
SOUND_EXCLUDE_ROUTINE
typedef BOOLEAN SOUND_EXCLUDE_ROUTINE(struct _LOCAL_DEVICE_INFO *,
SOUND_EXCLUDE_CODE);
This routine is called by the SOUNDLIB dispatch routines for the various
devices when a device resource needs to be serialized.
A SOUND_EXCLUDE_CODE parameter is passed:
SoundExcludeOpen and SoundExcludeClose request and release serial
reuse of the device.
SoundExcludeEnter and SoundExcludeLeave request temporary
synchronization to the device. Normally these are implemented by
the driver using a MUTEX object.
SOUND_DEVICE_INIT
typedef struct {
PCWSTR LeftVolumeName, RightVolumeName;
ULONG DefaultVolume;
ULONG Type;
ULONG DeviceType;
char Key[4];
PCWSTR PrototypeName;
PIO_DPC_ROUTINE DeferredRoutine;
SOUND_EXCLUDE_ROUTINE *ExclusionRoutine;
SOUND_DISPATCH_ROUTINE *DispatchRoutine;
SOUND_DISPATCH_ROUTINE *DevCapsRoutine;
SOUND_HW_SET_VOLUME_ROUTINE *HwSetVolume;
ULONG IoMethod;
} SOUND_DEVICE_INIT;
typedef SOUND_DEVICE_INIT CONST * PCSOUND_DEVICE_INIT;
This structure is passed to SoundCreateDevice to set up a device.
The data must not be freed and must be non-pated as SoundCreateDevice
does just keeps a copy of the data passed to it.
LeftVolumeName Name for saving the volume setting for the left channel
in the registry. Not required for devices with
MIXERs.
RightVolumeName Name for saving the volume setting for the right channel
in the registry. Not required for devices with
MIXERs.
DefaultVolume Initial volume setting on install. Note required
for devices with MIXERs.
Type Type of device. This is passed to IoCreateDevice
by SoundCreateDevice:
FILE_DEVICE_WAVE_IN for wave input
FILE_DEVICE_WAVE_OUT for wave output
FILE_DEVICE_MIDI_IN for MIDI input
FILE_DEVICE_MIDI_OUT for MIDI output
FILE_DEVICE_SOUND for everthing else
DeviceType Type used by SOUNDLIB and DRVLIB code.
(See soundcfg.h) :
WAVE_IN Wave in device
WAVE_OUT Wave out device
MIDI_IN Midi in device
MIDI_OUT Midi out device
AUX_DEVICE aux device
MIXER_DEVICE Mixer device
SYNTH_DEVICE Synth device (adlib or opl3)
These values are used in the registry to tell
the DRVLIB code in the driver DLL which type of
device each device name refers to.
Key Debugging. This value is put at the head of
the LOCAL_DEVICE_INFO structure for the device.
PrototypeName Name to use to create device name.
SoundCreateDevice will either try to use this
name as the device name or append a number starting
at 0 to it and increments it until it finds a free
name - see the CreationFlags parameter of
SoundCreateDevice.
DeferredRoutine For devices that support interrupts this is the
deferred procedure call routine. This is normally
either NULL (eg for MIXER, AUX and MIDI output devices)
or a routine supplied by SOUNDLIB.
ExclusionRoutine Called for mutual exclusion on the device - see
SOUND_EXCLUDE_ROUTINE.
DispatchRoutine Called when there is a device request for the device.
Normally a SOUNDLIB supplied routine.
HwSetVolume Sets the volume for the device. For devices with
MIXERs or no volume setting capability use
SoundNoVolume. See SOUND_HW_SET_VOLUME_ROUTINE.
IoMethod Determines the way the IO subsystem handles read
and write requests for the device.
Wave input DO_DIRECT_IO
Wave output DO_DIRECT_IO
Midi input DO_DIRECT_IO
Midi output DO_DIRECT_IO
Aux DO_BUFFERED_IO
Mixer DO_BUFFERED_IO
PSOUND_LINE_NOTIFY
typedef VOID (* PSOUND_LINE_NOTIFY)(struct _LOCAL_DEVICE_INFO *, UCHAR);
LOCAL_DEVICE_INFO is always for a MIXER device. This routine is called
by device code when a line status changes between active and inactive.
See SoundSetLineNotify.
LOCAL_DEVICE_INFO
typedef struct _LOCAL_DEVICE_INFO {
ULONG Key;
#define LDI_WAVE_IN_KEY (*(ULONG *)"LDWi")
#define LDI_WAVE_OUT_KEY (*(ULONG *)"LDWo")
#define LDI_MIDI_IN_KEY (*(ULONG *)"LDMi")
#define LDI_MIDI_OUT_KEY (*(ULONG *)"LDMo")
#define LDI_AUX_KEY (*(ULONG *)"LDAx")
#define LDI_MIX_KEY (*(ULONG *)"LDMx")
PVOID pGlobalInfo;
UCHAR DeviceType;
UCHAR DeviceNumber;
UCHAR DeviceIndex;
UCHAR CreationFlags;
#define SOUND_CREATION_NO_NAME_RANGE ((UCHAR)0x01)
#define SOUND_CREATION_NO_VOLUME ((UCHAR)0x02)
BOOLEAN PreventVolumeSetting;
UCHAR VolumeControlId;
PSOUND_LINE_NOTIFY
LineNotify;
WAVE_DD_VOLUME Volume;
LIST_ENTRY VolumeQueue;
struct _LOCAL_DEVICE_INFO *
MixerDevice;
BOOLEAN VolumeChanged;
PVOID DeviceSpecificData;
PVOID HwContext;
ULONG State;
PCSOUND_DEVICE_INIT
DeviceInit;
} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;
This struture is initialized by SoundCreateDevice. It must be
allocated from non-paged memory.
There is one LOCAL_DEVICE_INFO structure for each device. This
because the DeviceExtension member of the DEVICE_OBJECT structure
for the device.
pGlobalInfo A reference back to global driver or card instance
data (pGDI parameter of SoundCreateDevice).
DeviceType Same as DeviceType in SOUND_DEVICE_INIT
DeviceNumber Used internally by SOUNDLIB code to generate
the device name. Is 0xFF if no number is appended
to the ProtoTypeName member of the SOUND_DEVICE_INIT
structure.
DeviceIndex Passed as 'i' parameter in SoundCreateDevice. Can
be used to identify the device uniquely internally.
CreationFlags CreationFlags passed to SoundCreateDevice:
SOUND_CREATION_NO_NAME_RANGE Don't append number
to prototype name.
SOUND_CREATION_NO_VOLUME If volume setting not
supported.
PreventVolumeSetting Used internally to prevent volume being set
on devices opened without share access on write.
VolumeControlId Set by SoundSetVolumeControlId.
LineNotify Set by SoundSetLineNotify.
VolumeQueue List of SOUND_IOCTL_GET_CHANGED_VOLUME requests
not completed.
MixerDevice Pointer to the MIXER device for the card instance
if there is one. This MUST be set by the mixer
initialization code, it is not set by SOUNDLIB.
VolumeChanged If there is no mixer device used internally to
track whether volume settings need to be
updated in the Registry on system shutdown.
DeviceSpecificData Copy of DeviceSpecificData passed to
SoundCreateDevice.
HwContext Copy of pHw passed to SoundCreateDevice.
State Used internally for sound device types.
DeviceInit Copy of DeviceInit passed to SoundCreateDevice.
soundlib.h
SOUND_REGISTRY_CALLBACK_ROUTINE
typedef NTSTATUS
SOUND_REGISTRY_CALLBACK_ROUTINE(PWSTR RegistryPathName, PVOID Context);
This routine is called by SoundEnumSubkeys for each subkey found.
RegistryPathName Full path to the subkey
Context Context passed to SoundEnumSubkeys
wave.h
SOUND_DMA_BUFFER
typedef struct {
PADAPTER_OBJECT AdapterObject[2];
ULONG BufferSize;
PVOID VirtualAddress;
PHYSICAL_ADDRESS LogicalAddress;
PMDL Mdl;
} SOUND_DMA_BUFFER, *PSOUND_DMA_BUFFER;
Internal structure used by the wave device code.
SOUND_DOUBLE_BUFFER
typedef struct {
enum {LowerHalf = 0,
UpperHalf}
NextHalf;
ULONG BufferSize;
PUCHAR Buf;
ULONG StartOfData;
ULONG nBytes;
UCHAR Pad;
} SOUND_DOUBLE_BUFFER, *PSOUND_DOUBLE_BUFFER;
Internal structure used by the wave device code.
SOUND_BUFFER_QUEUE
typedef struct {
LIST_ENTRY QueueHead;
ULONG BytesProcessed;
ULONG UserBufferSize;
ULONG UserBufferPosition;
PUCHAR UserBuffer;
PIRP pIrp;
LIST_ENTRY ProgressQueue;
} SOUND_BUFFER_QUEUE, *PSOUND_BUFFER_QUEUE;
Internal structure used by the wave device code.
WAVE_INTERFACE_ROUTINE
typedef BOOLEAN WAVE_INTERFACE_ROUTINE(struct _WAVE_INFO *);
Type definition for callbacks to set the hardware (See WAVE_INFO).
SOUND_QUERY_FORMAT_ROUTINE
typedef NTSTATUS SOUND_QUERY_FORMAT_ROUTINE (PLOCAL_DEVICE_INFO, PPCMWAVEFORMAT);
Callback to find out if the wave format is supported. Although the
type specified here is PPCMWAVEFORMAT in fact any PWAVEFORMATEX is
passed.
enum {
SoundNoDMA,
SoundAutoInitDMA, // Use autoinitialize
SoundReprogramOnInterruptDMA, // Reprogram on interrupt
Sound2ChannelDMA // Keep 2 channels going
};
Type of DMA to support. Sound2ChannelDMA is not supported in the
wave device code but is meant for a device that uses 2 DMA channels
and alternates between them in hardware to achieve continuous sound.
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;
This is the context for all the wave device code. One WAVE_INFO
structure can support wave input and output serially but not in
parallel. If the sound card cannot support wave input and wave
output simultaneously the the same WAVE_INFO structure can be
passed to SoundCreateDevice for both wave input and wave output
devices. In this case the SoundExcludeRoutine must obviously
disallow both devices being open simultaneously. If simultanous
wave input and output are possible then different WAVE_INFO
structures are required for wave input and wave output devices.
The SOUNDLIB code supports low priority mode which allows a
wave input device nominate itself to be preemptible by other
input and output then resume. Only one user can be in low
priority mode at a time.
Key Debugging - should be "Wave"
DMABuf Internal management of DMA hardware
DoubleBuffer Internal management of DMA data
BufferQueue Internal management of queue of device requests
SamplesPerSec Current samples per second
BitsPerSample Current Bits per sample (per channel)
Channels Current number of channels
FormatChanged Set before calling the HwSetWaveFormat member
if the format has actually changed since
HwSetWaveFormat was last called.
WaveFormat Format for Non-PCM formats
LowPrioritySaved Low priority mode management
LowPriorityHandle Low priority mode management
LowPriorityModeSave Low priority mode management
MRB DMA internal
DmaSetupEvent Internal synchronziation
DpcEvent Internal synchronization with Dpc termination
TimerDpcEvent Internal - track rogue devices.
DeviceSpinLock Internal - Dpc routine synchronzation
LockHeld Internal - debugging
Interrupt The interrupt being used
Direction TRUE = output, FALSE = input
DMAType See Sound...DMA definitions above.
InterruptHalf Not used
DMABusy Internal
DpcQueued Overrun detection. This should be set in the ISR
just before IoRequestDpc is called. If is
already set the overrun has occurred and no Dpc should
be queued.
Overrun Set if overrun occurs.
HwContext Context to be passed to Hw... routines.
WaveStopWorkItem Internal. This work item is queued when DMA
completes. The HwStopDMA member is called from
the ExWorker thread so that it can wait for
slow devices if necessary.
WaveReallyComplete Internal.
Set in the ExWorker thread when HwStopDMA has
been called.
QueryFormat Call back to see if a proposed format is
supported.
HwSetupDMA Called when the DMA registers have been
initialized and the hardware should be told to
start its DMA.
HwStopDMA Called when DMA should stop but before the
DMA hardware has been shut down.
HwSetWaveFormat Called just before the DMA registers are
initialized to commence DMA.
TimerDpc Internal. Used to stop rogue devices.
DeviceCheckTimer Internal. Used to stop rogue devices.
DeviceBad Internal. Used to stop rogue devices.
TimerActive Internal. Used to stop rogue devices.
FailureCount Internal. Used to stop rogue devices.
midi.h
MIDI_INTERFACE_ROUTINE
typedef BOOLEAN MIDI_INTERFACE_ROUTINE(struct _MIDI_INFO *);
Type for callbacks
MIDI_INFO
typedef struct _MIDI_INFO {
ULONG Key;
#define MIDI_INFO_KEY (*(ULONG *)"Midi")
KSPIN_LOCK DeviceSpinLock;
#if DBG
BOOLEAN LockHeld;
#endif
LARGE_INTEGER RefTime;
LIST_ENTRY QueueHead;
PVOID HwContext;
PMIDI_INTERFACE_ROUTINE
HwStartMidiIn,
HwStopMidiIn;
BOOLEAN (* HwMidiRead)(
struct _MIDI_INFO *, PUCHAR);
VOID (* HwMidiOut)(
struct _MIDI_INFO *, PUCHAR, int);
BOOLEAN fMidiInStarted;
UCHAR InputPosition;
UCHAR InputBytes;
UCHAR MidiInputByte[64];
} MIDI_INFO, *PMIDI_INFO;
A single MIDI_INFO structure can be used to support simultaneous
MIDI input and output.
A MIDI_INFO structure is passed as the DeviceSpecificData parameter
for SoundCreateDevice for external midi input and output devices. For
synthsizer devices see below.
Key Debugging ( = "Midi")
DeviceSpinLock Internal. Synchronization with Dpc for MIDI input.
LockHeld Internal. Debugging.
RefTime Internal. Midi input Timing.
QueueHead Internal queue of requests for MIDI input.
HwContext Context to pass to Hw... routines.
HwStartMidiIn Start reading MIDI input from external source.
HwStopMidiIn Stop reading MIDI input from exteranl source.
HwMidiRead Read the next byte of MIDI input (or return FALSE
if there isn't one).
HwMidiOut Sent out a string of MIDI bytes.
fMidiInStarted Internal. MIDI input running.
InputPosition Internal. Manage buffer.
InputBytes Internal. Manage buffer.
MidiInputByte Internal. Buffer of input bytes.
mixer.h
For an understanding of the MIXER API refer to the Win32 SDK documetation.
PMIXER_DD_GET_SET_DATA
typedef NTSTATUS (* PMIXER_DD_GET_SET_DATA)(struct _MIXER_INFO * MixerInfo,
ULONG Id,
ULONG Length,
PVOID Data);
Callback type for getting and setting actual mixer data.
MixerInfo MIXER_INFO structure for this mixer.
Id For HwGetLineData a mixer Line Id.
For HwGetControlData, HwGetCombinedControlData,
HwSetControlData a Control Id.
Length Length of data.
Data The data.
MIXER_INFO
typedef struct _MIXER_INFO {
ULONG Key;
#define MIX_INFO_KEY (*(ULONG *)"Mix")
UCHAR NumberOfLines;
UCHAR NumberOfControls;
LARGE_INTEGER CurrentLogicalTime;
LIST_ENTRY NotifyQueue;
LIST_ENTRY ChangedItems;
PMIXER_DD_GET_SET_DATA HwGetLineData;
PMIXER_DD_GET_SET_DATA HwGetControlData;
PMIXER_DD_GET_SET_DATA HwGetCombinedControlData;
PMIXER_DD_GET_SET_DATA HwSetControlData;
} MIXER_INFO, *PMIXER_INFO;
A MIXER_INFO structure is passed as the DeviceSpecificdata parameter
to SoundCreateDevice for Mixer devices.
Key Debugging (= "Mix")
NumberOfLines Number of mixer lines
NumberOfControls Number of mixer controls
CurrentLogicalTime Internal. Control sending of notifications.
NotifyQueue Internal. Control sending of notifications.
ChangedItems Internal. Control sending of notifications.
HwGetLineData Retrieve line flags (See definition of
PMIXER_DD_GET_SET_DATA):
Length sizeof(ULONG)
Data pointer to a ULONG of flags
MIXERLINE_LINEF_ACTIVE - line is active
(mainly for wave devices so that the
application knows when to poll the
peak meter)
MIXERLINE_LINEF_DISCONNECTED - the
line is permanently unavailable
MIXERLINE_LINEF_SOURCE - this is a
source line (rather than a destination).
HwGetControlData Retrieve the information for a given control
(see the definition of PMIXER_DD_GET_SET_DATA):
Length length of control data to return.
For multiple channel or multiple
item controls this can either be
the length of all the control items
or just one. If it's the length of
just one then the control values
should be combined in a meaningful
way depending on the control type -
eg maximum for volume.
Data Where to put the control data
HwGetCombinedControlData Retrieve the combined information for a given
control. This will only ever be used for volume
controls. If the mixer supports volume setting
in hardware then just return 0xFFFF for all
channels. Otherwise if the master volume is
supported in hardware return the current value of
the control. If the master volume is simulated
return the combined volume and master volume as
a volume value.
(see the definition of PMIXER_DD_GET_SET_DATA):
Length length of control data to return.
For multiple channel or multiple
item controls this can either be
the length of all the control items
or just one. If it's the length of
just one then the control values
should be combined in a meaningful
way depending on the control type -
eg maximum for volume.
Data Where to put the control data
HwSetControlData Set the information for a given control
(see the definition of PMIXER_DD_GET_SET_DATA):
Length length of control data.
For multiple channel or multiple
item controls this can either be
the length of all the control items
or just one. If it's the length of
just one then the control value
should be interpreted in a meaningful
way depending on the control type -
eg set all values to this value for
volume.
Data The new value.
If the value of a control changes then
SoundMixerChangedItem should be called to
notify SOUNDLIB to dispatch any waiters for this
mixer. (See also SoundInitDataItem which sets
this mechanism up).
MIXER_DATA_ITEM
typedef struct _MIXER_DATA_ITEM {
LIST_ENTRY Entry;
LARGE_INTEGER LastSet;
USHORT Message;
USHORT Id;
} MIXER_DATA_ITEM, *PMIXER_DATA_ITEM;
Data item entry to control application notification. See
SoundInitDataItem and SoundMixerChangedItem.
synthdrv.h
typedef enum {
AdlibDevice = 5,
Opl3Device
}
Types of synthesizer device.
typedef struct {
ULONG Key; // For debugging
#define SYNTH_HARDWARE_KEY (*(ULONG *)"Hw ")
PUCHAR SynthBase; // base port address for synth
} SYNTH_HARDWARE, *PSYNTH_HARDWARE;
Internal SOUNDLIB.
typedef struct _GLOBAL_SYNTH_INFO {
ULONG Key;
#define SYNTH_KEY (*(ULONG *)"Syn ")
INTERFACE_TYPE BusType;
ULONG BusNumber;
KMUTEX MidiMutex;
ULONG MemType;
PDEVICE_OBJECT DeviceObject;
PDRIVER_OBJECT DriverObject;
SOUND_DISPATCH_ROUTINE
*DevCapsRoutine;
UCHAR DeviceInUse;
volatile BOOLEAN
InterruptFired; // Interrupt fired?
BOOLEAN IsOpl3; // It's an OPL3
SYNTH_HARDWARE Hw; // Hardware specific stuff
} GLOBAL_SYNTH_INFO, *PGLOBAL_SYNTH_INFO;
Mainly internal to SOUNDLIB - see definition of SynthInit.
SOUNDLIB Functions
------------------
SOUND_DISPATCH_ROUTINE
SoundAuxDispatch,
SoundMidiDispatch,
SoundWaveDispatch,
SoundMixerDispatch
These are the dispatch routines for the device handling in SOUNDLIB.
The appropriate routine address should be set in the DispatchRoutine member
of the SOUND_DEVICE_INIT structure passed to SoundCreateDevice.
VOID
SoundWaveDeferred(
PKDPC pDpc,
PDEVICE_OBJECT pDeviceObject,
PIRP pIrp,
PVOID Context
)
This is the SOUNDLIB Dpc routine used by the wave support in SOUNDLIB.
For wave devices this routine address should be set in the DeferredRoutine
member of the SOUND_DEVICE_INIT structure passed to SoundCreateDevice.
VOID
SoundMidiInDeferred(
IN PKDPC pDpc,
IN PDEVICE_OBJECT pDeviceObject,
IN OUT PIRP pIrpDeferred,
IN OUT PVOID Context
)
This is the SOUNDLIB Dpc routine used by the midi input support in SOUNDLIB.
For wave devices this routine address should be set in the DeferredRoutine
member of the SOUND_DEVICE_INIT structure passed to SoundCreateDevice.
NTSTATUS
SoundDispatch(
IN PDEVICE_OBJECT pDO,
IN PIRP pIrp
)
This is the SOUNDLIB main dispatch routine. The following entry points
in the driver object's dispatch table should point to it:
IRP_MJ_CLEANUP
IRP_MJ_CLOSE
IRP_MJ_CREATE
IRP_MJ_DEVICE_CONTROL
IRP_MJ_READ
IRP_MJ_WRITE
NTSTATUS
SoundSetShareAccess(
IN OUT PLOCAL_DEVICE_INFO pLDI,
IN PIO_STACK_LOCATION IrpStack
)
This is an internal SOUNDLIB function.
SOUND_HW_SET_VOLUME_ROUTINE SoundNoVolume
This can be used for the HwSetVolume member of SOUND_DEVICE_INIT when
the device either doesn't support volume setting or the volume is
controlled by a mixer.
VOID
SoundSaveDeviceVolume(
PLOCAL_DEVICE_INFO pLDI,
PWSTR KeyName
)
Save a volume setting. This should be called at shutdown time or
when the driver is unloaded. This routine is not used if the volume
is controlled by a mixer.
pLDI This device's device info. Same as the DeviceExtension
member of the device's DEVICE_OBJECT structure.
KeyName The registry key to store it under. The value names
is retrieved from the LeftVolumeName and
RightVolumeName members of the DeviceInit member of pLDI.
NTSTATUS
SoundGetBusNumber(
IN OUT INTERFACE_TYPE InterfaceType,
OUT PULONG BusNumber
)
Find the first number of the first bus of type InterfaceType.
InterfaceType Type of bus to search for.
BusNumber Bus number to return
Returns STATUS_SUCCESS if successful, otherwise an NTSTATUS code.
NTSTATUS SoundReportResourceUsage(
IN PDEVICE_OBJECT DeviceObject,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN PULONG InterruptNumber OPTIONAL,
IN KINTERRUPT_MODE InterruptMode,
IN BOOLEAN InterruptShareDisposition,
IN PULONG DmaChannel OPTIONAL,
IN PULONG FirstIoPort OPTIONAL,
IN ULONG IoPortLength
)
Reports resources in use to the system. Overwrites any previous resources
reported on the same DeviceObject.
DeviceObject Either a DEVICE_OBJECT or DRIVER_OBJECT structure. Use
DEVICE_OBJECT structures for stuff which is meant to be
permanent because this works better when supporting
multiple cards.
BusType Type of bus the card is on.
BusNumber Number of the bus the card is on.
InterruptNumber Pointer to the interrupt number, or NULL if no interrupt.
InterruptMode Interrupt mode (Latched or LevelSensitive) if InterruptNumber
is not NULL, otherwise ignored.
InterruptShareDisposition TRUE if interrupt can be shared. FALSE otherwise.
Ignored if InterruptNumber is NULL.
DmaChannel DMA channel to report or NULL if no DMA channel
is being reported.
FirstIoPort IO address or NULL if no IO address is being
reported.
IoPortLength Number of IO ports.
Ignored if FirstIoPort is NULL.
Returns STATUS_SUCCESS if successful, otherwise an NTSTATUS code which
usually means one of resources is in use by another driver.
VOID
SoundFreeDevice(
IN PDEVICE_OBJECT DeviceObject
)
Free the device and release unreport any resources reported on the
device object.
NTSTATUS
SoundCreateDevice(
IN PCSOUND_DEVICE_INIT DeviceInit,
IN UCHAR CreationFlags,
IN PDRIVER_OBJECT pDriverObject,
IN PVOID pGDI,
IN PVOID DeviceSpecificData,
IN PVOID pHw,
IN int i,
OUT PDEVICE_OBJECT *ppDevObj
)
Creates a new device object complete with dispatch routine. The
new device's DeviceExtension member of its DEVICE_OBJECT structure
will be a LOCAL_DEVICE_INFO structure.
DeviceInit Initialized SOUND_DEVICE_INIT structure. Must
not be freed until after the device is freed.
Must note be pageable.
CreationFlags Flags:
SOUND_CREATION_NO_NAME_RANGE Don't append number
to prototype name.
SOUND_CREATION_NO_VOLUME If volume setting not
supported.
pDriverObject Driver object passed to DriverEntry routine.
pGDI Global info - will be stored in the pGlobalInfo
of the LOCAL_DEVICE_INFO structure for the device.
DeviceSpecific Data structure relevant to the specific device:
WAVE_INFO For wave devices
MIDI_INFO For MIDI devices
MIXER_INFO For mixer devices
NULL Otherwise
pHw Hardware context. Stored in HwContext of
PLOCAL_DEVICE_INFO.
i Stored as DeviceIndex in LOCAL_DEVICE_INFO.
ppDevObj New DEVICE_OBJECT structure for device if successful.
Returns STATUS_SUCCESS if successful, otherwise an NTSTATUS code.
NTSTATUS
SoundSaveDeviceName(
IN PWSTR RegistryPathName,
IN PLOCAL_DEVICE_INFO pLDI
)
Save the device name in the Devices subkey of the card instance subkey of
the Parameters key of the driver's services node.
RegistryPathName Full path to the card instance subkey.
pLDI LOCAL_DEVICE_INFO for the device.
NTSTATUS
SoundCreateDeviceName(
PCWSTR PrePrefix,
PCWSTR Prefix,
UCHAR Index,
PUNICODE_STRING DeviceName
)
This is an internal SOUNDLIB function.
Create the device name (eg "\\Device\\SBWaveOut0") given the component
parts.
PrePrefix A prefix to append to the prefix - \Device\ or \DosDevices\
Prefix Main part of the name - SBWaveOut
Index A number to append to the name or 0xFF in which case no
number is appended.
NTSTATUS
SoundEnumSubkeys(
IN PUNICODE_STRING RegistryPathName,
IN PWSTR Subkey,
IN PSOUND_REGISTRY_CALLBACK_ROUTINE Callback,
IN PVOID Context
)
Walk the subkeys of the Parameters key of the services node calling the
card instance initialization.
RegistryPathName Full path to the driver's services node.
SubKey Usually "Parameters"
Callback Card instance init routine.
Context Context parameter to pass to Callback,
NTSTATUS
SoundOpenDevicesKey(
IN PWSTR RegistryPathName,
OUT PHANDLE DevicesKey
)
Open the devices key. This is necessary during cleanup when configuration
fails. In this case the key should be deleted using ZwDeleteKey, the
closed using ZwClose. Otherwise the DRVLIB code gets confused about which
devices are available.
PUCHAR
SoundMapPortAddress(
INTERFACE_TYPE BusType,
ULONG BusNumber,
ULONG PortBase,
ULONG Length,
PULONG MemType
)
Turn an IO address into a pointer suitable for using in the HAL Port IO
routines (READ_PORT_UCHAR etc). If the output MemType is 0 the during
cleanup MmUnmapIoSpace must be called to free the mapping.
BusType Type of bus
BusNumber Number of bus
PortBase Port number
Length Number of ports
MemType Type of memory detected - necessary for cleanup.
NTSTATUS
SoundConnectInterrupt(
IN ULONG InterruptNumber,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN PKSERVICE_ROUTINE Isr,
IN PVOID ServiceContext,
IN KINTERRUPT_MODE InterruptMode,
IN BOOLEAN ShareVector,
OUT PKINTERRUPT *Interrupt
)
Create a KINTERRUPT object and install an interrupt handler.
InterruptNumer Interrupt to connect
BusType Type of bus
BusNumber Number of bus
Isr Driver supplied ISR routine (see the Kernel Mode
Driver Design Guide).
ServiceContext Context for ISR
InterruptMode Latched or LevelSensitive.
ShareVector TRUE if interrupt is sharable, otherwise FALSE.
Interrupt Pointer to a KINTERRUPT structure in non-paged
memory.
Returns an NTSTATUS code.
NTSTATUS
SoundSetErrorCode(
IN PWSTR RegistryPath,
IN ULONG Value
)
Sets a configuration return code in the "Configuration Error" value of
the given key.
RegistryPath Full path to the registry key.
Value Value to save.
NTSTATUS
SoundWriteRegistryDWORD(
IN PCWSTR RegistryPath,
IN PCWSTR ValueName,
IN ULONG Value
)
Saves REG_DWORD value in the key given by RegistryPath under the name
ValueName.
RegistryPath Full path to the registry key.
ValueName Name of the value to use.
Value Value to store.
VOID
SoundEnter(
PLOCAL_DEVICE_INFO pLDI,
BOOLEAN Enter
)
Call the SoundExcludeRoutine of the device with the SoundExcludeEnter or
SoundExcludeLeave value.
pLDI LOCAL_DEVICE_INFO for the device.
Enter If TRUE use SoundExcludeEnter, otherwise
SoundExcludeLeave.
VOID
SoundDelay(
IN ULONG Milliseconds
)
Wait (for slow device).
Milliseconds Wait at least this number of Milliseconds.
LARGE_INTEGER
SoundGetTime(
VOID
)
Get a time value in 100 nanoseconds units. This has very high resolution
but may have some drift from the system time.
Returns a time value in 100 nanoseconds units.
VOID
SoundFreeQ(
PLIST_ENTRY ListHead,
NTSTATUS IoStatus
)
Mainly used internally to SOUNDLIB.
Free a list of IO Request Packets (IRPs) with the given status code. The
Cancel spin lock is used in case the requests are cancellable.
VOID
SoundAddIrpToCancellableQ(
PLIST_ENTRY QueueHead,
PIRP Irp,
BOOLEAN Head
)
Mainly used internally to SOUNDLIB.
Add an IRP to a queue. On this queue the IRP can be cancelled at any
time.
QueueHead Head of queue.
Irp IRP.
Head If TRUE add to head of queue, otherwise to tail.
PIRP
SoundRemoveFromCancellableQ(
PLIST_ENTRY QueueHead
)
Get the top of a cancellable queue and make it non-cancellable.
QueueHead Head of queue. Must be initialized with
InitializeListHead.
Returns NULL if no entry, or an IRP which is not labelled as cancellable.
VOID
SoundFreePendingIrps(
PLIST_ENTRY QueueHead,
PFILE_OBJECT FileObject
)
Frees all IRPs in a queue which refer to the given FILE_OBJECT.
QueueHead Head of queue.
FileObject File Object.
VOID
SoundVolumeNotify(
IN OUT PLOCAL_DEVICE_INFO pLDI
)
Used by MIXER code to notify a device when its volume has changed. This
is only necessary if volume setting is controlled in software such as the
windows sound system synthesizer.
VOID
SoundInitializeWaveInfo(
PWAVE_INFO WaveInfo,
UCHAR DMAType,
PSOUND_QUERY_FORMAT_ROUTINE QueryFormat,
PVOID HwContext
)
Set up a WAVE_INFO structure. Note that the HwSetupDMA, HwStopDMA,
HwSetWaveFormat members should initialized and the rest of the structure
0 before calling this.
WaveInfo WAVE_INFO structure to initialize.
DMAType Type of DMA to use. See Sound...DMA definitions above.
QueryFormat Format query routine.
HwContext Stored in HwContext member of WAVE_INFO.
NTSTATUS
SoundGetCommonBuffer(
IN PDEVICE_DESCRIPTION DeviceDescription,
IN OUT PSOUND_DMA_BUFFER SoundAutoData
)
Allocate a buffer for auto-initialize DMA. If the size specified is
not available a smaller size may be returned.
DeviceDescription Description of Adapter. Must be initialized.
SoundAutoData Returns results.
Returns NTSTATUS code.
VOID
SoundFreeCommonBuffer(
IN OUT PSOUND_DMA_BUFFER SoundAutoData
)
Free the buffer allocated by SoundGetCommonBuffer.
BOOLEAN
SoundPeakMeter(
IN PWAVE_INFO WaveInfo,
OUT PLONG Amplitudes
)
Return an amplitude setting from the device. This is done in software
by inspecting the wave samples.
WaveInfo WAVE_INFO for wave device.
Amplitudes 2 LONGs for left and right channels. Values
returned are between 0 and 0xFFFF.
ULONG
SoundGetDMABufferSize(
IN PWAVE_INFO WaveInfo
)
Find out the actual DMA buffer size being used for the current wave
format. This may be smaller than the actual size available. SOUNDLIB
tries to set a buffer size corresponding to 1/8 of a second if there is
sufficient space.
WaveInfo WAVE_INFO for wave device.
int
SoundTestWaveDevice(
IN PDEVICE_OBJECT pDO
)
See if the wave device is working. Used for checking interrupt and
DMA channel values if there is no better method.
VOID SoundInitMidiIn(
IN OUT PMIDI_INFO pMidi,
IN PVOID HwContext
)
Initialize a MIDI_INFO structure.
pMidi Pointer to MIDI_INFO structure to initialize. This should
be in non-paged memory. The following members should
be initialized before calling SoundInitMidiIn
HwStartMidiIn
HwStopMidiIn
HwMidiRead
HwMidiOut
and the rest of the structure should be 0.
HwContext Context for Hw... callbacks.
VOID
SoundInitMixerInfo(
IN OUT PMIXER_INFO MixerInfo,
PMIXER_DD_GET_SET_DATA HwGetLineData,
PMIXER_DD_GET_SET_DATA HwGetControlData,
PMIXER_DD_GET_SET_DATA HwGetCombinedControlData,
PMIXER_DD_GET_SET_DATA HwGetSetControlData
)
Initialize MIXER_INFO structure.
MixerInfo MIXER_INFO structure to initialize
HwGetLineData Callback for Line info (see HwGetLineData member
of MIXER_INFO).
HwGetControlData Callback for Line info (see HwGetControlData member
of MIXER_INFO).
HwGetCombinedControlData Callback for Line info (see HwGetControlData member
of MIXER_INFO).
HwGetSetControlData Callback for Line info (see HwSetControlData member
of MIXER_INFO).
NTSTATUS
SoundMixerDispatch(
IN OUT PLOCAL_DEVICE_INFO pLDI,
IN PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack
)
SOUNDLIB mixer device request handler. Set the DispatchRoutine member
of SOUND_DEVICE_INIT to this for mixer devices.
VOID
SoundSetLineNotify(
PLOCAL_DEVICE_INFO pLDI,
PSOUND_LINE_NOTIFY LineNotify
)
Register a routine to be called when the status of a line changes. This
is primarily for wave and midi lines where the mixer hardware may
need setting up for play or record and mixer notifications sent.
pLDI LOCAL_DEVICE_INFO for the device whose state
changes are to be notified.
LineNotify Routine to call.
VOID
SoundSetVolumeControlId(
PLOCAL_DEVICE_INFO pLDI,
UCHAR VolumeControlId
)
Set the control id for the volume control associated with a given device.
This allows SOUNDLIB to keep a device's volume settings in synch with
the mixer's settings.
pLDI Device whose volume is controlled.
VolumeControlId Id of control for controlling the device's volume.
VOID
SoundInitDataItem(
PMIXER_INFO MixerInfo,
PMIXER_DATA_ITEM MixerDataItem,
USHORT Message,
USHORT Id
)
Register a data item with the mixer. All lines and controls must be
registered so that notifications can be correctly generated by the
SOUNDLIB mixer code when SoundMixerChangedItem is called.
MixerInfo MIXER_INFO for device. Must have been initialized
with SoundInitMixerInfo.
MixerDataItem Item to be added to the list.
Message For Line type items use MM_MIXM_LINE_CHANGE
For control items use MM_MIXM_CONTROL_CHANGE
Id Line ID for if a line item, otherwise
the control id for a control item.
VOID
SoundMixerChangedItem(
IN OUT PMIXER_INFO MixerInfo,
IN OUT PMIXER_DATA_ITEM MixerItem
)
Notify a change to a mixer item.
MixerInfo MIXER_INFO for device. Must have been initialized
with SoundInitMixerInfo.
MixerDataItem Item which has changed.
NTSTATUS
SynthInit(
IN PDRIVER_OBJECT pDriverObject,
IN PWSTR RegistryPathName,
IN PGLOBAL_SYNTH_INFO pGDI,
IN ULONG SynthPort,
IN BOOLEAN InterruptConnected,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN PMIXER_DATA_ITEM MidiOutItem,
IN UCHAR VolumeControlId,
IN BOOLEAN Multiple,
IN SOUND_DISPATCH_ROUTINE *DevCapsRoutine
)
Initialize a Synthesizer device (Ad Lib or OPL3). Once this has been
called the device is handled entirely by SOUNDLIB (except for possible
interrupts which must be handled by the driver ISR).
pDriverObject DRIVER_OBJECT for driver.
RegistryPathName Card instance full registry path.
pGDI A zero-initialized GLOBAL_SYNTH_INFO structure.
SynthPort Port address of the synth (eg 0x388).
InterruptConnected Hardware will interrupt when synth timer expires.
BusType Type of bus (eg Isa) hardware is on.
BusNumber Number of bus hardware is on.
MidiOutItem Mixer item to signal if mixer controlled.
VolumeControlId Id for mixer control controlling synth volume.
Multiple Create indexed device name or unique name
(use FALSE if using port 0x388).
DevCapsRoutine Called back to return device caps.
Returns NTSTATUS code.
VOID
SynthCleanup(
IN PGLOBAL_SYNTH_INFO pGDI
)
Clean up synth on driver unload.