0% found this document useful (0 votes)
1K views

Audio Devices Design Guide

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views

Audio Devices Design Guide

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1076

Contents

Audio Drivers Design Guide


Windows 10: What's New for Audio
Windows Audio Architecture
WDM Audio Drivers Overview
WDM Audio Drivers Overview
Universal Windows Drivers for Audio
Universal Audio Architecture
Roadmap for Developing WDM Audio Drivers
Custom Audio Driver Type Decision Tree
Audio Signal Processing Modes
Custom Audio Drivers
Specifying the Topology
Specifying Pin Data Ranges
WDM Audio Architecture: Basic Concepts
WDM Audio Architecture: Basic Concepts
Introduction to WDM Audio Drivers
Introduction to WDM Audio Drivers
Basic Functions of a WDM Audio Driver
Vendor Audio Driver Options
WDM Audio Terminology
Sample Audio Drivers
KsStudio Utility
Audio Filters, Pins, and Nodes
Audio Filters, Pins, and Nodes
Audio Filters
Filter Factories
Pin Factories
Nodes and Connections
Audio Filter Graphs
Wave Filters
MIDI and DirectMusic Filters
Topology Filters
Audio Endpoints, Properties and Events
Audio Endpoints, Properties and Events
Audio Property Requests
Filter, Pin, and Node Properties
Audio Property Handlers
Basic Support Queries for Audio Properties
Audio Endpoint Builder Algorithm
Dynamic Subdevice Registration and Unregistration
Exposing Multichannel Nodes
Pin Category Property
Friendly Names for Audio Endpoint Devices
Audio Position Property
Pin Data-Range and Intersection Properties
Jack Description Property
Microphone Array Geometry Property
Microphone Array Geometry Property
Microphone Array Geometry Descriptor Format
Modified INF for MSVAD Micarray
Hardware Events
Audio Data Formats and Data Ranges
Audio Data Formats and Data Ranges
Audio Data Formats
Audio Data Ranges
Extensible Wave-Format Descriptors
Multichannel Formats for Home-Theater Systems
Multichannel Formats for Home-Theater Systems
Channel Mask
Mapping Stream Formats to Speaker Configurations
Header File Changes
Examples of Audio Data Formats and Data Ranges
Examples of Audio Data Formats and Data Ranges
Analog Audio Stream Data Range
DirectMusic Stream Data Format
DirectMusic Stream Data Range
DirectSound Stream Data Format
DirectSound Stream Data Range
MIDI Stream Data Format
MIDI Stream Data Range
PCM Stream Data Format
PCM Stream Data Range
PCM Multichannel Stream Data Format
PCM Multichannel Stream Data Range
PCM High Bitdepth Stream Data Format
PCM High Bitdepth Stream Data Range
Digital Rights Management
Digital Rights Management
DRM Overview
Content IDs and Content Rights
Forwarding DRM Content IDs
DRM Requirements
Developing and Debugging DRM Drivers
DRM Functions and Interfaces
WDM Audio Architecture: Advanced Topics
WDM Audio Architecture: Advanced Topics
Data-Intersection Handlers
Data-Intersection Handlers
Data Intersection
Default Data-Intersection Handlers
Proprietary Data-Intersection Handlers
Hardware Constraints on Sample Frequency
Output Buffer Size
Data Ranges with Discrete Values
Wild Cards
Data-Range Properties
Dynamic Audio Subdevices
Dynamic Audio Subdevices
Managing Dynamic Topologies
Driver Support for Dynamic Subdevices
Jack Descriptions for Dynamic Audio Subdevices
Multifunction Audio Devices
Multifunction Audio Devices
Multiple Audio Subdevices
Multifunction Device Limits
Supporting Non-PCM Wave Formats
Supporting Non-PCM Wave Formats
Background of Non-PCM Support
Requirements for a Non-PCM Pin Factory
Subformat GUIDs for Compressed Audio Formats
Converting Between Format Tags and Subformat GUIDs
KS Topology Considerations
Specifics for waveOut Clients
Specifics for DirectSound Clients
S/PDIF Pass-Through Transmission of Non-PCM Streams
Specifying AC-3 Data Ranges
Specifying WMA Pro Data Ranges
USB Audio Support for Non-PCM Formats
High Definition Audio DDI
High Definition Audio DDI
HD Audio and UAA
HD Audio and UAA
Intel's HD Audio Architecture
UAA Extensions to the HD Audio Architecture
HD Audio Bus Driver
UAA Class Drivers
Communicating Verbs with the HD Audio Codec
HD Audio DDI Programming Guidelines
Programming Guidelines
Differences Between the HD Audio DDI Versions
Managing Memory Buffers During Audio Resource Rebalance and Surprise
Removal Operations
Synchronous and Asynchronous Codec Commands
Wall Clock and Link Position Registers
Hardware Resource Management
Hardware Resource Management
Allocating DMA Engines
Allocating Link Bandwidth
Striping
Synchronizing Two or More Streams
Wake Enable
Data Copying and Caching Policy
Querying for an HD Audio DDI
Querying for an HD Audio DDI
Obtaining an HDAUDIO_BUS_INTERFACE DDI Object
Obtaining an HDAUDIO_BUS_INTERFACE_V2 DDI Object
Obtaining an HDAUDIO_BUS_INTERFACE_BDL DDI Object
WDM Audio Support in Different Versions of Windows
WDM Audio Support in Different Versions of Windows
Implementing Audio Module Communication
Implementing Audio Module Communication
Configure and query audio device modules
Low Latency Audio
Multiple Voice Assistant
Voice Activation
USB Audio 2.0 Drivers
Audio Hardware Resource Management
Bluetooth Bypass Guidelines for Audio Drivers
Bluetooth Bypass Guidelines for Audio Drivers
Windows Bluetooth host controller interface (HCI) Architectural Overview
Theory of Operation
Theory of Operation
HFP Device Startup
HFP Device Connection
HFP Device Removal
Kernel Streaming Considerations
Audio Endpoint Container ID
Management of I2S and SCO Resources
Bluetooth Bypass DDI Reference
Related Design Guidelines
Related Design Guidelines
Setting Properties and Registry Values
Setting Friendly Names, Registering APOs
Obtaining Bluetooth Address of HF Device
Hardware-Offloaded Audio Processing
Hardware-Offloaded Audio Processing
Architectural Overview
Driver Implementation for Offloaded Audio
Driver Implementation for Offloaded Audio
Implementation Overview
Driver Implementation Details
Driver Implementation Details
Helper Interfaces for Offloaded Audio Processing
Glitch Reporting for Offloaded Audio
PortCls Power Management Updates for SoC
PortCls Power Management Updates for SoC
PortCls Registry Power Settings
Immediate Idle Timeout Opt-in
PortCls Private PEP Context Sharing
PortCls D3 Exit Latency Requirement
WDM Audio Platform Differences
WDM Audio Platform Differences
Windows Vista Support for WDM Audio
WDM Audio Components
WDM Audio Components
User-Mode WDM Audio Components
Kernel-Mode WDM Audio Components
Kernel-Mode WDM Audio Components
USB Audio Class System Driver (Usbaudio.sys)
Wave and DirectSound Components
MIDI and DirectMusic Components
Virtual Audio Devices
Typical Audio Configurations
Typical Audio Configurations
Rendering and Capturing Wave Content
Rendering and Capturing MIDI Content
Rendering and Capturing Audio Content by Using a Port Class Audio Adapter
Rendering and Capturing Audio Content by Using the USBAudio Driver
Rendering Wave Content Using DirectSound Software and Hardware Buffers
Factors Governing Wave-Output Latency
Factors Governing Wave-Output Latency
WaveCyclic Latency
WavePci Latency
Avoiding Data Copying
Exploring the Windows Vista Audio Engine
Format Negotiation
Dynamic Format Change
Windows Audio Processing Objects
Windows Audio Processing Objects
Audio Processing Object Architecture
Implementing Audio Processing Objects
Implementing Hardware Offloaded APO Effects
Windows Default APOs
Windows Default APOs
Bass Boost
Bass Management
Enhanced Sound for Laptop Computers
Loudness Equalization DSP
Low Frequency Protection
Room Correction
Speaker Fill
Speaker Phantoming
Virtual Surround
Virtualized Surround Sound over Headphones
Audio Miniport Drivers
Audio Miniport Drivers
Introduction to Port Class
Introduction to Port Class
Implementation of Function-Specific Interfaces
PortCls Support by Operating System
Supporting a Device
Supporting a Device
WaveRT Port Driver
WaveRT Port Driver
Introducing the WaveRT Port Driver
Understanding the WaveRT Port Driver
Understanding the WaveRT Port Driver
Stream Latency During Playback
Stream Latency During Recording
Topology Port Driver
MIDI Port Driver
DMus Port Driver
Adapter Driver Construction
Adapter Driver Construction
Startup Sequence
Subdevice Creation
Miniport Driver Types by Operating System
COM in the Kernel
COM in the Kernel
Function Tables for Miniport Drivers
Creating Audio Driver Objects
Reference-Counting Conventions for COM Objects
Miniport Interfaces
Miniport Interfaces
WaveRT Miniport Driver
WaveRT Miniport Driver
Developing a WaveRT Miniport Driver
Topology Miniport Driver
MIDI Miniport Driver
DMus Miniport Driver
Installing a Port Class Audio Adapter
Installing a Port Class Audio Adapter
Specifying Version Information for an Audio Adapter
Installing Device Interfaces for an Audio Adapter
Installing Core System Components for an Audio Adapter
Installing Core System Components for an Audio Adapter
Installing in Windows
Installing Windows Multimedia System Support for an Audio Adapter
Installing an Audio Adapter Service in Windows
Customizing Control Panel
Branding Control Panel with Bitmaps or Icons
Adding New Digital Formats to Control Panel
Miscellaneous Installation Issues for an Audio Adapter
Miscellaneous Installation Issues for an Audio Adapter
Default Audio Volume Settings
Software Volume Control Support
Opting Out of Volume Level Persistence
Customizing HD Audio Driver Volume Settings
Operating System Upgrades
System-Wide Unique Device IDs
Media-Specific INF File Keywords
Retrieving Device Setup Information
Port Driver Helper Objects
Port Driver Helper Objects
DMA Channel Objects
Registry Key Objects
Resource List Objects
Service Sink and Service Group Objects
Interrupt Sync Objects
Power Management for Audio Devices
Power Management for Audio Devices
Implementing IAdapterPowerManagement
Implementing IPowerNotify
Audio Device Class Inactivity Timer Implementation
Version Numbers for Audio Drivers
Version Numbers for Audio Drivers
Internal and External Version Numbers
INF Driver-Version Entry
DirectX File Version Numbers
Other Implementation Issues for Audio Drivers
Other Implementation Issues for Audio Drivers
Writing 64-Bit Audio Drivers
Accessing PCI Configuration Space
Implement PnP Rebalance for PortCls Audio Drivers
Legacy Audio Interfaces
Legacy Audio Interfaces
WavePci Port Driver
WavePci Miniport Driver
Implementation Issues for WavePci Devices
Implementation Issues for WavePci Devices
Hardware Requirements for WavePci Devices
Performance Issues for a WavePci Miniport Driver
Reliability Issues for a WavePci Miniport Driver
WaveCyclic Port Driver
WaveCyclic Miniport Driver
Driver Support for DirectSound
Driver Support for DirectSound
DirectSound Hardware Acceleration in WDM Audio
DirectSound Hardware Acceleration in WDM Audio
Overview of DirectSound Hardware Acceleration
Supporting 2D DirectSound Acceleration in WDM Audio
Supporting 3D DirectSound Acceleration in WDM Audio
DirectSound Node-Ordering Requirements
Supporting a Mixture of 2D and 3D Pins
DirectSound Hardware-Acceleration and SRC Sliders
Exposing Custom Audio Property Sets
Prefetch Offsets
DirectSound Speaker-Configuration Settings
DirectSound Speaker-Configuration Settings
Translating Speaker-Configuration Requests
Applying Speaker-Configuration Settings
Proprietary Speaker-Configuration Utilities
DSSPEAKER_SURROUND Speaker Configuration
DSSPEAKER_DIRECTOUT Speaker Configuration
DirectSound Capture Effects
DirectSound Capture Effects
Exposing Hardware-Accelerated Capture Effects
AEC System Filter
Driver Support for DirectMusic
Driver Support for DirectMusic
DirectMusic DDI Overview
DirectMusic DDI Overview
User Mode Versus Kernel Mode
Custom Rendering in User Mode
Custom Rendering in User Mode
Synthesizers and Wave Sinks
IDirectMusicSynth and IDirectMusicSynthSink
MIDI to Wave
Synthesizer Timing
Synthesizer Timing
Synthesizer Latency
Time-Stamped Events
Clock Synchronization
DLS Download Support
Registering Your Synthesizer
Kernel Mode Hardware Acceleration DDI
Kernel Mode Hardware Acceleration DDI
DirectMusic WDM Kernel Streaming Background
Synthesizer Miniport Driver Overview
DirectMusic Miniport Driver Interface
DirectMusic Miniport Driver Interface
MIDI Transport
MIDI Transport
IMXF Interfaces
Allocator
A Wave Sink for Kernel-Mode Software Synthesizers
Latency Clocks
Miniport Driver Property Item Requests
Making PortDMus the Default DirectMusic Port Driver
Exposing Your Synthesizer as a Legacy Device
Voice Allocation
Default Sound Sample Sets
Support for DirectMusic Properties
Driver Support for Legacy Audio Interfaces
Driver Support for Legacy Audio Interfaces
Kernel Streaming Topology to Audio Mixer API Translation
Kernel Streaming Topology to Audio Mixer API Translation
Topology Pins
Topology Nodes
WDMAud Topology Parsing
SysTray and SndVol32
Exposing Filter Topology
WDM Audio Extensions to Legacy Windows Multimedia APIs
WDM Audio Extensions to Legacy Windows Multimedia APIs
Extended Capabilities from a WDM Audio Driver
System-Intercepted Device Messages
System-Intercepted Device Messages
Accessing the Preferred Device ID
Preferred Voice-Communications Device ID
Obtaining a Device Interface Name
Music Technology GUIDs
Audio Devices Troubleshooting
Audio Devices Troubleshooting Overview
USB Audio Device Not Playing
Audio Devices DDI Reference Overview
Audio Devices DDI Reference Overview
Audio Drivers Enumerations
Audio Drivers Property Sets
Audio Drivers Property Sets
KSPROPSETID_AC3
KSPROPSETID_Acoustic_Echo_Cancel
KSPROPSETID_Audio
KSPROPSETID_AudioEffectsDiscovery
KSPROPSETID_AudioEngine
KSPROPSETID_AudioGfx
KSPROPSETID_AudioModule
KSPROPSETID_AudioModule
KSPROPERTY_AUDIOMODULE_COMMAND
KSPROPERTY_AUDIOMODULE_DESCRIPTORS
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID
KSPROPSETID_AudioSignalProcessing
KSPROPSETID_BtAudio
KSPROPSETID_DirectSound3DBuffer
KSPROPSETID_DirectSound3DListener
KSPROPSETID_DrmAudioStream
KSPROPSETID_FMRXControl
KSPROPSETID_FMRXControl
KSPROPERTY_FMRX_STATE
KSPROPSETID_FMRXTopology
KSPROPSETID_Hrtf3d
KSPROPSETID_INTERLEAVEDAUDIO_FORMATINFORMATION
KSPROPSETID_Itd3d
KSPROPSETID_Jack
KSPROPSETID_RTAudio
KSPROPSETID_SoundDetector
KSPROPSETID_SoundDetector2
KSPROPSETID_Synth
KSPROPSETID_SynthClock
KSPROPSETID_Synth_Dls
KSPROPSETID_Sysaudio
KSPROPSETID_Sysaudio_Pin
KSPROPSETID_TelephonyControl
KSPROPSETID_TelephonyTopology
KSPROPSETID_TopologyNode
Audio Drivers Event Sets
Audio Drivers Event Sets
KSEVENTSETID_AudioControlChange
KSEVENTSETID_LoopedStreaming
KSEVENTSETID_PinCapsChange
KSEVENTSETID_SoundDetector
KSEVENTSETID_VolumeLimit
KSEVENTSETID_VolumeLimit
KSEVENT_VOLUMELIMIT_CHANGED
Audio Topology Nodes
Audio Topology Nodes
KSNODETYPE_3D_EFFECTS
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_ADC
KSNODETYPE_AGC
KSNODETYPE_AUDIO_ENGINE
KSNODETYPE_AUDIO_KEYWORDDETECTOR
KSNODETYPE_CHORUS
KSNODETYPE_DAC
KSNODETYPE_DELAY
KSNODETYPE_DEMUX
KSNODETYPE_DEV_SPECIFIC
KSNODETYPE_DMSYNTH
KSNODETYPE_DMSYNTH_CAPS
KSNODETYPE_DRM_DESCRAMBLE
KSNODETYPE_EQUALIZER
KSNODETYPE_FM_RX
KSNODETYPE_LOUDNESS
KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR
KSNODETYPE_MUTE
KSNODETYPE_MUX
KSNODETYPE_NOISE_SUPPRESS
KSNODETYPE_PEAKMETER
KSNODETYPE_PROLOGIC_DECODER
KSNODETYPE_PROLOGIC_ENCODER
KSNODETYPE_REVERB
KSNODETYPE_SRC
KSNODETYPE_STEREO_ENHANCE
KSNODETYPE_STEREO_WIDE
KSNODETYPE_SUM
KSNODETYPE_SUPERMIX
KSNODETYPE_SWMIDI
KSNODETYPE_SWSYNTH
KSNODETYPE_SYNTHESIZER
KSNODETYPE_TELEPHONY_BIDI
KSNODETYPE_TONE
KSNODETYPE_VOLUME
Audio Drivers Structures
Audio Drivers Interfaces
Audio Drivers Interfaces
IAudioSystemEffects
IAudioSystemEffects2
IKeywordDetectorOemAdapter
Bluetooth HFP DDI Reference
Bluetooth HFP DDI Reference
Bluetooth HFP DDI Structures
Bluetooth HFP DDI IOCTLs
High Definition Audio DDI Reference
High Definition Audio DDI Reference
HD Audio DDI Routines
HD Audio DDI Structures
HD Audio DDI Enumerations
DRM Functions
Audio Device Messages for MIDI
Legacy Audio Device Messages
Audio INF File Settings
Audio INF File Settings
SetupPreferredAudioDevices
PKEY_APO_SWFallback_ProcessingModes
PKEY_AudioDevice_EnableEndpointByDefault
PKEY_AudioDevice_NeverSetAsDefaultEndpoint
PKEY_AudioEndpoint_Default_VolumeInDb
PKEY_AudioEngine_OEMFormat
PKEY_AudioEngine_OEMPeriod
PKEY_CompositeFX_EndpointEffectClsid
PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid
PKEY_CompositeFX_KeywordDetector_ModeEffectClsid
PKEY_CompositeFX_KeywordDetector_StreamEffectClsid
PKEY_CompositeFX_ModeEffectClsid
PKEY_CompositeFX_Offload_ModeEffectClsid
PKEY_CompositeFX_Offload_StreamEffectClsid
PKEY_CompositeFX_StreamEffectClsid
PKEY_Devices_AudioDevice_Microphone_IsFarField
PKEY_FX_KeywordDetector_StreamEffectClsid
PKEY_FX_KeywordDetector_ModeEffectClsid
PKEY_FX_KeywordDetector_EndpointEffectClsid
PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_FX_EndpointEffectClsid
PKEY_FX_ModeEffectClsid
PKEY_FX_StreamEffectClsid
PKEY_FX_Offload_ModeEffectClsid
PKEY_FX_Offload_StreamEffectClsid
PKEY_SFX_Offload_ProcessingModes_Supported_For_Streaming
PKEY_MFX_Offload_ProcessingModes_Supported_For_Streaming
PKEY_EFX_ProcessingModes_Supported_For_Streaming
PKEY_MFX_ProcessingModes_Supported_For_Streaming
PKEY_SFX_ProcessingModes_Supported_For_Streaming
UsePositionLock
Port Class Audio Driver Reference
Port Class Audio Driver Reference
Audio Port Class Functions
Audio Helper Object Interfaces
Audio Port Object Interfaces
Audio Miniport Object Interfaces
Audio Miniport Auxiliary Interfaces
Audio Stream Object Interfaces
DirectMusic User-Mode Synth and Synth Sink Interfaces
Audio Power Management Interfaces
Macro Definitions for Obsolete Functions
Macro Definitions for Obsolete Functions
Obsolete Port Class Functions
Obsolete Kernel-Mode Driver-Support Functions
Ks.h
Ks.h
KSEVENT_PINCAPS_FORMATCHANGE
KSEVENT_PINCAPS_JACKINFOCHANGE
Ksmedia.h
Ksmedia.h
KSEVENT_CONTROL_CHANGE
KSEVENT_LOOPEDSTREAMING_POSITION
KSEVENT_SOUNDDETECTOR_MATCHDETECTED
KSJACK_DESCRIPTION
KSJACK_DESCRIPTION2
KSPROPERTY_AC3_ALTERNATE_AUDIO
KSPROPERTY_AC3_BIT_STREAM_MODE
KSPROPERTY_AC3_DIALOGUE_LEVEL
KSPROPERTY_AC3_DOWNMIX
KSPROPERTY_AC3_ERROR_CONCEALMENT
KSPROPERTY_AC3_LANGUAGE_CODE
KSPROPERTY_AC3_ROOM_TYPE
KSPROPERTY_AEC_MODE
KSPROPERTY_AEC_NOISE_FILL_ENABLE
KSPROPERTY_AEC_STATUS
KSPROPERTY_AUDIO_3D_INTERFACE
KSPROPERTY_AUDIO_AGC
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
KSPROPERTY_AUDIO_BASS
KSPROPERTY_AUDIO_BASS_BOOST
KSPROPERTY_AUDIO_BUFFER_DURATION
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_AUDIO_CHORUS_LEVEL
KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH
KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE
KSPROPERTY_AUDIO_COPY_PROTECTION
KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_DELAY
KSPROPERTY_AUDIO_DEMUX_DEST
KSPROPERTY_AUDIO_DEV_SPECIFIC
KSPROPERTY_AUDIO_DYNAMIC_RANGE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSPROPERTY_AUDIO_EQ_BANDS
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_FILTER_STATE
KSPROPERTY_AUDIO_LATENCY
KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION
KSPROPERTY_AUDIO_LOUDNESS
KSPROPERTY_AUDIO_MANUFACTURE_GUID
KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY
KSPROPERTY_AUDIO_MIC_SENSITIVITY
KSPROPERTY_AUDIO_MIC_SENSITIVITY2
KSPROPERTY_AUDIO_MIC_SNR
KSPROPERTY_AUDIO_MID
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
KSPROPERTY_AUDIO_MIX_LEVEL_TABLE
KSPROPERTY_AUDIO_MUTE
KSPROPERTY_AUDIO_MUX_SOURCE
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_PEAKMETER2
KSPROPERTY_AUDIO_POSITION
KSPROPERTY_AUDIO_POSITIONEX
KSPROPERTY_AUDIO_PREFERRED_STATUS
KSPROPERTY_AUDIO_PRESENTATION_POSITION
KSPROPERTY_AUDIO_PRODUCT_GUID
KSPROPERTY_AUDIO_QUALITY
KSPROPERTY_AUDIO_REVERB_LEVEL
KSPROPERTY_AUDIO_REVERB_TIME
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_STEREO_ENHANCE
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
KSPROPERTY_AUDIO_SURROUND_ENCODE
KSPROPERTY_AUDIO_TREBLE
KSPROPERTY_AUDIO_VOLUMELEVEL
KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION
KSPROPERTY_AUDIO_WIDE_MODE
KSPROPERTY_AUDIO_WIDENESS
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
KSPROPERTY_AUDIOENGINE_DESCRIPTOR
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT
KSPROPERTY_AUDIOENGINE_GFXENABLE
KSPROPERTY_AUDIOENGINE_LFXENABLE
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION
KSPROPERTY_AUDIOENGINE_MIXFORMAT
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL
KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID
KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID
KSPROPERTY_AUDIOMODULE
KSPROPERTY_AUDIOSIGNALPROCESSING
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
KSPROPERTY_DIRECTSOUND3DBUFFER_ALL
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME
KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MODE
KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION
KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY
KSPROPERTY_DIRECTSOUND3DLISTENER_ALL
KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION
KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION
KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION
KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
KSPROPERTY_FMRX_ANTENNAENDPOINTID
KSPROPERTY_FMRX_ENDPOINTID
KSPROPERTY_FMRX_VOLUME
KSPROPERTY_HRTF3D_FILTER_FORMAT
KSPROPERTY_HRTF3D_INITIALIZE
KSPROPERTY_HRTF3D_PARAMS
KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION
KSPROPERTY_ITD3D_PARAMS
KSPROPERTY_JACK
KSPROPERTY_JACK_CONTAINERID
KSPROPERTY_JACK_DESCRIPTION
KSPROPERTY_JACK_DESCRIPTION2
KSPROPERTY_JACK_SINK_INFO
KSPROPERTY_ONESHOT_DISCONNECT
KSPROPERTY_ONESHOT_RECONNECT
KSPROPERTY_RTAUDIO_BUFFER
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_CLOCKREGISTER
KSPROPERTY_RTAUDIO_GETREADPACKET
KSPROPERTY_RTAUDIO_HWLATENCY
KSPROPERTY_RTAUDIO_PACKETCOUNT
KSPROPERTY_RTAUDIO_POSITIONREGISTER
KSPROPERTY_RTAUDIO_PRESENTATION_POSITION
KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT
KSPROPERTY_RTAUDIO_SETWRITEPACKET
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT
KSPROPERTY_SOUNDDETECTOR
KSPROPERTY_SOUNDDETECTOR_ARMED
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSPROPERTY_SOUNDDETECTOR_RESET
KSPROPERTY_SOUNDDETECTOR_STREAMINGSUPPORT
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_COMPONENT_ID
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE
KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
KSPROPERTY_SYSAUDIO_INSTANCE_INFO
KSPROPERTY_SYSAUDIO_SELECT_GRAPH
KSPROPERTY_TELEPHONY_CALLCONTROL
KSPROPERTY_TELEPHONY_CALLHOLD
KSPROPERTY_TELEPHONY_CALLINFO
KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR
KSPROPERTY_TELEPHONY_MUTE_TX
KSPROPERTY_TELEPHONY_PROVIDERCHANGE
KSPROPERTY_TELEPHONY_PROVIDERID
KSPROPERTY_TELEPHONY_VOLUME
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
KSRTAUDIO_BUFFER_PROPERTY
Audio Devices Design Guide
12/5/2018 • 2 minutes to read • Edit Online

This section describes how to design Microsoft Windows Driver Model (WDM) audio drivers. These drivers control
audio adapters that render and capture streams containing audio data in wave and MIDI formats.
The following topics are discussed:
Windows 10: What's New for Audio Drivers
Windows Audio Architecture
Roadmap for Developing WDM Audio Drivers
WDM Audio Drivers Overview
WDM Audio Architecture: Basic Concepts
WDM Audio Architecture: Advanced Topics
WDM Audio Support in Different Versions of Windows
Windows Audio Processing Objects
Audio Miniport Drivers
Legacy Audio Interfaces
Windows 10: What's New for Audio Drivers
1/3/2019 • 6 minutes to read • Edit Online

This topic provides a high level summary of what's new in audio for Windows 10.

Feature Summary
Here are the new audio features in Windows 10.
Implementing Audio Module Communication
Low Latency Audio Improvements
Signal Processing Modes and Audio Categories
Hardware Offloaded APO Effects
Cortana Voice Activation
Windows Universal Drivers for Audio
Resource Management for Audio Drivers
PNP Rebalance for Audio Drivers

Low Latency Audio Improvements


Audio latency is the delay between that time that sound is created and when it is heard. Having low audio latency is
very important for several key scenarios, such as the following.
Pro Audio
Music Creation and Mixing
Communications such as Skype
Virtual and Augmented Reality
Games
The total latency of a device is the sum of the latencies of the following components:
Operating System
Audio Processing Objects
Audio Driver
Audio Hardware
In Windows 10 work was done to reduce the latency in the OS. Without any driver changes, applications in
Windows 10 will experience 4.5-16ms lower latency. In addition, if the driver has been updated to take advantage
of the new low latency DDIs that use small buffers to process audio data, then the latency will be reduced even
more. If a driver supports 3ms audio buffers, then the roundtrip latency is ~10ms.
The audio stack supports multiple packet sizes and dynamic packet resizing, in order to optimize the tradeoff
between latency and power based on the user’s scenario. In addition, streams will be prioritized, in order to ensure
that high priority streams (e.g. phone calls) have dedicated resources.
In order for audio drivers to support low latency, Windows 10 provides the following 3 new features:
1. [Mandatory] Declare the minimum buffer size that is supported in each mode.
2. [Optional, but recommended] Improve the coordination for the data flow between the driver and the OS.
3. [Optional, but recommended] Register the driver resources (interrupts, threads), so that they can be protected
by the OS in low latency scenarios. For more information, see Low Latency Audio.

Signal Processing Modes and Audio Categories


Signal Processing Modes
Drivers declare the supported audio signal processing modes for each device.
Audio categories (selected by applications) are mapped to audio modes (defined by drivers). Windows defines
seven audio signal processing modes. OEMs and IHVs can determine which modes they want to implement. The
modes are summarized in the table shown below.

Mode Render/Capture Description

Raw Both Raw mode specifies that there


should not be any signal processing
applied to the stream.
An application can request a raw
stream that is completely
untouched and perform its own
signal processing.
Default Both This mode defines the default audio
processing.

Movies * Render Movie audio playback

Media * Both Music audio playback (default for most


media streams)

Speech * Capture Human voice capture (e.g. input to


Cortana)

Communications * Both VOIP render and capture (e.g. Skype,


Lync)

Notification * Render Ringtones, alarms, alerts, etc.

Audio device drivers need to support at least the Raw or Default mode. Supporting additional modes is optional.
Dedicated modes for speech, movie, music and communications. Audio drivers will be able to define different type
of audio formats and processing, based on the stream type.
Audio Categories
The following table shows the audio categories in Windows 10.
In order to inform the system about the usage of an audio stream, applications have the option to tag the stream
with a specific audio stream category. In Windows 10 there are nine audio stream categories.

Categor y Description

Movie* Movies, video with dialog (Replaces ForegroundOnlyMedia)

Media* Default category for media playback (Replaces


BackgroundCapableMedia)

Game Chat* In-game communication between users (New category in


Windows 10)

Speech* Speech input (e.g. personal assistant) and output (e.g.


navigation apps) (New category in Windows 10)

Communications VOIP, real-time chat

Alerts Alarm, ring tone, notifications

Sound Effects Beeps, dings, etc

Game Media In game music

Game Effects Balls bouncing, car engine sounds, bullets, etc.

Other Uncategorized streams


* New in Windows 10.
For more information see Audio Signal Processing Modes and Audio Processing Object Architecture.

Hardware Offloaded APO Effects


Windows 10 supports hardware offloaded APO effects. APOs can be loaded on top of the offload pin. This allows
for the audio processing to be done in both software and hardware. In addition, the processing can change
dynamically. Some or all of the processing can be moved from the software APO to the DSP when there are
enough hardware resources and then moved back to the software APO when the load in the DSP increases.
For more information, see Implementing Hardware Offloaded APO Effects.

Cortana Voice Activation - Wake on Voice


Cortana, the personal assistant technology was first demonstarted at the Microsoft BUILD Developer Conference in
2013. Voice activation is a feature that enables users to invoke a speech recognition engine from various device
power states by saying a specific phrase - "Hey Cortana". The "Hey Cortana" Voice Activation (VA) feature allows
users to quickly engage an experience (e.g., Cortana) outside of his or her active context (i.e., what is currently on
screen) by using his or her voice. The feature is targeted for scenarios when the screen is off, idle or when it is fully
active. If the hardware supports buffering, users can then chain the key phrase and command phrase together. This
improves the end to end wake on voice experience for the user. For more information, see Voice Activation.

Windows Universal Drivers for Audio


Windows 10 supports one driver model that works for PC and 2:1’s and Windows 10 for phones and small screen
tablets. This means that IHVs can develop their driver in one platform and that driver works in all devices (desktops,
laptops, tablets, phones). The result is reduced development time and cost.
In order to develop Universal Audio Drivers, use the following tools:
1. Visual Studio 2015: New driver settings allow the “Target Platform” to be set to “Universal” to create a multi-
platform driver.
2. APIValidator: This is a WDK tool that checks whether driver is universal and highlights calls that need to be
updated.
3. Audio samples in GitHub: The sysvad and SwapAPO have been converted to be Universal Drivers. For more
information and pointers to GitHub sample code, see Universal Windows Drivers for Audio.

Resource Management for Audio Drivers


One challenge with creating a good audio experience on a low cost mobile device, is that some devices have
various concurrency constraints. For example, it is possible that the device can only play up to 6 audio streams
concurrently and supports only 2 offload streams. When there is an active phone call on a mobile device, it is
possible that the device supports only 2 audio streams. When the device is capturing audio, the device can only
play up to 4 audio streams.
Windows 10 includes a mechanism to express concurrency constraints to insure that high-priority audio streams
and cellular phone calls will be able to play. If the system does not have enough resources, then low priority
streams are terminated. This mechanism is only available in phones and tablets not on desktops or laptops.
For more information, see Audio Hardware Resource Management.

PNP Rebalance for Audio Drivers


PNP rebalancing is used in certain PCI scenarios where memory resources need to be reallocated. In that case,
some drivers are unloaded, and then reloaded at different memory locations, in order to create free contiguous
memory space. Rebalance can be triggered in two main scenarios:
1. PCI hotplug: A user plugs in a device and the PCI bus does not have enough resources to load the driver for the
new device. Some examples of devices that fall into this category include Thunderbolt, USB-C and NVME
Storage. In this scenario, memory resources need to be rearranged and consolidated (rebalanced) to support
the additional devices being added.
2. PCI resizeable BARs: After a driver for a device is successfully loaded in memory, it requests additional
resources. Some examples of devices include high-end graphics cards and storage devices. For more
information, see Implement PnP Rebalance for PortCls Audio Drivers.
Windows Audio Architecture
6/25/2019 • 2 minutes to read • Edit Online

This topic provided a high level summary of the Windows 10 audio architecture.

Windows 10 Audio Stack Diagram


This diagram provides a summary of the major elements of the Windows 10 audio stack.

APIs
Top level APIs
The top level APIs are used for application development. These APIs are in currently in use and supported.
XAML MediaElement class(C#, VB, C++)
HTML Audio object and Video object<tags> (used by websites and Windows Web Apps)
Windows.Media.Capture namespace (C#, VB, C++)
Microsoft Media Foundation (C++)
These older APIs are deprecated.
DirectShow
DirectSound
PlaySound
Windows.Media.MediaControlContract
Low level APIs
These lower level APIs are recommended for audio streaming.
WASAPI (High performance, but more complicated)
IXAudio2 (Typically used for games)
MIDI
This lower level API is recommended for enumeration.
Windows.Devices.Enumeration
These APIs are not recommended for Windows applications.
About MMDevice API (replaced by Windows.Devices.Enumeration)
DeviceTopology API
EndpointVolume API

Audio Engine
The audio engine consists of two related components, the Audio Device Graph (audiodg.exe), which loads the
Audio Engine (audioeng.dll).
The audio engine:
Mixes and processes audio streams. For more information about how the audio engine uses buffers to transfer
audio, see Understanding the WaveRT Port Driver.
Loads Audio Processing Objects (APOs), which are H/W-specific plugins that process the audio signal. For more
information about APOs, see Windows Audio Processing Objects.

Audio Service (audiosrv.dll)


The audio service:
Is used to setup and control audio streams.
Implements Windows policies for background audio playback, ducking, etc.

Audio Endpoint Builder (audioendpointbuilder.exe)


The Audio Endpoint Builder (audioendpointbuilder.exe):
Is used to discover new audio devices and create software audio endpoints. For more information about the
algorithm that is used, see Audio Endpoint Builder Algorithm.

Audio Drivers
Audio drivers:
Follow the port-miniport model. For more information, see WDM Audio Terminology and Developing a WaveRT
Miniport Driver.
Allow the audio stack to render and capture audio from several audio devices, including: integrated speakers
and microphones, headsets/headphones, USB devices, Bluetooth devices, HDMI, etc.
The port-minport model corresponds to the Advanced Linux Sound Architecture ALSA
For information on sample driver code, see Sample Audio Drivers.

Hardware
The audio hardware that is present on any give device varies but can include:
Audio Codec
DSP (optional)
Integrated speakers, microphone, etc
External devices: USB audio devices, Bluetooth audio devices, HDMI audio, etc.
Signal processing can also be implemented in the H/W (e.g. the codec or the DSP), instead of or in addition to
the APOs.
WDM Audio Drivers Overview
6/25/2019 • 2 minutes to read • Edit Online

Windows Driver Model (WDM) audio drivers make use of the kernel streaming (KS) components, which operate in
kernel mode and are part of the operating system.
Hardware vendors should make several design decisions before beginning development of a Windows-based
audio hardware device.
The first decision is whether to design an audio device that requires a vendor-supplied custom driver. Windows
contains operating-system support for PCI, USB, and IEEE 1394 devices that conform to the Microsoft Universal
Audio Architecture (UAA) guidelines. The vendor does not need to provide a custom driver for a UAA-compatible
audio device.
However, if a vendor-supplied custom audio driver is necessary, the vendor must choose whether the driver should
be designed to work in conjunction with the PortCls system driver (Portcls.sys) or the AVStream class system
driver (Ks.sys). Both PortCls and AVStream are part of the Windows operating system. PortCls is the correct choice
for most audio adapters. For more information about PortCls, see Introduction to Port Class. For more information
about AVStream, see AVStream Overview.
When designing a custom adapter driver that uses PortCls, the devices on the audio adapter are made available to
applications using WaveRT. For more information, see Introducing the WaveRT Port Driver.
Two additional decisions involve how to present the adapter topology and pin data ranges to audio applications.
The topology is a logical map of the data paths and control nodes in the adapter circuitry. The data ranges specify
the data formats that the devices can support in their wave and MIDI streams. Both decisions affect how the
devices on the audio adapter appear to applications.
In making all of the previously mentioned decisions, the hardware vendor must weigh the value of performance
enhancements against the cost of implementing them. Another consideration is whether a particular solution can
be made to work on a number of products in the Windows family. This section provides an overview of these
issues as well as references to more detailed documentation about specific topics.
This section includes the following topics:
Universal Audio Architecture
Audio Signal Processing Modes
Custom Audio Drivers
Specifying the Topology
Specifying Pin Data Ranges
Universal Windows Drivers for Audio
10/18/2019 • 9 minutes to read • Edit Online

In Windows 10 you can write a universal audio driver that will work across many types of hardware. This topics
discusses the benefits of this approach as well as the differences between different platforms. In addition to the
Universal Windows drivers for audio, Windows continues to support previous audio driver technologies, such as
WDM.

Getting Started with Universal Windows drivers for Audio


IHVs can develop a Universal Windows driver that works on all devices (desktops, laptops, tablets, phones). This
can reduces development time and cost for initial development and later code maintenance.
These tools are available to develop Universal Windows driver support:
Visual Studio 2015 Support: There is a driver setting to set “Target Platform” equal to “Universal”. For more
information about setting up the driver development environment, see Getting Started with Universal
Windows Drivers.
APIValidator Tool: You can use the ApiValidator.exe tool to verify that the APIs that your driver calls are valid
for a Universal Windows driver. This tool is part of the Windows Driver Kit (WDK) for Windows 10, and runs
automatically if you are using Visual Studio 2015 . For more information, see Validating Universal Windows
Drivers.
Updated DDI reference documentation: The DDI reference documentation is being updated to indicate
which DDIs are supported by Universal Windows drivers. For more information, see Audio Devices
Reference.

Create a Universal Audio Driver


For step-by-step guidance, see Getting Started with Universal Windows Drivers. Here is a summary of the steps:
1. Load the universal audio sysvad sample to use as starting point for your universal audio driver.
Alternatively, start with the empty WDM driver template and add in code from the universal sysvad sample
as needed for your audio driver.
2. In the project properties, set Target Platform to "Universal".
3. Create an installation package: If your target is device running Windows 10 for desktop editions (Home, Pro,
Enterprise, and Education), use a configurable INF file. If your target is device running Windows 10 Mobile,
use PkgGen to generate an .spkg file.
4. Build, install, deploy, and debug the driver for Windows 10 for desktop editions or Windows 10 Mobile.

Sample Code
Sysvad and SwapAPO have been converted to be Universal Windows driver samples. For more information, see
Sample Audio Drivers.

Available Programming Interfaces for Universal Windows drivers for


Audio
Starting with Windows 10, the driver programming interfaces are part of OneCoreUAP-based editions of
Windows. By using that common set, you can write a Universal Windows driver. Those drivers will run on both
Windows 10 for desktop editions and Windows 10 Mobile, and other Windows 10 versions.
The following DDIs to are available when working with universal audio drivers.
Audio Drivers Event Sets
Audio Drivers Interfaces
Audio Drivers Property Sets
Audio Drivers Structures
Audio Topology Nodes
High Definition Audio DDI Reference
Port Class Audio Driver Reference

Convert an Existing Audio Driver to a Universal Windows driver


Follow this process to convert an existing audio driver to a Universal Windows driver.
1. Determine whether your existing driver calls will run on OneCoreUAP Windows. Check the requirements
section of the reference pages. For more information see Audio Devices Reference.
2. Recompile your driver as a Universal Windows driver. In the project properties, set Target Platform to
"Universal".
3. Use the ApiValidator.exe tool to verify that the DDIs that your driver calls are valid for a Universal Windows
driver. This tool is part of the Windows Driver Kit (WDK) for Windows 10, and runs automatically if you are
using Visual Studio 2015. For more information, see Validating Universal Windows Drivers.
4. If the driver calls interfaces that are not part of OneCoreUAP, compiler displays errors.
5. Replace those calls with alternate calls, or create a code workaround, or write a new driver.

Creating a componentized audio driver installation


Overview
To create a smoother and more reliable install experience and to better support component servicing, divide the
driver installation process into the following components.
DSP (if present) and Codec
APO
OEM Customizations
Optionally, separate INF files can be used for the DSP and Codec.
This diagram summarizes a componentized audio installation.
A separate extension INF file is used to customize each base driver component for a particular system.
Customizations include tuning parameters and other system-specific settings. For more information, see Using an
Extension INF File.
An extension INF file must be a universal INF file. For more information, see Using a Universal INF File.
For information about adding software using INF files, see Using a Component INF File.
Submitting componentized INF files
APO INF packages must be submitted to the Partner Center separately from the base driver package. For more
information about creating packages, see Windows HLK Getting Started.
SYSVAD componentized INF files
To see an example of componentized INF files examine the sysvad/TabletAudioSample, on Github.

F IL E N A M E DESC RIP T IO N

ComponentizedAudioSample.inf The base componentized sample audio INF file.

ComponentizedAudioSampleExtension.inf The extension driver for the sysvad base with additional OEM
customizations.

ComponentizedApoSample.inf An APO sample extension INF file.

The traditional INF files continue to be available in the SYSVAD sample.

F IL E N A M E DESC RIP T IO N

tabletaudiosample.inf A desktop monolitic INF file that contains all of the


information needed to install the driver.

phoneaudiosample.inf A phone monolitic INF file that contains all of the information
needed to install the driver.

APO vendor specific tuning parameters and feature configuration


All APO vendor system specific settings, parameters, and tuning values must be installed via an extension INF
package. In many cases, this can be performed in a simple manner with the INF AddReg directive. In more complex
cases, a tuning file can be used.
Base driver packages must not depend on these customizations in order to function (although of course
functionality may be reduced).
UWP Audio Settings APPs
To implement an end user UI, use a Hardware Support App (HSA) for a Windows Universal Audio driver. For more
information, see Hardware Support App (HSA): Steps for Driver Developers.
Programmatically launching UWP Hardware Support Apps
To programmatically launch a UWP Hardware Support App, based on a driver event (for example, when a new
audio device is connected), use the Windows Shell APIs. The Windows 10 Shell APIs support a method for
launching UWP UI based on resource activation, or directly via IApplicationActivationManager. You can find more
details on automated launching for UWP applications in Automate launching Windows 10 UWP apps.
APO and device driver vendor use of the AudioModules API
The Audio Modules API/DDI is designed to standardize the communication transport (but not the protocol) for
commands passed between a UWP application or user-mode service to a kernel driver module or DSP processing
block. Audio Modules requires a driver implementing the correct DDI to support module enumeration and
communication. The commands are passed as binary and interpretation/definition is left up to the creator.
Audio Modules is not currently designed to facilitate direct communication between a UWP app and a SW APO
running in the audio engine.
For more information about audio modules, see Implementing Audio Module Communication and Configure and
query audio device modules.
APO HWID strings construction
APO Hardware IDs incorporate both standard information and vendor-defined strings.
They are constructed as follows:

SWC\VEN_v(4)&AID_a(4)&SUBSYS_ n(4)s(4) &REV_r(4)


SWC\VEN_v(4)&AID_a(4)&SUBSYS_ n(4)s(4)
SWC\VEN_v(4)&AID_a(4)

Where:
v(4) is the 4-character identifier for the APO device vendor. This will be managed by Microsoft.
a(4) is the 4-character identifier for the APO, defined by the APO vendor.
n(4) is the 4-character PCI SIG-assigned identifier for the vendor of the subsystem for the parent device. This is
typically the OEM identifier.
s(4) is the 4-character vendor-defined subsystem identifier for the parent device. This is typically the OEM
product identifier.
Plug and Play INF version and date evaluation for driver update
The Windows Plug and Play system evaluates the date and the driver version to determine which drive to install
when multiple drivers exist. For more information, see How Windows Ranks Drivers.
To allow the latest driver to be used, be sure and update the date and version, for each new version of the driver.
APO driver registry key
For third party-defined audio driver/APO registry keys, use HKR with the exception of
HKLM\System\CurrentControlSet.
Use a Windows Service to facilitate UWP <-> APO communication
A Windows Service is not strictly required for management of user-mode components like APOs, however, if your
design includes an RPC server to facilitate UWP <-> APO communication, we recommend implementing that
functionality in a Windows Service that then controls the APO running in the audio engine.
Building the Sysvad Universal Audio Sample for Windows 10 Desktop
Complete the following steps to build the sysvad sample for Windows 10 desktop.
1. Locate the desktop inf file (tabletaudiosample.inf) and set the manufacturer name to a value such as
"Contoso"
2. In Solution Explorer, right-click Solution 'sysvad' , and choose Configuration Manager. If you are deploying
to a 64 bit version of Windows, set the target platform to x64. Make sure that the configuration and
platform settings are the same for all of the projects.
3. Build the all of the projects in the sysvad solution.
4. Locate the output directory for the build from the build. For example it could be located in a directory like
this:

C:\Program Files (x86)\Windows Kits\10\src\audio\sysvad\x64\Debug\package

5. Navigate to the Tools folder in your WDK installation and locate the PnpUtil tool. For example, look in the
following folder: C:\Program Files (x86)\Windows Kits\10\Tools\x64\PnpUtil.exe .
6. Copy the following files to the system that you want to install the sysvad driver:

TabletAudioSample.sys The driver file.

tabletaudiosample.inf An information (INF) file that contains information needed to


install the driver.

sysvad.cat The catalog file.

SwapAPO.dll A sample driver extension for a UI to manage APOs.

PropPageExt.dll A sample driver extension for a property page.

KeywordDetectorAdapter.dll A sample keyword detector.

Install and test the driver


Follow these steps to install the driver using the PnpUtil on the target system.
1. Open and Administrator command prompt and type the following in the directory that you copied the
driver files to.
pnputil -i -a tabletaudiosample.inf
2. The sysvad driver install should complete. If there are any errors you can examine this file for additional
information: %windir%\inf\setupapi.dev.log
3. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Microsoft Virtual
Audio Device (WDM) - Sysvad Sample. This is typically under the Sound, video and game controllers node.
4. On the target computer, open Control Panel and navigate to Hardware and Sound > Manage audio
devices . In the Sound dialog box, select the speaker icon labeled as Microsoft Virtual Audio Device (WDM) -
Sysvad Sample, then click Set Default, but do not click OK. This will keep the Sound dialog box open.
5. Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound
dialog box, verify that there is activity in the volume level indicator associated with the Microsoft Virtual
Audio Device (WDM) - Sysvad Sample driver.

Building the Sysvad Universal Audio Sample for Windows 10 Mobile


Complete the following steps to build the sysvad sample for Windows 10 Mobile.
1. Locate the Mobile inf file (phoneaudiosample.inf) and set the manufacturer name to a value such as
"Contoso"
2. Build the following projects in the sysvad solution:
EndPointsCommon
PhoneAudioSample
3. Locate the output directory for the build from the . For example with a default location of Visual Studio in
could be located in a directory like this:

C:\Program Files (x86)\Windows Kits\10\src\audio\sysvad\x64\Debug\package`

4. Follow the guidance in Creating packages to create a package that contains the driver files for a mobile
image.
5. To install a mobile driver package (.spkg file), you will need to combine packages into a mobile OS image.
Use ImgGen to add the .spkg driver package to a full flash update (FFU) image that can then be flashed to a
mobile device. It may be necessary to remove other audio drivers that exist in the mobile image to allow for
testing of the sysvad virtual audio driver.
6. After the OS image contains the driver package is running, play a sound clip and validate that the sysvad
phone audio sample is functional. You can establish a kernel debugger connection to monitor the sysvad
virtual driver on a mobile device.
Universal Audio Architecture
12/5/2018 • 2 minutes to read • Edit Online

The Microsoft Universal Audio Architecture (UAA) enables audio devices that comply with the architecture to rely
entirely on the operating system for driver support.
To be UAA-compatible, a PCI audio adapter must conform to the Intel High Definition Audio specification, which is
the successor to the Intel Audio Codec '97 (AC'97) specification. Unlike AC'97, Intel High Definition Audio (Intel HD
Audio) standardizes the bus controller, in addition to the codec devices and the serial interface link (the link that
connects the controller to the codecs). The UAA design guidelines for Intel HD Audio devices contain additional
requirements that are not part of the Intel High Definition Audio specification. Windows Vista provides complete
driver support for UAA-compliant PCI audio adapters.
To be UAA-compatible, a USB audio device must conform to both the USB audio specification and the UAA design
guidelines for USB audio devices. USB audio devices can make use of the USBAudio class system driver
(Usbaudio.sys), which is supplied as part of Windows. By definition, a USB audio device that is compatible with the
USBAudio class system driver in Windows is UAA-compliant.
To be UAA-compatible, an IEEE 1394 AV/C audio device must conform to both the relevant IEEE 1394 specifications
and the UAA design guidelines for IEEE 1394 AV/C audio devices. IEEE 1394 audio devices can make use of the
AVCAudio class system driver (Avcaudio.sys), which is supplied as part of Windows.
For more information about the Microsoft UAA initiative, see the Universal Audio Architecture white paper. For
more information about Intel HD Audio, see the Intel HD Audio website. For a list of related specifications for USB
and IEEE 1394 audio devices, see USBAudio Class System Driver and AVCAudio Class System Driver.
Roadmap for Developing WDM Audio Drivers
6/25/2019 • 2 minutes to read • Edit Online

Audio drivers are based on the Windows driver model (WDM).


To create a WDM audio driver, perform the following steps:
1. Learn about Windows architecture and drivers.
You must understand the fundamentals of how drivers work in Windows operating systems. Knowing the
fundamentals will help you make appropriate design decisions and allow you to streamline your
development process. See Concepts for all driver developers.
2. Learn the fundamentals of WDM audio drivers.
Audio drivers in the Windows operating system versions from Windows XP to Windows Vista conform to
WDM and use the kernel streaming components. To understand the driver design decisions that you must
make, see Kernel Streaming, WDM Audio Drivers Overview and Introduction to WDM Audio Drivers.
3. Determine additional WDM audio driver design decisions.
For information about how to make design decisions, see Custom Audio Drivers, Audio Data Formats and
Data Ranges. If you need help to decide the type of audio driver to learn about, see Custom Audio Driver
Type Decision Tree.
4. Learn about Audio Processing Objects.
Audio processing objects (APOs), provide customizable software based digital signal processing for
Windows audio streams. To learn more, see Windows Audio Processing Objects.
5. Learn about the Windows driver build, test, and debug processes and tools.
Building a driver is not the same as building a user-mode application. See Developing, Testing, and
Deploying Drivers for information about Windows driver build, debug, and test processes, and driver
signing. See Driver Development Tools for information about building, testing, verifying, and debugging
tools.
6. Review audio driver samples in the WDK.
To access and review the audio driver samples in the WDK, see Sample Audio Drivers.
7. Make design decisions about your WDM audio driver.
See Audio Miniport Drivers and COM in the Kernel.
8. Develop, build, test, and debug your WDM audio driver.
For information about how to develop an audio driver for your specific audio adapter, see Adapter Driver
Construction. See Developing, Testing, and Deploying Drivers for information about iterative building,
testing, and debugging. This process will help ensure that you build a driver that works.
9. Create a driver package for your WDM audio driver.
For more information, see Creating a Driver Package. For information about how to install an audio adapter,
see Installing a Port Class Audio Adapter.
10. Sign and distribute your WDM audio driver.
The final step is to sign (optional) and distribute the driver. If your driver meets the quality standards that
are defined for the Windows Certification Program, you can distribute it through the Microsoft Windows
Update program. For more information, see Distributing a driver package.
These are the basic steps. Additional steps might be necessary based on the needs of your individual driver.
Custom Audio Driver Type Decision Tree
6/25/2019 • 2 minutes to read • Edit Online

Use this decision tree with Step 3 of Roadmap for Developing WDM Audio Drivers. The tree helps you determine
the type of audio driver to learn about. The system-supplied port class driver (PortCls) provides a set of port
drivers that implement most of the basic functionality. These port drivers simplify the development process for the
driver developer. High definition (HD) audio and AC97 drivers are typically based on the PortCls class driver,
whereas USB and 1394 drivers are usually based on the AVStream class.

If your audio device is based on the universal audio architecture (UAA) standard, it is UAA-compatible. A UAA-
compatible audio device can use the system-supplied UAA class drivers and does not need a custom driver, but you
can provide your own Windows Audio Processing Objects.
If your audio device is not UAA-compatible or it is UAA-compatible but you want to implement customized
features, you must decide whether you want to develop a driver with Bus Master DMA support. If you want to
provide Bus Master DMA support, for example, you must develop a PortCls-based audio driver.
For information about how to develop custom audio drivers and how to choose a port driver, see the following
topics:
Custom Audio Drivers
Provides an overview of PortCls and AVStream audio drivers and discusses the pros and cons of each type.
AVStream Overview
Provides an architectural overview of AVStream-based drivers and highlights the cases where this type of driver is
the best choice.
You must also decide about the data format that your audio driver will use and the range of formats it will support.
For more information about data formats and ranges, see Audio Data Formats and Data Ranges.
To complete steps for audio driver development, see Roadmap for Developing WDM Audio Drivers.
Audio Signal Processing Modes
10/23/2019 • 12 minutes to read • Edit Online

Drivers declare the supported audio signal processing modes for each device.

Available Signal Processing Modes


Audio categories (selected by applications) are mapped to audio modes (defined by drivers). Windows defines
seven audio signal processing modes. OEMs and IHVs can determine which modes they want to implement. It is
recommended that IHVs/OEMs utilize the new modes to add audio effects that optimize the audio signal to
provide the best user experience. The modes are summarized in the table shown below.

Mode Render/Capture Description

Raw Both Raw mode specifies that there


should not be any signal
processing applied to the stream.
An application can request a raw
stream that is completely
untouched and perform its own
signal processing.

Default Both This mode defines the default audio


processing.

Movies * Render Movie audio playback

Media * Both Music audio playback (default for most


media streams)

Speech * Capture Human voice capture (e.g. input to


Cortana)

Communications * Both VOIP render and capture (e.g. Skype,


Lync)

Notification * Render Ringtones, alarms, alerts, etc.

* New in Windows 10.

Signal Processing Mode Driver Requirements


Audio device drivers need to support at least the Raw or Default mode. Supporting additional modes is optional.
It is possible that not all modes might be available for a particular system. Drivers define which signal processing
modes they support (i.e. what types of APOs are installed as part of the driver) and inform the OS accordingly. If a
particular mode is not supported by the driver, then Windows will use the next best matching mode.
The following diagram shows a system that supports multiple modes:
Windows Audio Stream Categories
In order to inform the system about the usage of an audio stream, applications have the option to tag the stream
with a specific audio stream category. Applications can set the audio category, using any of the audio APIs, just
after creating the audio stream. In Windows 10 there are nine audio stream categories.

Categor y Description

Movie Movies, video with dialog (Replaces ForegroundOnlyMedia)

Media Default category for media playback (Replaces


BackgroundCapableMedia)

Game Chat In-game communication between users (New category in


Windows 10)

Speech Speech input (e.g. personal assistant) and output (e.g.


navigation apps) (New category in Windows 10)

Communications VOIP, real-time chat

Alerts Alarm, ring tone, notifications

Sound Effects Beeps, dings, etc

Game Media In game music

Game Effects Balls bouncing, car engine sounds, bullets, etc.

Other Uncategorized streams

As mentioned previously, audio categories (selected by applications) are mapped to audio modes (defined by
drivers). Applications can tag each of their streams with one of the 10 audio categories.
Applications do not have the option to change the mapping between an audio category and a signal processing
mode. Applications have no awareness of the concept of an "audio processing mode". They cannot find out what
mode is used for each of their streams.
WASAPI Code Sample
The following WASAPI code from the WASAPIAudio sample shows how to set different audio categories.

// The ActivateAudioInterfaceAsync is a replacment for IMMDevice::Activate


IActivateAudioInterfaceAsyncOperation *asyncOp = nullptr;
HRESULT hr = S_OK;

String ^defaultRender = Windows::Media::Devices::MediaDevice::GetDefaultAudioRenderId(


Windows::Media::Devices::AudioDeviceRole::Default );

hr = ActivateAudioInterfaceAsync( defaultRender->Data(), __uuidof( IAudioClient3 ), nullptr, this, &asyncOp );


if ( FAILED( hr ) ) { … }

// the app’s implementation of IActivateAudioInterfaceCompetionHandler is invoked asynchronously


HRESULT ActivateAudioInterfaceCompletionHandler::ActivateCompleted( IActivateAudioInterfaceAsyncOperation
*activateOperation ) {
HRESULT hr = S_OK;
HRESULT hrActivateResult = S_OK;
IUnknown *pUnknown = nullptr;
IAudioClient3 *pAudioClient3 = nullptr;

hr = activateOperation->GetActivateResult( &hrActivateResult, &pUnknown );


if ( FAILED( hr ) ) { … }
if ( FAILED( hrActivateResult ) ) { … }

hr = pUnknown->QueryInterface( IID_PPV_ARGS( &pAudioClient3 ) );


if ( FAILED( hr ) ) { … }

// The IAudioClient3::SetClientProperties call needs to happen after activation completes,


// but before the call to IAudioClient3::Initialize or IAudioClient3::InitializeSharedAudioStream.
AudioClientProperties props = {};
props.cbSize = sizeof(props);
props.eCategory = AudioCategory_GameEffects;
pAudioClient3->SetClientProperties( &props );
if ( FAILED( hr ) ) { … }

hr = pAudioClient3->InitializeSharedAudioStream( … );
if ( FAILED( hr ) ) { … }

Signal Processing Modes and Effects


OEMs define what effects will be used for each mode. Windows defines a list of seventeen types of audio effects.
For information on how to associate APOs with modes, see Implementing Audio Processing Objects.
It is possible for applications to ask what effects would be applied to a specific stream for either RAW or non- RAW
processing. Applications can also ask to be notified when the effects or raw processing state change. The
application may use this information to determine if a specific streaming category like communication is available,
or if only RAW mode is in use. If only RAW mode is available, the application can determine how much audio
processing of its own to add.
If System.Devices.AudioDevice.RawProcessingSupported is true, applications also have the option to set a "use
RAW" flag on certain streams. If System.Devices.AudioDevice.RawProcessingSupported is false, applications
cannot set the "use RAW" flag.
Applications have no visibility into how many modes are present, with the exception of RAW/non-RAW.
Applications should request the optimal audio effect processing, regardless of the audio hardware configuration.
For example, tagging a stream as Communications will let Windows know to pause background music.
For more information about the static audio stream categories, see AudioCategory enumeration and
MediaElement.AudioCategory property.

CLSIDs for System Effects


FX_DISCOVER_EFFECTS_APO_CLSID
This is the CLSID for the MsApoFxProxy.dll “proxy effect” which queries the driver to get the list of active effects;

FX_DISCOVER_EFFECTS_APO_CLSID = "{889C03C8-ABAD-4004-BF0A-BC7BB825E166}"

KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE
KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE is an identifier to Kernel Streaming that identifies that the
specific attribute that is being referenced, is the signal processing mode attribute.
The #define statements shown here, are available in the KSMedia.h header file.

#define STATIC_KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE 0xe1f89eb5, 0x5f46, 0x419b, 0x96, 0x7b, 0xff, 0x67,


0x70, 0xb9, 0x84, 0x1
DEFINE_GUIDSTRUCT("E1F89EB5-5F46-419B-967B-FF6770B98401", KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE);
#define KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE DEFINE_GUIDNAMED(KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE)

KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE is used to by mode aware drivers with a KSDATARANGE


structure which contain a KSATTRIBUTE_LIST . This list has a single element in it which is a KSATTRIBUTE . The
Attribute member of the KSATTRIBUTE structure is set to KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE.

Audio Effects
The following audio effects are available for use in Windows 10.

Acoustic Echo Cancellation (AEC) Acoustic Echo Cancellation (AEC) improves audio quality
by removing echo, after it after it is already present in the
audio stream.

Noise Suppression (NS) Noise Suppression (NS) suppresses noise such as


humming and buzzing, when it is present in the audio
stream.

Automatic Gain Control (AGC) Automatic Gain Control (AGC) - is designed to provide a
controlled signal amplitude at its output, despite variation
of the amplitude in the input signal. The average or peak
output signal level is used to dynamically adjust the
input-to-output gain to a suitable value, enabling a stable
level of output, even with a wide range of input signal
levels.
Beam Forming (BF) Beam Forming (BF) is a signal processing technique used
for directional signal transmission or reception. This is
achieved by combining elements in a phased array in
such a way that signals at particular angles experience
constructive interference while others experience
destructive interference. The improvement compared with
omnidirectional reception/transmission is known as the
receive/transmit gain (or loss).

Constant Tone Removal Constant tone removal is used to attenuate constant


background noise such as tape hiss, electric fans or hums.

Equalizer The Equalizer effect is used to alter the frequency


response of an audio system using linear filters. This
allows for different parts of the signal to be boosted,
similar to a treble or bass setting.

Loudness Equalizer The loudness equalizer effect reduces perceived volume


differences by leveling the audio output so that louder
and quieter sounds are closer to an average level of
loudness.

Bass Boost In systems such as laptops that have speakers with


limited bass capability, it is sometimes possible to increase
the perceived quality of the audio by boosting the bass
response in the frequency range that is supported by the
speaker. Bass boost improves sound on mobile devices
with very small speakers by increasing gain in the mid-
bass range.

Virtual Surround Virtual surround uses simple digital methods to combine


a multichannel signal into two channels. This is done in a
way that allows the transformed signal to be restored to
the original multichannel signal, using the Pro Logic
decoders that are available in most modern audio
receivers. Virtual surround is ideal for a system with a
two-channel sound hardware and a receiver that has a
surround sound enhancement mechanism.

Virtual Headphones Virtualized surround sound allows users who are wearing
headphones to distinguish sound from front to back as
well as from side to side. This is done by transmitting
spatial cues that help the brain localize the sounds and
integrate them into a sound field. This has the effect of
making the sound feel like it transcends the headphones,
creating an "outside-the-head" listening experience. This
effect is achieved by using an advanced technology called
Head Related Transfer Functions (HRTF). HRTF generates
acoustic cues that are based on the shape of the human
head. These cues not only help listeners to locate the
direction and source of sound but it also enhances the
type of acoustic environment that is surrounding the
listener.
Speaker Fill Most music is produced with only two channels and is,
therefore, not optimized for the multichannel audio
equipment of the typical audio or video enthusiast. So
having music emanate from only the front-left and front-
right loudspeakers is a less-than-ideal audio experience.
Speaker fill simulates a multichannel loudspeaker setup. It
allows music that would otherwise be heard on only two
speakers to be played on all of the loudspeakers in the
room, enhancing the spatial sensation.

Room Correction Room correction optimizes the listening experience for a


particular location in the room, for example, the center
cushion of your couch, by automatically calculating the
optimal combination of delay, frequency response, and
gain adjustments.
The room correction feature better matches sound to the
image on the video screen and is also useful in cases
where desktop speakers are placed in nonstandard
locations. room correction processing is an improvement
over similar features in high-end receivers because it
better accounts for the way in which the human ear
processes sound.
Calibration is performed with the help of a microphone,
and the procedure can be used with both stereo and
multichannel systems. The user places the microphone
where the user intends to sit and then activates a wizard
that measures the room response. The wizard plays a set
of specially designed tones from each loudspeaker in turn,
and measures the distance, frequency response, and
overall gain of each loudspeaker from the microphone's
location.

Bass Management There are two bass management modes: forward bass
management and reverse bass management.
Forward bass management filters out the low frequency
content of the audio data stream. The forward bass
management algorithm redirects the filtered output to
the subwoofer or to the front-left and front-right
loudspeaker channels, depending on the channels that
can handle deep bass frequencies. This decision is based
on the setting of the LRBig flag. To set the LRBig flag, the
user uses the Sound applet in Control Panel to access the
Bass Management Settings dialog box. The user selects a
check box to indicate, for example, that the front-right
and front-left speakers are full range and this action sets
the LRBig flag. To clear this flag, click the check box to
clear it.
Reverse bass management distributes the signal from the
subwoofer channel to the other output channels. The
signal is directed either to all channels or to the front-left
and front-right channels, depending on the setting of the
LRBig flag. This process uses a substantial gain reduction
when mixing the subwoofer signal into the other
channels. The bass management mode that is used
depends on the availability of a subwoofer and the bass-
handling capability of the main speakers. In Windows, the
user provides this information via the Sound applet in
Control Panel.
Environmental Effects Environmental effects work to increase the reality of audio
playback by more accurately simulating real-world audio
environments. There are a number of different
environments that you can select, for example "stadium"
simulates the acoustics of a sports stadium.

Speaker Protection The purpose of speaker protection is to suppress


resonant frequencies that would cause the speakers to do
physical harm to any of the PCs' system components. For
example, some physical hard drives can be damaged by
playing a loud sound at just the right frequency.
Secondarily, speaker protection works to minimize
damage to speakers, by attenuating the signal, when it
exceeds certain values.

Speaker Compensation Some speakers are better at reproducing sound than


others. For example, a particular speaker may attenuate
sounds below 100 Hz. Sometimes audio drivers and
firmware DSP solutions have knowledge about the
specific performance characteristics of the speakers they
are playing to, and they can add processing designed to
compensate for the speaker limitations. For example, an
endpoint effect (EFX) could be created that applies gain to
frequencies below 100 Hz. This effect, when combined
with the attenuation in the physical speaker, results in
enhanced audio fidelity.

Dynamic Range Compression Dynamic range compression amplifies quiet sounds by


narrowing or "compressing" an audio signal's dynamic
range. Audio compression amplifies quiet sounds which
are below a certain threshold while loud sounds remain
unaffected.

The #define statements shown here, are available in the KSMedia.h header file.
DEFAULT

#define STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT 0xc18e2f7e, 0x933d, 0x4965, 0xb7, 0xd1, 0x1e, 0xef, 0x22,
0x8d, 0x2a, 0xf3
DEFINE_GUIDSTRUCT("C18E2F7E-933D-4965-B7D1-1EEF228D2AF3", AUDIO_SIGNALPROCESSINGMODE_DEFAULT);
#define AUDIO_SIGNALPROCESSINGMODE_DEFAULT DEFINE_GUIDNAMED(AUDIO_SIGNALPROCESSINGMODE_DEFAULT)

RAW

#define STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW 0x9e90ea20, 0xb493, 0x4fd1, 0xa1, 0xa8, 0x7e, 0x13, 0x61, 0xa9,
0x56, 0xcf
DEFINE_GUIDSTRUCT("9E90EA20-B493-4FD1-A1A8-7E1361A956CF", AUDIO_SIGNALPROCESSINGMODE_RAW);
#define AUDIO_SIGNALPROCESSINGMODE_RAW DEFINE_GUIDNAMED(AUDIO_SIGNALPROCESSINGMODE_RAW)

ACOUSTIC ECHO CANCELLATION


#define STATIC_AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION 0x6f64adbe, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,
0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adbe-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION);
#define AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION
DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION)

NOISE SUPPRESSION

#define STATIC_AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION 0x6f64adbf, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adbf-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION);
#define AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION)

AUTOMATIC GAIN CONTROL

#define STATIC_AUDIO_EFFECT_TYPE_AUTOMATIC_GAIN_CONTROL 0x6f64adc0, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc0-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_AUTOMATIC_GAIN_CONTROL);
#define AUDIO_EFFECT_TYPE_AUTOMATIC_GAIN_CONTROL DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_AUTOMATIC_GAIN_CONTROL)

BEAMFORMING

#define STATIC_AUDIO_EFFECT_TYPE_BEAMFORMING 0x6f64adc1, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc1-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_BEAMFORMING);
#define AUDIO_EFFECT_TYPE_BEAMFORMING DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_BEAMFORMING)

CONSTANT TONE REMOVAL

#define STATIC_AUDIO_EFFECT_TYPE_CONSTANT_TONE_REMOVAL 0x6f64adc2, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc2-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_CONSTANT_TONE_REMOVAL);
#define AUDIO_EFFECT_TYPE_CONSTANT_TONE_REMOVAL DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_CONSTANT_TONE_REMOVAL)

EQUALIZER

#define STATIC_AUDIO_EFFECT_TYPE_EQUALIZER 0x6f64adc3, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc3-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_EQUALIZER);
#define AUDIO_EFFECT_TYPE_EQUALIZER DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_EQUALIZER)

LOUDNESS EQUALIZER

#define STATIC_AUDIO_EFFECT_TYPE_LOUDNESS_EQUALIZER 0x6f64adc4, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc4-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_LOUDNESS_EQUALIZER);
#define AUDIO_EFFECT_TYPE_LOUDNESS_EQUALIZER DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_LOUDNESS_EQUALIZER)

BASS BOOST

#define STATIC_AUDIO_EFFECT_TYPE_BASS_BOOST 0x6f64adc5, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc5-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_BASS_BOOST);
#define AUDIO_EFFECT_TYPE_BASS_BOOST DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_BASS_BOOST)
VIRTUAL SURROUND

#define STATIC_AUDIO_EFFECT_TYPE_VIRTUAL_SURROUND 0x6f64adc6, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc6-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_VIRTUAL_SURROUND);
#define AUDIO_EFFECT_TYPE_VIRTUAL_SURROUND DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_VIRTUAL_SURROUND)

VIRTUAL HEADPHONES

#define STATIC_AUDIO_EFFECT_TYPE_VIRTUAL_HEADPHONES 0x6f64adc7, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc7-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_VIRTUAL_HEADPHONES);
#define AUDIO_EFFECT_TYPE_VIRTUAL_HEADPHONES DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_VIRTUAL_HEADPHONES)

ROOM CORRECTION

#define STATIC_AUDIO_EFFECT_TYPE_ROOM_CORRECTION 0x6f64adc9, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adc9-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_ROOM_CORRECTION);
#define AUDIO_EFFECT_TYPE_ROOM_CORRECTION DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_ROOM_CORRECTION)

BASS MANAGEMENT

#define STATIC_AUDIO_EFFECT_TYPE_BASS_MANAGEMENT 0x6f64adca, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adca-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_BASS_MANAGEMENT);
#define AUDIO_EFFECT_TYPE_BASS_MANAGEMENT DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_BASS_MANAGEMENT)

ENVIRONMENTAL EFFECTS

#define STATIC_AUDIO_EFFECT_TYPE_ENVIRONMENTAL_EFFECTS 0x6f64adcb, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adcb-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_ENVIRONMENTAL_EFFECTS);
#define AUDIO_EFFECT_TYPE_ENVIRONMENTAL_EFFECTS DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_ENVIRONMENTAL_EFFECTS)

SPEAKER PROTECTION

#define STATIC_AUDIO_EFFECT_TYPE_SPEAKER_PROTECTION 0x6f64adcc, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adcc-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_SPEAKER_PROTECTION);
#define AUDIO_EFFECT_TYPE_SPEAKER_PROTECTION DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_SPEAKER_PROTECTION)

SPEAKER COMPENSATION

#define STATIC_AUDIO_EFFECT_TYPE_SPEAKER_COMPENSATION 0x6f64adcd, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,


0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adcd-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_SPEAKER_COMPENSATION);
#define AUDIO_EFFECT_TYPE_SPEAKER_COMPENSATION DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_SPEAKER_COMPENSATION)

DYNAMIC RANGE COMPRESSION


#define STATIC_AUDIO_EFFECT_TYPE_DYNAMIC_RANGE_COMPRESSION 0x6f64adce, 0x8211, 0x11e2, 0x8c, 0x70, 0x2c,
0x27, 0xd7, 0xf0, 0x01, 0xfa
DEFINE_GUIDSTRUCT("6f64adce-8211-11e2-8c70-2c27d7f001fa", AUDIO_EFFECT_TYPE_DYNAMIC_RANGE_COMPRESSION);
#define AUDIO_EFFECT_TYPE_DYNAMIC_RANGE_COMPRESSION
DEFINE_GUIDNAMED(AUDIO_EFFECT_TYPE_DYNAMIC_RANGE_COMPRESSION)
Custom Audio Drivers
6/25/2019 • 2 minutes to read • Edit Online

Audio devices that are not UAA-compatible require vendor-supplied custom drivers. In addition, a UAA-compatible
audio adapter can incorporate proprietary features that are not supported by the UAA class drivers; these features
are accessible to applications only if the vendor provides a custom audio driver. Only the standard UAA features
are accessible through the system-supplied UAA drivers. For information about UAA-supported features, see the
Universal Audio Architecture white paper.
Two options are available to hardware vendors for writing custom audio drivers: developing a custom audio-
adapter driver for use with the PortCls system driver (Portcls.sys), or developing a custom minidriver for use with
the AVStream class system driver (Ks.sys).
Most custom drivers for audio adapters use PortCls, which is supplied as part of the operating system. The PortCls
system driver (Portcls.sys) contains a built-in audio-driver infrastructure that makes the task of writing a custom
audio driver easier. PortCls implements several port drivers, each of which is specialized to manage the generic
functions of a particular type of wave, MIDI, or mixer device. After selecting an appropriate set of port drivers to
manage the audio functions on the audio adapter, the vendor develops a complementary set of miniport drivers
that work in conjunction with the selected port drivers and control the hardware-dependent features of the audio
devices.
The vendor can also support an audio device by developing a custom AVStream class minidriver. The minidriver
works in conjunction with the AVStream class system driver, which is supplied as part of the operating system.
Implementing an AVStream driver is more difficult than using PortCls, but doing so might still be appropriate for
devices that integrate audio and video. An AVStream driver might also be necessary for an existing USB or IEEE
1394 audio device that fails to comply with the requirements of the system-supplied USBAudio or AVCAudio class
system driver.
For nearly all PCI audio adapters that require vendor-supplied custom drivers, vendors should choose PortCls.
The AVStream class system driver (Ks.sys) lacks most of the audio-specific support functions that exist in PortCls.
For more information about PortCls, see Introduction to Port Class. For more information about AVStream, see
AVStream Overview.
Specifying the Topology
10/23/2019 • 6 minutes to read • Edit Online

After a hardware vendor decides which miniport drivers to write for the wave and MIDI devices, the next step is to
represent the kernel streaming (KS) topology of these devices. The KS topology consists of a set of data structures
that describe the data paths that audio or MIDI streams follow as they flow through each device. Through this
topology, the driver exposes the control nodes (for example, volume control) that lie along each path. Typically, an
application uses the Windows multimedia mixerXxx functions to explore the topology by enumerating the
sequence of nodes along each path. For example, after discovering a volume-level control node, an application can
set the volume level on that node. For more information about Windows multimedia, see the Microsoft Windows
SDK documentation. For more information about the representation of KS topologies by the mixerXxx functions,
see Kernel Streaming Topology to Audio Mixer API Translation.
PortCls provides six port drivers: WavePci, WaveCyclic, WaveRT, MIDI, DMus, and Topology. (WaveRT has been
available since Windows Vista and is the recommended approach.) The Topology port driver controls the portion of
the audio adapter circuitry that mixes together the rendering streams from the wave and MIDI devices. It also
controls the selection of capture streams from input jacks. In spite of its somewhat misleading name, the Topology
port driver does not embody all of an audio adapter's topology, although typically it does contain a large portion of
it. The other port drivers contribute the remaining portions of the adapter's topology.
Each port driver is paired with a corresponding miniport driver to form a KS filter that represents a particular
device (wave, MIDI, or mixer) on the audio adapter, as shown in the following table.

F ILT ER T Y P E DESC RIP T IO N

WaveXxx filter Represents a wave device that converts a wave output


stream to an analog audio signal or that converts an
analog audio signal to a wave input stream.

MIDI or DMus filter Represents a MIDI device that plays or captures a MIDI
stream.

Topology filter Represents the adapter's mixer circuitry.

The miniport driver implements the filter's device-specific functions, including the definition of the portion of the
adapter topology that the device encompasses. The port driver takes care of the generic filter operations, including
communication with the operating system, for each type of filter.
Each filter has one or more KS pins that serve as pathways for streams of audio data to enter and leave the filter.
Typically, the pins on the Topology filter are tied to the pins on the wave, MIDI, and DMus filters through hardwired
connections in the adapter circuitry. These filters and their interconnections together form a KS filter graph that
embodies the adapter's topology.
The following figure shows the topology of an example audio adapter.
In the preceding figure, the topology at the top level consists of the connections among the MIDI, WaveXxx, and
topology filters. In addition, each filter has its own internal topology, which consists of the data paths through the
filter and the control nodes that lie along each path. The nodes are labeled as shown in the following table.

L A B EL DESC RIP T IO N K S N O DE- T Y P E GUID

Synth Synthesizer node KSNODETYPE_SYNTHESIZER

DAC Digital-to-audio converter node KSNODETYPE_DAC

ADC Analog-to-digital converter node KSNODETYPE_ADC

Volume Volume-level control node KSNODETYPE_VOLUME

Mute Mute control node KSNODETYPE_MUTE

Sum Summation node KSNODETYPE_SUM

MUX Multiplexer node KSNODETYPE_MUX

In the preceding figure, the pins on the left side of the audio adapter represent the logical connections (not physical
connections) through which data streams enter the adapter from the system bus or enter the system bus from the
adapter. These pins are logically connected to source and sink pins on other filters (not shown) that are external to
the adapter. Typically, these filters are software modules that, together with the adapter topology, form a larger
filter graph whose topology can be explored by applications using the mixerXxx functions. For example, the pin
labeled "PCM Wave Out" in the preceding figure is logically connected to the user-mode audio engine in Windows.
These logical connections are maintained by DMA transfers over the system bus.
In contrast, the pins on the left edge of the topology filter are physically connected to pins on the MIDI and
WaveXxx filters. These connections are hardwired and cannot be changed by software.
The bridge pins on the right side of the audio adapter represent audio jacks on the system chassis. These pins are
referred to as bridge pins because they bridge the boundary between the KS filter graph and the external world.
Filters, pins, and nodes typically have properties that are accessible to clients (kernel-mode components or user-
mode applications) of the audio driver. A client can send a KS property request to a filter, pin, or node either to
query for the current value of a property or to change the property value. For example, a volume-level control
node has a KSPROPERTY_AUDIO_VOLUMELEVEL property, which a client can change through a KS property
request. A summation node is an example of a node type that typically has no properties.
For simplicity, the WaveXxx filter in the preceding figure provides only a single pin for accepting a PCM wave
output stream from the system bus. In contrast, some wave devices provide multiple pins for PCM wave output
and contain hardware for internally mixing the streams that enter the pins. These devices provide hardware
acceleration for applications that use DirectSound by accepting PCM streams that play from the applications'
sound buffers. For DirectSound to use these pins, they must provide additional nodes for two-dimensional (2-D)
and three-dimensional (3-D) processing, as described in DirectSound Hardware Acceleration in WDM Audio.
This type of hardware acceleration is supported in Windows Server 2003, Windows XP, Windows 2000, and
Windows Me/98, but it is not supported in Windows Vista. Windows Vista makes no use of the hardware
acceleration pins on older wave devices.
In the preceding figure, the physical connections between the MIDI, WaveXxx, and topology filters all transport
analog audio signals. However, a different topology device might achieve a similar effect by accepting digital output
streams from the MIDI and wave devices, digitally mixing them, and converting the digital mix to an analog output
signal.
The "Non-PCM Wave Out" pin at the lower-left corner of the preceding figure accepts a non-PCM output stream in
an S/PDIF pass-through format, such as AC-3-over-S/PDIF or WMA Pro-over-S/PDIF. Using one of these formats,
the device simply transmits the compressed data over the S/PDIF link without decoding the data. For this reason,
the data path to the "S/PDIF Out" pin on the lower-right corner of the preceding figure contains no volume or mute
nodes. For more information about non-PCM audio formats and S/PDIF pass-through transmission, see
Supporting Non-PCM Wave Formats. Additional information is available in the white paper titled Audio Driver
Support for the WMA Pro-over-S/PDIF Format at the audio technology website.
The miniport driver presents its topology to the port driver in the form of a PCFILTER_DESCRIPTOR structure.
This structure describes all of the filter's pins and nodes, and it specifies how the pins and nodes connect to each
other.
Instead of designing a monolithic topology filter, as shown in the preceding figure, the mixer circuitry in the audio
adapter can be partitioned into several topology filters. For example, in the preceding figure, the data paths that
drive the speakers might be implemented as one topology filter, and the data paths that capture audio data from
input devices can be implemented as a separate topology filter. When the data paths in a particular topology filter
are not in use, that portion of the adapter can be powered down without disabling the entire adapter. For more
information, see Dynamic Audio Subdevices.
Specifying Pin Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

After defining a topology to represent the data paths and control nodes in your devices, the next step is to define
the data ranges for each configurable pin. A configurable pin can be created, configured, and connected to a wave
or MIDI stream under software control. In contrast, a physical connection or bridge pin exists implicitly and can
neither be created nor configured under software control.
Before connecting a configurable pin to serve as a sink or source for a wave or MIDI stream, the pin must be
configured to handle the data format for the stream. Typically, the pin can be configured to accept one of several
stream formats. For example, a PCM wave-output pin might accept the following ranges of PCM stream
parameters:
Sample rates of 11.025 kHz, 22.05 kHz, 44.1 kHz, and 48 kHz
Sample sizes of 8, 16, 24, and 32 bits
Any number of channels from 1 through 8
For each type of configurable pin, a miniport driver describes the various stream data formats that the pin can
handle. These parameter ranges can be specified as an array of data-range descriptors, as shown in the following
code example.

static KSDATARANGE_AUDIO PinDataRangesPcm[] =


{
{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
8, // Maximum number of channels
8, // Minimum number of bits-per-sample
32, // Maximum number of bits-per-channel
11025, // Minimum rate
48000 // Maximum rate
}
};

Note that the PinDataRangesPcm array in the preceding example contains a single data-range descriptor of type
KSDATARANGE_AUDIO . More generally, a data-range array can contain an arbitrary number of descriptors. For
example, a non-PCM wave-output pin might support both AC-3-over-S/PDIF and WMA Pro-over-S/PDIF formats.
Each of these two formats is specified by a separate data-range descriptor. Thus, the pin's data-range array would
contain at least two KSDATARANGE_AUDIO structures.
A configurable pin that supports the music stream format from an application that uses DirectMusic or the
Windows multimedia midiInXxx and midiOutXxx functions uses a data-range descriptor of type
KSDATARANGE_MUSIC .
The port driver obtains the data-range information from the miniport driver and uses this information, wherever
possible, to handle requests for information about the data formats that each pin can support. In the case of a pin
with a simple PCM data range, the port driver is able to handle the intersection requests for that pin. In an
intersection request, a client supplies a set of data ranges that represent possible data formats for a stream. If
possible, the port driver's intersection handler picks a particular data format from the data ranges in the request
that also falls within its pin's data ranges. This format represents an intersection of the two sets of data ranges.
Hence, both the client and the pin can process a stream with this format. For more complex data ranges, the
miniport driver can provide its own intersection handler, which the port driver then uses instead of its own, default
handler. The intersection handler of the miniport driver can allow for any format requirements that might be
difficult to express to the port driver as an array of data ranges. For more information, see Data-Intersection
Handlers. Additional information is available in the white paper titled Multiple Channel Audio Data and WAVE Files
at the audio technology website.
WDM Audio Architecture: Basic Concepts
6/25/2019 • 2 minutes to read • Edit Online

This section presents the basic architectural concepts of Windows Driver Model (WDM) audio drivers. The WDM
audio architecture is based on kernel streaming (KS) services and is supported in Microsoft Windows 2000 and
later and in Windows Me/98. For information about KS services, see Kernel Streaming.
This section discusses the following topics:
Introduction to WDM Audio Drivers
Audio Filters, Pins, and Nodes
Audio Endpoints, Properties and Events
Audio Data Formats and Data Ranges
Digital Rights Management
Introduction to WDM Audio Drivers
6/25/2019 • 3 minutes to read • Edit Online

Kernel streaming (KS) services support kernel-mode processing of data streams for audio and for other types of
continuous media. Conceptually, a stream undergoes processing as it flows along a data path containing some
number of processing nodes. A set of related nodes is grouped together to form a KS filter, which represents a
more-or-less independent block of stream-processing functionality. More complex functions can be constructed in
a modular way by cascading several filters together to form a filter graph.
A typical audio adapter card might contain audio devices for playing a wave stream through a set of speakers,
converting the audio signal from a microphone to a wave stream, and synthesizing sound from a MIDI stream. The
adapter driver can wrap each of these audio devices in a KS filter that it exposes to the operating system. The
operating system connects the filters to other filters to form filter graphs that process audio streams on behalf of
application programs.
KS filters are connected together through their pins. A pin on an audio filter can be thought of as an audio jack. A
client instantiates an input or output pin on a filter when the client needs to route a data stream into or out of that
filter. In some contexts, the terms pin and stream can be used interchangeably.
The output pin of the upstream filter is connected to the input pin of the downstream filter. The data stream from
the output pin must have a data format that the input pin can accept. Data buffering is typically required to smooth
out momentary mismatches in the rates at which an output pin produces data and an input pin consumes it.
A KS filter is implemented as a kernel-mode driver object that encapsulates some number of related stream-
processing functions. The functionality can be implemented in software or in hardware. In this model, an audio
adapter can be viewed as a collection of hardware devices, and the adapter driver exposes each of these devices to
the audio system as an individual filter.
An adapter driver exposes a collection of filter factories to the audio system. Each filter factory is capable of
instantiating filters of a particular type:
If the adapter contains one or more devices that are similar or identical in function, the driver groups the
filters for those devices together into the same filter factory.
If the adapter contains several different types of devices, those devices are presented through several
different filter factories.
A KS filter exposes a collection of pin factories to the audio system. Each pin factory is capable of instantiating pins
of a particular type. If the filter can provide one or more pins that are similar or identical in function, the filter
groups those pins together into the same pin factory. For example, a filter that performs audio mixing might have
one pin factory that can instantiate a single output pin and a second pin factory that can instantiate several input
pins.
KS services are built upon the Windows Driver Model. Note that the term KS filter must be distinguished from the
term filter driver, which is another WDM concept. A filter driver resides in a WDM driver stack and can intercept
and modify the I/O request packets (IRPs) that propagate through the stack. Upper- and lower-level filter drivers
reside above and below the function driver, respectively. In this section, the term filter refers to a KS filter rather
than a filter driver unless noted otherwise. For more information about filter drivers, see Types of WDM Drivers.
This section contains the following topics:
Basic Functions of a WDM Audio Driver
Vendor Audio Driver Options
WDM Audio Terminology
Sample Audio Drivers
KsStudio Utility
For updates and information about new features of the WDM audio architecture, see the audio technology website.
Basic Functions of a WDM Audio Driver
6/25/2019 • 2 minutes to read • Edit Online

A Microsoft Windows Driver Model (WDM) audio driver provides the following functionality:
The driver exposes all the types of input and output streams, and the number of instances of each stream
type that it can support. The driver provides this information in the form of a set of pin factories and the
number of pins that each factory can instantiate. For example, a simple audio device might input a single
PCM audio stream and output a single PCM audio stream. The filter for this device contains two pin
factories--one for the input stream an one for the output stream--and each pin factory supports only a
single pin instance. If the adapter card contains only one of these devices, the adapter driver provides a filter
factory containing only a single instance of a filter with these capabilities.
The driver supports one or more property sets. For example, all audio drivers should support
KSPROPSETID_Audio, but some audio drivers might support additional property sets as well. Clients of the
driver use property requests both to discover a filter's capabilities and to change the filter's configurable
settings.
The driver optionally supports a hardware clock. This clock should be readable and writable so that streams
can synchronize with other streams on the same or different hardware. For additional information, see
KSPROPSETID_Clock.
The driver optionally supports other media interfaces, such as KSINTERFACE_STANDARD_STREAMING ,
KSINTERFACE_MEDIA_WAVE_QUEUED , or KSINTERFACE_STANDARD_LOOPED_STREAMING .
Vendor Audio Driver Options
6/25/2019 • 2 minutes to read • Edit Online

To take advantage of the built-in system support for audio devices, Microsoft recommends that vendors use one of
the following:
A port class adapter driver (see Audio Miniport Drivers) for an ISA or PCI adapter card
The USB Audio class driver (see USBAudio Class System Driver) for a USB Audio device
A custom IEEE 1394 device driver (see AVCAudio Class System Driver) for an IEEE 1394 audio device
However, if these options are not sufficient, a vendor can implement one of the following:
A proprietary KS filter (see KS Filters)
Microsoft does not recommend a proprietary KS filter because they are difficult to implement, and are
unnecessary for most ISA, PCI, and USB devices.
Stream class minidriver (see Streaming Minidrivers)
Microsoft does not recommend a proprietary stream class minidriver because it is difficult to implement,
although it can be appropriate for devices that integrate audio and video.
For an in-depth discussion of the available options for providing driver support for an audio device, see Getting
Started with WDM Audio Drivers.
WDM Audio Terminology
10/23/2019 • 7 minutes to read • Edit Online

This section describes the differences in terminology between the Microsoft Windows Driver Model (WDM) audio
driver architecture and the generic Windows layered driver architecture. The generic driver architecture is
exemplified by SCSI port/miniport drivers (see Storage Driver Architecture).
The terms defined by the generic and WDM audio driver architectures are similar, but they do have some
important differences, as described below.
Miniport Driver (Generic)
The miniport driver (generic) is the hardware-specific driver for an adapter that resides on a system bus (for
example, PCI or ISA). This driver has a single entry point, DriverEntry, and registers a table of functions with a port
driver. This table of functions serves as the miniport driver's upper-edge interface.
The miniport driver sits below the port driver in the driver stack. That is, all calls to the miniport driver are made
from the port driver and all calls out of the miniport driver are to the port driver's lower-edge interface.
The following figure illustrates the meaning of the terms stack, upper-edge interface, and lower-edge interface as
they are used in this context. The block representing the port driver is stacked on top of the block representing the
miniport driver. Hence, the miniport driver sits below the port driver in the "stack".

The port and miniport drivers communicate through the software interfaces that they expose to each other. In the
preceding figure, these interfaces are associated with the lower-edge of the block representing the port driver and
the upper-edge of the block representing the miniport driver. This representation is the source of the terms "lower-
edge interface" and "upper-edge interface".
Port Driver (Generic)
The port driver (generic) surrounds a miniport driver.
The port driver:
Implements WDM streaming filters.
Provides a common interface to the rest of the operating system.
Handles I/O requests from the system and recasts these requests as calls into the miniport driver's function
table.
Provides the miniport driver with a library of support functions (the port driver's lower-edge interface).
The port driver hides many of the details of the operating system from the miniport driver, and the miniport driver
hides the specifics of the underlying hardware from the port driver. The implementation of the port driver might
undergo changes for different operating system releases, but the port driver's interface to the miniport driver
remains more-or-less unchanged, enabling the miniport driver to be largely platform-independent.
Minidriver (Generic)
The minidriver (generic) represents a hardware component on a bus. The minidriver uses the bus driver to
communicate to the physical device over the bus, and it binds together the bus driver and one or more class
drivers.
Class drivers help the minidriver present the physical device to clients as a type of logical device. In WDM
environments, a minidriver typically receives requests in IRP form from class drivers, and sends requests in IRP
form to a bus driver.
A minidriver might also have to communicate with several class drivers. An example of a minidriver that binds to
multiple class drivers is a minidriver for a CD-ROM drive on an IEEE 1394 bus. It might bind to a file-system driver
so that the drive can be accessed from the file system. However, it also binds to a Redbook system driver so that
audio can be streamed from CDs.
Bus Driver (Generic)
The bus driver (generic) gives minidrivers access to a physical bus. The Microsoft Windows hardware abstraction
layer (HAL) is sometimes referred to as the system bus driver because it provides access to the system bus. For
more information, see Bus Drivers.
Class Driver (Generic)
The class driver (generic) implements behavior that is common across a class of similar devices.
The class driver:
Eliminates duplication of functionality in hardware-specific drivers.
Is not bus-specific.
Is not aware of resource issues (for example, DMA and interrupts).
Miniport Driver (WDM Audio )
The miniport driver (WDM audio) implements a function-specific interface for a function on an audio adapter card
that resides on a system bus. A miniport driver is a component of an adapter driver. It is not recognized as a driver
by the operating system. In this regard, an audio miniport driver differs from a generic miniport driver.
Unlike generic miniport drivers, audio miniport drivers do not implement DriverEntry, are not registered, and do
not rely entirely on their respective port drivers for support. Multiple audio miniport drivers that address multiple
functions can be linked into a single adapter driver (and associated with a single device object).
Adapter Driver (WDM Audio )
The adapter driver (WDM audio) serves as a container for all miniport drivers associated with a given adapter. This
adapter driver is recognized as a driver by the operating system and is contained in its own .sys file.
The audio adapter driver consists of a set of miniport drivers and additional code that addresses initialization
issues. For example, an adapter driver implements a DriverEntry entry point.
Port Driver (WDM Audio )
The port driver (WDM audio) implements a KS filter on behalf of a miniport driver and operates in the context of a
port class driver. The port driver exposes the miniport driver's function-specific code as a KS filter to the system
and is responsible for implementing adapter-independent functionality.
Unlike the generic port driver, the audio port driver shares the device object and is, therefore, instantiated
differently. An audio port driver is also more closely resembles a generic class driver than it does a generic port
driver in that it implements behavior that is expected of a class of devices (it is not bus-independent).
Port Class Driver (WDM Audio )
The port class driver (WDM audio) serves as a container for a collection of port drivers, each of which provides
support for a different type of audio hardware function. The following figure shows the relationships between the
audio port class and adapter drivers.

An adapter driver manages an adapter card that might contain several different hardware functions. As shown in
the preceding figure, the adapter driver contains a miniport driver to manage each type of hardware function.
Similarly, the port class driver is designed to provide support to adapter cards with multiple hardware functions.
The port class driver provides a port driver for each of the well defined function types that it supports. The adapter
driver binds its miniport driver for a particular function to the corresponding port driver for that function type. The
port driver for each function handles communication with the WDM audio clients that use the function. The
miniport driver contains all of the hardware-specific code for managing that function.
The port class driver (WDM audio) primarily functions as a container for multiple subdevices that are associated
with a single device object. Bus drivers create a single physical device object (PDO) for each Plug and Play (PnP)
node they enumerate.
In the case of an audio adapter, a single PnP node frequently contains multiple audio functions. To expose the
various functions associated with a node as distinct devices typically requires writing a bus driver for the adapter.
The bus driver enumerates the hardware functions and creates corresponding PDOs. In this scenario, one or more
function-specific drivers need to bind to the PDOs and negotiate with the bus driver for access to shared resources
on the adapter.
The port class driver uses the kernel streaming driver's ability to expose various aspects of a single device object in
order that the operating system recognizes the device as a set of distinct subdevices.
A reference string is appended to the device name to specify the desired subdevice. The kernel streaming driver
dispatches creation IRPs based on this reference string. After a file object is created, the kernel streaming driver
provides dispatching of IRPs that are targeted at the file object that represents the subdevice. In addition, the port
class driver implements a COM-based model for packaging subdevices.
An adapter driver instantiates a port driver and a miniport driver and binds them together by passing a pointer to
the miniport driver as a parameter to the port driver's initialization function (see the code example in Subdevice
Creation). The resulting port/miniport driver stack constitutes a KS filter that represents one of the subdevice types
that the port class driver supports.
The port class driver's PcRegisterSubdevice function registers the subdevice, which is perceived as a device by
the rest of the system. The port driver receives creation IRPs targeted at the device object, but for only those IRPs
that are specified by the reference string under which the subdevice is registered. The port driver also receives the
IRPs targeted at the file objects that are associated with the subdevice. The port driver is responsible for the
subdevice's behavior as a KS filter and for communicating appropriately with the miniport driver.
For more information about designing drivers for multifunction audio cards, see Multifunction Audio Devices.
Sample Audio Drivers
6/25/2019 • 2 minutes to read • Edit Online

SYSVAD Audio Sample


System Vir tual Audio Device Driver Sample (SYSVAD)
The SYSVAD driver highlights many important features of the WDM audio architecture. These are working
implementations with source code that can serve as a starting point for writing a custom driver for a proprietary
audio device.
The sysvad solution file contains the following projects.
TabletAudioSample
The TabletAudioSample project demonstrates how to develop a WDM audio driver that exposes support
for multiple audio devices. Some of these audio devices are embedded (speakers, mic arrays) in the system
while others are pluggable (headphone speaker/mic, Bluetooth headsets speaker/mic). The driver uses
WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an
actual hardware-based adapter and highlights the different aspects of the audio offloading WDM audio
driver architecture. For more information about the Windows audio engine, see Hardware-Offloaded Audio
Processing (Windows Drivers).
PhoneAudioSample
The PhoneAudioSample project is very similar to the TabletAudioSample project. It includes optimizations
for mobile devices.
EndpointsCommon
The EndpointsCommon project contains common code to both the tablet and phone. For more
information, see Universal Windows Drivers for Audio.
SwapAPO
The SwapAPO project demonstrates how to develop audio processing objects. It includes sample code that
demonstrates how to register and unregister audio processing objects, and also shows how to customize a
Control Panel property page to reflect the available features in the processing object. For more
information, see Windows Audio Processing Objects.
KeywordDetectorAdapter
The KeywordDetectorAdapter project demonstrates how to develop a keyword detector adapter. For more
information, see Voice Activation.
Download and extract the Sysvad audio sample from GitHub
The SYSVAD audio sample is available on the Windows Driver Samples GitHub.
You can browse the Sysvad audio sample here:
https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad
Follow these steps to download and open the SYSVAD sample.
a. You can use GitHub tools to work with the samples. You can also download the universal driver samples in one
zip file.
https://github.com/Microsoft/Windows-driver-samples/archive/master.zip
b. Download the master.zip file to your local hard drive.
c. Right click Windows-driver-samples-master.zip, and choose Extract All . Specify a new folder, or browse to an
existing one that will store the extracted files. For example, you could specify C:\DriverSamples\ as the new folder
into which the files will be extracted.
d. After the files are extracted, navigate to the following subfolder.
C:\DriverSamples\Audio\Sysvad
Open the driver solution in Visual Studio
In Microsoft Visual Studio, Click File > Open > Project/Solution... and navigate to the folder that contains the
extracted files (for example, C:\DriverSamples\Audio\Sysvad). Double-click the Sysvad solution file to open it.
In Visual Studio locate the Solution Explorer. (If this is not already open, choose Solution Explorer from the
View menu.) In Solution Explorer, you can see one solution that has six projects.

Archived Audio Samples


These audio samples support previous versions of the Microsoft Windows Driver Kit (WDK). They are available as
part of the zip file download available here.
Microsoft Vir tual Audio Device Driver Sample (Msvad)
AC97 Driver (Ac97)
DirectMusic UART Driver Sample (Dmusuar t)
DirectMusic Software Synthesizer Sample (ddksynth)
FM Synthesizer (Fmsynth)
Audio Adapters Samples
Audio Processing Codec Samples
Msfilter Sample Codec (MsFilter)
Msgsm610 Sample Codec (gsm610)
For details, see the readme documentation that accompanies each of these samples in the WDK.
For information on the WDK samples, see Windows Driver Kit Samples Pack (Windows Drivers).
KsStudio Utility
12/5/2018 • 2 minutes to read • Edit Online

The KsStudio utility (Ksstudio.exe) is included with the software tools in the Microsoft Windows Driver Kit (WDK).
KsStudio is a kernel streaming tool that can be used to build, examine, and test WDM KS filter graphs in Windows
Me/98 and in Windows 2000 and later. One of KsStudio's most useful features is its ability to construct a graphical
representation of a filter graph that shows both the pin-to-pin connections between filters and the filters' internal
nodes. Although KsStudio is designed primarily for audio filter graphs, it can be used to build and explore graphs
containing any type of WDM KS filter.
To install KsStudio and its help file, KsStudio.chm:
Run the WDK setup application.
From the list of components, click Driver Development Kit , click Tools for Driver Developers , and then
click Audio/Video streaming tools .
Setup installs the platform-specific versions of KsStudio.exe in the x86, amd64, and ia64 subdirectories of the
\tools\avstream directory. It installs the help file, KsStudio.chm, in the \tools\avstream directory. To open the help
file, double-click KsStudio.chm.
An earlier version of KsStudio, which is named Grapher (Grapher.exe), is included in the Windows 2000 and
Windows Me Driver Development Kits (DDKs).
For more information about KsStudio, see the help file for the KsStudio utility in the WDK.
Audio Filters, Pins, and Nodes
6/25/2019 • 2 minutes to read • Edit Online

A Microsoft Windows Driver Model (WDM) adapter driver exposes its audio hardware as a collection of filter
factories, each of which can create one or more filter instances. A kernel streaming (KS) filter object can encapsulate
an audio hardware function that performs some type of digital processing of the wave audio data that streams
through the filter. For example, the filter might do rendering or synthesis of a stream, or it might add reverb to a
stream.
A filter instance exposes pin factories, each of which can create one or more pin instances. These pins can be
connected to the pins of other filters to produce filter graphs. To be part of an audio filter graph, a filter must have
one or more pin instances.
A pin represents an input or output connection point through which a data stream enters or exits the filter. Each pin
specifies the range of data formats that it can support, and only a stream with a compatible format can flow
through the pin.
A filter for a WDM audio device exposes its internal topology in the form of nodes and connections.
Topology nodes lie on the data paths that pass through the filter. A node represents a point of control within the
filter. Each node logically encapsulates a modular chunk of the filter's functionality and performs digital-signal
processing on the data stream that passes through the node. A node might represent a volume control, for
example, that can be adjusted under software control.
The filter object also specifies the connections between its various pins and nodes. Implicit in these connections is
the ordering of nodes along each data path through the filter.
This section presents the features of filters, pins, and nodes that are specific to WDM audio drivers. The following
topics are discussed:
Audio Filters
Filter Factories
Pin Factories
Nodes and Connections
Audio Filter Graphs
Wave Filters
MIDI and DirectMusic Filters
Topology Filters
For a more general discussion of kernel-streaming filters, pins, and nodes, see KS Minidriver Architecture.
Audio Filters
12/5/2018 • 2 minutes to read • Edit Online

A KS filter is a kernel object and is identified by a kernel object handle. In the following figure, the large box in the
center is a KS filter that represents an audio device. The data stream flows into the filter from the left, passes
through a couple of nodes for processing, and exits the filter on the right. The filter is created by a filter factory,
which is shown as a box with dashed edges at the bottom of the filter.

In the figure, two pins are instantiated on the filter. The pin on the left is a data sink, and the pin on the right is a
data source. Data flows into the filter through the sink pin and flows out of the filter through the source pin.
By convention, usage of the terms source and sink in KS is buffer-centric (or perhaps, more generally, connection-
centric). A data buffer is frequently required at the point at which a source pin on one filter connects to the sink pin
of another. The buffer smoothes out irregularities in the rates at which data arrives from the source pin and exits
into the sink pin. (Of course, not all connections require buffering. A bufferless connection might occur between
two devices on the same adapter card, for example, where the sink and source data rates are more easily matched.)
In contrast, the mixer API's terminology for SRC and DST (source and destination) mixer lines is device-centric:
The stream enters a mixer device through the SRC mixer line.
The stream exits a mixer device through the DST mixer line.
In other words, a SRC mixer line maps to a data-sink pin on a KS filter, and a DST mixer line maps to a data-source
pin. For more information, see Kernel Streaming Topology to Audio Mixer API Translation.
For the sake of simplicity, the figure omits the filter's pin factories, which create the pin instances.
In addition to being data sinks and data sources, pins and filters can also be IRP sinks and IRP sources. Not only
can pins and filters receive IRPs--they can send IRPs as well. The three dark arrows in the figure represent IRPs. The
pin on the left side of the figure is an IRP sink. The pin on the right is an IRP source. The figure also shows an IRP
being sent to the filter object itself.
Filter Factories
10/23/2019 • 3 minutes to read • Edit Online

An audio adapter driver provides filter factories to manage the instantiation of filters. Each filter factory can
instantiate one or more KS filters of a particular type. If a filter type encapsulates a particular hardware function,
the number of filters of that type that the factory can instantiate is limited by the underlying hardware resources.
Because a filter factory manages a largely autonomous block of hardware functionality, each filter factory can be
considered to be a device driver in its own right. In fact, the term adapter driver as it is used in the preceding
paragraph, refers to a collection of related drivers--filter factories--that are packaged together to manage the
various hardware functions on an adapter card.
As with any other Microsoft Windows Driver Model (WDM) driver, a filter factory handles power management and
setup functionality. During installation, the INF file for the driver registers one or more filter device names (see
Device Identification Strings). This process loads the names into the system registry and associates each filter
factory with one or more KS filter categories, as described in Installing Device Interfaces for an Audio Adapter. All
audio devices are classified under KSCATEGORY_AUDIO, but an audio device might also be classified under
additional categories such as KSCATEGORY_RENDER (for an audio rendering device) or KSCATEGORY_CAPTURE
(for an audio capture device). The driver advertises the general capabilities of a device by means of the various
categories under which it registers the filter for that device. When the SysAudio system driver, for example,
requires an audio device of a particular type, it looks in the registry for devices that fall into the appropriate
categories.
The operating system uses the Setup API, as described in Device Installation Components, to discover and
enumerate all the KSCATEGORY_AUDIO filter factories in the registry. The registry entry for each factory specifies
both the filter factory's friendly name and its device name, which is a long string that a client passes to the create-
file call that instantiates the filter. This call might be made to ZwCreateFile from kernel mode or to CreateFile
from user mode. A filter is a kernel-mode object and is identified by a kernel handle. The create-file call returns an
instance handle that clients can use to refer to the filter. User-mode clients or upstream filters in the audio graph
can use this handle to send or forward IOCTL requests to the filter. For more information about CreateFile , see the
Microsoft Windows SDK documentation.
A typical WDM audio adapter card might reside on a PCI bus, for example, and contain several I/O connectors for
rendering or capturing wave data. A single audio device on this card might contain analog audio-out jacks for
driving a set of speakers and a lineout cable, and analog audio-in jacks for receiving signals from a microphone
and a linein cable. The WDM audio system represents the device as a filter and represents the audio jacks as pins
on that filter.
The filter for an audio device is implemented as separate port and miniport drivers that are bound together to act
in unison:
The miniport driver contains the hardware-specific code.
The port driver contains the generic code that is common to all filters of a particular type.
The vendor writes the miniport driver, which contains all the proprietary code that the filter needs to manage the
audio hardware. The operating system provides the port driver, which is accessible through the PortCls system
driver (Portcls.sys; see Port Class Adapter Driver and PortCls System Driver). Dividing the filter implementation
into port and miniport drivers simplifies the task of writing a driver for a proprietary device.
When a filter factory instantiates a filter, it first creates the miniport driver object for the filter. The filter factory then
creates an instance of the appropriate port object and binds the miniport driver object to that instance in order to
form a fully functioning filter. The code example in Subdevice Creation illustrates this process. The port and
miniport drivers communicate with each other through well-defined software interfaces. For more information
about these interfaces, see Miniport Interfaces and Supporting a Device.
An audio filter exposes the structure of the underlying audio device as a collection of pin factories, nodes, and
internal connections. The miniport driver consolidates this information into a filter descriptor, which is a structure
of type PCFILTER_DESCRIPTOR . This structure, in turn, contains individual descriptors for the filter's pin factories,
nodes, and internal connections. These descriptors are structures of the following types:
PCPIN_DESCRIPTOR
PCNODE_DESCRIPTOR
PCCONNECTION_DESCRIPTOR
To obtain the filter descriptor from the miniport driver, the port driver calls the IMinipor t::GetDescription
method.
For an example of how a driver sets up its PCFILTER_DESCRIPTOR structure, see the header file Table.h in the sb16
sample audio driver in the Windows Driver Kit (WDK).
Pin Factories
10/23/2019 • 3 minutes to read • Edit Online

An audio filter's pin factories describe all of the pins that the filter can instantiate. As mentioned previously, an
audio miniport driver stores pin information in an array of PCPIN_DESCRIPTOR structures. Each structure
specifies a pin factory, and a pin factory is identified by its index in the array. This index is frequently referred to as
the pin ID.
A PCPIN_DESCRIPTOR structure contains an automation table and a KSPIN_DESCRIPTOR structure.
The KSPIN_DESCRIPTOR structure contains the following information about the pins in the pin factory:
Filter-relative direction of data flow
Filter-relative direction of communication flow (In all current Windows versions, KS filters use IRPs for
communication.)
Pin category
Friendly name
Instance capabilities
Data-format capabilities
The structure's Categor y and Name members specify the pin factory's pin category and friendly name. For each
pin factory in the filter, the miniport driver specifies a combination of Categor y and Name GUIDs that together
uniquely identify the pin factory. If two or more pin factories share the same Categor y value, each pin factory has
a Name value that distinguishes it from the others. If only a single pin factory has a particular Categor y value,
that value is sufficient to identify the pin factory, and the Name value for that pin factory can be set to NULL . For
a coding example, see Exposing Filter Topology. For information about pin categories, see Pin Category Property.
A pin factory specifies the range of data formats that it supports as an array of extended KSDATARANGE
structures:
A pin factory that supports a range of wave or DirectSound data formats for its input or output stream
specifies an array of KSDATARANGE_AUDIO structures.
A pin factory that supports a range of MIDI or DirectMusic data formats for its input or output stream
specifies an array of KSDATARANGE_MUSIC structures.
KSDATARANGE_AUDIO and KSDATARANGE_MUSIC are extended versions of KSDATARANGE. For examples of both
types of data ranges, see Audio Data Formats and Data Ranges.
Before connecting a sink pin on one filter to a source pin on another filter, a graph builder (for example, the
SysAudio system driver) can search the data ranges for a compatible format. The graph builder typically calls the
filter's data-intersection handler, which allows the filter itself to choose a compatible format.
A filter can have multiple pin factories, and a pin factory can support multiple pin instances.
Having multiple pin factories on a filter is useful for distinguishing separate data paths for the different
types of data that flow through the filter. For example, one pin factory might support PCM data streams,
and another pin factory might support AC-3 streams.
A single filter can support rendering and capture streams simultaneously. The rendering and capture paths
have separate sets of filter factories.
Having multiple pin instances on a sink-pin factory frequently implies mixing, in which case the filter
contains a SUM node (KSNODETYPE_SUM ).
Like filters, pins are kernel objects and are identified by kernel handles. The handle for a pin instance is created by
calling KsCreatePin . As a kernel object, a pin can be specified as the target of an IRP. A client of the driver specifies
the pin handle when sending an IOCTL request to a pin.
When building an audio filter graph, SysAudio links one filter to another by connecting their pins. A source pin
from one filter can be connected to the sink pin of another filter. Data and IRPs from the source pin flow into the
sink pin through this connection. To make the connection, a graph builder (typically SysAudio) creates the source
pin first by calling KsCreatePin and then creates the sink pin by calling KsCreatePin again. In the second call,
however, the client specifies that the new sink pin is to be connected to the source pin that was created in the first
call.
Nodes and Connections
10/23/2019 • 2 minutes to read • Edit Online

The filter provides a description of its topology nodes in the form of an array of node descriptors
(PCNODE_DESCRIPTOR structures). Each descriptor in the array describes a single node and contains a GUID
that specifies the node type (for example, KSNODETYPE_REVERB ). For a list of the standard node types that are
defined for audio devices, see Audio Topology Nodes.
The filter identifies each of its nodes by the node's index in the descriptor array. For example, when sending a node-
specific property request to a filter or to a particular pin on a filter, a client includes the node ID (the array index) in
the request in order to identify the target node.
The filter provides a description of its internal connections in the form of an array of connection descriptors
(PCCONNECTION_DESCRIPTOR structures). Each descriptor describes one of the filter's internal connections. A
descriptor can either describe a connection between a pin and a node or a connection between two nodes.
The nodes and connections that the filter exposes together define the filter's internal topology. The topology is a
map of the audio device's internal layout and should accurately reflect the organization of the hardware that it
represents. The Microsoft Windows Multimedia mixer API, for example, translates the filter's internal connections
into mixer lines and its nodes into controls on the mixer lines (see Kernel Streaming Topology to Audio Mixer API
Translation). Any inaccuracies in the filter's internal topology are reflected in the mixer-line representation and may
cause errors or unexpected behavior in an application that uses the mixer API.
Audio Filter Graphs
6/25/2019 • 2 minutes to read • Edit Online

A KS filter graph is a collection of KS filters that have been connected together to process one or more data
streams. An audio filter graph is a KS filter graph that consists of filters that process audio data streams. For
example, the following figure is a simplified diagram of an audio filter graph that performs audio rendering and
capture.

In the figure, the filter graph extends from the pins at the top of the two wave filters to the pins at the bottom of
the two topology filters. The user-mode software modules and external audio devices (that is, the speaker and
microphone) lie outside the graph.
The four filters in the lower half of the figure represent hardware devices on an audio adapter that can render and
capture wave streams. Each of the filters shown in the figure is implemented by binding a port driver to a
miniport driver. The adapter driver forms a wave filter by binding the WaveRT, WavePci, or WaveCyclic port driver
to a corresponding WaveXxx miniport driver. The adapter driver forms a topology filter by binding the Topology
port driver to a Topology miniport driver.
On the left side of the figure, the audio stream from a DirectSound or waveOut application (top) plays through a
speaker (bottom). On the right side, a DirectSoundCapture or waveIn application (top) records the stream that is
input from a microphone (bottom). On both sides, an instance of the audio engine, which performs mixing for the
system in Windows Vista, is interposed between the wave filter and the application. (In Windows Server 2003,
Windows XP, Windows 2000, and Windows Me/98, the KMixer system driver is the system mixer.)
The audio engine is a versatile software filter that runs in user mode and can readily convert between a variety of
audio formats and sample rates at its source and sink pins. The audio engine can typically accommodate the
differences between the stream format that the hardware is configured for and the stream format that the
application expects.
At the bottom of the preceding figure, the source pin that drives the speaker and the sink pin that receives the
microphone signal are labeled as bridge pins. A bridge pin bridges the boundary between a filter graph and the
external world.
In the preceding figure, the data path shown between each wave filter and its corresponding topology filter
typically represents a physical connection: a fixed, hardware connection on the audio adapter that cannot be
configured by software.
Because a bridge pin or a pin with a physical connection is permanently connected, the pin exists implicitly and
cannot be instantiated or deleted. Thus, there are no bridge pin objects (instances of bridge pins) to send IRPs to,
although you can query a filter object for the KSPROPSETID_Pin properties of its bridge pins. The same rule
applies to pins with physical connections.
The signal that passes through a bridge pin or physical connection can be either analog or digital.
For example, in the preceding figure, the two bridge pins both handle analog signals. The bridge pin on the left
transmits the output signal from a DAC (digital-to-analog converter), which drives a speaker. The bridge pin on
the right receives the signal from a microphone, which enters an ADC (analog-to-digital converter). However, a
bridge pin might also represent an S/PDIF connector on an audio device. In this case, the signal that passes
through the bridge pin is digital rather than analog.
Wave Filters
10/23/2019 • 8 minutes to read • Edit Online

Wave filters represent devices that render and/or capture wave-formatted digital audio data. Applications typically
access the capabilities of these devices either through the DirectSound API or through the Microsoft Windows
multimedia waveOutXxx and waveInXxx functions. For information about the wave formats that WDM audio
drivers can support, see WAVEFORMATEX and WAVEFORMATEXTENSIBLE .
A wave-rendering filter receives as input a wave digital audio stream and outputs either an analog audio signal (to
a set of speakers or external mixer) or a digital audio stream (to an S/PDIF connector, for example).
A wave-capture filter receives as input either an analog audio signal (from a microphone or input jack) or a digital
stream (from an S/PDIF connector, for example). The same filter outputs a wave stream containing digital-audio
data.
A single wave filter can perform both rendering and capture simultaneously. This type of filter might, for example,
represent an audio device that can play audio through a set of speakers and record audio through a microphone
at the same time. Alternately, the wave-rendering and wave-capture hardware might be represented as separate
wave filters, as described in Dynamic Audio Subdevices.
An audio adapter driver forms a wave filter by binding a wave miniport driver, which the hardware vendor
implements as part of the adapter driver, with a wave port driver, which the system implements. The miniport
driver handles all the hardware-specific operations for the wave filter, and the port driver manages all the generic
wave-filter functions.
The PortCls system driver (Portcls.sys) implements three wave port drivers: WaveRT, WavePci, and WaveCyclic.
The three types of wave filter operate as follows:
A WaveRT filter allocates a buffer for wave data and makes that buffer directly accessible to the user-mode
client. The buffer can consist of contiguous or noncontiguous blocks of memory, depending on the
hardware capabilities of the wave device. The client accesses the buffer as a contiguous block of virtual
memory. The buffer is cyclic, which means that when the device's read (for rendering) or write (for capture)
pointer reaches the end of the buffer, it automatically wraps around to the beginning of the buffer.
A WavePci filter directly accesses the client's buffer. Although the client accesses the buffer as a single,
contiguous block of virtual memory, the WavePci filter must access the buffer as a series of possibly
noncontiguous memory blocks. Blocks containing successive portions of the rendering or capture stream
are queued up at the device. When the device's read or write pointer reaches the end of one block, it moves
to the beginning of the next block in the queue.
A WaveCyclic filter allocates a buffer consisting of a single, contiguous block of memory for use as its
output (for rendering) or input (for capture) buffer. This buffer is cyclic. Because the buffer is not directly
accessible to the client, the driver must copy data between the driver's cyclic buffer and the client's user-
mode buffer.
WaveRT is preferred over WavePci and WaveCyclic. WavePci and WaveCyclic were used with earlier versions of
Windows.
A WaveRT filter can represent an audio device that resides on a system bus, such as PCI or PCI Express. The
primary advantage of a WaveRT filter over a WaveCyclic or WavePci filter is that a WaveRT filter allows a user-
mode client to exchange audio data directly with the audio hardware. In contrast, WaveCyclic and WavePci filters
both require periodic software intervention by the driver, which increases the latency of the audio stream. In
addition, audio devices both with and without scatter/gather DMA capabilities can be represented as WaveRT
filters. For more information, see the A Wave Port Driver for Real-Time Audio Streaming white paper.
WaveRT Filters
A WaveRT filter is implemented as a port/miniport driver pair. In Windows Vista and later, a WaveRT filter factory
creates a WaveRT filter as follows:
It instantiates a WaveRT miniport driver object.
It instantiates a WaveRT port driver object by calling PcNewPor t with GUID value CLSID_Por tWaveRT .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process. The port and miniport drivers communicate with
each other through their IPortWaveRT and IMiniportWaveRT interfaces.
For more information, see the A Wave Port Driver for Real-Time Audio Streaming white paper.
Information for previous versions of Windows
WaveCyclic Information for previous versions of Windows
A WaveCyclic filter can represent an audio device that connects to a system bus, such as ISA, PCI, PCI Express, or
PCMCIA. As the name "WavePci" implies, a WavePci filter usually represents a device that connects to a PCI bus,
although, in principle, a WavePci device might instead connect to an ISA bus, for example. Unlike the simpler
devices that are supported by WaveCyclic, a device supported by WavePci must have scatter/gather DMA
capabilities. An audio device that resides on PCI bus but lacks scatter/gather DMA can be represented as a
WaveCyclic filter but not as a WavePci filter.
WavePci Information for previous versions of Windows
A WavePci device is able to perform scatter/gather DMA transfers to or from buffers that can be located at
arbitrary memory addresses and that begin and end with arbitrary byte alignments. In contrast, the DMA
hardware for a WaveCyclic device requires only the ability to move data to or from a single buffer that the device's
miniport driver allocates. A WaveCyclic miniport driver is free to allocate a cyclic buffer that meets the limited
capabilities of its DMA channel. For example, the DMA channel for a typical WaveCyclic device might require a
buffer that satisfies the following restrictions:
The buffer is located in a certain region of the physical address space.
The buffer is contiguous in physical as well as in virtual address space.
The buffer begins and ends on even four- or eight-byte boundaries.
In return for this simplicity, however, a WaveCyclic device must rely on software copying of data to or from the
cyclic buffer, whereas a WavePci device relies on the scatter/gather capabilities of its DMA hardware to avoid such
copying. The IRPs that deliver wave audio data to a rendering device or retrieve data from a capture device are
accompanied by data buffers, and each of these buffers contains a portion of the audio stream that is being
rendered or captured. A WavePci device is able to access these buffers directly through its scatter/gather DMA
engine, whereas a WaveCyclic device requires that the data be copied to its cyclic buffer from the IRP, or vice versa.
WavePci Filters
Note: WavePci Information for previous versions of Windows
A WavePci filter is implemented as a port/miniport driver pair. A WavePci filter factory creates a WavePci filter as
follows:
It instantiates a WavePci miniport driver object.
It instantiates a WavePci port driver object by calling PcNewPor t with GUID value CLSID_Por tWavePci .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process. The port and miniport drivers communicate with
each other through their IPortWavePci and IMiniportWavePci interfaces.
For more information, see Implementation Issues for WavePci Devices.
WaveCyclic Filters
Note: WaveCyclic Information for previous versions of Windows
A WaveCyclic filter is implemented as a port/miniport driver pair. A WaveCyclic filter factory creates a WaveCyclic
filter as follows:
It instantiates a WaveCyclic miniport driver object.
It instantiates a WaveCyclic port driver object by calling PcNewPor t with GUID value
CLSID_Por tWaveCyclic .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process. The port and miniport drivers communicate with
each other through their IPortWaveCyclic and IMiniportWaveCyclic interfaces.
The WaveCyclic filter's cyclic buffer always consists of a contiguous block of virtual memory. The port driver's
implementation of the IDmaChannel::AllocateBuffer method always allocates a buffer that is contiguous in
both physical and virtual memory address space. If, as mentioned previously, the WaveCyclic device's DMA engine
imposes additional constraints on the buffer memory, the miniport driver is free to implement its own buffer-
allocation method to meet these constraints.
A WaveCyclic miniport driver that asks for a large buffer (for example, eight physically contiguous memory pages)
should be prepared to settle for a smaller buffer size if the operating system denies the original request. An audio
device might occasionally be unloaded and reloaded to rebalance system resources (see Stopping a Device to
Rebalance Resources).
A WaveCyclic device with built-in, bus-mastering DMA hardware is called a master device. Alternatively, a
WaveCyclic device can be a subordinate device with no built-in DMA-hardware capabilities. A subordinate device
has to rely on the system DMA controller to perform any data transfers that it requires. For more information
about master and subordinate devices, see IDmaChannel and IDmaChannelSlave.
A WaveCyclic miniport driver can implement its own DMA-channel object instead of using the default DMA-
channel object, which is created by one of the port driver's New XxxDmaChannel methods:
IPor tWaveCyclic::NewMasterDmaChannel
IPor tWaveCyclic::NewSlaveDmaChannel
The adapter driver's custom IDmaChannel implementation can perform custom handling of data to meet special
hardware constraints. For example, the Windows Multimedia functions use wave formats in which 16-bit samples
are always signed values, but the audio-rendering hardware might be designed to use unsigned 16-bit values
instead. In this case, the driver's custom IDmaChannel::CopyTo method can be written to convert the signed
source values to the unsigned destination values that the hardware requires. Although this technique can be
useful for working around hardware-design flaws, it can also incur a significant cost in software overhead.
For an example of a driver that implements its own DMA-channel object, see the Sb16 sample audio adapter in
the WDK. If the constant OVERRIDE_DMA_CHANNEL is defined to be TRUE , the conditional compilation
statements in the source code enable the implementation of a proprietary IDmaChannel object, which the driver
uses in place of the default IDmaChannel object from the IPortWaveCyclic::New XxxDmaChannel call.
MIDI and DirectMusic Filters
10/23/2019 • 6 minutes to read • Edit Online

MIDI and DirectMusic filters represent devices that synthesize, output, or capture MIDI music data. Applications
typically access the capabilities of these devices either through the DirectMusic API or through the Microsoft
Windows Multimedia midiOut Xxx and midiIn Xxx functions. For more information about these interfaces, see the
Microsoft Windows SDK documentation.
A MIDI or DirectMusic synthesizer filter receives as input a MIDI stream consisting of time-stamped MIDI events.
The filter outputs either of the following:
A wave-formatted digital audio stream
Analog audio signals that can drive a set of speakers
A MIDI or DirectMusic output filter receives as input a MIDI stream consisting of time-stamped MIDI events. The
filter outputs raw MIDI messages to an external MIDI sound module.
A MIDI or DirectMusic capture filter takes as input a series of raw MIDI messages from a MIDI keyboard or other
external MIDI device. The filter outputs a MIDI stream consisting of time-stamped MIDI events.
A single MIDI or DirectMusic filter can perform a combination of the three functions--synthesis, output, and
capture--depending on the capabilities of the device that the filter represents. For example, a pure MPU-401 device
performs output and capture but not synthesis.
MIDI Filter
A MIDI filter is implemented as a port/miniport driver pair. A MIDI filter factory creates a MIDI filter as follows:
It instantiates a MIDI miniport driver object.
It instantiates a MIDI port driver object by calling PcNewPor t with GUID value CLSID_Por tMidi .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process. The port and miniport drivers communicate with
each other through their IPortMidi and IMiniportMidi interfaces.
To support MIDI output and synthesizer devices, the MIDI port driver contains a software sequencer that outputs
raw MIDI messages to the miniport driver with a timer resolution of one millisecond.
DirectMusic Filter
A DirectMusic filter provides a superset of the functionality of a MIDI filter. The superset includes these additional
capabilities:
DLS (downloadable sound) resources that contain waveform and articulation data describing MIDI
instruments. A KSPROPERTY_SYNTH_DLS_DOWNLOAD set-property request downloads a DLS
resource to a filter.
Channel groups for expanding the number of selectable instruments. The DMUS_KERNEL_EVENT
structure, which is used to package each time-stamped MIDI message in a MIDI stream, specifies which
channel group to use for that message.
64-bit time stamps with 100-nanosecond resolution in support of hardware MIDI sequencing. The
DMUS_KERNEL_EVENT structure specifies the high-resolution time stamp for a MIDI message.
With channel groups, the number of notes that can be played simultaneously is no longer limited to the 16
channels of the original MIDI specification. It is limited only by the number of voices available in the synthesizer.
A DirectMusic filter is implemented as a port/miniport driver pair. A DirectMusic filter factory creates a
DirectMusic filter as follows:
It instantiates a DMus (DirectMusic) miniport driver object.
It instantiates a DMus port driver object by calling PcNewPor t with GUID value CLSID_Por tDMus .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process. The port and miniport drivers communicate with
each other through their IPortDMus and IMiniportDMus interfaces.
To support DirectMusic synthesizer devices, the DMus port driver contains a low-resolution (one millisecond)
software sequencer that can output time-stamped MIDI events to the hardware sequencer's buffer in advance of
when they are scheduled to be played. To support DirectMusic output devices, the port driver's software sequencer
can also be configured to output raw MIDI messages at the times they are to be played.
Enumerating MIDI and DirectMusic Devices
When enumerating MIDI input or output devices through the Windows Multimedia midiInXxx or midiOutXxx
functions, an application can see only WDM devices whose miniport drivers expose MIDI pins. These are pins that
manage raw MIDI streams but lack support for advanced features such as DLS and channel groups. However,
when enumerating devices through DirectMusic, an application can see WDM devices with both MIDI pins and
DirectMusic pins. DirectMusic pins manage time-stamped MIDI streams and support DLS and channel groups.
When implementing a custom miniport driver, a hardware vendor typically writes either a MIDI miniport driver or
a DMus miniport driver, but not both. A MIDI miniport driver can expose only MIDI pins. However, a DMus
miniport driver can expose both MIDI and DirectMusic pins, which eliminates the need to write a separate MIDI
miniport driver. For an example of a MIDI pin on a DirectMusic filter, see the Dmusuart sample audio driver in the
Windows Driver Kit (WDK).
When specifying a data range for a MIDI or DirectMusic pin, a MIDI or DMus miniport driver specifies a major
format of type KSDATAFORMAT_TYPE_MUSIC and a subformat of type KSDATARANGE_SUBTYPE_MIDI for a MIDI
pin or KSDATARANGE_SUBTYPE_DIRECTMUSIC for a DirectMusic pin. Examples of data range descriptors for MIDI
and DirectMusic pins appear in MIDI Stream Data Range and DirectMusic Stream Data Range, respectively.
A MIDI pin instance on a MIDI filter exposes an IMiniportMidiStream interface. A MIDI or DirectMusic pin instance
on a DirectMusic filter exposes an IMXF interface.
In Windows Me/98, DirectMusic sometimes enumerates the same MPU-401 device twice. The reason is that some
hardware vendors expose their MPU-401 devices both as legacy, pre-WDM MIDI devices and as WDM devices. For
the legacy device, DirectMusic enumerates an MPU-401 device that represents the direct path from DMusic.dll to
Ihvaudio.dll. For the WDM device, DirectMusic enumerates the same MPU-401 device through a circuitous path
consisting of the following sequence of components:
1. DMusic.dll
2. DMusic16.dll
3. MMSystem.dll
4. WDMAud.drv
5. WDMAud.sys
6. The vendor's miniport driver
The MIDI synthesizer that shows up in the Windows multimedia control panel (Mmsys.cpl) will have the same
name as the WDM device.
System-Supplied Port and Miniport Drivers
Several system-supplied MIDI and DMus miniport drivers are built into the PortCls system driver:
The FMSynth miniport driver provides an interface to a MIDI device that implements OPL3-style FM
synthesis.
The UART miniport driver supports a MIDI device with an MPU-401 hardware interface, but this driver is
now obsolete (after Windows 98 Gold) and is supported only for existing adapter drivers. New adapter
driver code should instead use the DMusUART miniport driver (in Windows 98 SE and Windows Me, and in
Windows 2000 and later), which supersedes UART and implements a superset of its functionality.
Adapter drivers can access the system-supplied miniport drivers by calling the PcNewMinipor t function. The
FMSynth and DMusUART miniport drivers are also included as sample audio drivers in the Windows Driver Kit
(WDK). By modifying the source code in these samples, hardware vendors can extend the drivers to manage their
devices' proprietary features.
DMusUART is an example of a DMus miniport driver that exposes both MIDI and DirectMusic pins, but does not
support either DLS downloads or hardware sequencing. The miniport driver's DirectMusic rendering pin has a
synth node (KSNODETYPE_SYNTHESIZER ) that supports several KSPROPSETID_Synth properties. The miniport
driver includes itself in categories KSCATEGORY_RENDER and KSCATEGORY_CAPTURE, but not in
KSCATEGORY_SYNTHESIZER (because it does not contain an internal synthesizer). For details, see the DMusUART
sample audio driver in the WDK.
Note that in Windows XP and later, the MIDI and DMus port drivers use the same internal software
implementation. This means that the CLSID_Por tMidi and CLSID_Por tDMus GUIDs are equivalent when calling
PcNewPor t . Applications written for previous versions of Windows should see no change in behavior resulting
from consolidation of the MIDI and DMus port drivers.
Topology Filters
10/23/2019 • 7 minutes to read • Edit Online

A topology filter represents the portion of the circuitry on an audio adapter card that handles interactions among
the various wave and MIDI streams that are managed on the card. This circuitry does mixing of rendering streams
and multiplexing of capture streams.
A topology filter provides the bridge pins (see Audio Filter Graphs) that represent the audio adapter's physical
connections to external devices. These connections typically carry analog output signals that drive speakers and
analog input signals from microphones. A topology filter's bridge pins might also represent analog linein and
lineout jacks, and possibly even digital input and output connectors.
The term "topology filter" is in one sense a misnomer. In spite of its name, a topology filter is only one of several
types of audio filter that expose their internal topology or layout. Although the topology filter contains key
topological features, it does not necessarily contain the adapter's entire topology. Wave and MIDI filters have their
own topologies. For example, a minimal WaveCyclic or WavePci filter (see Wave Filters) might expose a topology
that consists of two pins and either a DAC (digital-to-analog converter) or ADC (analog-to-digital converter)
depending on whether the underlying device does audio rendering or capture.
A topology filter is implemented as a port/miniport pair. A topology filter factory creates a topology filter as
follows:
It instantiates a Topology miniport driver object.
It instantiates a Topology port driver object by calling PcNewPor t with GUID value CLSID_Por tTopology .
It calls the port driver's IPor t::Init method to bind the miniport driver to the port driver.
The code example in Subdevice Creation illustrates this process.
The Topology port and miniport drivers communicate with each other through their respective IPortTopology and
IMiniportTopology interfaces. These interfaces are relatively simple compared to those for wave and MIDI port and
miniport drivers because topology filters do not need to explicitly manage the streams that pass through their
pins. A topology filter's pins represent hardwired connections in the adapter hardware. The physical connection
underlying a topology filter pin typically carries an analog audio signal, but might carry a digital audio stream
instead, depending on the hardware implementation.
In contrast to the IMiniportWaveCyclic, IMiniportWavePci, IMiniportMidi, and IMiniportDMus interfaces, the
IMiniportTopology interface has no NewStream method.
Most of the functionality of a topology filter is provided by its property handlers. The topology filter exists
primarily to provide topology information to the SysAudio system driver and to applications that use the Microsoft
Windows Multimedia mixer API. The property handlers in the topology filter provide access to the various controls
(such as volume, equalization, and reverb) that audio adapters typically offer. Through property requests, the mixer
API can enumerate the control nodes in the adapter hardware, discover connections between nodes, and both
query and set the nodes' control parameters. The SndVol32 application (see SysTray and SndVol32) uses the mixer
API to discover the adapter's per-stream volume and mute controls.
When building a filter graph, SysAudio queries the topology filter for the
KSPROPERTY_PIN_PHYSICALCONNECTION properties at its pins to determine which wave, MIDI, or
DirectMusic filter pin is connected to which topology filter pin.
Unlike a wave, MIDI, or DirectMusic filter, a topology filter does not instantiate pins. Thus, no pin objects are
available to handle queries for a topology filter's pin properties. The topology filter itself handles all queries
regarding the physical connections at its pins. For more information, see KSPROPSETID_Pin.
Similar to other types of audio filters, a topology filter uses an array of PCCONNECTION_DESCRIPTOR
structures to describe its internal topology. The miniport driver exposes this array in the PCFILTER_DESCRIPTOR
structure that it outputs from the IMinipor t::GetDescription method. The array specifies the topology as a list of
connections between the topology filter's nodes and pins (see Nodes and Connections). The WDMAud system
driver translates these connections and nodes into the mixer lines and controls that the mixer API exposes to
applications. As discussed in Audio Filters, an input pin on a KS filter maps to a SRC mixer line, and an output pin
on a filter maps to a DST mixer line.
A typical audio adapter can play wave and MIDI files through a speaker, and can capture audio signals from a
microphone and a MIDI synthesizer. The code example below contains the PCCONNECTION_DESCRIPTOR array for
a topology filter that exposes these capabilities:

// topology pins
enum
{
KSPIN_TOPO_WAVEOUT_SRC = 0,
KSPIN_TOPO_SYNTHOUT_SRC,
KSPIN_TOPO_SYNTHIN_SRC,
KSPIN_TOPO_MIC_SRC,
KSPIN_TOPO_LINEOUT_DST,
KSPIN_TOPO_WAVEIN_DST
};

// topology nodes
enum
{
KSNODE_TOPO_WAVEOUT_VOLUME = 0,
KSNODE_TOPO_WAVEOUT_MUTE,
KSNODE_TOPO_SYNTHOUT_VOLUME,
KSNODE_TOPO_SYNTHOUT_MUTE,
KSNODE_TOPO_MIC_VOLUME,
KSNODE_TOPO_SYNTHIN_VOLUME,
KSNODE_TOPO_LINEOUT_MIX,
KSNODE_TOPO_LINEOUT_VOLUME,
KSNODE_TOPO_WAVEIN_MUX
};

static PCCONNECTION_DESCRIPTOR MiniportConnections[] =


{
// FromNode---------------------FromPin------------------ToNode-----------------------ToPin

{ PCFILTER_NODE, KSPIN_TOPO_WAVEOUT_SRC, KSNODE_TOPO_WAVEOUT_VOLUME, 1 },


{ KSNODE_TOPO_WAVEOUT_VOLUME, 0, KSNODE_TOPO_WAVEOUT_MUTE, 1 },
{ KSNODE_TOPO_WAVEOUT_MUTE, 0, KSNODE_TOPO_LINEOUT_MIX, 1 },

{ PCFILTER_NODE, KSPIN_TOPO_SYNTHOUT_SRC, KSNODE_TOPO_SYNTHOUT_VOLUME, 1 },


{ KSNODE_TOPO_SYNTHOUT_VOLUME, 0, KSNODE_TOPO_SYNTHOUT_MUTE, 1 },
{ KSNODE_TOPO_SYNTHOUT_MUTE, 0, KSNODE_TOPO_LINEOUT_MIX, 2 },

{ PCFILTER_NODE, KSPIN_TOPO_SYNTHIN_SRC, KSNODE_TOPO_SYNTHIN_VOLUME, 1 },


{ KSNODE_TOPO_SYNTHIN_VOLUME, 0, KSNODE_TOPO_WAVEIN_MUX, 1 },

{ PCFILTER_NODE, KSPIN_TOPO_MIC_SRC, KSNODE_TOPO_MIC_VOLUME, 1 },


{ KSNODE_TOPO_MIC_VOLUME, 0, KSNODE_TOPO_WAVEIN_MUX, 2 },

{ KSNODE_TOPO_LINEOUT_MIX, 0, KSNODE_TOPO_LINEOUT_VOLUME, 1 },
{ KSNODE_TOPO_LINEOUT_VOLUME, 0, PCFILTER_NODE, KSPIN_TOPO_LINEOUT_DST },

{ KSNODE_TOPO_WAVEIN_MUX, 0, PCFILTER_NODE, KSPIN_TOPO_WAVEIN_DST }


};

Constant PCFILTER_NODE in the preceding code example is the null node ID and is defined in header file
Portcls.h. For a description of how this constant is used to distinguish external pins on a filter from logical pins on
a node, see PCCONNECTION_DESCRIPTOR .
Each pin name in the preceding code example ends with either "SRC" or "DST" depending on whether the mixer
API maps the pin to a source or destination mixer line. To avoid confusion, remember that source and destination
mixer lines map to sink (input) and source (output) KS filter pins, respectively. For more information, see Audio
Filters.
The PCCONNECTION_DESCRIPTOR array in the preceding code example describes the topology filter in the
following figure.

The topology filter in the figure has four input (sink) pins on the left and two output (source) pins on the right. The
data paths that connect the top two input pins and top output pin mix the two analog signals that have been
rendered from the wave and MIDI streams that are being played back. The data paths that connect the bottom two
input pins and bottom output pin multiplex the captured analog signals that are being recorded.
The four input pins operate as follows:
The KSPIN_TOPO_WAVEOUT_SRC pin is physically connected to the output pin of a wave filter, which
renders a wave stream from a source such as a .wav file to produce the analog signal at the pin.
The KSPIN_TOPO_SYNTHOUT_SRC pin is physically connected to the output pin of a synth filter, which
might render, for example, a MIDI stream from a source such as a .mid file to produce the analog signal at
the pin.
The KSPIN_TOPO_SYNTHIN_SRC pin is physically connected to a synthesizer that generates an analog
signal. (Note that a more practical hardware design might take a MIDI input stream from an MPU-401 MIDI
interface and convert it directly to wave format, bypassing the topology filter altogether.)
The KSPIN_TOPO_MIC_SRC pin is physically connected to an input jack that takes an analog signal from a
microphone.
The two output pins operate as follows:
The KSPIN_TOPO_LINEOUT_DST pin is physically connected to an analog lineout jack that typically drives a
set of speakers.
The KSPIN_TOPO_WAVEIN_DST pin is physically connected to the input pin of a wave filter, which converts
the analog signal to a wave stream and writes it to a destination such as a .wav file.
The volume and mute nodes (see KSNODETYPE_VOLUME and KSNODETYPE_MUTE ) are used to control the
volume levels of the various streams. The SUM node (see KSNODETYPE_SUM ) mixes the audio streams from the
wave and MIDI inputs. The MUX node (see KSNODETYPE_MUX ) selects between the two input streams.
The figure uses a dashed arrow to indicate a connection between two nodes or between a pin and a node. The
arrow points in the direction of data flow. The diagram shows a total of 13 connections, each of which corresponds
to one of the 13 elements in the PCCONNECTION_DESCRIPTOR array in the preceding code example.
In addition to the topology filter, the adapter driver creates other filters--wave, FM synth, wave table, and so on--
that connect to the pins on the topology filter.
For example, the wave filter that is physically connected to the topology filter's KSPIN_TOPO_WAVEOUT_SRC pin
contains a DAC (represented by a KSNODETYPE_DAC node) that converts PCM data to the analog signal that it
outputs to the topology filter's pin. The FM-synth or a wavetable synth filter that is physically connected to the
topology filter's KSPIN_TOPO_SYNTHOUT_SRC pin similarly converts MIDI data to an analog signal that it outputs
to the topology filter's pin. The topology filter mixes the analog signals from these two pins and outputs the mixed
signal to the speakers.
The topology filter's physical connections to other filters that represent other hardware devices on the same
adapter card need to be distinguished from other types of connections to filters. For example, certain pins on
wave, MIDI, and DirectMusic filters can be connected or disconnected under software control.
During device startup, the adapter driver registers the topology filter's physical connections by calling
PcRegisterPhysicalConnection once per connection. The port driver needs this information in order to respond
to KSPROPERTY_PIN_PHYSICALCONNECTION get-property requests.
Audio Endpoints, Properties and Events
6/25/2019 • 2 minutes to read • Edit Online

The PortCls system driver supports a subset of the intrinsic operations that are described in KS Properties, Events,
and Methods.
The port drivers in Portcls.sys support properties and events by providing handlers for some property and event
requests and by forwarding other requests to the miniport drivers' handlers.
The current implementations of the WaveCyclic, WavePci, MIDI, and DMus port drivers provide the following:
Support for properties on a filter and its pins and nodes
Support for events on pins and nodes but not for events on the filter
A client can specify the handle to a filter or pin instance as the target for a property or event request. A request for
a node property or event specifies a node ID in addition to a filter or pin handle. For more information, see Filter,
Pin, and Node Properties.
The Topology port driver provides the following:
Support for properties on a filter and its nodes
Support for events on nodes
The pins on a topology filter represent hardwired connections that exist permanently and thus cannot be
instantiated or deleted.
None of the port drivers provide support for methods on either the filter or its pins and nodes. The port drivers
never handle method requests, and they never forward these requests to miniport drivers for handling.
Audio adapter drivers support some or all of the following standard property sets:
KSPROPSETID_AC3
KSPROPSETID_Acoustic_Echo_Cancel
KSPROPSETID_Audio
KSPROPSETID_DirectSound3DBuffer
KSPROPSETID_DirectSound3DListener
KSPROPSETID_DrmAudioStream
KSPROPSETID_General
KSPROPSETID_Hrtf3d
KSPROPSETID_Jack
KSPROPSETID_Pin
KSPROPSETID_Synth
KSPROPSETID_Synth_Dls
KSPROPSETID_TopologyNode
All audio drivers support the KSPROPSETID_Audio property set.
Some audio adapter drivers support the following event set:
KSEVENTSETID_AudioControlChange
In addition, audio adapter drivers are free to provide property handlers for other property sets that are defined in
header file Ksmedia.h. Drivers can also define and support their own custom property and event sets, but only an
application that knows about a custom property or event will be able to use it.
This section discusses audio-specific properties and events. It contains the following topics:
Audio Property Requests
Filter, Pin, and Node Properties
Audio Property Handlers
Basic Support Queries for Audio Properties
Audio Endpoint Builder Algorithm
Dynamic Subdevice Registration and Unregistration
Exposing Multichannel Nodes
Pin Category Property
Friendly Names for Audio Endpoint Devices
Audio Position Property
Pin Data-Range and Intersection Properties
Jack Description Property
Microphone Array Geometry Property
Hardware Events
Audio Property Requests
10/23/2019 • 2 minutes to read • Edit Online

Clients of a Microsoft Windows Driver Model (WDM) audio driver can send requests for KS properties to the KS
filters and pins that the driver has instantiated. For example, a user-mode client can send a KS property request by
calling the DeviceIoControl function (see the Microsoft Windows SDK documentation) with an I/O-control code
of IOCTL_KS_PROPERTY. This function sends an IRP containing the property request to the specified filter or pin
object.
Audio drivers support get, set, and basic-support requests on properties (KSPROPERTY_TYPE_GET,
KSPROPERTY_TYPE_SET, and KSPROPERTY_TYPE_BASICSUPPORT). For more information, see Audio Drivers
Property Sets.
A client can send requests for three kinds of properties: filter properties, pin properties, and node properties. For
more information, see Filter, Pin, and Node Properties.
When sending a filter-property request to a filter object, the client specifies the target filter by its instance handle
(see Filter Factories). Similarly, when sending a pin-property request to a pin object, the target pin is specified by its
instance handle (see Pin Factories). Either type of request contains a KSPROPERTY structure that specifies the
following:
A GUID that identifies the property set
An index that identifies a property item within the specified property set
Flags that indicate the type of property request (get, set, or basic-support)
Related properties are gathered together to form a property set. A particular property is identified by its property
set and by an index that specifies its position within that set.
A node-property request contains a KSNODEPROPERTY structure, which combines a KSPROPERTY structure and
a node ID. Depending on the node property, the target for the property request is either a filter instance or a pin
instance.
If a filter can create more than one instance of a particular node type, the target for the request is specified by a pin
handle. The handle identifies the pin instance at the beginning or end of the data path on which the node instance
resides. In the case of a filter containing a SUM or MUX node (see KSNODETYPE_SUM and
KSNODETYPE_MUX ), the following rules apply:
If the property belongs to a node that lies downstream from a sink (input) pin and upstream from the SUM
or MUX node, the property request is sent to the sink pin.
If the property belongs to a node that lies downstream from a SUM or MUX node and upstream from a
source (output) pin, the property request is sent to the source pin. (Also, a property request for a SUM or
MUX node is sent to the source pin.)
With these conventions, a particular node on a particular data path can be identified uniquely.
For information about using the mixer API to traverse the nodes in a data path, see Kernel Streaming Topology to
Audio Mixer API Translation.
Filter, Pin, and Node Properties
10/23/2019 • 9 minutes to read • Edit Online

Microsoft Windows Driver Model (WDM) audio drivers represent an audio device as a KS filter, and they represent
a hardware buffer on the device as a pin on the filter. When a client sends a property request to one of these filter
or pin objects, the port driver receives the request and routes the request to the appropriate property handler in
the port driver or miniport driver.
Audio devices support three kinds of properties:
Filter proper ties
A filter property is a property of the filter as a whole rather than a property of a particular pin or node
within the filter. Requests for filter properties specify filter handles, but they do not specify node IDs.
Pin proper ties
A pin property is a property of a particular pin instance on the filter. Requests for these properties specify
pin handles, but they do not specify node IDs.
Node proper ties
A node property is a property of a topology node within the filter. A request for a node property specifies a
filter handle or pin handle, plus a node ID.
Whether a node-property request specifies a filter or pin handle depends on whether the node is unique to the
filter. For more information, see the following Node Properties section.
The following figure shows these three kinds of property request: a pin-property request sent to a pin instance, a
node-property request sent to a node (on a filter or pin instance), and a filter-property request sent to a filter
instance.

Typically, the port driver handles most requests for filter and pin properties, and the miniport driver handles
requests for node properties.
The port driver supplies its own built-in handlers for the filter and pin properties that are used by the SysAudio
system driver (see KSPROPSETID_Sysaudio and KSPROPSETID_Sysaudio_Pin) and WDMAud system driver. A
miniport driver does not need to implement handlers for properties that the port driver handles. A typical
miniport driver provides few, if any, handlers for filter and pin properties. The miniport driver supplies the
handlers for node properties that represent hardware-dependent features of the audio device. The port drivers
supply no built-in handling of node properties, with the exception of KSPROPERTY_TOPOLOGY_NAME .
When both the port driver and miniport driver supply handlers for the same property, the port driver uses its own
handler and ignores the miniport driver's handler.
Filter Descriptors
The port driver obtains pointers to the miniport driver's property handlers by calling the
IMinipor t::GetDescription method. Through this method, the port driver retrieves a pointer to the miniport
driver's filter descriptor, which is a structure of type PCFILTER_DESCRIPTOR . This structure specifies the miniport
driver's property handlers for filter, pin, and node properties:
The PCFILTER_DESCRIPTOR structure's AutomationTable member points to the automation table for the
filter. This table specifies the miniport driver's property handlers for filter properties.
The PCFILTER_DESCRIPTOR structure's Pins member contains the automation tables for the pins. Each table
specifies the property handlers for the pin properties of a particular pin type.
The PCFILTER_DESCRIPTOR structure's Nodes member contains the automation tables for the topology
nodes inside the filter. Each table specifies the property handlers for the node properties of a particular
node type.
Filter Properties
The port driver accesses the miniport driver's filter-property handlers through the AutomationTable member of
PCFILTER_DESCRIPTOR. Typically, this automation table contains few handlers because the port driver supplies its
own built-in handlers for all the filter properties that SysAudio and WDMAud use to query and configure audio
devices.
However, the miniport driver can supply handlers for filter properties such as
KSPROPERTY_GENERAL_COMPONENTID that provide hardware-dependent information that is not available
to the port driver. Two of the sample audio drivers in the Microsoft Windows Driver Kit (WDK) handle the
KSPROPERTY_GENERAL_COMPONENTID property. For more information, see the miniport driver
implementations in the Msvad and Sb16 samples.
All the port drivers in Portcls.sys provide handling for the KSPROPSETID_Pin and KSPROPSETID_Topology
property sets. All the properties in these sets are filter properties, with the exception of
KSPROPERTY_TOPOLOGY_NAME , which is a node property (that uses a filter handle, not a pin handle, to
specify the target for the request). The port drivers support the following subset of the KSPROPSETID_Pin
properties:
KSPROPERTY_PIN_CATEGORY
KSPROPERTY_PIN_CINSTANCES
KSPROPERTY_PIN_COMMUNICATION
KSPROPERTY_PIN_CONSTRAINEDDATARANGES
KSPROPERTY_PIN_CTYPES
KSPROPERTY_PIN_DATAFLOW
KSPROPERTY_PIN_DATAINTERSECTION
KSPROPERTY_PIN_DATARANGES
KSPROPERTY_PIN_GLOBALCINSTANCES
KSPROPERTY_PIN_INTERFACES
KSPROPERTY_PIN_MEDIUMS
KSPROPERTY_PIN_NAME
KSPROPERTY_PIN_NECESSARYINSTANCES
KSPROPERTY_PIN_PHYSICALCONNECTION
KSPROPERTY_PIN_PROPOSEDATAFORMAT
KSPROPERTY_PIN_PROPOSEDATAFORMAT2
These properties provide information about the pin factories belonging to a filter. Typically, clients query the filter
for these properties before creating pin instances. The port drivers support all four of the KSPROPSETID_Topology
properties, which provide information about the filter's internal topology.
In addition, the DMus port driver provides a handler for the KSPROPERTY_SYNTH_MASTERCLOCK property,
which is a get-only property of a DirectMusic filter. KSPROPERTY_SYNTH_MASTERCLOCK is a member of the
KSPROPSETID_SynthClock property set.
Pin Properties
The port driver accesses the miniport driver's pin-property handlers through the Pins member of
PCFILTER_DESCRIPTOR. This member points to an array of pin descriptors, and each descriptor points to the
automation table for a pin type (identified by a pin ID, which is simply the array index).
Typically, these automation tables contain few entries because the port driver supplies its own handlers for all the
pin properties that SysAudio and WDMAud use. A miniport driver has the option of supplying handlers for one or
more pin properties that the port driver does not handle, but only clients that know about these properties can
send property requests for them.
With the exception of the Topology port driver, all the port drivers in Portcls.sys supply built-in handlers for the
following pin properties:
KSPROPERTY_CONNECTION_STATE
KSPROPERTY_CONNECTION_DATAFORMAT
KSPROPERTY_CONNECTION_ALLOCATORFRAMING
KSPROPERTY_STREAM_ALLOCATOR
KSPROPERTY_STREAM_MASTERCLOCK
KSPROPERTY_AUDIO_POSITION
KSPROPERTY_DRMAUDIOSTREAM_CONTENTID
Some of the properties in this list require hardware-dependent information from the miniport driver. When the
port driver receives an IRP containing a request for one of these properties, it does not pass the IRP to the
miniport driver. Instead, the port driver handles the request itself, but its handler obtains the information it needs
by calling an entry point in the miniport driver. For example, the port driver supplies its own property handler for
KSPROPERTY_AUDIO_POSITION requests. This handler simply calls the miniport driver stream's GetPosition
method (for example, IMinipor tWavePciStream::GetPosition ) to get the current position.
Node Properties
The port driver accesses the miniport driver's node-property handlers through the Nodes member of
PCFILTER_DESCRIPTOR. This member points to an array of node descriptors, and each descriptor points to the
automation table for a node type (identified by a node ID, which is simply the array index). Typically, all or most of
the property handlers belonging to a miniport driver reside in the Nodes array. An audio driver represents the
hardware controls in an audio device as topology nodes, and it uses the property mechanism to provide clients
with access to the hardware-dependent control settings.
As described previously, a client sends a filter-property request to a filter handle, and a pin-property request to a
pin handle. Unlike a filter or pin instance, a node is not a kernel object and does not have a handle. A client sends a
node-property request to either a pin handle or a filter handle, but the request also specifies a node ID to indicate
that the request is for a node property rather than a pin or filter property.
The following are general rules for determining whether a node property should use a filter handle or pin handle:
If a filter contains several instances of a particular pin type, and each pin of that type contains a node with a
particular node ID, then each pin instance contains an instance of the node. In this case, a node-property
request must specify a pin handle (rather than just a filter handle) to distinguish among several instances of
the same node type. The combination of pin handle and node ID unambiguously identifies a particular node
instance as the target for the request.
If a filter contains only one instance of a particular node, a node property request specifies a filter handle.
The combination of filter handle and node ID is sufficient to unambiguously identify the node that is the
target for the request.
Before implementing a handler for a particular node property, however, the driver writer should refer to Audio
Drivers Property Sets to check whether the target for the property should be specified as a filter handle or pin
handle.
The port drivers in Portcls.sys currently do not provide built-in handling of node properties, with the exception of
KSPROPERTY_TOPOLOGY_NAME.
Overspecified and Underspecified Property Requests
Drivers should be prepared to deal with property requests from clients that do not follow the preceding rules.
Requests can be either overspecified or underspecified:
Overspecified requests
If a property request requires only a filter handle, but the client sends the request to a pin handle instead,
the target for the request is overspecified. However, drivers typically treat the request as valid; that is, they
treat the request as though it had been sent to the filter containing the pin.
Underspecified requests
If a property request requires a pin handle, but a client sends the request to a filter handle instead, the
target for the request is underspecified. For example, if a filter contains several pin instances with the same
node type, and a client sends a request for a property of that node type to a filter handle rather than a pin
handle, the driver has no way to determine which node instance should receive the request. In this case, the
behavior depends on the driver. Instead of automatically failing all underspecified requests, some drivers
treat an underspecified set-property request as valid. In this case, the interpretation is that the request sets
the default value for the specified node ID. When a pin factory creates a new node instance, the property
belonging to the new node is initialized to the default value. A request that changes the default value has no
effect on node instances created before the request. In addition, drivers uniformly fail underspecified get-
property requests because the handler has no way to determine which node instance to query for the
property.
Exceptions to the Rules
For historical reasons, a few audio properties have behavioral quirks that violate these general rules. The following
are examples:
As described in Applying Speaker-Configuration Settings, a client can change an audio device's speaker
configuration by setting the KSPROPERTY_AUDIO_CHANNEL_CONFIG property of a 3-D node
(KSNODETYPE_3D_EFFECTS ). The speaker-configuration setting is global because it changes the speaker
configuration for all streams that are part of the mix that the device plays through the speakers. According
to the general rule, a node-property request that affects the filter as a whole should specify a filter handle
(plus a node ID). However, this particular property requires a pin handle instead of a filter handle. The pin
handle designates the pin instance containing the 3-D node that is the target for the request.
KSPROPERTY_SYNTH_VOLUME and KSPROPERTY_SYNTH_MASTERCLOCK are properties of a synth
node (KSNODETYPE_SYNTHESIZER ). Although both are node properties, requests for these properties
do not include node IDs. (Note that the property descriptor for the request is a structure of type
KSPROPERTY , not KSNODEPROPERTY .) This behavior violates the general rule that a node property
requires a node ID. Despite this discrepancy, a miniport driver that supports either property should supply
the property handler through the Nodes member of PCFILTER_DESCRIPTOR (instead of the Pins member).
Audio Property Handlers
10/23/2019 • 5 minutes to read • Edit Online

A miniport driver stores information about each property that it supports in a PCPROPERTY_ITEM structure. This
structure contains the following information about the property:
The property-set GUID and property ID (or index)
A function pointer to the handler routine for the property
Flags specifying the property operations that the handler supports
The miniport driver provides an automation table (specified by a PCAUTOMATION_TABLE structure) for the filter.
The driver provides additional automation tables for the filter's pin types and node types - each pin or node type
has its own table. Each automation table contains a (possibly empty) array of PCPROPERTY_ITEM structures, and
each of these structures describes one property of the filter, pin, or node. When a client sends a property request to
a filter, pin, or node, the port driver routes the request through the automation table to the appropriate property
handler.
A miniport driver can specify a unique property handler routine for each property. However, if a driver handles
several similar properties, these can sometimes be consolidated into a single handler routine for convenience.
Whether to provide a unique handler for each property or to consolidate several properties into a single handler is
an implementation decision to be made by the driver writer and should be transparent to clients that submit
property requests.
A user-mode client can send a get, set, or basic-support property request by calling the Microsoft Win32 function
DeviceIoControl with the dwIoControlCode call parameter set to IOCTL_KS_PROPERTY. The operating system
converts this call to an IRP , which it dispatches to the class driver. For more information, see KS Properties.
When a client sends a KS property request (that is, an IOCTL_KS_PROPERTY I/O-control IRP) to a filter handle or pin
handle, the KS system driver (Ks.sys) delivers the request to the port driver for the filter object or pin object. If the
miniport driver provides a handler for the property, the port driver forwards the request to the handler. Before
forwarding the request, the port driver converts the information from the property request into the format
specified by the PCPROPERTY_REQUEST structure. The port driver passes this structure to the miniport driver's
handler.
The MajorTarget member of PCPROPERTY_REQUEST points to the primary miniport driver interface for the audio
device. For example, for a WavePci device, this is a pointer to the miniport driver object's IMiniportWavePci
interface.
In the case of a KS property request sent to a filter handle, the MinorTarget member of PCPROPERTY_REQUEST is
NULL . In the case of a request sent to a pin handle, MinorTarget points to the stream interface for the pin. For
example, for a WavePci device, this is a pointer to the stream object's IMiniportWavePciStream interface.
The Instance and Value members of PCPROPERTY_REQUEST point to the input and output buffers, respectively, of
the KS property request. (The buffers are specified by the lpInBuffer and lpOutBuffer parameters of the
DeviceIoControl function.) These buffers contain the property descriptor (instance data) and property value
(operation data), respectively, as described in Audio Drivers Property Sets. The Value member points to the start of
the output buffer, but the Instance pointer is offset from the start of the input buffer.
The input buffer begins with either a KSPROPERTY or KSNODEPROPERTY structure. The port driver copies the
information from this structure into the PCPROPERTY_REQUEST structure's Node , Proper tyItem , and Verb
members. If any data follows the KSPROPERTY or KSNODEPROPERTY structure in the buffer, the port driver loads
the Instance member with a pointer to this data. Otherwise, it sets Instance to NULL .
If the input buffer begins with a KSPROPERTY structure, which contains no node information, the port driver sets
the PCPROPERTY_REQUEST structure's Node member to ULONG(-1). In this case, the port driver calls the
appropriate handler from the miniport driver's automation table for the filter or pin, depending on whether the
target for the property request is specified by a filter handle or pin handle. (If the table does not specify a handler
for the property, the port driver handles the request instead.)
If the input buffer begins with a KSNODEPROPERTY structure, the port driver copies the node ID from this structure
into the PCPROPERTY_REQUEST structure's Node member and calls the appropriate handler from the miniport
driver's automation table for the node. (Again, if the table does not specify a handler for the property, the port
driver handles the request instead.)
The port driver checks the KSPROPERTY_TYPE_TOPOLOGY bit in the operation flags of the property request to
determine which of the two structures, KSPROPERTY or KSNODEPROPERTY, resides at the beginning of the input
buffer:
If this bit is set, the request is for a node property, and the input buffer begins with a KSNODEPROPERTY
structure.
Otherwise, the input buffer begins with a KSPROPERTY structure.
For more information about KSPROPERTY_TYPE_TOPOLOGY, see KSPROPERTY .
The PCPROPERTY_REQUEST structure's InstanceSize and ValueSize members specify the sizes of the buffers
pointed to by the Instance and Value members. ValueSize is equal to the size of the output buffer of the
property request, but InstanceSize is the size of the data that follows the KSPROPERTY or KSNODEPROPERTY
structure in the input buffer. That is, InstanceSize is the size of the input buffer minus the size of the KSPROPERTY
or KSNODEPROPERTY structure. If no additional data follows this structure, the port driver sets InstanceSize to
zero (and Instance to NULL ).
For example, if the client specifies a KSNODEPROPERTY_AUDIO_CHANNEL structure as the instance data in the
input buffer, the port driver passes the handler a PCPROPERTY_REQUEST structure whose Instance member
points to the KSNODEPROPERTY_AUDIO_CHANNEL structure's Channel member, and whose InstanceSize
member contains the value
sizeof (KSNODEPROPERTY_AUDIO_CHANNEL) - sizeof (KSNODEPROPERTY)
Before submitting a get-property request to retrieve a property value, the client should allocate an output buffer
into which the miniport driver's property handler can write the property value. For some properties, the size of the
output buffer is device-dependent, and the client must query the property handler for the required buffer size. In
these cases, the client submits an initial property request with an output buffer pointer of nullptr and an output
buffer length of zero. The handler responds by returning the required buffer size along with the status code
STATUS_BUFFER_OVERFLOW. The client then retrieves the property value by allocating an output buffer of the
specified size and sending this buffer in a second get-property request.
If the specified buffer size is too small to receive any of the requested information, the method returns
STATUS_BUFFER_TOO_SMALL.
In some cases, PortCls port drivers return STATUS_BUFFER_TOO_SMALL instead of STATUS_BUFFER_OVERFLOW in
response to a property request with a non-zero output buffer address and size. Required buffer size is not returned
in such cases.
For more information, see Using NTSTATUS Values and these blog posts:
How to return the number of bytes required for a subsequent operation
STATUS_BUFFER_OVERFLOW really should be named STATUS_BUFFER_OVERFLOW_PREVENTED
Basic Support Queries for Audio Properties
10/23/2019 • 3 minutes to read • Edit Online

When specifying the data for a set-property request to a filter, pin, or node, the client frequently needs to know the
valid data ranges for the value or values that it specifies for the property. Ranges can vary from device to device,
and possibly even from node to node within the same device.
Some properties are defined to allow set-property requests to specify values that are out-of-range, but miniport
drivers silently clamp those values to the supported range (for example, see
KSPROPERTY_AUDIO_VOLUMELEVEL ). A subsequent get request for the same property retrieves the driver's
actual settings for the value or values, which might be clamped versions of the values that the client specified in the
set request.
However, a client might need to know the range for a property value instead of simply relying on the miniport
driver to automatically clamp an out-of-range value. For example, a windowed application that presents a volume-
control slider for an audio device might need to know the device's volume range in order to map that range to the
full length of the slider.
The driver's handler routine for a particular property should be able to provide range information in response to a
basic-support property request (KSPROPERTY_TYPE_BASICSUPPORT). When sending a basic-support property
request to a driver, a client provides a value buffer into which the property handler writes the basic-support
information, which consists of a KSPROPERTY_DESCRIPTION structure that might be followed by property-
specific data. This data typically consists of specifications for one or more parameter ranges, depending on the
property.
In general, the client does not know in advance how large this value buffer should be and must send one or two
preliminary requests to the property handler to determine the value size. The format for these preliminary
requests is well defined. Clients expect drivers to follow these conventions when handling a basic-support request:
If the request specifies the value size as sizeof (ULONG) then the property handler should write the value of
the AccessFlags member of the KSPROPERTY_DESCRIPTION structure into the ULONG-sized value buffer.
The handler sets the KSPROPERTY_TYPE_BASICSUPPORT flag bit if it provides further support for basic-
support property requests.
If the request specifies the value size as sizeof (KSPROPERTY_DESCRIPTION), the handler should write a
KSPROPERTY_DESCRIPTION structure into the data buffer. The handler sets the DescriptionSize field of the
structure equal to that structure's size plus the size of all of the additional, property-specific information that
the handler has available to load into the data buffer following the structure. This is the size of the value
buffer that the client needs to allocate to contain the property's basic-support information.
If the request specifies a value size that is large enough to contain both the KSPROPERTY_DESCRIPTION
structure and the property-specific information, the handler should write the KSPROPERTY_DESCRIPTION
structure into the start of the buffer, and it should write the property-specific information into the portion of
the data buffer that follows the end of the KSPROPERTY_DESCRIPTION structure. When writing the
KSPROPERTY_DESCRIPTION structure, the handler should set the DescriptionSize field to that structure's
size plus the size of the property-specific information that follows the structure.
If the request specifies a value size that does not match one of these three cases, the property handler rejects the
request and returns status code STATUS_BUFFER_TOO_SMALL.
The property-specific information that the handler writes into the value buffer might include data ranges for
property values. The MembersSize member of KSPROPERTY_MEMBERSHEADER indicates whether data ranges
are included:
MembersSize is zero if no ranges are needed. This is the case, for example, if property values are of type
BOOL.
MembersSize is nonzero if the KSPROPERTY_MEMBERSHEADER structure is followed by range descriptors
for one or more property values.
For a property value of type BOOL, no range descriptor is needed because the range is implicitly limited to the
values TRUE and FALSE . However, range descriptors are needed to specify the ranges of property values with
integer types.
For example, the basic-support request for a KSPROPERTY_AUDIO_VOLUMELEVEL property on a volume node
(KSNODETYPE_VOLUME ) retrieves the minimum and maximum volume settings for that node. In this case, the
client needs to allocate a value buffer that is large enough to contain the following structures:
KSPROPERTY_DESCRIPTION
KSPROPERTY_MEMBERSLIST
KSPROPERTY_STEPPING_LONG
The three structures are packed into adjacent locations in the buffer in the order shown in the preceding list. When
handling the request, the miniport driver writes the minimum and maximum volume levels into the Bounds
member of the KSPROPERTY_STEPPING_LONG structure.
For an example of a basic-support request with an array of range descriptors, see the figure in Exposing
Multichannel Nodes. For more information about basic-support property requests, see KS Properties. For code
examples, refer to the property-handler implementations in the sample audio drivers in the Microsoft Windows
Driver Kit (WDK).
Audio Endpoint Builder Algorithm
10/23/2019 • 6 minutes to read • Edit Online

In Windows Vista and later versions of Windows, the AudioEndpointBuilder is a system service that enumerates,
initializes, and activates the audio endpoints in a system. This topic provides an overview of the algorithm that is
used by the AudioEndpointBuilder service.
The AudioEndpointBuilder service uses an algorithm to discover and enumerate endpoints. The algorithm was
designed to simplify the system access to multiplexed (MUXed) capture devices and to help work with topologies
that involve multiple host pins and multiple bridge pins, or both.
In Windows XP, the audio model used the term audio device to refer to a conceptual device in the Plug and Play
(PnP) tree. In Windows Vista and later versions of Windows, the concept of an audio device has been redesigned
to better represent the device that the user physically interacts with.
With two new APIs in Windows Vista, MMDevice API and WASAPI, you can access and manipulate these new audio
devices. The MMDevice API refers to the new audio devices as endpoints.
The AudioEndpointBuilder service monitors the KSCATEGORY_AUDIO class for device interface arrivals and
removals. When an audio device driver registers a new instance of the KSCATEGORY_AUDIO device interface class,
the AudioEndpointBuilder service detects the device interface notification and uses an algorithm to examine the
topology of the audio devices in the system and take appropriate action.
The following list summarizes how the algorithm that is used by AudioEndpointBuilder works:
1. Looks for any unconnected bridge pins.
2. Creates an endpoint for any unconnected bridge pins. For example, when the AudioEndpointBuilder finds
an unconnected bridge pin with a pin-category GUID of KSNODETYPE_SPEAKER, it creates a speaker
endpoint for this bridge pin. For more information about KSNODETYPE_SPEAKER and other pin-category
GUIDS, see Ksmedia.h in WinDDK\<build number>\inc\api.
3. Sets the default properties for the endpoint. For example, AudioEndpointBuilder sets the name, icon, and
the form factor.
4. Determines whether there is a path from the endpoint to a host pin that supports pulse code modulation
(PCM), audio codec-3 (AC3), or Windows media video (WMV). A host pin is a KSPIN structure with its
Communication member set to KSPIN_COMMUNICATION_SINK or KSPIN_COMMUNICATION_BOTH. For
more information about the KSPIN structure, see KSPIN .
5. Populates the endpoint PropertyStore with property information from the registry keys of the audio device
interface.
6. Sets the state of the endpoint. The state of the endpoint can be one of the following three values:
Active. This indicates that a path exists as described in Step 4.
Unplugged. If the audio device supports jack detection, this state indicates that a path exists for the
endpoint, and the jack is unplugged from the physical connector on the audio adapter.
Not present. This state indicates that a path was not found in Step 4, and jack detection is not
supported by this endpoint.
7. Sets this endpoint as the default endpoint, if that is what is specified in the associated INF file.
After the endpoints have been enumerated, clients of the audio system can manipulate them directly by using the
new Windows Vista APIs (as indicated previously) or indirectly by using the more familiar APIs such as Wave,
DShow or DirectSound. New API methods have been provided so that audio clients can start with the MMDevice
ID of an endpoint and access the Wave or DirectSound ID for the same endpoint.
When you use endpoints, you can take advantage of the following:
The same globally unique ID (GUID) is available regardless of how often you restart your machine. Having
this persistent GUID is more reliable than saving a waveOut ID or a friendly name for the endpoint.
The same PropertyStore is available regardless of how often you restart your machine. The audio device-
related metadata is saved in the endpoint PropertyStore.
Multiplexed (MUX) and de-multiplexed (DEMUX) pins are managed automatically and enumerated by the
AudioEndpointBuilder service.
If you develop your own audio device driver and INF file to work with your audio device, and develop an audio
application, or both, it is best to be aware of the following issues and best practices. When you develop drivers and
applications with these recommendations in mind, you produce drivers, INF files, and audio clients that work more
effectively with the AudioEndpointBuilder.
Naming convention. The naming convention that is used for the endpoints is based on the friendly names
of the bridge pins. However, in the case of speaker endpoints, the name has been hardcoded to "Speakers"
and cannot be altered by your driver or a third-party application.
Suboptimal topologies. Certain topologies are considered to be suboptimal because of the algorithm that is
used by the AudioEndpointBuilder to enumerate endpoints. For example, when you create one of these
suboptimal topologies, you create host pins that have hidden endpoints and cannot be seen by the
AudioEndpointBuilder or splitters (split endpoints) that the AudioEndpointBuilder cannot link to their
associated host pins.
Hidden endpoints
In the following diagram, the KS filter is shown to have two host pins that are connected to a single
bridge pin (Speaker).

When the AudioEndpointBuilder discovers this bridge pin, it traces a path back to only one of the
host pins, sets the default values for the bridge pin, creates and activates a Speaker endpoint, and
continues to discover other bridge pins. Thus, the other host pin remains hidden from the
AudioEndpointBuilder.
In the preceding diagram, the problematic topology has been redesigned so that the
AudioEndpointBuilder can discover the two host pins (PCM and AC-3/ PCM) because it can now see
two bridge pins (Speaker and SPDIF).
Splitters
Another type of suboptimal topology is created when one host pin connects to more than one bridge
pin. The following diagram shows a topology in which a PCM host pin connects to a Speaker bridge
pin and a SPDIF bridge pin.

In this case the AudioEndpointBuilder discovers one bridge pin and traces a path back to the PCM
host pin, sets default values, and then creates and activates a Speaker endpoint. When the
AudioEndpointBuilder discovers the next bridge pin, it traces a path back to the same PCM host pin,
sets default values, and then creates and activates a SPDIF endpoint. However, although both
endpoints have been initialized and activated, streaming to one of them makes it impossible to
stream to the other at the same time; in other words, they are mutually exclusive endpoints.
The following diagram shows a redesign of this topology in which separate connections exist. This
design makes it possible for the AudioEndpointBuilder to trace a path back to the PCM host pin for
each of the two bridge pins.

Endpoint format. When the audio engine is running in shared mode, the format for the endpoint assumes a
specific setting as directed by the INF file at the time of installation. For example, the audio driver for an
audio device uses its associated INF file to set the default endpoint to a 44.1-kHz, 16-bit, stereo PCM format.
After installation, you must use Control Panel or a third-party application to change the endpoint format.
Default device. The endpoint that is set as the default device is selected at the time of installation by using
information in the INF file. After installation has completed, you must use Control Panel or a third-party
application to select another endpoint to be the default endpoint.
Note If your INF file does not select an endpoint to be set as default during installation, a client application can
use the MMDevice API to select an endpoint. The API bases its selection on the form factor rank and whether the
endpoint is a render or a capture endpoint. The following table shows the selection order.

REN DER RA N K C A P T URE RA N K

Speakers Microphone
REN DER RA N K C A P T URE RA N K

Line-out Line-in

SPDIF SPDIF

If you use the MMDevice API to select a default endpoint and the available endpoints are ranked the same, the
MMDevice API will alphabetize the Endpoint IDs to determine which endpoint to select as default. For example, if
an audio adapter has both line-out and line-in connectors, and the associated INF file does not select either one to
be the default at the time of installation, the MMDevice API identifies which Endpoint IDs is first alphabetically and
sets that connector as the default. This selection persists after you restart the system because the Endpoint IDs are
persistent. However, the selection does not persist if a higher-ranking endpoint (for example, a second adapter
with a microphone connector) appears in the system.
Dynamic Subdevice Registration and Unregistration
10/23/2019 • 2 minutes to read • Edit Online

Devices that support some form of jack presence detection are called dynamic devices, and their jacks must
support the KSPROPERTY_JACK_DESCRIPTION property. The following steps show the algorithm that is used
by the driver of a dynamic device to create, register, or unregister the associated subdevices for these dynamic
devices. The subdevices are created in the form of filters.
The following steps show what happens when there is an audio device plugged into the jack when the audio device
driver is loaded:
1. The driver uses jack presence detection to determine that there is a device plugged into the jack. The driver
calls PcRegisterSubdevice to register a topology filter with Portcls. A KSCATEGORY_AUDIO interface is
created as a result of the topology filter registration.
2. The audio stack is notified when the KSCATEGORY_AUDIO interface is created and the AudioEndpoint
Builder creates and initializes an associated endpoint, and then sets its state to active.
3. The driver registers a wave filter with Portcls and the audio stack is notified.
4. The driver calls PcRegisterPhysicalConnection to connect the wave filter with the topology filter. This
physical connection is then registered with Portcls.
5. The driver sets the IsConnected member of the KSJACK_DESCRIPTION structure to TRUE to indicate that
there is a device plugged into the jack.
Note If the audio device lacks jack presence detection, the IsConnected member must always be TRUE . To
confirm whether the device supports jack presence detection, a client application can call
IKsJackDescription2::GetJackDescription2 to read the JackCapabilities flag of the KSJACK_DESCRIPTION2
structure. If this flag has the JACKDESC2_PRESENCE_DETECT_CAPABILITY bit set, it indicates that the endpoint
supports jack presence detection. In that case, the return value of the IsConnected member can be interpreted as
an accurate reflection of the insertion status of the jack.
The following steps explain what happens if there is no audio device plugged into the jack when the driver is
loaded:
1. The driver uses jack presence detection to determine that there is no device plugged into the jack. But it
registers a topology filter with Portcls for the jack, and a KSCATEGORY_AUDIO interface is created.
2. The audio stack is notified when the KSCATEGORY_AUDIO interface is created. The AudioEndpointBuilder
queries the miniport driver to determine from the KSJACK_DESCRIPTION property whether to set the
state of the endpoint as unplugged.
3. The driver sets the IsConnected member of the KSJACK_DESCRIPTION structure to FALSE to indicate
that there is no device plugged into the jack.
For more information about the different states of an audio endpoint, see Audio Endpoint Builder Algorithm.
To comply with the preceding description of the subdevice registration and unregistration processes, devices
drivers that support jack presence detection must react in the following manner, in response to plug insertion and
removal:
Device driver response to a plug inser tion
1. Driver must call PcRegisterSubdevice to register a wave filter with Portcls. Note The driver already called
PcRegisterSubdevice on the topology filter when the driver was loaded with no device plugged into the
jack.
2. The driver must call PcRegisterPhysicalConnection to register the "wave to topology filter" connection
with Portcls.
3. The driver must set the IsConnected member of the KSJACK_DESCRIPTION structure to TRUE .
Device driver response to a plug removal
1. Driver must call IUnregisterPhysicalConnection::UnregisterPhysicalConnection to unregister the
physical connection between the wave filter and the topology filter.
2. Driver must call IUnregisterSubdevice::UnregisterSubdevice to unregister the wave filter.
3. Driver must set the IsConnected member of the KSJACK_DESCRIPTION structure FALSE .
Exposing Multichannel Nodes
10/23/2019 • 6 minutes to read • Edit Online

In versions of Microsoft Windows prior to Windows XP, WDM audio drivers do not have a streamlined way of
exposing multichannel nodes of the following types:
KSNODETYPE_VOLUME
KSNODETYPE_MUTE
KSNODETYPE_TONE
In particular, no mechanism exists for explicitly querying a node for the number of channels that it supports.
Although workarounds exist for this problem, they have drawbacks. For example, a client can use the
KSPROPERTY_AUDIO_VOLUMELEVEL property to iteratively query a volume node (KSNODETYPE_VOLUME )
for the volume level of each channel--0, 1, and so on--until the request returns an error indicating that no more
channels exist. However, this technique requires multiple queries and is too inefficient to handle newer
multichannel audio devices. In Windows XP and later operating systems, this limitation is resolved by defining two
additional flag bits in the Flags member of the KSPROPERTY_MEMBERSHEADER structure, which the property
handler outputs in response to a basic-support query:
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL
During a basic-support property request on a node, the handler sets this flag bit to indicate that the
MembersCount member of KSPROPERTY_MEMBERSHEADER contains the number of channels that the
node supports. For Windows Vista and later Windows operating systems, this flag must be set for every
channel property.
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM
The handler performs a bitwise OR between this flag bit and the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL flag bit to indicate that a single property
value is applied uniformly across all channels in a node. For example, if the hardware provides only a single
volume-level control for all channels, the basic-support handler for the volume node sets the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag to indicate this restriction. If this flag is not
set, the volume level for each channel can be controlled independently of the volume levels for the other
channels.
Note The KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag is not used by the Windows Vista
operating system.
In miniport drivers for Windows XP and later, the property handler for a multichannel volume node should set the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL bit in response to a
KSPROPERTY_AUDIO_VOLUMELEVEL basic-support query. The handler returns an array of
KSPROPERTY_STEPPING_LONG structures--one for each channel exposed by the node--and sets
MembersSize to sizeof (KSPROPERTY_STEPPING_LONG). Each array element describes a channel's minimum and
maximum volume levels and the delta between successive values in the range. A different range can be specified
for each individual channel so that channels with non-uniform ranges can be exposed correctly. For example, a
subwoofer channel might have a range that differs from that of the other channels.
The following code example shows how to handle a basic-support query for an audio property with non-uniform
property values. Variable pDescription in the first line of code below points to the KSPROPERTY_DESCRIPTION
structure at the beginning of the data buffer into which the handler writes the basic-support information:
//
// Fill in the members header.
//
PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);

pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
pMembers->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
pMembers->MembersCount = ulNumChannels;
pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;

//
// Fill in the stepped range with the driver default.
//
PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
pRange->Reserved = 0;

for (ULONG i=0; i<ulNumChannels; i++)


{
pRange[i].Bounds.SignedMinimum = ulChannelMin[i];
pRange[i].Bounds.SignedMaximum = ulChannelMax[i];
pRange[i].SteppingDelta = ChannelStepping[i];
}

pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
sizeof(KSPROPERTY_MEMBERSHEADER) +
ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);

The following figure shows the layout of the data buffer for this example. The pDescription, pMembers, and
pRange pointers are shown pointing to their respective offsets within the buffer.

For this example, the handler sets MembersCount to ulNumChannels , the number of channels. The size in bytes
of the range array is
MembersSize * MembersCount
Note that if the KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag were set in this example, the
handler would set all of the KSPROPERTY_STEPPING_LONG structures in the array to the same range.
The basic-support handler for a tone node's KSPROPERTY_AUDIO_BASS , KSPROPERTY_AUDIO_TREBLE , or
KSPROPERTY_AUDIO_MID property operates in similar fashion.
If a multichannel node has a property with a per-channel property value of type BOOL, the basic-support handler
must fill in values for a stepping range array. In this case, the handler sets the members to the values shown in the
code example that follows. Two examples of this type of property are the KSPROPERTY_AUDIO_MUTE property
of a mute node and the KSPROPERTY_AUDIO_BASS_BOOST property of a tone node.
The following code example shows how to handle the basic-support request for a multichannel node, in the case of
a property with a per-channel property value of type BOOL:

//
// Fill in the members header.
//
PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);

pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
pMembers->MembersSize = sizeof (KSPROPERTY_STEPPING_LONG);
pMembers->MembersCount = ulNumChannels;
pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;

pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
sizeof(KSPROPERTY_MEMBERSHEADER) +
ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);

//
// Fill in the stepped range with values in FOR loop.
//
PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
pRange->Reserved = 0;

for (ULONG i=0; i<ulNumChannels; i++)


{
pRange[i].Bounds.SignedMinimum = 0;
pRange[i].Bounds.SignedMaximum = 1;
pRange[i].SteppingDelta = 1;
}

Notice that in the preceding code example, the FOR loop uses a zero (0) and a one (1) to set the minimum and
maximum values for the per-channel ranges. This is because we're configuring a multichannel node with a per-
channel property value of type BOOL.
If the channel property is uniform, a bitwise OR operation can be performed between the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag and the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL flag and the result assigned to the pMembers-
>Flags member. This value is used to indicate that the hardware applies the same property value uniformly across
all channels in a node.
Using the KSPROPERTY_MEMBER_FLAG_UNIFORM and KSPROPERTY_MEMBER_FLAG_MULTICHANNEL flags
eliminates the need to group the channels into pairs and expose a separate stereo volume node for each pair of
channels, as is done in the Ac97 sample driver in the Windows Driver Kit (WDK). Because Windows versions earlier
than Windows XP do not support these flags, the basic-support handler for your driver must use the
IPortClsVersion interface to query for the Portcls.sys version in order to determine whether to use these flags.
The topology parser (in the kernel-mode WDMAud system driver, Wdmaud.sys) obtains an audio device's topology
from its WDM audio driver. The parser exposes that device as a traditional mixer device through the legacy
Windows Multimedia mixer API. In Windows XP and later, WDMAud uses the
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL flag to determine the number of channels to
report in the cChannels member of the MIXERLINE structure. Additionally, if the node's basic-support handler
specifies the KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag, WDMAud sets the
MIXERCONTROL_CONTROLF_UNIFORM flag in the corresponding MIXERCONTROL structure. Through this flag,
applications can determine whether they can adjust each channel individually or all channels uniformly through a
master control. For more information about MIXERCONTROL, MIXERLINE, and the mixer API, see the Microsoft
Windows SDK documentation.
In Windows XP and later, the SndVol32 volume-control program (see SysTray and SndVol32) displays controls for
multichannel devices, as shown in the following figure.

If SndVol32 detects a line that has more than two channels, it replaces the normal pan control with a button
labeled Speaker Volume , which appears above the main volume slider in the preceding figure. Clicking on the
Speaker Volume button will bring up a dialog displaying controls for all of the channels for a particular line, as
shown in the following figure.

Because the mixer API exposes channels by number, it infers the channel names from the speaker configuration
that is currently selected in the Advanced Audio Proper ties dialog in the Windows multimedia control panel
(Mmsys.cpl).
For example, if a device exposes four channels on a line and the user has selected "Quadraphonic speakers", the
channel names will be "Left" (channel 0), "Right" (channel 1), "Back Left" (channel 2), and "Back Right" (channel 3),
as shown in the preceding figure. Changing the speaker configuration to "Surround sound speakers" will result in a
channel mapping of "Left" (channel 0), "Right" (channel 1), "Front Center" (channel 2), and "Back Center" (channel
3).
At the driver level, the KSPROPERTY_AUDIO_CHANNEL_CONFIG property uses a mask value of
KSAUDIO_SPEAKER_QUAD or KSAUDIO_SPEAKER_SURROUND to represent a quadraphonic or surround speaker
configuration, respectively. Header file Ksmedia.h defines these values as follows:
#define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)

#define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \


SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)

Either mask contains four bits that specify the speaker positions of the four channels. In either case, the
KSPROPERTY_AUDIO_VOLUMELEVEL property identifies these same four channels as channels 0, 1, 2, and 3,
respectively.
If the node's basic-support handler sets the KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM flag bit, the
sliders shown in the Speaker Volume dialog move in unison with changes made to any single slider.
Pin Category Property
10/23/2019 • 4 minutes to read • Edit Online

Microsoft Windows Driver Model (WDM) audio drivers for USB audio devices, IEEE 1394 audio devices, and audio
devices on internal buses all represent their devices as KS filters with pins. A WDM audio driver maintains one
KSPIN_DESCRIPTOR structure for each pin type that it supports. Within this structure, the driver stores the
KSPROPSETID_Pin properties of the pin type. Among those properties is the KSPROPERTY_PIN_CATEGORY
property. A request for this property retrieves the KS pin category GUID from the KSPIN_DESCRIPTOR
structure's Categor y member. This GUID indicates the general category of functionality that the pin provides. For
example, a particular pin category GUID, KSNODETYPE_HEADPHONES, identifies a pin as an output jack for
headphones.
In the case of a wave audio device on an internal bus (for example, PCI), the PortCls miniport driver contains an
array of pin descriptors, each of which describes a pin type in the filter that represents the device. Each pin
descriptor is a PCPIN_DESCRIPTOR structure containing an embedded KSPIN_DESCRIPTOR structure with a
pin category GUID. Upon receiving a KSPROPERTY_PIN_CATEGORY property request from a client, the port
driver retrieves the pin category GUID from the miniport driver's pin descriptor for the specified pin type. For
more information about pin descriptors, see Pin Factories.
A USB audio device has some number of terminals through which digital streams and analog signals can enter
and exit the device. When constructing a KS filter to represent a USB audio device, the USBAudio class system
driver translates the terminals on the device into pins on the filter. The header file Ksmedia.h defines a mapping for
each USB terminal type identifier to a KS pin category GUID. The following six tables show the terminal type
identifiers and their corresponding pin category GUIDs.
Input Terminal Types
USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0201 KSNODETYPE_MICROPHONE

0x0202 KSNODETYPE_DESKTOP_MICROPHONE

0x0203 KSNODETYPE_PERSONAL_MICROPHONE

0x0204 KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE

0x0205 KSNODETYPE_MICROPHONE_ARRAY

0x0206 KSNODETYPE_PROCESSING_MICROPHONE_ARRAY

Output Terminal Types


USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0301 KSNODETYPE_SPEAKER
USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0302 KSNODETYPE_HEADPHONES

0x0303 KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO

0x0304 KSNODETYPE_DESKTOP_SPEAKER

0x0305 KSNODETYPE_ROOM_SPEAKER

0x0306 KSNODETYPE_COMMUNICATION_SPEAKER

0x0307 KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER

Bidirectional Terminal Types


USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0401 KSNODETYPE_HANDSET

0x0402 KSNODETYPE_HEADSET

0x0403 KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION

0x0404 KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE

0x0405 KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE

Telephony Terminal Types


USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0501 KSNODETYPE_PHONE_LINE

0x0502 KSNODETYPE_TELEPHONE

0x0503 KSNODETYPE_DOWN_LINE_PHONE

External Terminal Types


USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0601 KSNODETYPE_ANALOG_CONNECTOR
USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0602 KSNODETYPE_DIGITAL_AUDIO_INTERFACE

0x0603 KSNODETYPE_LINE_CONNECTOR

0x0604 KSNODETYPE_LEGACY_AUDIO_CONNECTOR

0x0605 KSNODETYPE_SPDIF_INTERFACE

0x0606 KSNODETYPE_1394_DA_STREAM

0x0607 KSNODETYPE_1394_DV_STREAM_SOUNDTRACK

Embedded Function Terminal Types


USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x0701 KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE

0x0702 KSNODETYPE_EQUALIZATION_NOISE

0x0703 KSNODETYPE_CD_PLAYER

0x0704 KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE

0x0705 KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE

0x0706 KSNODETYPE_MINIDISK

0x0707 KSNODETYPE_ANALOG_TAPE

0x0708 KSNODETYPE_PHONOGRAPH

0x0709 KSNODETYPE_VCR_AUDIO

0x070A KSNODETYPE_VIDEO_DISC_AUDIO

0x070B KSNODETYPE_DVD_AUDIO

0x070C KSNODETYPE_TV_TUNER_AUDIO
USB T ERM IN A L ID K S P IN C AT EGO RY GUID

0x070D KSNODETYPE_SATELLITE_RECEIVER_AUDIO

0x070E KSNODETYPE_CABLE_TUNER_AUDIO

0x070F KSNODETYPE_DSS_AUDIO

0x0710 KSNODETYPE_RADIO_RECEIVER

0x0711 KSNODETYPE_RADIO_TRANSMITTER

0x0712 KSNODETYPE_MULTITRACK_RECORDER

0x0713 KSNODETYPE_SYNTHESIZER

For more information about USB terminal type identifiers, see the Universal Serial Bus Device Class Definition for
Terminal Types (release 1.0), which is available at the USB Implementers Forum website.
All pin category GUIDs in the preceding tables have parameter names of the form KSNODETYPE_XXX. Note that KS
node type GUIDs also have KSNODETYPE_XXX parameter names. This naming convention creates some potential
for confusion between pin category GUIDs and node type GUIDs. Fortunately, nearly every KSNODETYPE_XXX
parameter identifies either a pin category or a node type, but not both. The one exception to the rule is
KSNODETYPE_SYNTHESIZER , which can identify either a pin category or a node type, depending on the context.
For a list of node type GUIDs, see Audio Topology Nodes.
When instantiating a USB audio device, the USBAudio class system driver queries the device for its internal
topology, including its terminals. With this information, the USBAudio driver constructs a filter to represent the
device and translates each terminal into a corresponding pin on the filter. During this process, the driver translates
each USB terminal type identifier into the corresponding KS pin category GUID, which is one of the GUIDs in the
preceding tables. The driver constructs a KSPIN_DESCRIPTOR structure to describe the pin, and it writes the pin
category GUID into the structure.
A PortCls miniport driver does not necessarily use only the category GUIDs that appear in the preceding six tables.
For example, a driver might define and use a custom pin category GUID to describe a pin type whose functional
category falls outside the categories in the tables. Naturally, a custom pin category GUID is useful only to clients
that recognize the GUID.
The audio subsystem maintains a list of pin category GUIDs and their associated friendly names in the system
registry. The GUIDs and friendly names are stored in the registry path
HKLM\SYSTEM\CurrentControlSet\Control\MediaCategories. The media class installer copies the GUID-name
pairs into the registry from the Ks.inf file located in the Inf subfolder of the main Windows folder (for example,
C:\Windows\Inf\Ks.inf).
In Windows Vista and later, the operating system uses pin categories to associate friendly names with audio
endpoint devices. For more information about how to associate friendly names with audio endpoint devices, see
Friendly Names for Audio Endpoint Devices.
In Windows XP, Windows 2000, and Windows Millennium Edition, the operating system makes only limited use of
pin categories. The WDMAud system driver acts on behalf of the mixer API to translate pin category GUIDs into
MIXERLINE_COMPONENTTYPE_XXX values for use by client applications. WDMAud recognizes only a subset of the
pin category GUIDs that appear in the preceding six tables. In addition, for historical reasons, WDMAud recognizes
two pin category GUIDs, KSCATEGORY_AUDIO and PINNAME_CAPTURE, that do not appear in the tables. For
more information about the translation of pin categories to mixer lines, see Topology Pins. For information about
the mixer API, see the Windows SDK documentation.
Friendly Names for Audio Endpoint Devices
10/23/2019 • 5 minutes to read • Edit Online

In Windows Vista, Windows Server 2008 and later versions of Windows, the audio subsystem supports the notion
of an audio endpoint device, for example, speakers, headphones, microphones, and CD players. This concept of
audio endpoints helps create user-friendly audio applications that have user interfaces that refer to the endpoint
devices that users directly manipulate. These endpoints have friendly names such as "speakers", "headphones",
"microphone", and "CD player" that applications can display in their user interfaces. For more information about
endpoint devices, see Audio Endpoint Devices.
The audio subsystem models a Plug and Play (PnP) device on an audio adapter as a KS filter. Data streams enter
and exit the filter through KS pins. A bridge pin is a KS pin through which an audio endpoint device connects to a
KS filter. For more information about bridge pins, see Audio Filter Graphs.
The audio subsystem obtains information about an audio endpoint device by examining the properties of the
bridge pin that the endpoint device connects to. One such property is the pin category property
(KSPROPERTY_PIN_CATEGORY ).
For each KS filter, the adapter driver supplies a table of PCPIN_DESCRIPTOR structures that describe the
properties of the KS pins on the filter. The pin category GUID is stored in the KsPinDescriptor.Categor y member
of the PCPIN_DESCRIPTOR structure. For a bridge pin, the value of the pin category GUID indicates the type of
endpoint that connects to the bridge pin. For example, the pin-category GUID KSNODETYPE_MICROPHONE
indicates that the bridge pin connects to a microphone, the GUID KSNODETYPE_SPEAKER indicates that the bridge
pin connects to speakers, and so on. The KSNODETYPE_XXX GUIDs are defined in the Ksmedia.h header file.
In addition the PCPIN_DESCRIPTOR includes a GUID that can be used to identify the pin by a unique name. This
pin name GUID is stored in the KsPinDescriptor.Name member of the PCPIN_DESCRIPTOR structure. This name
GUID is used by the (KSPROPERTY_PIN_NAME ) property to associate a friendly name found in the registry with
the pin.
The audio subsystem invokes the KSPROPERTY_PIN_NAME property to associate a friendly name with an audio
endpoint. KS handles this request by first searching for a unicode string in the registry describing the
KsPinDescriptor.Name GUID. If KS does not find an entry, it searches the registry for a unicode string describing
the KsPinDescriptor.Categor y GUID.
Starting with Windows 10 REDSTONE 5 when searching the registry, KS first looks for an entry in the device's
software key. This is created by the INF through an AddReg section referenced by the [Models] section of the
device driver's INF. The AddReg section constructs these entries using the HKR\MediaCategories key. This allows
the driver developer to create device-specific friendly names for both Name and Category GUIDs, whether the
GUID is unique to the device or not.
If an entry has not been installed in the device's software key or the driver is running on an operating system prior
to Windows 10 REDSTONE 5 , KS looks under HKLM\SYSTEM\CurrentControlSet\Control\MediaCategories
registry key. This second key is treated as a global name space. Starting with Windows 10 REDSTONE 5 this
space is reserved for global defintions and should not be modified by new drivers. Modification of entries under
this key will not be supported in a future OS release.
Audio devices that expose pins with standard categories GUIDs should include / needs the inbox KS.INF or
KSCAPTUR.INF name registration in your device INF. These inbox INFs contain default friendly name definitions for
pre-defined category GUIDs that your driver may wish to populate. These are the same GUIDs found in the
KsPinDescriptor.Categor y member of the PCPIN_DESCRIPTOR structure. For example, the category GUID
KSNODETYPE_MICROPHONE entry has the associated friendly name "microphone" and the category GUID
KSNODETYPE_SPEAKER entry has the associated friendly name "speakers," and so on.
The GUIDs and friendly names for both Category and Name GUIDs are stored under the HKR\MediaCategories
while global definitions HKLM\SYSTEM\CurrentControlSet\Control\MediaCategories paths. For each GUID-name
pair in the registry, the GUID string is used as a sub-key under the MediaCategories key. Under the GUID key the
friendly name a Unicode string value under the "Name" variable.
If none of the friendly names and pin categories defined by the audio subsystem adequately describes your device,
you can define your own pin category and name GUIDs and associate friendly names with them in your INF. To
ensure that your pin-category GUID is unique, use a utility such as Uuidgen.exe to generate the GUID. Next, modify
the INF file that installs your audio adapter to write the pin-category GUID and friendly name to the registry path
HKR\MediaCategories. The following code example shows a fragment of an INF file that adds two pin-category
GUIDs and their associated friendly names to the registry:

[Manufacturer]
MyOEMName=Unicorn,NTamd64

[Unicorn.NTamd64]
MyDeviceName=MyDevice,Root\MyDevice

[MyDevice.NT]
Include=ks.inf, kscaptur.inf
Needs=KS.Registration, KSCAPTUR.Registration.NT
CopyFiles=MyDevice.CopyFiles
AddReg=PinNameRegistration

...

[PinNameRegistration]
HKR,%MediaCategories%\%GUID.MyNewEndpointCategory%,Name,,%Name.MyNewEndpointCategory%
HKR,%MediaCategories%\%GUID.MyNewEndpointName%,Name,,%Name.MyNewEndpointName%

...

[Strings]
MyOEMName="Unicorns Inc."
MyDeviceName="Sparkly Unicorn"
MediaCategories="MediaCategories"

GUID.MyNewEndpointCategory="{B72FBD1A-4634-4240-B207-0E6B52F3701C}"
GUID.MyNewEndpoint_2="{71DD3A5D-E303-49A0-ACEE-908634AA9520}"

Name.MyNewEndpointCategory="Unicorn"
Name.MyNewEndpointName="Fred the Unicorn"

Both GUID strings were generated by Uuidgen.exe.


Applications can access the properties of an audio endpoint device by using the device's IProper tyStore interface.
The interface uses the property keys defined in the Functiondiscoverykeys_devpkey.h and Mmdeviceapi.h header
files to identify the properties. An application can use the PKEY_Device_FriendlyName property key to retrieve
the friendly name of an endpoint device. For space-constrained user interfaces, a shorter version of the friendly
name can be retrieved by using the PKEY_Device_DeviceDesc property key. For more information about these
property keys, see IMMDevice::OpenPropertyStore.
An IProper tyStore interface instance maintains a persistent property store for an audio endpoint device. The
property store copies its initial value for the PKEY_Device_DeviceDesc property key from the friendly name
string that is associated with the KS pin category GUID in the registry path
HKLM\SYSTEM\CurrentControlSet\Control\MediaCategories. Applications can read the
PKEY_Device_DeviceDesc property value (the name string) from the property store, but they cannot change the
value. However, users can modify the name by using the Windows multimedia control panel, Mmsys.cpl. For
example, in Windows Vista, you can use the following steps to modify the name of a rendering endpoint device:
1. To run Mmsys.cpl, open a Command Prompt window and enter the following command:

mmsys.cpl

(Alternatively, you can run Mmsys.cpl by right-clicking the speaker icon in the notification area, which is
located on the right side of the taskbar, and clicking Playback Devices .)
2. Click the name of a rendering device, and then click Proper ties .
3. In the Properties window, click the General tab. The friendly name should appear in a text box at the top of
the property sheet. You can edit the friendly name, and then save your changes by clicking OK .
The preceding steps change the friendly name that is stored in the property store for the audio endpoint device.
These steps have no effect on the friendly names associated with other audio endpoint devices that belong to the
same KS pin category. They also have no effect on any component that might query KS directly for a name.
Audio Position Property
10/23/2019 • 7 minutes to read • Edit Online

The client of an audio driver uses the KSPROPERTY_AUDIO_POSITION property to get and set the current
position in an audio stream. The property uses a KSAUDIO_POSITION structure to describe the current position.
The structure contains two members: PlayOffset and WriteOffset .
The PlayOffset and WriteOffset members define the boundaries of the region of the client buffer that is
currently reserved for the exclusive use of the audio device. The client must assume that the device might currently
be accessing any of the data contained in this region. Hence, the client must access only the portions of the buffer
that lie outside this region. The boundaries of the region move as the stream advances.
If the client buffer is looped (that is, the stream type is KSINTERFACE_STANDARD_LOOPED_STREAMING ),
PlayOffset and WriteOffset are buffer-relative offsets. That is, they are specified as byte offsets from the start of
the looped client buffer. When either offset increments to the end of the buffer, it wraps around to the start of the
buffer. (The offset at the start of the buffer is zero.) Thus, neither offset ever exceeds the buffer size.
If the client buffer is nonlooped (that is, the stream type is KSINTERFACE_STANDARD_STREAMING ),
PlayOffset and WriteOffset are stream-relative offsets. That is, they are specified as byte offsets from the start of
the stream. These offsets can be thought of as offsets into an idealized buffer that contains the entire stream and is
contiguous from beginning to end.
In the case of a render stream, the PlayOffset member specifies the play position of the stream, and the
WriteOffset member specifies the write position of the stream. The following figure shows the play and write
positions in a client buffer.

The play position is the byte offset of the sample that is currently being played (that is, the sample that is latched at
the input of the digital-to-analog converter, or DAC). The write position is the position beyond which the client can
safely write to the buffer. As the stream plays, the play and write positions move from left to right in the preceding
figure. The client's writes must stay ahead of the write position. In addition, if the buffer is looped, the client's writes
must never overtake the play position.
Although the WaveCyclic or WavePci port driver relies on the miniport driver to keep track of the play position, the
port driver keeps track of the write position. The WaveCyclic and WavePci port drivers update the write position as
follows:
WaveCyclic
Each time the WaveCyclic port driver calls IDmaChannel::CopyTo to copy a new block of data to the cyclic
buffer (from the client buffer), the write position advances to the location (in the client buffer) of the last
byte in the data block.
WavePci
By default, each time the WavePci miniport driver calls IPor tWavePciStream::GetMapping to acquire a
new mapping (of a portion of the client buffer) and the call succeeds, the write position advances to the
location (in the client buffer) of the last byte in the new mapping.
If the WavePci miniport driver overrides the default behavior by specifying a prefetch offset to the port
driver, the current write position is always equal to the sum of the current play position and the prefetch
offset. For more information, see Prefetch Offsets.
In the case of a capture stream, the PlayOffset member specifies the record position of the stream, and the
WriteOffset member specifies the read position of the stream. The following figure shows the record and read
positions in a client buffer.

The record position is the byte offset of the latest sample to be latched at the output of the analog-to-digital
converter, or ADC. (This position specifies the buffer location into which the audio device's DMA engine will
eventually write the sample.) The read position is the position beyond which the client cannot safely read from the
buffer. As the recording of the stream progresses, the read and record positions advance from left to right in the
preceding figure. The client's reads must trail the read position. In addition, if the buffer is looped, the client's reads
must stay ahead of the record position.
Although the WaveCyclic or WavePci port driver relies on the miniport driver to keep track of the record position,
the port driver keeps track of the read position. The WaveCyclic and WavePci port drivers update the read position
as follows:
WaveCyclic
Each time the WaveCyclic port driver calls IDmaChannel::CopyFrom to copy a new block of data from the
cyclic buffer (to the client buffer), the read position advances to the location (in the client buffer) of the last
byte in the data block.
WavePci
Each time the WavePci miniport driver calls IPor tWavePciStream::ReleaseMapping to release a
previously acquired mapping (of a portion of the client buffer), the read position advances to the location (in
the client buffer) of the last byte in the released mapping.
Miniport drivers do not need to implement handler routines for KSPROPERTY_AUDIO_POSITION property
requests. Instead, the WaveCyclic and WavePci port drivers handle these requests on behalf of miniport drivers.
When handling a get-property request, a WaveCyclic or WavePci port driver already has all the information it
needs to calculate the WriteOffset value, but it still needs information from the miniport driver to calculate the
PlayOffset value. To obtain this information, the port driver calls the miniport driver's
IMinipor tWaveCyclicStream::GetPosition or IMinipor tWavePciStream::GetPosition method.
For a render stream, the GetPosition method retrieves the play position - the byte offset of the sample that is
currently being played through the DAC. For a capture stream, the GetPosition method retrieves the record
position - the byte offset of the latest sample to be captured by the ADC.
Note that the offset value retrieved by a GetPosition call is either a play position corresponding to the signal
currently being transmitted through the speaker jack or a record position corresponding to the signal currently
being received through the microphone jack. It is not the DMA position. (The DMA position is the byte offset of the
sample that the DMA engine in the audio device is currently transferring to or from the DMA buffer.)
Some audio hardware contains a position register to keep track of the byte offset of the sample currently in each
DAC or ADC, in which case the GetPosition method simply retrieves the contents of the position register for the
appropriate stream. Other audio hardware can only supply the driver with the DMA position, in which case the
GetPosition method must provide a best estimate of the byte offset of the sample in the DAC or ADC by taking
into account the current DMA position and the buffering delays internal to the device.
Although the property handler in the WaveCyclic or WavePci port driver must distinguish between looped and
nonlooped buffers to determine whether to provide a stream-relative or buffer-relative byte offset, this detail (that
is, whether a buffer is looped or nonlooped) is transparent to the miniport driver.
The IMinipor tWaveCyclicStream::GetPosition method always reports a buffer-relative play or record position
regardless of whether the client buffer is looped or nonlooped. If the client buffer is looped, the property handler
converts the buffer-relative position reported by the miniport driver, which is expressed as an offset into the cyclic
buffer, to an offset into the client buffer, which the handler then writes to the PlayOffset member. If the client
buffer is nonlooped, the property handler converts the buffer-relative play position to a stream-relative play
position before writing it to the PlayOffset member.
The IMinipor tWavePciStream::GetPosition method always reports a stream-relative play or record position
regardless of whether the client buffer is looped or nonlooped. If the client buffer is looped, the property handler
converts the stream-relative play position to a buffer-relative play position (expressed as an offset into the client
buffer) before writing it to the PlayOffset member in the KSAUDIO_POSITION structure in the property request. If
the client buffer is nonlooped, the property handler writes the stream-relative position to the PlayOffset member.
The play or record position is zero immediately following initialization of the stream. A transition to the
KSSTATE_STOP state (see KSSTATE ) resets the position to zero. When the stream is halted by a transition from
KSSTATE_RUN to KSSTATE_PAUSE or KSSTATE_ACQUIRE, the position freezes. It unfreezes when the stream
transitions from KSSTATE_PAUSE or KSSTATE_ACQUIRE back to KSSTATE_RUN.
For example implementations of GetPosition methods for WaveCyclic and WavePci miniport drivers, see the
sample audio drivers in the Windows Driver Kit (WDK).
Pin Data-Range and Intersection Properties
10/23/2019 • 2 minutes to read • Edit Online

Several property requests provide information about the data formats for the audio streams that an audio device
is capable of handling at its input and output pins.
The audio-stream data formats that a pin is capable of supporting are expressed in a KSMULTIPLE_ITEM array of
KSDATARANGE -derived structures. Pin data-range support is exposed through the following three
KSPROPSETID_Pin properties on the filter:
KSPROPERTY_PIN_DATARANGES This property reports data ranges that are static and represent all possible
formats supported. Typically, data ranges are contained in a static array in the adapter driver.
KSPROPERTY_PIN_CONSTRAINEDDATARANGES This property reports data ranges that are dynamic and
represent the subset of formats supported at the time of the property request. The property handler should
contain the logic to decide which formats the pin is capable of supporting at run time. For example, a hardware
implementation could have DMA constraints that do not allow support for full-duplex in certain format
combinations. KSPROPERTY_PIN_DATAINTERSECTION This property selects a data format from a list of data
ranges. Selection is based on dynamic capabilities and the format is taken from the subset of formats that the
driver can support at the time of the property request. To use this property, the caller supplies an array of data
ranges. Beginning at the first element, the property handler searches the array until it finds a data range that it is
currently capable of supporting. If successful, the handler outputs a data format that is taken from that data range
and returns STATUS_SUCCESS. Otherwise, the handler returns STATUS_NO_MATCH. The audio-system components
use the KSPROPERTY_PIN_DATARANGES and KSPROPERTY_PIN_DATAINTERSECTION properties. Miniport drivers
should support these properties. Support for KSPROPERTY_PIN_CONSTRAINEDDATARANGES is optional.
For more information, see Audio Data Formats and Data Ranges.
Note The KSPROPERTY_PIN_DATARANGES and KSPROPERTY_PIN_CONSTRAINEDDATARANGES each begin on
an 8-byte-aligned address.
Jack Description Property
10/23/2019 • 8 minutes to read • Edit Online

In Windows Vista and later, the KSPROPERTY_JACK_DESCRIPTION property describes an audio jack or other
physical connector on an audio adapter. The property value describes the color of the jack, the physical location of
the jack, the connector type, and other jack features. The purpose of this information is to help the user to find the
correct jack for plugging in an audio endpoint device such as a microphone, headphones, or speakers. For more
information, see Audio Endpoint Devices.
If a KS filter on an audio adapter supports the KSPROPERTY_JACK_DESCRIPTION property, the Windows
multimedia control panel, Mmsys.cpl, displays the jack information for the bridge pins on the filter. A bridge pin
represents a connection (typically, a jack) to an audio endpoint device. Although the property value contains
information about a pin (or rather, the jack or jacks that are associated with the pin), the property is a property of
the filter, not of the pin. For more information about bridge pins, see Audio Filter Graphs. For more information
about filter properties and pin properties, see Filter, Pin, and Node Properties.
An audio application can obtain the KSPROPERTY_JACK_DESCRIPTION property value for an audio endpoint device
by calling the IKsJackDescription::GetJackDescription method in the DeviceTopology API. For example, an
application can use the jack information to help the user to distinguish a microphone plugged into a green XLR
jack from a microphone plugged into an orange XLR jack. For more information about the DeviceTopology API, see
Device Topologies.
The Microsoft HD Audio class driver automatically constructs the KSPROPERTY_JACK_DESCRIPTION property
values from the data that it reads from the pin-configuration registers in an HD Audio codec. However, any KS-
based audio driver can implement support for this property in its filter automation tables. For more information
about the HD Audio class driver, see HD Audio and UAA. For more information about pin-configuration registers,
see Pin Configuration Guidelines for High Definition Audio Devices white paper.
An audio endpoint device can connect to a bridge pin through one or more jacks. For example, a set of (two-
channel) stereo speakers requires one jack, but a set of 5.1 surround-sound speakers requires three jacks
(assuming that each jack handles two of the six channels).
The description for each jack is contained in a KSJACK_DESCRIPTION structure. For example, the
KSPROPERTY_JACK_DESCRIPTION property value for an audio endpoint device with one jack contains one
KSJACK_DESCRIPTION structure, but the property value for an endpoint device with three jacks contains three
KSJACK_DESCRIPTION structures. In either case, the KSJACK_DESCRIPTION structure or structures in the property
value are preceded by a KSMULTIPLE_ITEM structure that specifies the size of the property value. For more
information, see KSPROPERTY_JACK_DESCRIPTION .
Jack information is particularly useful for helping users to distinguish among the jacks that connect to a
multichannel speaker configuration. The following code example shows an array of KSJACK_DESCRIPTION
structures that an audio driver uses to describe the three jacks for a set of 5.1 surround speakers:
KSJACK_DESCRIPTION ar_5dot1_Jacks[] =
{
// Jack 1
{
(SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
RGB(0,255,0), // Color (green)
eConnType3Point5mm, // ConnectionType
eGeoLocRear, // GeoLocation
eGenLocPrimaryBox, // GenLocation
ePortConnJack, // PortConnection
TRUE // IsConnected
},
// Jack 2
{
(SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY), // (C,Sub)
RGB(0,0,255), // (red)
eConnType3Point5mm,
eGeoLocRear,
eGenLocPrimaryBox,
ePortConnJack,
TRUE
},
// Jack 3
{
(SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT), // (SL,SR)
RGB(0,255,255), // (yellow)
eConnType3Point5mm,
eGeoLocRear,
eGenLocPrimaryBox,
ePortConnJack,
TRUE
}
};

If the audio hardware can detect whether the device is plugged in, the driver dynamically updates the value of this
member to indicate whether the device is currently plugged in (TRUE ) or unplugged (FALSE )
In the preceding code example, the IsConnected member in each array element is set to TRUE to indicate that the
endpoint device is plugged into the jack. However, if the hardware lacks jack presence detection, IsConnected
must always be set to TRUE , whether there is a device plugged into the jack. To remove the ambiguity that results
from this dual meaning of the TRUE return value, a client application can call
IKsJackDescription2::GetJackDescription2 to read the JackCapabilities flag of the KSJACK_DESCRIPTION2
structure. If this flag has the JACKDESC2_PRESENCE_DETECT_CAPABILITY bit set, it indicates that the endpoint does
in fact support jack presence detection. In that case, the value of the IsConnected member can be interpreted as
an accurate reflection of the insertion status of the jack.
The RGB macro that appears in the preceding structures is defined in header file Wingdi.h in the Windows SDK.
In addition, an array of jack descriptions can be used to show that two or more jacks are functionally equivalent to
each other. In the following code example, the audio driver combines the jack descriptions for a yellow RCA jack
and for a black digital-optical jack into one array to indicate to the user that the two jacks carry the same signal:
KSJACK_DESCRIPTION ar_SPDIF_Jacks[] =
{
// Jack 1
{
(SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
RGB(0,255,255), // Color (yellow)
eConnTypeRCA, // ConnectionType (RCA)
eGeoLocRear, // GeoLocation
eGenLocPrimaryBox, // GenLocation
ePortConnJack, // PortConnection
TRUE // IsConnected
},
// Jack 2
{
(SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // (L,R)
RGB(0,0,0), // (black)
eConnTypeOptical, // (optical)
eGeoLocRear,
eGenLocPrimaryBox,
ePortConnJack,
TRUE
}
};

In the preceding code example, the values of the ChannelMapping members in the two KSJACK_DESCRIPTION
structures are identical.
The "Simple" MSVAD sample driver in the WDK (in sample directory Src\Audio\Msvad\Simple) can be adapted to
support the KSPROPERTY_JACK_DESCRIPTION property. This sample driver is convenient for demonstrating the
use of the property because it does not require actual hardware. Thus, it can be installed on any computer running
Windows. (However, only Windows Vista and later operating systems provide full support for the
KSPROPERTY_JACK_DESCRIPTION property.) For more information about this sample, see Windows Driver Kit
Samples.
The topology filter for the Simple MSVAD sample defines three bridge pins. These pins are listed in the following
table.

P IN ID DESC RIP T IO N

KSPIN_TOPO_SYNTHIN_SOURCE MIDI input jack

KSPIN_TOPO_MIC_SOURCE Microphone input jack

KSPIN_TOPO_LINEOUT_DEST Stereo speaker output jack

The remainder of this topic explains how to modify the Simple MSVAD sample driver to provide the jack
information for the three bridge pins.
First, the jack information for these pins can be specified as follows:
// Describe MIDI input jack (pin ID = KSPIN_TOPO_SYNTHIN_SOURCE).
static KSJACK_DESCRIPTION SynthIn_Jack[] =
{
{
0, // ChannelMapping
RGB(255,255,0), // Color (cyan)
eConnType3Point5mm, // ConnectionType
eGeoLocRear, // GeoLocation
eGenLocPrimaryBox, // GenLocation
ePortConnJack, // PortConnection
TRUE // IsConnected
}
};

// Describe microphone jack (pin ID = KSPIN_TOPO_MIC_SOURCE).


static KSJACK_DESCRIPTION MicIn_Jack[] =
{
{
0,
RGB(0,128,255), // (orange)
eConnType3Point5mm,
eGeoLocFront,
eGenLocPrimaryBox,
ePortConnJack,
TRUE
}
};

// Describe stereo speaker jack (pin ID = KSPIN_TOPO_LINEOUT_DEST).


static KSJACK_DESCRIPTION LineOut_Jack[] =
{
{
(SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
RGB(0,255,0), // (green)
eConnType3Point5mm,
eGeoLocRear,
eGenLocPrimaryBox,
ePortConnJack,
TRUE
}
};

The preceding code example sets the ChannelMapping members for the two capture pins to 0. Only analog
rendering pins should have nonzero ChannelMapping values.
The primary modification to the Simple MSVAD sample is to add the following property handler to the
implementation of the topology miniport in sample file Mintopo.cpp:

#define ARRAY_LEN(a) sizeof(a)/sizeof(a[0]);


#define MAXIMUM_VALID_PIN_ID KSPIN_TOPO_WAVEIN_DEST

NTSTATUS
CMiniportTopology::PropertyHandlerJackDescription(
IN PPCPROPERTY_REQUEST PropertyRequest)
{
PAGED_CODE();

ASSERT(PropertyRequest);

DPF_ENTER(("[PropertyHandlerJackDescription]"));

NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;


ULONG nPinId = (ULONG)-1;

if (PropertyRequest->InstanceSize >= sizeof(ULONG))


{
{
nPinId = *((PULONG)(PropertyRequest->Instance));

if (nPinId > MAXIMUM_VALID_PIN_ID)


{
ntStatus = STATUS_INVALID_PARAMETER;
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
ntStatus = PropertyHandler_BasicSupport(
PropertyRequest,
KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET,
VT_ILLEGAL);
}
else
{
PKSJACK_DESCRIPTION pJack = NULL;
ULONG cJacks = 0;

switch (nPinId)
{
case KSPIN_TOPO_SYNTHIN_SOURCE:
pJack = SynthIn_Jack;
cJacks = ARRAY_LEN(SynthIn_Jack);
break;
case KSPIN_TOPO_MIC_SOURCE:
pJack = MicIn_Jack;
cJacks = ARRAY_LEN(MicIn_Jack);
break;
case KSPIN_TOPO_LINEOUT_DEST:
pJack = LineOut_Jack;
cJacks = ARRAY_LEN(LineOut_Jack);
break;
default:
break;
}

ULONG cbNeeded = sizeof(KSMULTIPLE_ITEM) +


sizeof(KSJACK_DESCRIPTION) * cJacks;

if (PropertyRequest->ValueSize == 0)
{
PropertyRequest->ValueSize = cbNeeded;
ntStatus = STATUS_BUFFER_OVERFLOW;
}
else if (PropertyRequest->ValueSize < cbNeeded)
{
ntStatus = STATUS_BUFFER_TOO_SMALL;
}
else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value;

pMI->Size = cbNeeded;
pMI->Count = cJacks;

// Copy jack description structure into Value buffer.


// RtlCopyMemory correctly handles the case Length=0.
PKSJACK_DESCRIPTION pDesc = (PKSJACK_DESCRIPTION)(pMI + 1);

RtlCopyMemory(pDesc, pJack, pMI->Size * pMI->Count);

ntStatus = STATUS_SUCCESS;
}
}
}

return ntStatus;
}
NTSTATUS
PropertyHandler_TopoFilter(IN PPCPROPERTY_REQUEST PropertyRequest)
{
PAGED_CODE();

ASSERT(PropertyRequest);

DPF_ENTER(("[PropertyHandler_TopoFilter]"));

// PropertyRequest structure is filled by PortCls.


// MajorTarget is a pointer to miniport object for miniports.
//
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget;

if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack) &&


(PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION))
{
ntStatus = pMiniport->PropertyHandlerJackDescription(PropertyRequest);
}

return ntStatus;
}

The preceding code example refers to the three KSJACK_DESCRIPTION variables - SynthIn_Jack, MicIn_Jack, and
LineOut_Jack - that were defined previously. If the client queries the filter for the jack description of a valid pin, but
one that is not a bridge pin (and therefore has no jack description), the query succeeds (with status code
STATUS_SUCCESS), but the property handler returns an empty jack description consisting of a KSMULTIPLE_ITEM
structure and nothing else. If the client specifies an invalid pin ID (that identifies a nonexistent pin), the handler
returns status code STATUS_INVALID_PARAMETER.
Two additional modifications to the Simple MSVAD sample are required to support the
KSPROPERTY_JACK_DESCRIPTION property. These are:
Add the declaration of the Proper tyHandlerJackDescription method in the preceding code example to
the CMiniportTopology class definition in header file Mintopo.h.
Implement an automation table for the topology filter and load the address of this table into the
AutomationTable member of the PCFILTER_DESCRIPTOR structure in header file Toptable.h. This
structure is named Minipor tFilterDescriptor .
To implement the automation table for the filter, insert the following code into header file Toptable.h (before the
definition of Minipor tFilterDescriptor ):

static PCPROPERTY_ITEM PropertiesTopoFilter[] =


{
{
&KSPROPSETID_Jack,
KSPROPERTY_JACK_DESCRIPTION,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_TopoFilter
}
};

DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTopoFilter, PropertiesTopoFilter);

In the preceding code example, the Handler member of the PCPROPERTY_ITEM structure contains a function
pointer to the property handler that was added to Mintopo.cpp in a previous step. To make the property handler
accessible from the header file, insert an extern function declaration for PropertyHandler_TopoFilter at the start of
the header file.
For more information about the jack description property, see Jack Descriptions for Dynamic Audio Subdevices.
Microphone Array Geometry Property
10/23/2019 • 4 minutes to read • Edit Online

In Windows Vista and later, support is provided for microphone arrays. In most situations, a single microphone
embedded in a laptop or monitor does not capture sound very well. An array of microphones performs better to
isolate a sound source and reject ambient noise and reverberation. The
KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property specifies the geometry of a microphone array. The
property value, KSAUDIO_MIC_ARRAY_GEOMETRY , describes the array type (linear, planar, and so on), the
number of microphones in the array and other features.
This topic describes how external USB microphone arrays can use the microphone array support provided with
Windows Vista. An external USB microphone array must provide the parameters required to describe the
geometry and other features of its array in response to a GET_MEM request.
The USB microphone array uses a standard format to provide the geometry information. The Windows Vista USB
audio class driver must use the same format when it reads the geometry information. For more information about
the standard format, see Microphone Array Geometry Descriptor Format.
An application can call IPart::GetSubType to retrieve information about a jack to determine if the device plugged
into the jack is a microphone array. IPar t::GetSubType returns a pin-category GUID that represents the input jack
type. If the device that is plugged in is a microphone array, the returned GUID is equal to
KSNODETYPE_MICROPHONE_ARRAY. The application can also help you determine whether you plugged your
microphone array into the wrong jack. In the latter scenario, the returned pin-category GUID is either for a
different device or it indicates that there is no device plugged into the microphone jack. For more information
about the pin category GUIDs, see Pin Category Property.
After an application discovers a microphone array that is plugged into the correct input jack, the next step is to
determine the geometry of the array. There are three basic geometries: linear, planar, and three dimensional (3-D).
The geometry information also provides details such as the frequency range and x-y-z coordinates of each
microphone.
The following code example shows a KSAUDIO_MIC_ARRAY_GEOMETRY structure that an audio driver uses to
describe an external USB microphone array:

KSAUDIO_MIC_ARRAY_GEOMETRY mic_Array =
{
0x100,// usVersion (1.0)
KSMICARRAY_MICARRAYTYPE_LINEAR,// usMicArrayType
7854, // wVerticalAngleBegin (45 deg; PI/4 radians x 10000)
-7854, // wVerticalAngleEnd
0, // lHorizontalAngleBegin
0, // lHorizontalAngleEnd
25, // usFrequencyBandLo in Hz
19500, // usFrequencyBandHi in Hz
2, // usNumberOfMicrophones
ar_mic_Coordinates // KsMicCoord
};

In the preceding code example, the ar_mic_Coordinates variable is an array of the


KSAUDIO_MICROPHONE_COORDINATES structure and it contains the coordinates for the microphones in the
microphone array.
The following code example shows how the ar_mic_Coordinates array is used to describe the geometric locations
of the microphones in the microphone array as described in the preceding code example:
KsMicCoord ar_mic_Coordinates[] =
{
// Array microphone 1
{
KSMICARRAY_MICTYPE_CARDIOID,// usType
100, // wXCoord (mic elements are 200 mm apart)
0,// wYCoord
0, // wZCoord
0,// wVerticalAngle
0,// wHorizontalAngle
},
// Array microphone 2
{
KSMICARRAY_MICTYPE_CARDIOID,// usType
-100, // wXCoord
0,// wYCoord
0, // wZCoord
0,// wVerticalAngle
0,// wHorizontalAngle
}
};

In the preceding code example, the x-y-z coordinates are given for each microphone in the microphone array,
together with the vertical and horizontal angles that describe their effective work areas.
To modify the Micarray MSVAD sample driver to provide array geometry information for a virtual microphone
array, you must perform the following tasks.
First, navigate to Src\Audio\Msvad\Micarray and locate the Mintopo.cpp file. Edit the property handler section in
Mintopo.cpp so that the KSAUDIO_MIC_ARRAY_GEOMETRY structure contains information about the microphone
array. The specific section of code that you must modify is shown in the following code example:

// Modify this portion of PropertyHandlerMicArrayGeometry


PKSAUDIO_MIC_ARRAY_GEOMETRY pMAG = (PKSAUDIO_MIC_ARRAY_GEOMETRY)PropertyRequest->Value;

// fill in mic array geometry fields


pMAG->usVersion = 0x0100; // Version of Mic array specification (0x0100)
pMAG->usMicArrayType = (USHORT)KSMICARRAY_MICARRAYTYPE_LINEAR; // Type of Mic Array
pMAG->wVerticalAngleBegin = -7854; // Work Volume Vertical Angle Begin (-45 degrees)
pMAG->wVerticalAngleEnd = 7854; // Work Volume Vertical Angle End (+45 degrees)
pMAG->wHorizontalAngleBegin = 0; // Work Volume Horizontal Angle Begin
pMAG->wHorizontalAngleEnd = 0; // Work Volume Horizontal Angle End
pMAG->usFrequencyBandLo = 100; // Low end of Freq Range
pMAG->usFrequencyBandHi = 8000; // High end of Freq Range

pMAG->usNumberOfMicrophones = 2; // Count of microphone coordinate structures to follow.

pMAG->KsMicCoord[0].usType = (USHORT)KSMICARRAY_MICTYPE_CARDIOID;
pMAG->KsMicCoord[0].wXCoord = -100; // mic elements are 200 mm apart
pMAG->KsMicCoord[0].wYCoord = 0;
pMAG->KsMicCoord[0].wZCoord = 0;
pMAG->KsMicCoord[0].wVerticalAngle = 0;
pMAG->KsMicCoord[0].wHorizontalAngle = 0;

pMAG->KsMicCoord[1].usType = (USHORT)KSMICARRAY_MICTYPE_CARDIOID;
pMAG->KsMicCoord[1].wXCoord = 100; // mic elements are 200 mm apart
pMAG->KsMicCoord[1].wYCoord = 0;
pMAG->KsMicCoord[1].wZCoord = 0;
pMAG->KsMicCoord[1].wVerticalAngle = 0;
pMAG->KsMicCoord[1].wHorizontalAngle = 0;

The preceding code example shows information that was provided for a linear microphone array that has two
microphone elements, each of which is a cardioid type and located 100 mm from the center of the array.
For the second modification, edit the Msvad.inf file as shown in Modified INF for MSVAD Micarray.
After you complete the file modifications, complete the following procedure to build and install the sample driver
for the microphone array.
1. Start the WDK build environment in which you want to work. For example, the x86 Free Build Environment.
2. Navigate to the Src\Audio\Msvad folder.
3. Type the build command, and then press Enter.
4. Copy the modified Msvad.inf file to the following folder that was created by the build process:
Src\Audio\Msvad\Micarray\objfre_wlh_x86\i386
5. Verify that the folder in Step 4 contains a file called Vadarray.sys.
6. Open the Control Panel and use Add Hardware to manually install the sample driver.
7. Open the Sound applet in Control Panel and click the Recording tab to verify that you can see the virtual
microphone array you just installed.
For information about how to develop an application to discover microphone arrays, see Appendix C of How to
Build and Use Microphone Arrays for Windows Vista.
Microphone Array Geometry Descriptor Format
1/3/2019 • 3 minutes to read • Edit Online

A USB audio microphone array must describe itself to the system to which it is connected. This means that the
parameters that are required to describe the array must be embedded in the array device itself. Array geometry
information is retrieved from the device by using a GET_MEM request.
Information about USB audio device geometry must be provided in a standard format. As such, USB microphone
arrays that are intended to work with the Windows Vista USB audio class driver must provide a descriptor that uses
the information format that is defined in the following table.

O F F SET F IEL D SIZ E VA L UE DESC RIP T IO N

0 guidMicArrayID 16 Globally unique A unique ID that


identifier (GUID) marks the
beginning of the
microphone array
information in
memory (
{07FE86C1-8948-
4db5-B184-
C5162D4AD314}
).

16 wDescriptorLengt 2 Number The length in


h bytes of the
microphone array
information,
including the
GUID and length
fields.

18 wVersion 2 Binary coded The version


decimal (BCD) number of the
microphone array
specification,
followed by this
descriptor.

20 wMicArrayType 2 Number The following


values are
defined:
00: Linear.
01: Planar.
02: 3-dimensional
(3D).
03-FFFF:
Reserved
O F F SET F IEL D SIZ E VA L UE DESC RIP T IO N

22 wWorkVertAngBe 2 Number The start of the


g work volume
vertical angle.

24 wWorkVertAngEn 2 Number The end of the


d work volume
vertical angle.

26 wWorkHorAngBe 2 Number The beginning of


g the work volume
horizontal angle.

28 wWorkHorAngEn 2 Number The end of the


d work volume
horizontal angle.

30 wWorkFreqBandL 2 Number The lower bound


o of the work
frequency range.

32 wWorkFreqBandH 2 Number The upper bound


i of the work
frequency range.

34 wNumberOfMics 2 Number The number of


individual
microphone
definitions that
follow.

36 wMicrophoneTyp 2 Number A number that


e(0) uniquely identifies
the type of
microphone 0:
00: Omni-
Directional
01: SubCardioid
02: Cardioid
03: SuperCardioid
04: HyperCardioid
05: 8 Shaped
0F - FF: Vendor
defined
O F F SET F IEL D SIZ E VA L UE DESC RIP T IO N

38 wXCoordinate(0) 2 Number The x-coordinate


of microphone 0.

40 wYCoordinate(0) 2 Number The y-coordinate


of microphone 0.

42 wZCoordinate(0) 2 Number The z-coordinate


of microphone 0.

44 wMicVertAngle(0) 2 Number The main


response axis
(MRA) vertical
angle of
microphone 0.

46 wMicHorAngle(0) 2 Number The MRA


horizontal angle
of microphone 0.

... ... ... ... Microphone


definitions 1 to n-
2.

34+((n-1)12) wMicType(n-1) Number A number that


uniquely identifies
the type of
microphone n-1:
00: Omni-
Directional
01: SubCardioid
02: Cardioid
03: SuperCardioid
04: HyperCardioid
05: 8 Shaped
0F - FF: Vendor
defined

36+((n-1)12) wXCoordinate(n- Number The x-coordinate


1) of microphone n-
1.

38+((n-1)12) wYCoordinate(n- 2 Number The y-coordinate


1) of microphone n-
1.
O F F SET F IEL D SIZ E VA L UE DESC RIP T IO N

40+((n-1)12) wZCoordinate(n- 2 Number The z-coordinate


1) of microphone n-
1.

42+((n-1)12) wMicVertAngle(n- 2 Number The MRA vertical


1) angle of
microphone n-1.

44+((n-1)12) wMicHorAngle(n- 2 Number The MRA


1) horizontal angle
of microphone n-
1.

For a detailed example about how to use this information format in a descriptor for a 4-element microphone array,
see Appendix A of the How to Build and Use Microphone Arrays for Windows Vista white paper.
Note
When you include a version number in the microphone array information, it allows the descriptor to be
updated after the original specifications are implemented. The version number is a BCD value. For example,
the current version (1.0) is represented as 0x0100.
The offset and size values are in bytes.
All angles are expressed in units of 1/10000 radians. For example, 3.1416 radians is expressed as 31416. The
value can range from -31416 to 31416, inclusive.
X-y-z coordinates are expressed in millimeters. The value can range from -32767 to 32767, inclusive.
For information about the orientation, axes, and the positive directions of the angles of the coordinate
system, see Appendix B in the microphone array white paper.
Frequency values are expressed in Hz. The range of frequency values is bounded only by the size of the field
from wWorkFreqBandLo to wWorkFreqBandHi .
Modified INF for MSVAD Micarray
12/5/2018 • 2 minutes to read • Edit Online

This topic shows how to modify the Micarray.inf sample file to provide setup information about how to install the
sample microphone array described in Microphone Array Geometry Property.
Navigate to Src\Audio\Msvad to locate Micarray.inf. Make a copy of the original file under a new name, and then
edit Micarray.inf as follows:

// Modified micarray.inf file tailored for a microphone array


[Version]
Signature="$CHICAGO$"
Class=MEDIA
Provider=%MSFT%
ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318}
DriverVer = 02/22/2007, 6.0.6000.1
CatalogFile=msvad.cat

[SourceDisksNames]
222="MSVAD Driver Disk","",222

[SourceDisksFiles]
vadarray.sys=222

;;This syntax is only recognized on Windows XP and later versions of Windows- it is needed to install 64-bit
drivers on
;;Windows Server 2003 with Service Pack 1 (SP1) and later versions of Windows Server.

[Manufacturer]
%MfgName%=MicrosoftDS,NTAMD64,NTIA64

;; For Windows Server 2003 Service Pack 1 (SP1) and later versions of Windows, a 64-bit OS will not install a
driver
;; unless the Manufacturer and Models Sections explicitly show it is a driver for that platform
;; But the individual model section decorations (or lack thereof) work as they always have.
;; All of the model sections referred to are undecorated or NT-decorated, hence work on all platforms

[MicrosoftDS]
%MSVAD_MicArray.DeviceDesc%=MSVAD_MicArray,*MSVADMicArray

;; This section enables you to install on x64-based systems

[MicrosoftDS.NTAMD64]
%MSVAD_MicArray.DeviceDesc%=MSVAD_MicArray,*MSVADMicArray

;; This section enables you to install on Itanium-based systems

[MicrosoftDS.NTIA64]
%MSVAD_MicArray.DeviceDesc%=MSVAD_MicArray,*MSVADMicArray

[DestinationDirs]
MSVAD_MicArray.CopyList=10,system32\drivers

;======================================================
; MSVAD_MICARRAY
;======================================================
[MSVAD_MicArray]
AlsoInstall=ks.registration(ks.inf),wdmaudio.registration(wdmaudio.inf)
CopyFiles=MSVAD_MicArray.CopyList
AddReg=MSVAD_MicArray.AddReg

[MSVAD_MicArray.CopyList]
[MSVAD_MicArray.CopyList]
vadarray.sys

[MSVAD_MicArray.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave%,MSVAD.I.Wave
AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_Wave%,MSVAD.I.Wave
AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Topology%,MSVAD.I.Topo

[MSVAD_MicArray.AddReg]
HKR,,AssociatedFilters,,"wdmaud,swmidi,redbook"
HKR,,Driver,,vadarray.sys

HKR,Drivers,SubClasses,,"wave,midi,mixer"

HKR,Drivers\wave\wdmaud.drv,Driver,,wdmaud.drv
HKR,Drivers\midi\wdmaud.drv,Driver,,wdmaud.drv
HKR,Drivers\mixer\wdmaud.drv,Driver,,wdmaud.drv

HKR,Drivers\wave\wdmaud.drv,Description,,%MSVAD_MicArray.DeviceDesc%
HKR,Drivers\midi\wdmaud.drv,Description,,%MSVAD_MIDI%
HKR,Drivers\mixer\wdmaud.drv,Description,,%MSVAD_MicArray.DeviceDesc%

;======================================================
; COMMON
;======================================================
[MSVAD.I.Wave]
AddReg=MSVAD.I.Wave.AddReg
[MSVAD.I.Wave.AddReg]
HKR,,CLSID,,%Proxy.CLSID%
HKR,,FriendlyName,,%MSVAD.Wave.szPname%

[MSVAD.I.Topo]
AddReg=MSVAD.I.Topo.AddReg
[MSVAD.I.Topo.AddReg]
HKR,,CLSID,,%Proxy.CLSID%
HKR,,FriendlyName,,%MSVAD.Topo.szPname%

;======================================================
; MSVAD_MICARRAY
;======================================================
[MSVAD_MicArray.NT]
Include=ks.inf,wdmaudio.inf
Needs=KS.Registration, WDMAUDIO.Registration
CopyFiles=MSVAD_MicArray.CopyList
AddReg=MSVAD_MicArray.AddReg

[MSVAD_MicArray.NT.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave%,MSVAD.I.Wave
AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_Wave%,MSVAD.I.Wave
AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Topology%,MSVAD.I.Topo

[MSVAD_MicArray.NT.Services]
AddService=msvad_micarray,0x00000002,msvad_MicArray_Service_Inst

[msvad_MicArray_Service_Inst]
DisplayName=%msvad_micarray.SvcDesc%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%10%\system32\drivers\vadArray.sys

;======================================================
; COMMON
;======================================================
[Strings]
MSFT="Microsoft"
MfgName="Microsoft Audio DDK"
MSVAD_MicArray.DeviceDesc="Sample Virtual Audio Device (Mic Array) (WDM)"

MSVAD.Wave.szPname="MSVAD Wave"
MSVAD.Wave.szPname="MSVAD Wave"
MSVAD.Topo.szPname="MSVAD Topology"
MSVAD_MIDI="MSVAD -> WDM Midi Device"

Proxy.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
KSCATEGORY_RENDER="{65E8773E-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}"

KSNAME_Wave="Wave"
KSNAME_Topology="Topology"

msvad_micarray.SvcDesc="Sample Virtual Audio Device (Mic Array) (WDM)"

MediaCategories="SYSTEM\CurrentControlSet\Control\MediaCategories"
Simple.NameGuid="{946A7B1A-EBBC-422a-A81F-F07C8D40D3B4}"
Simple.Name="MSVAD (Simple)"

After you modify the file as shown in the preceding example, save it in its original location. For more information
about how to build the microphone array sample driver, see Microphone Array Geometry Property.
Hardware Events
10/23/2019 • 2 minutes to read • Edit Online

Some audio devices provide hardware volume-control knobs, mute switches, or other types of manual controls.
Applications can respond to changes in these controls by adjusting the volume or otherwise changing the way that
the audio stream is played. When the user adjusts a hardware control, the miniport driver uses the IPortEvents
interface to inform the port driver that a hardware event has occurred. The port driver, in turn, notifies the
application of the event so that it can read the new control setting from the device.
Your miniport driver can query the port driver for the IPor tEvents interface at the time that it services the Init call
(see IMinipor tWavePci::Init , for example) from the port driver. On Microsoft Windows 98 SE, Windows Me, and
Windows 2000 and later, that query succeeds. For a code example, see the Sb16 sample audio adapter in the
Windows Driver Kit (WDK).
When the port driver calls your driver's IMinipor t::GetDescription method, the method outputs a
PCFILTER_DESCRIPTOR structure that specifies, among other things, the events that your device supports.
Events can be specified in the automation tables for the Pins and Nodes members of PCFILTER_DESCRIPTOR, and
in the AutomationTable member, which points to the automation table for the filter itself. Each event is specified
by a PCEVENT_ITEM structure. Your driver should set the PCEVENT_ITEM structure's Set and Id members to
KSEVENTSETID_AudioControlChange and KSEVENT_CONTROL_CHANGE , and should load a pointer to your
driver's EventHandler routine into the Handler member. Your driver should also set the
PCEVENT_ITEM_FLAG_BASICSUPPORT bit in the Flags member to indicate basic support for control-change
events, and it should set the PCEVENT_ITEM_FLAG_ONESHOT and/or PCEVENT_ITEM_FLAG_ENABLE bits to
indicate that it supports one-shot and/or recurring notification.
When an application later calls the mixerOpen function (described in the Microsoft Windows SDK documentation)
to request notification of a particular event, the port driver then calls your driver's EventHandler routine with a
pointer to a PCEVENT_REQUEST structure. This structure's Verb member is set to PCEVENT_VERB_ADD and its
EventItem member specifies the event that is to be enabled. The PCEVENT_REQUEST structure also contains a
pointer to a KSEVENT_ENTRY structure that your driver should treat as opaque system data. After enabling the
event, your handler should call IPor tEvents::AddEventToEventList with the same KSEVENT_ENTRY pointer. With
this call, the handler acknowledges that the event is enabled.
When the hardware event occurs and your driver's interrupt-service routine detects a mute or a volume change,
your driver signals the event to the port driver by calling IPor tEvents::GenerateEventList with a set of
parameters that describe the event. For example, the following call describes a control change in a lineout-volume
node:

pPE->GenerateEventList(NULL, KSEVENT_CONTROL_CHANGE,
FALSE, ULONG(-1), TRUE, LINEOUT_VOL);

During this call, the port driver searches its event list for all events that match the call parameters and sends
notification to the clients that are monitoring these events. In this example, pPE is a pointer to the IPor tEvents
object, and LINEOUT_VOL is the node ID that the miniport driver assigns to the lineout-volume node. Unspecified
parameters (such as the event-set GUID and pin ID in the preceding example) are treated as wildcards and always
match the corresponding parameters in the list.
Audio Data Formats and Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

Audio drivers use the KSDATAFORMAT and KSDATARANGE structures to specify audio stream formats:
The digital format of a KS data stream is specified by a KS format descriptor that begins with a
KSDATAFORMAT structure.
The range of stream formats that a KS pin can support is specified by an array of KS data ranges; each array
element is a range descriptor that begins with a KSDATARANGE structure.
For more information about these two structures, see KS Data Formats and Data Ranges. For more information
about KS data ranges, see Data Range Intersections in AVStream.
The remainder of this section discusses the following topics:
Audio Data Formats
Audio Data Ranges
Extensible Wave-Format Descriptors
Multichannel Formats for Home-Theater Systems
Examples of Audio Data Formats and Data Ranges
Audio Data Formats
10/23/2019 • 2 minutes to read • Edit Online

To specify the data format for a wave audio stream, the KSDATAFORMAT structure is followed immediately by
either a WAVEFORMATEX or KSDSOUND_BUFFERDESC structure, and the Specifier member of
KSDATAFORMAT is accordingly set to one of the following two values:
KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Indicates that the data format belongs to a wave stream that is being used by a waveIn or waveOut
application. In this case, if the KSDATAFORMAT structure's FormatSize is large enough, the data-format
specifier following the KSDATAFORMAT structure is a WAVEFORMATEX structure.
KSDATAFORMAT_SPECIFIER_DSOUND
Indicates that the data format belongs to a wave stream that is being used by a DirectSound application. In
this case, the data-format specifier following the KSDATAFORMAT structure is a KSDSOUND_BUFFERDESC
structure, which contains an embedded WAVEFORMATEX structure.
The KSDATAFORMAT_WAVEFORMATEX structure encapsulates both a KSDATAFORMAT structure and the
WAVEFORMATEX structure that follows it. Similarly, the KSDATAFORMAT_DSOUND structure encapsulates both
a KSDATAFORMAT structure and the DSOUND_BUFFERDESC structure that follows it.
For either KSDATAFORMAT_WAVEFORMATEX or KSDATAFORMAT_DSOUND, the last item in the structure is an
embedded WAVEFORMATEX structure; in the case of KSDATAFORMAT_DSOUND, the WAVEFORMATEX structure is
contained in the embedded DSOUND_BUFFERDESC structure. In either case, the WAVEFORMATEX structure might
be the beginning of a WAVEFORMATEXTENSIBLE structure, in which case the wFormatTag member of
WAVEFORMATEX is set to the value WAVE_FORMAT_EXTENSIBLE. For more information, see Extensible Wave-
Format Descriptors.
To specify the data format for a MIDI stream or DirectMusic stream, the KSDATAFORMAT structure is sufficient; it is
not followed by any additional information.
For examples of wave and DirectSound data formats, see PCM Stream Data Format and DirectSound Stream Data
Format. For examples of MIDI and DirectMusic data formats, see MIDI Stream Data Format and DirectMusic Stream
Data Format.
Audio Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

Each pin on a KS filter declares which data formats it supports. The pin factory exposes this information as an array
of data ranges. Unlike the format descriptors described previously, a data range describes a range of data formats.
For example, the data range for a wave pin specifies the range of sample sizes, frequencies, and channels that the
pin supports.
When the miniport driver instantiates a pin, it configures the pin to handle a stream with a particular data format
that it selects from the pin's data ranges. This work is done by the miniport driver's data-intersection handler, which
selects an audio data format that is common to two pins so that they can be connected. For more information, see
Data-Intersection Handlers.
For information about using property requests to query audio pins for their data ranges and select data
intersections, see Pin Data-Range and Intersection Properties.
To specify a data range for a wave pin, the KSDATARANGE structure is followed by information describing the
range of sample sizes, frequencies, and channels that the pin supports. This information, including the
KSDATARANGE structure itself, is encapsulated in the KSDATARANGE_AUDIO structure.
To specify a data range for a MIDI or DirectMusic pin, the KSDATARANGE structure is followed by additional
information, including the maximum number of channels and notes that can be played at the same time. This
information, along with the KSDATARANGE structure itself, is encapsulated in the KSDATARANGE_MUSIC
structure.
This document presents several examples of data ranges that use the KSDATARANGE_AUDIO and
KSDATARANGE_MUSIC structures:
For example declarations of wave and DirectSound data ranges, see PCM Stream Data Range and
DirectSound Stream Data Range.
For example declarations of MIDI and DirectMusic data ranges, see MIDI Stream Data Range and
DirectMusic Stream Data Range.
For example declarations of data ranges for non-PCM formats, see Specifying AC-3 Data Ranges and
Specifying WMA Pro Data Ranges.
Extensible Wave-Format Descriptors
10/23/2019 • 7 minutes to read • Edit Online

The following figure shows the data-format descriptor for a wave audio stream.

As indicated in the figure, the amount of additional format information following the KSDATAFORMAT structure
varies depending on the data format.
Audio systems use this type of format descriptor in several ways:
A format descriptor like the one shown in the preceding figure is passed as a call parameter to a miniport
driver's NewStream method (for example, see IMinipor tWaveCyclic::NewStream ).
The ResultantFormat parameter of the IMinipor t::DataRangeIntersection method points to a buffer into
which the method writes a format descriptor like the one shown in the preceding figure.
The KSPROPERTY_PIN_DATAINTERSECTION get-property request retrieves a format descriptor like the
one shown in the preceding figure.
The KSPROPERTY_PIN_PROPOSEDATAFORMAT set-property request accepts a format descriptor like
the one shown in the preceding figure.
A similar format is used for the KsCreatePin function's Connect call parameter. This parameter points to the
KSPIN_CONNECT structure at the beginning of a buffer that also contains a format descriptor. The format
descriptor, which immediately follows the KSPIN_CONNECT structure, begins with a KSDATAFORMAT
structure like the one shown in the preceding figure.
The format information that follows the KSDATAFORMAT structure should be either a
WAVEFORMATEXTENSIBLE structure or a WAVEFORMATEX structure. WAVEFORMATEXTENSIBLE is an
extended version of WAVEFORMATEX that can describe a broader range of formats than WAVEFORMATEX.
WAVEFORMATEX is an extended version of the pre-WDM WAVEFORMAT structure. WAVEFORMAT is obsolete and
is not supported by the WDM audio subsystem in any version of Microsoft Windows.
Similarly, the PCMWAVEFORMAT structure is an extended version of WAVEFORMAT that is obsolete, but for which
the WDM audio subsystem provides limited support.
For information about WAVEFORMAT and PCMWAVEFORMAT, see the Microsoft Windows SDK documentation.
The four wave-format structures--WAVEFORMAT, PCMWAVEFORMAT, WAVEFORMATEX, and
WAVEFORMATEXTENSIBLE--all begin with the same five members, starting with wFormatTag . The preceding
figure shows these four structures superimposed on each other to highlight the portions of the structures that are
identical. PCMWAVEFORMAT and WAVEFORMATEX extend WAVEFORMAT by adding a wBitsPerSample member,
but WAVEFORMATEX also adds a cbSize member. WAVEFORMATEXTENSIBLE extends WAVEFORMATEX by adding
three members, beginning with Samples .wValidBitsPerSample. (Samples is a union whose other member,
wValidSamplesPerBlock , is used instead of wValidBitsPerSample for some compressed formats.) The
wFormatTag member, which immediately follows the end of the KSDATAFORMAT structure in the buffer, specifies
what kind of format information follows KSDATAFORMAT. The KMixer system driver supports only PCM formats
that use one of the three format tags shown in the following table.

W F O RM AT TA G VA L UE M EA N IN G

WAVE_FORMAT_PCM Integer PCM data format specified by WAVEFORMATEX or


PCMWAVEFORMAT.

WAVE_FORMAT_IEEE_FLOAT Floating-point PCM data format specified by


WAVEFORMATEX.

WAVE_FORMAT_EXTENSIBLE Extended data format specified by


WAVEFORMATEXTENSIBLE.

In fact, KMixer supports only a subset of the PCM formats that can be described by these tag values (and it
supports no non-PCM formats). USB audio devices (see USBAudio Class System Driver) are restricted to this
subset because all PCM-formatted USB audio streams pass through KMixer. (Some non-PCM USB audio streams
can bypass KMixer; for more information, see USB Audio Support for Non-PCM Formats.) However, in Windows XP
and earlier, DirectSound applications can overcome KMixer's restrictions by connecting directly to hardware pins
on WaveCyclic and WavePci devices that support formats not supported by KMixer. For more information, see
DirectSound Hardware Acceleration in WDM Audio.
Note the ambiguity in the meaning of the WAVE_FORMAT_PCM tag value in the preceding table--it can specify
either a WAVEFORMATEX or PCMWAVEFORMAT structure. However, these two structures are nearly identical. The
only difference is that WAVEFORMATEX contains a cbSize member and PCMWAVEFORMAT does not. According to
the WAVEFORMATEX specification, cbSize is ignored if wFormatTag = WAVE_FORMAT_PCM (because cbSize is
implicitly zero); cbSize is used for all other formats. Thus, in the case of a PCM format, PCMWAVEFORMAT and
WAVEFORMATEX contain the same information and can be treated identically.
WAVEFORMATEX can specify only a subset of the formats that WAVEFORMATEXTENSIBLE can specify. Unlike
WAVEFORMATEX, WAVEFORMATEXTENSIBLE can do the following:
1. Specify the number of bits per sample separately from the size of the sample container. For example, a 20-
bit sample can be stored left-justified within a three-byte container. WAVEFORMATEX, which fails to
distinguish the number of data bits per sample from the sample container size, is unable to describe such a
format unambiguously.
2. Assign specific speaker locations to audio channels in multichannel streams. WAVEFORMATEX lacks this
capability and can adequately support only mono and (two-channel) stereo streams.
Any format that is described by WAVEFORMATEX can also be described by WAVEFORMATEXTENSIBLE. For
information about converting a WAVEFORMATEX structure to WAVEFORMATEXTENSIBLE, see Converting Between
Format Tags and Subformat GUIDs.
WAVEFORMATEX is sufficient for describing formats with sample sizes of 8 or 16 bits, but
WAVEFORMATEXTENSIBLE is necessary to adequately describe formats with a sample precision of greater than 16
bits. Here are two examples:
A stream with a sample precision of 24 bits can use a 32-bit container size for efficient processing, but can
be converted to use a 24-bit container to improve storage efficiency without loss of data.
When processing a stream with 24-bit sample data, a rendering device that provides only 20 bits of
precision can use dithering to improve the fidelity of its output signal. Dithering, however, requires
additional processing time, and if the original stream is accurate to only 20 bits, the additional processing is
unnecessary.
In both of these examples, preserving signal quality while making the right tradeoff between processing and
storage efficiency is possible only if both the sample precision and container size are known.
If a simple format can be unambiguously described by either a WAVEFORMATEX or a WAVEFORMATEXTENSIBLE
structure, an audio driver has the option of selecting either structure to describe the format. However, audio drivers
have typically used WAVEFORMATEX to specify mono and (two-channel) stereo PCM formats with 8-bit or 16-bit
samples, and some older applications might expect all audio drivers to use WAVEFORMATEX to specify these
formats.
If a driver supports an audio format that can be unambiguously specified as either a WAVEFORMATEX or a
WAVEFORMATEXTENSIBLE structure, the driver should recognize the format regardless of which of the two
structures a client application or component uses to specify the structure. For example, if an audio device supports
a 44.1-kHz, 16-bit, stereo PCM format, the miniport driver's KSPROPERTY_PIN_PROPOSEDATAFORMAT property
handler and its implementation of the NewStream method should accept that format regardless of whether the
format is specified as a WAVEFORMATEX or a WAVEFORMATEXTENSIBLE structure.
To simplify the processing of format data, drivers typically use WAVEFORMATEXTENSIBLE structures to internally
represent formats. This approach might require the conversion of an input WAVEFORMATEX structure to an
internal WAVEFORMATEXTENSIBLE representation, or the conversion of an internal WAVEFORMATEXTENSIBLE
representation to an output WAVEFORMATEX structure.
When converting a format descriptor from WAVEFORMATEX to WAVEFORMATEXTENSIBLE, if the wFormatTag
member of the WAVEFORMATEX structure is either WAVE_FORMAT_PCM or WAVE_FORMAT_IEEE_FLOAT, set the
dwChannelMask member of the WAVEFORMATEXTENSIBLE structure to either SPEAKER_FRONT_CENTER (for a
mono stream) or SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT (for a stereo stream). The
SPEAKER_FRONT_XXX constants are defined in header file Ksmedia.h.
In all Windows releases except for Windows 98 "Gold", KMixer supports a range of WAVEFORMATEXTENSIBLE
PCM formats that have multiple channels and have up to 32 bits per sample.
The subset of WAVEFORMATEX PCM formats that KMixer supports differs between Windows releases, as shown in
the following table.

W IN DO W S REL EA SE PA C K ED SA M P L E SIZ ES N UM B ER O F C H A N N EL S

Windows 98 "Gold" 8, 16, 24, and 32 bits Multichannel

Windows 98 SE 8 and 16 bits only Mono and stereo only

Windows 98 SE + hotfix 8, 16, 24, and 32 bits Mono and stereo only
W IN DO W S REL EA SE PA C K ED SA M P L E SIZ ES N UM B ER O F C H A N N EL S

Windows 2000 8 and 16 bits only Mono and stereo only

Windows Me 8, 16, 24, and 32 bits Mono and stereo only

Windows XP and later 8 and 16 bits only Mono and stereo only

In WAVEFORMATEXTENSIBLE, dwBitsPerSample is the container size, and wValidBitsPerSample is the number


of valid data bits per sample. Containers are always byte-aligned in memory, and the container size must be
specified as a multiple of eight bits.
Before the WAVEFORMATEXTENSIBLE structure was defined, vendors had to register each new wave format with
Microsoft so that an official, 16-bit format tag could be assigned to the format. (The format tag is contained in the
wFormatTag member of the WAVEFORMATEX structure.) A list of registered format tags appears in public header
file Mmreg.h (for example, WAVE_FORMAT_MPEG).
With WAVEFORMATEXTENSIBLE, registering formats is no longer necessary. Vendors can independently assign
GUIDs to their new formats as needed. (The format GUID is contained in the SubFormat member of
WAVEFORMATEXTENSIBLE.) However, Microsoft lists some of the more popular format GUIDs in public header file
Ksmedia.h (for example, KSDATAFORMAT_SUBTYPE_MPEG). Before defining a new format GUID, vendors should
check the list of KSDATAFORMAT_SUBTYPE_XXX constants in Ksmedia.h to determine whether an appropriate GUID
has already been defined for a particular format.
When using WAVEFORMATEXTENSIBLE, set wFormatTag to WAVE_FORMAT_EXTENSIBLE and SubFormat to the
appropriate format GUID. For integer PCM formats, set SubFormat to KSDATAFORMAT_SUBTYPE_PCM. For PCM
formats that encode sample values as floating-point numbers, set SubFormat to
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT. For either of these formats, set cbSize to
sizeof (WAVEFORMATEXTENSIBLE)-sizeof (WAVEFORMATEX). For information about using
WAVEFORMATEXTENSIBLE to describe non-PCM data formats, see Supporting Non-PCM Wave Formats.
Multichannel Formats for Home-Theater Systems
10/23/2019 • 4 minutes to read • Edit Online

A relatively inexpensive solution for a home-theater system is to connect a set of surround-sound speakers to an
audio adapter on a computer that is running the Windows operating system. Alternately, the user can connect an
external audio/video (A/V) receiver between the adapter outputs and the speakers. In response to the popularity of
home-theater systems, 5.1- and 7.1-channel audio content that has been authored for these systems is becoming
increasingly available.
To accurately render multichannel audio content on a home-theater system requires an audio-format descriptor
that can assign speaker positions to audio channels in multichannel streams. As discussed previously, the
WAVEFORMATEXTENSIBLE structure can specify such speaker assignments.
To help provide audio driver support for home-theater systems, Microsoft has defined a new 7.1-channel speaker
configuration for Microsoft Windows XP and later. This configuration is supported in Windows Vista, Windows XP
with Service Pack 2 (SP2), and Windows Server 2003 with Service Pack 1 (SP1). It is not supported in Windows
Server 2003 with no service packs installed, Windows XP with Service Pack 1, or Windows XP with no service
packs installed.
The new 7.1-channel speaker configuration is shown in the following figure, which is taken from the Windows
multimedia control panel (Mmsys.cpl) in Windows XP with SP2.

The Windows multimedia control panel assigns the name "7.1 home theater speakers" to the new 7.1-channel wide
speaker configuration shown in the preceding figure.
The following figure shows the older 7.1-channel configuration, which is supported in Windows 2000 and later and
in Windows Me/98.

In Windows XP with SP2, the multimedia control panel assigns the name "7.1 wide configuration speakers" to the
older configuration shown in the preceding figure.
In Windows XP with SP2, you can find the two configurations shown in the two preceding figures by following
these steps:
1. In Control Panel (Category View), click Sounds, Speech, and Audio Devices .
2. In the Sounds, Speech, and Audio Devices pane, under Pick a task , click Adjust the system volume .
3. In the Sounds and Audio Devices Proper ties property sheet, on the Volume tab, under Speaker
settings , click Advanced .
4. In the Advanced Audio Proper ties property sheet, under Speaker setup , open the drop-down list and
select one of the two 7.1 speaker configurations.
The configuration shown in the 7.1 Wide Configuration Speakers figure is the Sony Dynamic Digital Sound (SDDS)
configuration, which was introduced in 1993 for use in motion picture theaters. However, few, if any, home-theater
systems use this configuration. Instead, 8-speaker home-theater systems are likely to use the new 7.1 configuration
shown in the 7.1 Home Theater Speakers figure. In addition, minimal home theater content has been authored for
the SDDS configuration, and users can expect most of the available 7.1-channel content to be formatted for the
new 7.1 configuration.
Although the new "7.1 home theaters speakers" configuration largely supplants the old "7.1 wide configuration
speakers" configuration, Windows will continue to support the old configuration, to provide backward
compatibility.
In Windows 2000 and later and in Windows Me/98, the 5.1-channel speaker configuration assigns channels 5 and
6 to the back-left and back-right speakers, respectively. In Windows Vista, Windows Server 2003 with SP1, and
Windows XP with SP2, the 5.1-channel configuration remains unchanged. In contrast to the 7.1-channel
configuration, these Windows versions do not define a new 5.1 format descriptor to distinguish the 5.1 side-
speaker configuration from the 5.1 back-speaker configuration. Because the two configurations are so similar,
defining two 5.1 configurations might have caused confusion among users regarding which configuration to use
and whether to play content authored for one configuration on the other configuration. When positioning the
speakers in a 6-speaker home-theater system, users tend not to distinguish between side and back speaker
positions. Instead, speaker positioning is more likely to be determined by the shape of the room and the placement
of the furniture in the room.
The 5.1-channel surround-sound speaker configuration is shown in the following figure, which is taken from the
Windows multimedia control panel in Windows XP with SP2.

The Windows multimedia control panel assigns the name "5.1 surround sound speakers" to the 5.1-channel
speaker configuration shown in the preceding figure.
Although the differences between the 5.1-channel side-speaker and back-speaker configurations might be
transparent to users, they are not transparent to audio hardware vendors. As mentioned previously, 5.1-channel
content is typically authored for side speakers rather than for back speakers. Thus, when playing 5.1-channel
content through the "7.1 home theater speakers" configuration, the vendor should ensure that the two side-
speaker channels in the 5.1-channel stream play through the side speakers rather than the back speakers. Similarly,
when playing content authored for the "7.1 home theater speakers" configuration through a 5.1 speaker
configuration with side speakers, the channels for the 7.1 side speakers most naturally map to the side speakers in
the 5.1 configuration. For an audio device with stream-processing capabilities, another alternative is for the device
to attempt to preserve the content in channels 4 and 5 by mixing them with channels 6 and 7 before playing them
through the side speakers in the 5.1 configuration.
This section includes:
Channel Mask
Mapping Stream Formats to Speaker Configurations
Header File Changes
Channel Mask
10/23/2019 • 2 minutes to read • Edit Online

In Windows, the WAVEFORMATEXTENSIBLE structure defines the data format for a multichannel PCM audio
stream. This structure specifies parameters such as the number of bits per PCM sample, the number of channels in
the stream, and the channel mask. The channel mask specifies the mapping of channels to speakers. The following
figure shows the individual bits in the channel mask.

Each bit in the channel mask represents a particular speaker position. If the mask assigns a channel to a particular
speaker position, the mask bit that represents that position is set to 1; all mask bits for unassigned speaker
positions are set to 0. The WAVEFORMATEXTENSIBLE structure defines additional bits in the channel mask that are
not shown in the preceding figure, but these bits have no bearing on the home-theater speaker configurations
under discussion and are omitted for simplicity.
The encoding of speaker positions in the channel mask in the preceding figure is similar to that used for the
property value of a KSPROPERTY_AUDIO_CHANNEL_CONFIG property request. For more information, see
KSAUDIO_CHANNEL_CONFIG .
The following table shows the meaning of each mask bit in the preceding figure.

B IT N UM B ER SP EA K ER P O SIT IO N DESC RIP T IO N

0 FL Front left

1 FR Front right

2 FC Front center

3 LFE Low-frequency effects

4 BL Back left

5 BR Back right

6 FLC Front left of center

7 FRC Front right of center

8 BC Back center

9 SL Side left
B IT N UM B ER SP EA K ER P O SIT IO N DESC RIP T IO N

10 SR Side right

For example, the 7.1 home theater speakers configuration is described by a channel mask value of 0x63F, which
indicates that the eight channels in the stream are assigned to the following speaker positions (and in the following
order): FL, FR, FC, LFE, BL, BR, SL, and SR. For another example, the 7.1 wide configuration speakers
configuration is described by a channel mask value of 0xFF, which indicates that the eight channels in the stream
are assigned to the following speaker positions: FL, FR, FC, LFE, BL, BR, FLC, and FRC.
The following figure shows the correspondence between the channel mask 0x63F and the 7.1 home theater
speakers configuration.

The left side of the preceding figure shows the recording of audio content into the 7.1 home theater speakers
stream format. The small circle at the center of the grid represents the listener's position. Each small, black
rectangle represents a microphone. The eight channels are numbered from 0 to 7. The FL microphone records into
channel 0, the FR microphone records into channel 1, and so on.
The right side of the preceding figure shows the same 7.1-channel stream being played back through an eight-
speaker surround configuration. In this case, each small, black rectangle represents a speaker. Seven of the
speakers are mapped to positions on the grid surrounding the listener. The mapping does not assign a grid
position to the LFE speaker (subwoofer); this omission is based on the assumption that these speakers typically
produce only low-frequency sounds, which are nondirectional.
Mapping Stream Formats to Speaker Configurations
12/5/2018 • 6 minutes to read • Edit Online

When asked to play a stream format that does not match the audio device's speaker configuration, the audio driver
has several options:
Decline to play the stream.
Play the stream by performing a one-to-one mapping of individual channels to speakers. If any channels are
left over after a channel has been mapped to each speaker, discard the leftover channels. Conversely, if any
speakers are left over after all of the channels have been assigned to speakers, play silence through the
leftover speakers.
Play the stream by mixing the channels in the original stream to generate precisely the number of channels
required for the speaker configuration. If there are more channels in the original stream than there are
speakers, this approach avoids loss of the content that would result from simply discarding the excess
channels. The mixing and format conversion can be performed in software or hardware.
Regarding the third option, the driver should avoid directly performing software mixing. Instead, the hardware
vendor should install a global-effects (GFX) software module to process the stream before it reaches the audio
device. In Windows Vista, global effects are implemented as GFX audio processing objects (APOs). In Windows
Server 2003 and Windows XP, global effects were implemented as GFX filters.
Playing a 5.1-Channel Stream on a 7.1 Speaker Configuration
The following figure shows a stream that is recorded for a 5.1 surround sound speakers configuration (left) but is
played through a 7.1 home theater speakers configuration (right).

In the preceding figure, the recorded 5.1 format does not contain channel information for the BL and BR speaker
positions in the 7.1 speaker configuration. Thus, these two speakers are silent. (Another, more difficult alternative
would be for the audio device to synthesize two additional channels for the BL and BR speakers by mixing the
content from the original six channels in the recording.)
According to the definitions for the channel-mask bits, the channel mask for recording the 5.1 stream shown on the
left side of the preceding figure should be 0x60F, which assigns the six channels to the following speaker positions:
FL, FR, FC, LFE, SL, and SR. (This is the side-speaker 5.1 configuration discussed earlier.) In fact, the channel mask for
the 5.1 stream is 0x3F rather than 0x60F for reasons that were mentioned previously and will now be explained in
detail.
In earlier versions of Windows (Windows Server 2003, Windows XP with SP1, Windows 2000, and Windows
Me/98), the interpretation of the channel mask 0x3F is that it assigns the six channels in the 5.1 format to the
following speaker positions: FL, FR, FC, LFE, BL, and BR. (This is the back-speaker 5.1 configuration.) However, the
interpretation in Windows Vista, Windows Server 2003 with SP1, and Windows XP with SP2 is different: by
convention, the 5.1 format with the channel mask 0x3F is interpreted to mean the side-speaker 5.1 configuration
instead of the back-speaker 5.1 configuration.
Interpreting the channel mask in this manner eliminates the requirement to introduce a second 5.1-channel format
descriptor to distinguish the side-speaker 5.1 configuration from the back-speaker 5.1 configuration. These two
configurations are so similar that typical users might have difficulty distinguishing between them. Although having
only a single 5.1-channel format descriptor avoids confusing users, it does require hardware vendors to remember
to interpret the 0x3F channel mask to mean that channels 5 and 6 are assigned to the SL and SR speaker positions
instead of the BL and BR positions. In return for having to remember this special-case interpretation of the channel
mask for a 5.1 stream, vendors can spare users the difficulty of distinguishing between two very similar 5.1-
channel format descriptors.
Vendors who believe that at least some of their users might want to distinguish between the side-speaker 5.1
configuration and back-speaker 5.1 configuration have the option of providing a user-interface (UI) program for
this purpose. Through the UI, users can select whether channels 4 and 5 in a 5.1-channel stream should drive the
back speakers rather than the side speakers in a 7.1 home theater speakers configuration.
Playing a 7.1-Channel Stream on a 5.1 Speaker Configuration
The following figure shows a stream recorded for a 7.1 home theater speakers configuration (left) being played
through a 5.1 surround sound speakers configuration (right). The channel mask for the 7.1-channel stream is
0x63F.

In this example, channels 6 and 7, which contain the data for the side speaker positions in the 7.1 configuration,
play through the side speaker positions in the 5.1 configuration. The audio device simply discards channels 4 and 5,
which contain the data for the back speaker positions in the 7.1 configuration, when it plays the stream on the 5.1
configuration. As mentioned previously, another alternative (not shown in the preceding figure) is for the device to
attempt to preserve the content in channels 4 and 5 by mixing them with channels 6 and 7 before playing them
through the side speakers in the 5.1 configuration.
System Mixer Behavior
In Windows Server 2003, Windows XP, Windows 2000, and Windows Me/98, the multichannel audio streams that
the audio device plays are typically generated by the software system mixer, Kmixer.sys. Before the stream can
begin playing, the system mixer and audio driver must negotiate a stream format that both mixer and driver can
handle.
When asked to play a multichannel stream with a format that does not match the audio device's speaker
configuration, the audio driver can decline the request, in which case the negotiation continues.
The system mixer can convert content from a 5.1-channel input stream into a 7.1-channel output stream (to the
audio device), and vice versa, although it prefers to avoid such conversions to preserve the quality of the input
stream. Thus, the system mixer begins the negotiation by asking the driver to accept a stream with the same format
as the highest quality input stream to the system mixer. Typically, this means that if the system mixer has an input
stream in a 5.1- or 7.1-channel format, it will ask the driver to accept a stream in the same format. If the driver
rejects this format, the system mixer continues negotiating by asking the driver if it can handle other stream
formats.
For example, if the driver for an audio device with a 5.1 speaker configuration declines a request from the system
mixer to play a 7.1-channel stream, the system mixer continues the negotiation by offering to convert the 7.1-
channel stream to a 5.1-channel stream. If the driver accepts this format, the system mixer performs the stream
conversion for the driver.
When designing an audio driver, the driver writer must decide whether to handle its own format conversions or
rely on the system mixer to do the conversions. The driver might need to handle the conversions in either of the
following situations:
If the driver requires the conversion to be performed in a manner that differs from the conversion
performed by the system mixer.
If the driver must play streams that bypass the system mixer.
In the second situation, a stream can bypass the system mixer if is being played from a Microsoft DirectSound
hardware-accelerated buffer directly to a hardware-mixing pin on the audio device. Also, some "pro audio"
applications send their streams directly to the audio device either to avoid the latency of the system mixer or to
prevent the mixing process from altering the digital sample values in the original audio stream.
In Windows Server 2003 with SP1 and Windows XP with SP2, if the system mixer produces a 5.1-channel output
stream, the mixer always sets the stream's channel mask to 0x3F. The system mixer behaves this way even if it
receives a 5.1-channel input stream with a channel mask of 0x60F. With this behavior, an audio driver never
receives a 5.1-channel stream with a channel mask of 0x60F from the mixer.
If the system mixer receives a 7.1-channel input stream with a channel mask of 0x63F and produces a 5.1-channel
output stream (with a channel mask of 0x3F), the mixer copies channels 6 and 7 in the input stream to channels 4
and 5 in the output stream. The mixer discards channels 4 and 5 (for the two back speakers) from the 7.1-channel
input stream. This behavior ensures that the channels containing the content for the two side speakers in the 7.1-
channel stream play through the side speakers in the 5.1 speaker configuration.
Header File Changes
10/23/2019 • 2 minutes to read • Edit Online

The Windows Driver Kit (WDK) contains two header files that define the speaker configurations that are supported
by the Windows multimedia control panel:
Ksmedia.h defines the channel masks for the KSAUDIO_CHANNEL_CONFIG structure that is used by the
KSPROPERTY_AUDIO_CHANNEL_CONFIG property request.
Dsound.h defines a list of speaker-configuration identifiers that can be submitted to the
IDirectSound::SetSpeakerConfig method. For more information about this method, see the Windows
SDK documentation.
In Windows Server 2003, Windows XP with SP1, Windows 2000, and Windows Me/98, Ksmedia.h defines the
channel masks that are shown in the following table for 5.1- and 7.1-channel streams.

PA RA M ET ER N A M E C H A N N EL M A SK SP EA K ER P O SIT IO N S

KSAUDIO_SPEAKER_5POINT1 0x3F FL, FR, FC, LFE, BL, BR

KSAUDIO_SPEAKER_7POINT1 0xFF FL, FR, FC, LFE, BL, BR, FLC, FRC

The two channel masks in the preceding table represent the 5.1 speaker configuration and the 7.1 speaker
configuration. To identify the same two speaker configurations, Dsound.h defines the following speaker-
configuration IDs:

#define DSSPEAKER_5POINT1 0x00000006


#define DSSPEAKER_7POINT1 0x00000007

In Windows XP with SP2 and later versions of Windows, Ksmedia.h defines the channel masks shown in the
following table for 5.1- and 7.1-channel streams.

PA RA M ET ER N A M E C H A N N EL M A SK SP EA K ER P O SIT IO N S

KSAUDIO_SPEAKER_5POINT1 0x3F FL, FR, FC, LFE, BL, BR

KSAUDIO_SPEAKER_7POINT1_SURR 0x63F FL, FR, FC, LFE, BL, BR, SL, SR


OUND

By comparing the two preceding tables, the following points are apparent:
The meaning of the channel mask 0x3F in the first table has not changed in the second table, even though in
Windows SP2 and later versions of Windows, KSAUDIO_SPEAKER_5POINT1 is interpreted to use SL and SR
speakers instead of BL and BR.
A new channel mask that has the value 0x63F is supported. This channel mask represents the 7.1 home
theater speaker configuration.
Note In Windows Vista and later versions of Windows, the KSAUDIO_SPEAKER_7POINT1 speaker
configuration is no longer supported. As a result, it is not an available option in Control Panel.
To represent the same set of speaker configurations, Dsound.h defines the following speaker-configuration IDs:

#define DSSPEAKER_5POINT1 0x00000006


#define DSSPEAKER_7POINT1 0x00000007
#define DSSPEAKER_7POINT1_SURROUND 0x00000008
#define DSSPEAKER_7POINT1_WIDE DSSPEAKER_7POINT1

DSSPEAKER_7POINT1_SURROUND represents the new 7.1 home theater speaker configuration in Control Panel.
DSSPEAKER_7POINT1 and DSSPEAKER_7POINT1_WIDE are both names for the same 7.1 wide configuration
speakers configuration.
For more information about speaker configuration for DirectSound, see DirectSound Speaker-Configuration
Settings.
Examples of Audio Data Formats and Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

The following examples show how to use the KSDATAFORMAT and KSDATARANGE structures to describe some
of the more common formats for audio streams:
Analog Audio Stream Data Range
DirectMusic Stream Data Format
DirectMusic Stream Data Range
DirectSound Stream Data Format
DirectSound Stream Data Range
MIDI Stream Data Format
MIDI Stream Data Range
PCM Stream Data Format
PCM Stream Data Range
PCM Multichannel Stream Data Format
PCM Multichannel Stream Data Range
PCM High Bitdepth Stream Data Format
PCM High Bitdepth Stream Data Range
Analog Audio Stream Data Range
6/25/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE structure to describe the data range for an analog audio stream.

DataRange.FormatSize = sizeof(KSDATARANGE);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE);

Typically, a miniport driver uses this type of data range to describe the analog signal passing through a bridge pin,
which represents a hardwired connection on an audio adapter card. For more information about bridge pins, see
Audio Filter Graphs. Also, see the code example in Exposing Filter Topology.
DirectMusic Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATAFORMAT structure to describe the data format of a DirectMusic stream.

DataFormat.FormatSize = sizeof(KSDATAFORMAT);
DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DIRECTMUSIC);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE);
DirectMusic Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_MUSIC structure to describe the data range for a DirectMusic stream.

DataRange.FormatSize = sizeof(KSDATARANGE_MUSIC);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DIRECTMUSIC);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE);
Technology = STATICGUIDOF(KSMUSIC_TECHNOLOGY_WAVETABLE);
Channels = 0;
Notes = 0;
ChannelMask = 0xFFFF;
DirectSound Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATAFORMAT_DSOUND structure to describe the data format of a DirectSound stream.

DataFormat.FormatSize = sizeof(KSDATAFORMAT_DSOUND);
DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND);
BufferDesc.Flags = KSDSOUND_BUFFER_LOCHARDWARE;
BufferDesc.Control = KSDSOUND_BUFFER_CTRL_3D;
BufferDesc.WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
BufferDesc.WaveFormatEx.nChannels = 2;
BufferDesc.WaveFormatEx.nSamplesPerSec = 22050;
BufferDesc.WaveFormatEx.nAvgBytesPerSec = 88200;
BufferDesc.WaveFormatEx.nBlockAlign = 4;
BufferDesc.WaveFormatEx.wBitsPerSample = 16;
BufferDesc.WaveFormatEx.cbSize = 0;
DirectSound Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_AUDIO structure to describe the data range for a DirectSound stream.

DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND);
MaximumChannels = 4; // max number of channels, or -1 for unlimited
MinimumBitsPerSample = 2;
MaximumBitsPerSample = 16; // 16, 24, 32, etc.
MinimumSampleFrequency = 5000;
MaximumSampleFrequency = 48000;

The member values in this example are similar to those of the PCM multichannel stream data range example, with
the exception of the MaximumBitsPerSample value. This value is set to the sample container size and should be
a multiple of eight. For example, if the device supports 20 bits of valid audio data in 24-bit containers, the value for
MaximumBitsPerSample should be set to 24.
MIDI Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATAFORMAT structure to describe the data format of a MIDI stream.

DataFormat.FormatSize = sizeof(KSDATAFORMAT);
DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE);
MIDI Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_MUSIC structure to describe the data range for a MIDI stream.

DataRange.FormatSize = sizeof(KSDATARANGE_MUSIC);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE);
Technology = STATICGUIDOF(KSMUSIC_TECHNOLOGY_PORT);
Channels = 0;
Notes = 0;
ChannelMask = 0xFFFF;
PCM Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATAFORMAT_WAVEFORMATEX structure to describe the data format of a PCM stream.

DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX);
DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
Format.wFormatTag = WAVE_FORMAT_PCM;
Format.nChannels = 2;
Format.nSamplesPerSec = 44100;
Format.nAvgBytesPerSec = 176400;
Format.nBlockAlign = 4;
Format.wBitsPerSample = 16;
Format.cbSize = 0;
PCM Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_AUDIO structure to describe the data range for a PCM stream.

DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
MaximumChannels = 2;
MinimumBitsPerSample = 2;
MaximumBitsPerSample = 16;
MinimumSampleFrequency = 5000;
MaximumSampleFrequency = 48000;
PCM Multichannel Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses an extended version of a KSDATAFORMAT_WAVEFORMATEX structure to describe the data
format of a PCM multichannel stream.

DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEXTENSIBLE);


DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
Format.nChannels = 4;
Format.nSamplesPerSec = 44100;
Format.nAvgBytesPerSec = 352800;
Format.nBlockAlign = 8;
Format.wBitsPerSample = 16;
Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
Format.wValidBitsPerSample = 16;
Format.dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
Format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
PCM Multichannel Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_AUDIO structure to describe the data range for a PCM multichannel stream.

DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
MaximumChannels = 4; // max number of channels, or -1 for unlimited
MinimumBitsPerSample = 2;
MaximumBitsPerSample = 16;
MinimumSampleFrequency = 5000;
MaximumSampleFrequency = 48000;
PCM High Bitdepth Stream Data Format
10/23/2019 • 2 minutes to read • Edit Online

This example uses an extended version of a KSDATAFORMAT_WAVEFORMATEX structure to describe the data
format of a PCM high-bitdepth stream. This is similar to the PCM multichannel example, with the exception of the
values for Format.wBitsPerSample and Format.wValidBitsPerSample that appear below.

DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEXTENSIBLE);


DataFormat.Flags = 0;
DataFormat.SampleSize = 0;
DataFormat.Reserved = 0;
DataFormat.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataFormat.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataFormat.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
Format.nChannels = 4;
Format.nSamplesPerSec = 44100;
Format.nAvgBytesPerSec = 529200;
Format.nBlockAlign = 8;
Format.wBitsPerSample = 24;
Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
Format.wValidBitsPerSample = 20;
Format.dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
Format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
PCM High Bitdepth Stream Data Range
10/23/2019 • 2 minutes to read • Edit Online

This example uses a KSDATARANGE_AUDIO structure to describe the data range for a PCM high-bitdepth stream.

DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
DataRange.Flags = 0;
DataRange.SampleSize = 0;
DataRange.Reserved = 0;
DataRange.MajorFormat = STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO);
DataRange.SubFormat = STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM);
DataRange.Specifier = STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX);
MaximumChannels = 4; // max number of channels, or -1 for unlimited
MinimumBitsPerSample = 2;
MaximumBitsPerSample = 24; // 24, 32, etc.
MinimumSampleFrequency = 5000;
MaximumSampleFrequency = 48000;

The member values in this example are similar to those in the PCM Multichannel Stream Data Range example, with
the exception of the MaximumBitsPerSample value, which is greater than 16. This value is set to the maximum
number of valid bits supported. For example, if the device supports 20 bits of valid audio data in 24-bit containers,
the value for MaximumBitsPerSample should be set to 20.
Digital Rights Management
12/5/2018 • 2 minutes to read • Edit Online

Digital Rights Management (DRM) provides content providers with the means to protect their proprietary music or
other data from unauthorized copying and other illegal uses. DRM technology protects digital content by
encrypting it and attaching to it usage rules that determine the conditions under which a user can play back the
content. Usage rules typically prevent copying or limit the number of times that the content plays. The operating
system works together with drivers to enforce these rules.
DRM is designed to be transparent to users unless they attempt to violate the usage rules that they agreed to when
they purchased the digital content.
Any digital-audio content that is protected by DRM can be played only by trusted audio drivers. These are drivers
that have passed hardware compatibility testing by Microsoft to verify that they are DRM-compliant and contain
no loopholes through which the DRM security measures can be circumvented.
In addition, protected content cannot be played when a debugger is attached to the driver.
For Microsoft Windows Me drivers, WHQL (Microsoft Windows Hardware Quality Lab) testing for DRM
compliance is optional. However, for drivers in Windows XP and later, DRM compliance is required. For details, see
the DRM Requirements topic in the following list.
This section presents the following topics:
DRM Overview
Content IDs and Content Rights
Forwarding DRM Content IDs
DRM Requirements
Developing and Debugging DRM Drivers
DRM Functions and Interfaces
DRM Overview
12/5/2018 • 2 minutes to read • Edit Online

DRM for digital audio is implemented on Microsoft Windows 2000 and later, and Windows Me/98. However, only
Microsoft Windows XP and later, and Windows Me, implement DRM security within the kernel. Currently, Windows
provides no DRM security for MIDI streams or for DLS sets.
DRM-protected digital content is stored in encrypted form on a disk or other storage-media type. The encryption
algorithm scrambles the content to make it unintelligible until it has been decrypted. During playback, the content
remains scrambled as it is read from the disk and buffered in memory. Near the end of the data path, the DRMK
system driver (Drmk.sys) unscrambles the data and feeds it directly to the audio driver to be played. By limiting the
extent of the data path over which unscrambled content is transmitted, DRMK makes the content less vulnerable to
unauthorized copying.
In Windows 2000 and Windows 98, a security loophole allows users to easily load rogue drivers that route the
playback of secure content to disk in unencrypted form. Windows XP and later, and Windows Me, close this
loophole by allowing only trusted audio drivers to play DRM-protected content.
In Windows XP and later, and Windows Me, secure content remains scrambled while it traverses the audio-data
path until it enters the protected environment of the kernel. Within the kernel, protected components unscramble
the data and feed the unscrambled data to a trusted driver for playback. When configuring a filter graph to play
back an unscrambled audio stream, DRMK authenticates the adapter driver for each KS filter that it places in the
graph. The system informs the driver of the usage rules for the protected content. The driver, in turn, advises DRMK
of any downstream filters to which it routes the content, and the system authenticates those filters as well. This
process continues until the graph is complete. The system rejects the entire graph if the digital playback stream
passes through any component that is not DRM-compliant.
A DRM-compliant driver must prevent unauthorized copying while digital content is being played. In addition, the
driver must disable all digital outputs that can transmit the content over a standard interface (such as S/PDIF)
through which the decrypted content can be captured. Note that this requirement does not apply to USB devices.
Currently, DRMK plays secure content only through a USB speaker device with no digital outputs.
Content IDs and Content Rights
10/23/2019 • 2 minutes to read • Edit Online

A content ID (identifier) is a ULONG value that the DRMK system driver generates at runtime to identify DRM-
protected content in the audio-data stream that feeds into a particular pin.
Content rights are a digital representation of the rights granted by the content provider to the user for playing and
copying DRM-protected content. Content rights are specified in the form of a DRMRIGHTS structure that DRMK
passes to the audio driver.
DRMRIGHTS contains two flags: DigitalOutputDisable and CopyProtect . If the DigitalOutputDisable flag is
set, the driver must disable any digital outputs that connect to external devices (through an S/PDIF connector, for
example). If the CopyProtect flag is set, the driver must disable features that might allow a persistent copy of the
secure content to be saved to disk or to any other form of nonvolatile storage. For example, typical audio hardware
allows a playback signal to be routed through the capture channel. If this signal is in digital form, the captured
signal may be a perfect digital copy of the input signal. If the playback mix contains data from any stream that has
a CopyProtect flag set, the driver must mute the playback-capture path.
A DRM-compliant audio driver must support the IDrmAudioStream interface on its WaveCyclic and WavePci
miniport driver objects, which expose sink pins for rendering audio data. In order to obtain a reference to an
IDrmAudioStream object from the driver, DRMK calls the Quer yInterface method on the pin. The pin has an
interface of type IMiniportWaveCyclicStream or IMiniportWavePciStream. The IDrmAudioStream interface
supports only one method, IDrmAudioStream::SetContentId (in addition to the three IUnknown methods).
When DRMK calls SetContentId , it passes in a content ID and content rights, which the driver associates with the
pin's data stream.
Instead of calling the DRM functions in Drmk.sys directly, a WaveCyclic or WavePci miniport driver can access the
DRM functions through the IDrmPort2 interface (IDrmPor t2 is derived from base class IDrmPort). In Microsoft
Windows XP and later, the WaveCyclic and WavePci port drivers support IDrmPor t2 . The miniport driver obtains a
reference to the port driver's IDrmPor t2 interface by calling the port object's Quer yInterface method with
REFIID IID_IDrmPort2.
Some audio drivers support hardware mixing and can handle several input data streams at the same time. This
type of driver must keep track of both the content IDs for the individual streams and the composite content rights
of all the streams. The driver calls IDrmPor t::CreateContentMixed to determine the composite rights for a
mixed stream and to create a content ID to identify that stream. When the driver finishes using the content ID, it
must call IDrmPor t::DestroyContent to delete the content ID.
Each time an input stream is added to or removed from a mixer, the driver must delete the content ID for the old
mix and create a new content ID for the new mix. Before deleting an old content ID, the driver must first
successfully forward a new content ID to all the streams to which it previously forwarded the old content ID. For
more information, see Forwarding DRM Content IDs.
Forwarding DRM Content IDs
10/23/2019 • 5 minutes to read • Edit Online

The DRMK system driver unscrambles an audio playback stream containing protected content. DRMK implements
a KS filter that takes an input stream containing the scrambled data, unscrambles it, and feeds the unscrambled
stream into a data path consisting of some number of kernel-resident modules. These modules can be KS filters or
other types of drivers. The data path typically ends in an audio-rendering device that converts the digital content to
an analog signal that can be played through speakers.
Before allowing the unscrambled content to enter the data path, DRMK verifies that the data path is secure. To do
so, DRMK authenticates each module in the data path, beginning with the module at the upstream end of the data
path and moving downstream to the other end of the data path. The following figure illustrates this process.

In the preceding figure, the solid arrows represent the data path, and the dashed arrows represent the
communications necessary to verify that the data path is secure. The unscrambled data enters the path only after
DRMK has finished authenticating all of the modules in that path.
After DRMK authenticates each module, that module provides DRMK with information about the next module in
the data path so that it can also be authenticated. As each module is authenticated, it receives the DRM content ID
that identifies the stream.
Beginning at the upstream end of the secure data path, DRMK forwards the content ID to module A, which in turn
forwards the content ID to module B. This process continues until the content ID is forwarded to module Z, the last
module in the secure data path.
The following figure shows a pair of adjacent modules in the data path.
The module on the upstream side calls one of the following DRM functions to provide DRMK with information
about the downstream module and to forward the content ID to that module:
DrmFor wardContentToDeviceObject
DrmFor wardContentToInterface
DrmAddContentHandlers
Each of these "forwarding" functions provides DRMK with the DRM content ID that identifies the protected stream,
and with information that DRMK needs to authenticate the downstream module. The choice of which of these three
functions to call depends on the type of interface that the two adjacent modules use to communicate with each
other as they manage the transfer of protected content:
1. If the upstream module calls IoCallDriver to communicate with the downstream module, the downstream
module is a part of a WDM driver. In this case, the upstream module calls
DrmFor wardContentToDeviceObject to provide DRMK with the device object representing the
downstream module. DRMK uses the device object to authenticate the downstream module.
2. If the two modules communicate through a COM interface that the downstream module implements, the
upstream module calls DrmFor wardContentToInterface . This call provides DRMK with a pointer to the
downstream module's COM interface. DRMK calls only the IUnknown methods in this interface and makes
no assumptions about the other methods, although the two modules themselves must agree on what these
methods do. DRMK verifies that the entry point for each method in the interface belongs to an
authenticated module. If the entry points are distributed among several modules, DRMK authenticates all of
these modules.
3. If the two modules use neither a COM interface nor the IoCallDriver function to communicate, the
upstream module calls DrmAddContentHandlers to provide DRMK with a list of entry points to "content
handlers" that are implemented in the downstream module. DRMK does not call the content handlers and
makes no assumptions regarding the functions they perform. DRMK does, however, authenticate the
module (or modules) in which the entry points reside.
After being authenticated, the downstream module requires the following information:
The DRM content ID that identifies the stream containing the protected content. The module requires this ID
to inform DRMK of any module, further downstream, to which it plans to send the protected content.
The DRM content rights associated with the protected content. The module requires the content rights in
order to enforce the appropriate level of security.
Each of the three forwarding functions provides this information to the module in a slightly different manner:
1. The DrmFor wardContentToDeviceObject function sends a
KSPROPERTY_DRMAUDIOSTREAM_CONTENTID set-property request to the downstream module's
device object. This request forwards the stream's content ID and content rights to the downstream module.
2. The DrmFor wardContentToInterface function queries the downstream module's COM interface for the
IDrmAudioStream interface. If the query succeeds, the function calls the IDrmAudioStream::SetContentId
method to forward the content ID and content rights to the downstream module.
3. In the case of the DrmAddContentHandlers function, the caller (the upstream module) is responsible for
forwarding the stream's content ID and content rights to the downstream module. Once
DrmAddContentHandlers returns with a success code indicating that the downstream module has been
authenticated, the upstream module passes the content ID and content rights to the downstream module by
calling one of its content handlers.
If the upstream module is a WaveCyclic or WavePci miniport driver, it can call the appropriate DRM function
indirectly through one of the following methods:
IDrmPor t2::For wardContentToDeviceObject
IDrmPor t::For wardContentToInterface
IDrmPor t2::AddContentHandlers
For more information, see DRM Functions.
For simplicity, the preceding discussion assumes that each module in the data path accepts a stream from a single
source and forwards that stream to at most one downstream module. In fact, a module can forward a stream to
two or more downstream modules, but it must first authenticate each downstream module by calling one of the
three forwarding functions. Similarly, a module can mix together several input streams, but it must respect the
content rights of the input streams by providing the appropriate level of protection to the mixed output stream. For
more information, see the discussion of the DrmCreateContentMixed function in Content IDs and Content
Rights.
A typical secure data path consists of the KMixer system driver followed by a wave filter that represents the audio
rendering device. The filter is implemented as a WaveCyclic or WavePci miniport driver in combination with the
corresponding port driver. To verify that the data path is secure, DRMK forwards the content ID to KMixer, which in
turn forwards the content ID to the filter. The port driver, which implements the generic filter functionality, receives
the content ID and forwards it to the miniport driver. Specifically, the port driver calls the
DrmFor wardContentToInterface function to forward the content ID to the stream object that the miniport
driver has instantiated to represent the wave-output pin on the audio rendering device. One of the parameter
values for this call is a pointer to the stream object's IMiniportWaveCyclicStream or IMiniportWavePciStream
interface. Through this interface, the function queries the stream object for its IDrmAudioStream interface and
calls that interface's SetContentId method.
For more information, see the implementations of the SetContentId method in the sb16 and msvad sample
drivers in the Microsoft Windows Driver Kit (WDK).
DRM Requirements
10/23/2019 • 2 minutes to read • Edit Online

This section presents the requirements that an audio miniport driver must meet to pass DRM-compliance testing
by Microsoft Windows Hardware Quality Lab (WHQL). These requirements apply specifically to WaveCyclic and
WavePci audio miniport drivers, which are hardware-specific counterparts to the WavePci and WaveCyclic port
drivers in the Port Class Library (Portcls.sys). DRM-compliance testing is not currently available for USB drivers.
In Windows Me and in Windows XP and later, only trusted audio drivers can play DRM-protected content. Windows
identifies a trusted driver by means of a DRM-specific digital signature that is stored in the driver's .cat (catalog)
files. Microsoft issues a DRM signature only for a driver that passes the DRM-compliance test as part of the
hardware-compatibility testing administered by WHQL.
For Windows Me drivers, the DRM-compliance test is optional and is performed only at the hardware vendor's
request. The DRM signature is separate from and in addition to the Windows-logo signature. Note that a driver that
passes the Windows-logo test but not the DRM-compliance test still can play content that is not protected by DRM
security.
For Windows XP and later, however, the DRM-compliance test is a required part of WHQL testing. A driver must
pass the DRM-compliance test in order to qualify for the "Designed for Windows XP" logo.
The DRM-compliance test requires a trusted audio driver to do the following:
The audio miniport driver must implement the IDrmAudioStream interface in its stream objects, which must
return an object of type IDrmAudioStream if queried for IID_IDrmAudioStream.
When copy protection is requested (DRMRIGHTS .CopyProtect = TRUE ), the audio driver must disable the
ability to capture the stream currently being played back. This means that the driver must not save the
unprotected digital content to any form of nonvolatile storage, which includes hard disk, EEPROM, memory
card, and memory stick. Also, the driver must disable the capture multiplexer on an output D/A converter
and otherwise prevent the loopback of digital content.
When an audio driver is asked to disable the digital audio output on the device
(DRMRIGHTS.DigitalOutputDisable = TRUE ), it must disable all digital audio outputs that are capable of
transmitting content over a standard interface through a standard interconnection scheme. Digital outputs
include--but are not strictly limited to--S/PDIF, IEEE 1394, parallel, serial, modem, and network ports. (This
requirement does not currently apply to USB.)
When handling secure content, an audio driver must never attach an untrusted driver to its stack. In other
words, the audio driver must rely only on other components that also contain DRM signatures. The driver
must never facilitate the transfer of audio data to any component that does not have a DRM signature. In
particular, if a driver passes digital content to another component, the driver must use the DRM APIs in the
kernel to inform the DRMK system driver of this fact.
In addition to passing the DRM-compliance test, the audio device and driver must not allow a user to select a mode
of operation that defeats or subverts the DRM components in the kernel. Specifically, the driver must not provide
registry settings, user control panels, or other means of disabling the DRM functions.
Developing and Debugging DRM Drivers
10/23/2019 • 2 minutes to read • Edit Online

The following checklist may help driver writers avoid some common pitfalls:
If the driver disables wave-out capture and S/PDIF output while DRM-protected content plays, the driver
should remember to enable them again after the DRM-protected content finishes playing (and the DRM
buffer is destroyed).
If the device performs hardware mixing, the driver should keep track of any changes in composite usage
rights that occur when streams are added to or removed from the mix. Any time the mix includes one or
more copy-protected DRM streams, for example, capture should be muted. It should remain muted if
capture is turned on while the protected mix is playing.
After a change to the filter graph or to the property settings that are associated with a stream, the driver
might need to immediately update the stream's copy-protection and output-enable settings. The driver
should synchronize its operation to prevent protected content from being copied to a capture buffer or
digital output. For example, when the input stream to a capture multiplexer changes, the driver should not
allow secure content to become vulnerable during the time required to turn muting on and off.
The DRMK system driver prevents the kernel debugger from connecting while DRM-protected content is playing.
Anti-debugging armor is one of several measures that DRMK uses to make protected content opaque. Once your
driver is ready to be tested, however, you can debug its DRM-compliant features by using the following technique:
Temporarily modify the wave stream's SetState method (for example, see
IMinipor tWavePciStream::SetState ) to call IDrmAudioStream::SetContentId and set the
DRMRIGHTS parameter's CopyProtect member to TRUE .
After you finish debugging, remember to remove the SetContentId call.
With this technique, you can play unprotected content as though it were DRM-protected content but avoid
disabling the debugger.
For example, you can use the debugger to verify that your driver prevents the content from being recorded. Try to
trick the driver into enabling recording of the wave-out stream through the capture MUX by changing the
SndVol32 program's volume and mute settings. The sliders should reflect the changes you make to their settings,
which are persistent, but the capture MUX should continue to mute the wave-out stream until the "protected"
content finishes playing. Only then should the new settings take effect.
DRM Functions and Interfaces
10/23/2019 • 2 minutes to read • Edit Online

The system driver components Drmk.sys and Portcls.sys implement a collection of DRM functions and interfaces
that drivers use for managing the digital rights of kernel-streaming audio content. The Drmk.sys component
implements a number of DrmXxx functions, and Portcls.sys implements a DRM-specific set of PcXxx functions,
and also the IDrmPort and IDrmPort2 interfaces.
The following DRM functions are available:
DrmAddContentHandlers
Provides the system with a driver interface consisting of a list of functions for handling protected content.
DrmCreateContentMixed
Creates a DRM content ID to identify a KS audio stream containing mixed content from several input streams.
DrmDestroyContent
Deletes a DRM content ID. DrmFor wardContentToDeviceObject
Authenticates a driver and sends it the DRM content ID and content rights that the system has assigned to a stream
containing protected content. DrmFor wardContentToFileObject
Obsolete function. DrmFor wardContentToInterface
Authenticates a driver object and sends it the DRM content ID and content rights that the system has assigned to a
stream containing protected content. DrmGetContentRights
Retrieves the DRM content rights that the system has assigned to a DRM content ID. The functions in this list are
declared in header file Drmk.h. The kernel-mode DRMK system driver, Drmk.sys, exports the entry points for these
functions.
In Windows XP and later, the PortCls system driver, Portcls.sys, exports a different set of entry points for the same
set of DRM functions. The names of the PortCls functions are similar to those in the previous list, except that they
use the prefix Pc instead of Drm:
PcAddContentHandlers
PcCreateContentMixed
PcDestroyContent
PcFor wardContentToDeviceObject
PcFor wardContentToFileObject
PcFor wardContentToInterface
PcGetContentRights
These function names are declared in header file Portcls.h. The entry points in Portcls.sys do nothing more than call
the corresponding functions in Drmk.sys. The PortCls entry points are provided simply for convenience so that an
audio driver that is already connected to Portcls.sys does not need to explicitly load Drmk.sys.
In Windows XP and later, the same set of functions is also exposed as methods in the IDrmPort and IDrmPort2
interfaces:
IDrmPor t2::AddContentHandlers
IDrmPor t::CreateContentMixed
IDrmPor t::DestroyContent
IDrmPor t2::For wardContentToDeviceObject
IDrmPor t::For wardContentToFileObject
IDrmPor t::For wardContentToInterface
IDrmPor t::GetContentRights
The IDrmPor t and IDrmPor t2 interfaces are declared in header file Portcls.h and are implemented in Portcls.sys.
These methods do nothing more than call the corresponding functions in Drmk.sys. A miniport driver obtains a
reference to a IDrmPor t x interface by querying its port driver for this interface. The advantage to using a
IDrmPor t x interface instead of the corresponding DrmXxx or PcXxx functions is that the driver can use this query
to determine at run time whether the operating system version supports DRM or not. This simplifies the task of
writing a single driver that can run both in newer versions of Windows that support DRM and in older versions
that do not. IDrmPor t2 is derived from IDrmPor t and provides two additional methods.
The WaveCyclic and WavePci port drivers use the IDrmAudioStream interface if it is supported by the
corresponding miniport driver. The port driver calls the IDrmAudioStream::SetContentId method to assign
DRM protection to the digital content in an audio stream.
The DEFINE_DRMRIGHTS_DEFAULT macro, which is defined in header file Drmk.h, initializes the members of a
DRMRIGHTS structure to their default values.
WDM Audio Architecture: Advanced Topics
12/5/2018 • 2 minutes to read • Edit Online

This section discusses advanced architectural features of Microsoft Windows Driver Model (WDM) audio drivers. It
presents the following topics:
Data-Intersection Handlers
Multifunction Audio Devices
Dynamic Audio Subdevices
Supporting Non-PCM Wave Formats
High Definition Audio DDI
Data-Intersection Handlers
6/25/2019 • 2 minutes to read • Edit Online

This section discusses data-intersection handlers in Microsoft Windows Driver Model (WDM) audio drivers. For a
broader discussion of data-intersection handling for KS filters in general, see DataRange Intersections in
AVStream.
In older versions of Windows such as Windows XP, the SysAudio system driver constructs a virtual audio device by
connecting together pairs of audio-filter pins to form an audio filter graph. Before a source pin on one filter can be
connected to a sink pin of another, SysAudio must negotiate a common format that the two pins can use to
exchange data. The details of this negotiation are largely delegated to the data-intersection handlers that are
implemented in the individual filters.
Similarly, in Windows Vista and later, the audio engine must negotiate a common stream format with the data-
intersection handler in the wave filter that represents the audio rendering device.
An adapter driver creates a WaveRT filter for an audio device by binding one of its miniport drivers to the
corresponding port driver from Portcls.sys. The port driver contains a default data-intersection handler, but the
default handler always gives the miniport driver's proprietary data-intersection handler the first opportunity to
determine a common format. If the proprietary handler declines this opportunity, however, the port driver's
default handler determines the format.
The port driver's default data-intersection handler is designed to deal with the most common hardware features.
For simple audio devices, the default handler provides a convenient alternative to implementing a proprietary
handler in the adapter driver. However, adapters with more advanced features might need proprietary handlers in
order to expose the full capabilities of the hardware.
The remainder of this section describes some of the limitations of the port driver's default data-intersection
handler and presents the techniques that are needed to design a proprietary data-intersection handler for an
adapter driver. The following topics are discussed:
Data Intersection
Default Data-Intersection Handlers
Proprietary Data-Intersection Handlers
Hardware Constraints on Sample Frequency
Output Buffer Size
Data Ranges with Discrete Values
Wild Cards
Data-Range Properties
Data Intersection
10/23/2019 • 3 minutes to read • Edit Online

In an audio filter graph, an audio stream can flow from the source pin of one filter to the sink pin of another filter
only if the two pins support a common format for the stream. Similarly, a client can send an audio stream to a sink
pin on a filter or receive an audio stream from a source pin on a filter only if the client and pin support a common
stream format. Audio filters use a technique called data intersection (short for data-range intersection) to identify a
stream format that is common to two pins or to a client and a pin.
For example, in Windows Server 2003, Windows XP, Windows 2000, and Windows Me/98, the SysAudio system
driver uses the data-intersection technique to construct an audio filter graph by connecting pairs of filter pins that
support compatible audio data formats.
A pin factory specifies the set of formats that each pin supports as an array of data ranges, where each data range
is a structure of type KSDATARANGE_AUDIO . A data range specifies a general format type, which can be
KSDATAFORMAT_WAVEFORMATEX or KSDATAFORMAT_DSOUND . In addition, the data range specifies a
range of values for each of the following parameters:
Bits per sample
Sample frequency
Number of channels
The KSDATARANGE_AUDIO structure specifies both minimum and maximum values for the bits-per-sample and
sample-frequency ranges but only a maximum for the number-of-channels range. The minimum number of
channels is implicitly one.
The job of negotiating a common data format for two pins consists of finding two data ranges--one from each pin-
-that intersect each other. A pair of data ranges intersect if:
They support the same general wave format (KSDATAFORMAT_WAVEFORMATEX or
KSDATAFORMAT_DSOUND).
Their bits-per-sample ranges overlap.
Their sample-frequency ranges overlap.
As mentioned previously, the KSDATAFORMAT_AUDIO structure implies a hardware model in which the minimum
number of channels supported by a pin is always one. According to this model, the number-of-channels ranges for
any two pins should always overlap because both pins support at least one channel. Obviously, a hardware adapter
with a minimum number of channels greater than one does not conform to this model, but the adapter driver can
include a proprietary data-intersection handler to deal with this type of issue (see the example in Proprietary Data-
Intersection Handlers).
Upon finding a pair of intersecting data ranges for the two pins, the handler selects a common data format from
the region of intersection as follows:
The number of bits per sample is selected from the region in which the two bits-per-sample ranges overlap.
The sample frequency is selected from the region in which the two sample-frequency ranges overlap.
The number of channels is selected from the region in which the two number-of-channels ranges overlap.
For example, when negotiating a common format for an audio port driver's sink pin and the source pin of another
filter (typically, the KMixer system driver), SysAudio first obtains the source pin's data-range array. SysAudio then
sends a KSPROPERTY_PIN_DATAINTERSECTION request to the sink pin and includes the source pin's data-
range array with this request. The kernel-streaming layer intercepts the request and iteratively calls the port
driver's data-intersection handler once for each successive element in the source pin's data-range array, beginning
with the first element, until the handler succeeds in finding a data intersection.
With each call that SysAudio makes to the port driver's data-intersection handler, the handler first obtains the sink
pin's data-range array from the miniport driver. It then iterates through the array, beginning with the first element,
until it succeeds in finding an intersection between a sink-pin data range and the current source-pin data range.
The handler selects a common format that lies within the intersection and outputs this format to the caller.
At each step in the iteration, the port driver calls the miniport driver's proprietary data-intersection handler with
the two data ranges--one for each of the two pins. If at any step the proprietary handler declines to handle a data-
intersection check between the two data ranges, the port driver's data-intersection handler performs the check
instead.
To summarize, the search for an intersection between a source-pin data range and a sink-pin data range is an
iterative process:
In the outer loop, the kernel-streaming layer iterates through successive elements in the source pin's data-
range array, beginning with the first array element.
In the inner loop, the port driver iterates through successive elements in the sink pin's data-range array,
beginning with the first array element.
The search stops upon finding the first data intersection. This process tends to favor the elements toward the
beginning of each pin's data-range array. When specifying an array of data ranges for a pin, an adapter driver
should order the array elements by placing data ranges for preferred formats toward the beginning of the array.
Default Data-Intersection Handlers
10/23/2019 • 2 minutes to read • Edit Online

An adapter's proprietary data-intersection handler (the miniport driver object's


IMinipor t::DataRangeIntersection method) can decline to perform the data-intersection check by returning the
STATUS_NOT_IMPLEMENTED status code. In this case, the port driver's default data-intersection handler performs
the check on behalf of the adapter.
You can implement a minimal data-intersection handler for your adapter driver as a DataRangeIntersection
method that declines all data-intersection requests by returning STATUS_NOT_IMPLEMENTED.
The current implementation of the port driver's default handler is limited in the types of data ranges that it can
handle:
Only PCM data formats
Only mono and stereo audio streams
An adapter driver that supports non-PCM or multichannel formats should implement a proprietary data-
intersection handler instead of relying on the port driver to handle data intersections for these formats.
In addition, the default handler supports only audio formats that can be specified by a
KSDATAFORMAT_DSOUND or KSDATAFORMAT_WAVEFORMATEX structure. It does not support any format
containing a WAVEFORMATEXTENSIBLE structure, which is needed, for example, to specify the channel mask for
a format with more than two channels.
When choosing a common format from the intersection between two data ranges, the port driver's default handler
always selects the highest value in each parameter's region of intersection:
If the intersection spans more than one valid sample frequency (11, 22, and 44 kHz, for example), the default
handler picks the highest frequency.
If the intersection spans more than one valid bits-per-sample value (8, 16, and 32 bits, for example), the
default handler picks the largest value.
If the intersection spans both mono and stereo formats, the default handler picks stereo.
If the default handler selects a format that is unsatisfactory, the adapter driver has the option of rejecting the
format by failing the NewStream call (for example, see IMinipor tWavePci::NewStream ) when SysAudio
attempts to create a sink pin with the format. If the call fails, SysAudio will not continue looking for data
intersections. Instead, it will attempt to create a connection by iterating through a list of the PCM formats that are
supported by system filters such as KMixer until it finds one that the adapter's sink pin can support as well. The list
is ordered with higher quality formats first. As before, the adapter rejects unsatisfactory formats in the list by
failing the NewStream calls for those formats.
Proprietary Data-Intersection Handlers
10/23/2019 • 2 minutes to read • Edit Online

You can overcome the limitations of the default data-intersection handler by writing a proprietary handler for your
adapter. A proprietary handler is implemented as the IMinipor t::DataRangeIntersection method on a miniport
driver object. See the sample adapter drivers in the Microsoft Windows Driver Kit (WDK) for examples of
DataRangeIntersection methods.
A proprietary data-intersection handler can compensate for nonstandard hardware features that cannot be
adequately specified in the KSDATARANGE_AUDIO structure. For example, the AC97 sample adapter driver in
the WDK manages hardware that can support two or more audio channels during playback, but cannot support
mono. The sample's DataRangeIntersection method determines whether the data range for the other filter's
source pin is limited to mono (that is, MaximumChannels < 2). If so, it fails the call by returning
STATUS_NO_MATCH.
A proprietary data-intersection handler has the option of handling data intersections on some of its pins and
allowing the port driver's default data-intersection handler to handle data intersections on the other pins.
The remainder of this section presents guidelines for implementing proprietary data-intersection handlers.
Hardware Constraints on Sample Frequency
10/23/2019 • 2 minutes to read • Edit Online

Some audio devices require that the sample frequency at the adapter filter's sink pin match the frequency of a
digital output port or the input stream from a microphone. For example, Sound Blaster 16-compatible hardware
typically has a single crystal, which constrains its input and output streams to run at the same clock rate. An
adapter that can support more than one clock rate for its various on-board audio streams might still need to
restrict the number of different clock rates to some small number.
For these reasons, an adapter driver might need to constrain the sample frequency on one on-board stream to
match that of another on-board stream. For example, a Sound Blaster 16-compatible adapter might require that
the sample frequency at the adapter's sink pin match the rate at which the latches are clocked at the output DACs.
As explained previously, KMixer is the system mixer in Windows Server 2003, Windows XP, Windows 2000, and
Windows Me/98. When KMixer's source pin is connected to an adapter's sink pin, KMixer might need to call the
adapter's SetFormat method (for example, see IMinipor tWavePciStream::SetFormat ) to adjust the sample
frequency at the connection to match the highest sample frequency of the audio streams at its inputs. If the adapter
is unable to change the frequency--perhaps because it is constrained by the clock rates of other on-board streams-
-it can fail the SetFormat call. In this case, KMixer will respond by making more SetFormat calls with successively
lower sample frequencies until the call succeeds. Once KMixer has settled on a reduced sample frequency, it will
sample-down its higher frequency input streams accordingly.
Output Buffer Size
10/23/2019 • 2 minutes to read • Edit Online

The miniport driver's IMinipor t::DataRangeIntersection method copies the structure that specifies the
negotiated data format into a buffer that is allocated by the caller. The method's OutputBufferLength parameter
specifies the buffer's size in bytes. Note that the size of the format structure varies with the selected format. In
order to avoid writing past the end of the buffer, the DataRangeIntersection method should first verify that the
allocated buffer is big enough to contain the format.
For a mono or stereo format, the minimum size for the output buffer is either
sizeof (KSDATAFORMAT_WAVEFORMATEX ) or sizeof (KSDATAFORMAT_DSOUND ), depending on whether a
WAVEFORMATEX or DirectSound format has been selected.
If the wave format supports more than two channels, the WAVEFORMATEX structure that is embedded at the end
of theKSDATAFORMAT_WAVEFORMATEX structure expands to occupy an additional number of bytes that is
equal to the difference
sizeof (WAVEFORMATEXTENSIBLE ) - sizeof (WAVEFORMATEX )
Data Ranges with Discrete Values
10/23/2019 • 2 minutes to read • Edit Online

If your audio device supports sample frequencies of 11, 22, and 44 kHz, for example, you can specify all three
frequencies as a range of 11 to 44 kHz in a single KSDATARANGE_AUDIO structure. This technique has the
benefit of being concise. A potential disadvantage is that a buggy data-intersection handler might choose an invalid
parameter value (for example, 27 kHz) that falls within the range. In this case, the adapter driver has no option but
to fail the NewStream call (for example, see IMinipor tWavePci::NewStream ) that attempts to create a pin with
the invalid format.
Another approach is to provide a list of data ranges in which each data range specifies a discrete value rather than
a range of values for each parameter. For example, instead of providing a single data range to specify a range of
sample frequencies from 11 to 44 kHz, the data-range array can contain three separate elements for 11, 22, and 44
kHz. In each of these elements, the maximum and minimum sample frequencies are set to the same value (11, 22,
or 44 kHz). The benefit of this approach is that it eliminates any ambiguity about the precise values that are
supported. Also, if one discrete value is preferred over another, the data range containing this value can be moved
to a position in the array that is ahead of the data range containing the other value. A minor disadvantage of
discrete values is that they can increase the size of the data-range array.
Wild Cards
10/23/2019 • 2 minutes to read • Edit Online

The header file Ks.h defines the following wild-card parameters for KS data ranges :
KSDATAFORMAT_TYPE_WILDCARD
KSDATAFORMAT_SUBTYPE_WILDCARD
KSDATAFORMAT_SPECIFIER_WILDCARD
The MajorFormat , Subformat , and Specifier members of the DataRange member of the
KSDATARANGE_AUDIO structure can be set to these values. A wild card matches any corresponding value to
which it is being compared, including any data formats that might be defined in the future. System filters that can
move data without understanding the data format are the primary users of wild cards. Adapter drivers should
avoid specifying wild cards in the data ranges for their filter pins, but they should be prepared to accept wild cards
in the data ranges for the client filter's pins.
Data-Range Properties
6/25/2019 • 2 minutes to read • Edit Online

Data ranges are used not only for data intersection, but can be accessed as device properties as well (see Pin Data-
Range and Intersection Properties). For this reason, an adapter driver whose data-intersection handler takes care of
all format negotiations on its pins should still include a complete set of data ranges. The data ranges should reflect
as closely as possible the data-format preferences that are embodied in the adapter's data-intersection handler.
A pin's data ranges can be accessed through the following properties:
KSPROPERTY_PIN_DATARANGES
KSPROPERTY_PIN_CONSTRAINEDDATARANGES
These two properties designate the pin's static data ranges and constrained data ranges, respectively.
Constrained data ranges provide more accurate information about the current capabilities of a device because they
are dynamically updated to account for any on-board resources that have already been allocated for other
purposes. By comparison, static data ranges might inaccurately report hardware capabilities that depend on
resources that are no longer available.
In the current PortCls implementation, the default data-intersection handlers in the port drivers use only an
adapter's static data ranges.
Dynamic Audio Subdevices
10/23/2019 • 2 minutes to read • Edit Online

Some audio adapters can dynamically change their internal topologies at run time. By using the system-supplied
capabilities in the PortCls system driver (Portcls.sys), adapter drivers can provide software support for dynamically
configurable audio hardware.
For example, the Intel High Definition Audio Specification uses the term audio codec to refer to an integrated audio
adapter that connects to a High Definition Audio (HD Audio) controller through an HD Audio Link interface. A
typical audio codec supports jack-presence detection: when a plug is inserted into or removed from a jack, the
hardware generates an interrupt to notify the driver of the change in the hardware configuration. For example, the
driver responds to the insertion of a plug into the headphones jack by creating a KS filter to represent the audio
subdevice for the headphones. The driver assigns hardware resources to the filter (for example, headphones might
require a volume control and a digital-to-analog converter, or DAC) and registers the filter as an audio device.
When the user unplugs the headphones, the driver responds by freeing the resources, deleting the filter, and
removing it from the registry.
This behavior ensures that when an audio application checks to see which audio devices are registered, it finds
only the devices that are currently plugged in. If a device is unplugged, it does not appear in the registry.
In Windows Vista, Windows Server 2003 with Service Pack 1 (SP1), and Windows XP with Service Pack 2 (SP2),
PortCls supports the IUnregisterSubdevice and IUnregisterPhysicalConnection interfaces. Audio adapter drivers
use these two interfaces to delete audio subdevices that are no longer in use. Earlier versions of Windows,
including Windows Server 2003 and Windows XP, do not support these interfaces. In these earlier versions of
Windows, subdevices can be created but not deleted--once a subdevice is created, it exists for the lifetime of the
adapter driver object.
The IUnregisterSubdevice interface contains a single method that the adapter driver can use to "unregister" a
subdevice that the driver registered through a previous call to the PcRegisterSubdevice routine:
IUnregisterSubdevice::UnregisterSubdevice
The IUnregisterPhysicalConnection interface contains three methods that the adapter driver can use to
unregister physical connections between subdevices:
IUnregisterPhysicalConnection::UnregisterPhysicalConnection
IUnregisterPhysicalConnection::UnregisterPhysicalConnectionFromExternal
IUnregisterPhysicalConnection::UnregisterPhysicalConnectionToExternal
These methods remove connections that the driver registered through previous calls to the
PcRegisterPhysicalConnection , PcRegisterPhysicalConnectionFromExternal , and
PcRegisterPhysicalConnectionToExternal routines. PortCls stores the information from a
PcRegisterPhysicalConnectionXxx call so that the port driver can subsequently use the information to respond to
the KSPROPERTY_PIN_PHYSICALCONNECTION property requests. When deleting a subdevice from an
adapter's topology, the driver must unregister the subdevice's physical connections to that portion of the topology.
Failure to unregister the subdevice's physical connections can cause memory leaks. PortCls supports the
PcRegisterXxx routines in Windows 2000 and later and in Windows Me/98.
The following topics in this section describe how to implement driver support for adapters with dynamic
topologies:
Managing Dynamic Topologies
Driver Support for Dynamic Subdevices
Jack Descriptions for Dynamic Audio Subdevices
Managing Dynamic Topologies
10/23/2019 • 3 minutes to read • Edit Online

An audio adapter contains some number of subdevices for servicing external audio devices, such as speakers and
microphones, that the user plugs into the adapter's front- or back-panel audio jacks. Each subdevice services a
particular audio jack or group of jacks.
The audio driver describes each subdevice by presenting a topology that is essentially a map of the internal
connections and processing elements within the subdevice. System-supplied Windows API modules and vendor-
supplied control-panel applications use the topology information to determine the capabilities of the subdevice
and to identify its internal points of control. For more information, see Exposing Filter Topology.
WDM audio drivers that were developed before the IUnregisterSubdevice and IUnregisterPhysicalConnection
interfaces became available have mostly static topologies. For these drivers, after the adapter driver creates a
miniport driver object to manage a subdevice, that object and its associated subdevice persist for the lifetime of the
adapter driver object.
However, in a dynamically configurable audio adapter, the adapter driver can create and delete subdevices at run
time to reflect changes in the hardware configuration as the user plugs external devices into audio jacks and
removes them. This behavior allows subdevices to operate as logically independent hardware functions. In other
words, each subdevice can be powered up, configured, and shut down independently of the other subdevices.
Each subdevice has an internal topology that consists of the following:
The data paths through the subdevice.
The topology nodes (for example, volume control) that process the data streams that flow along the data
paths.
The subdevice's physical connections to other subdevices in the same adapter.
When an adapter driver dynamically removes a subdevice, it frees the hardware resources that are bound to the
subdevice's internal topology. The adapter driver can then use these resources to create a new subdevice with a
possibly different topology.
When configuring a new audio subdevice, the adapter driver registers the subdevice's driver interface as an
instance of one or more device interface classes, and the I/O manager adds one or more registry entries that
contain symbolic links associating the interface classes and interface instances. To access the subdevice, a user-
mode client retrieves the symbolic link from the registry and passes it as a call parameter to the CreateFile
function. Typically, the client is a Windows API module, such as Dsound.dll or Wdmaud.drv, or a vendor-supplied
control panel or audio utility program. For more information about CreateFile , see the Microsoft Windows SDK
documentation.
When the miniport driver calls the IUnregisterSubdevice::UnregisterSubdevice method to remove a
subdevice, the PortCls system driver (Portcls.sys) tells the I/O manager to remove the symbolic link for the
associated device interface from the registry. Components that are registered for device interface removal events
receive notification when the interface is removed.
The audio adapter can contain jack-presence circuitry to notify the miniport driver when a plug is inserted into or
removed from an audio jack. When the user inserts a plug into an audio jack, the adapter driver adds the device
interface of the associated subdevice to the registry. When the user removes a plug from an audio jack, the adapter
driver removes the corresponding device interface from the registry.
Audio adapters that support dynamic topologies have the following benefits:
User friendly
Unless desktop speakers, headphones, and other external audio devices are actually plugged into audio
jacks on the audio adapter's front or rear panels, the system does not present these devices to audio
applications as available for use.
Power efficient
When the user removes a plug from an audio jack, the driver can power down the portion of the adapter
circuitry that services that jack.
Configurable
After removing a subdevice, the driver can use the hardware resources that were bound to the subdevice's
internal topology to create a new subdevice with a possibly different topology.
Driver Support for Dynamic Subdevices
10/23/2019 • 2 minutes to read • Edit Online

The code example in Subdevice Creation shows how to use the PcRegisterSubdevice routine to register a
subdevice. The SB16 sample audio driver in the Windows Driver Kit (WDK) shows how to use the
PcRegisterPhysicalConnection routine to register the physical connections between subdevices that are
contained in the same audio adapter.
The IUnregisterSubdevice and IUnregisterPhysicalConnection interfaces complement the PcRegisterXxx routines.
These interfaces contain methods that the sample driver uses to "unregister" devices that were previously
registered by calls to the PcRegisterXxx routines. As mentioned previously, these two interfaces are available in
Windows Server 2003 with SP1 and later and Windows XP with SP2, but not in earlier Windows versions. Thus, the
earlier Windows versions lack support for dynamic topologies, although a hot-fix package with dynamic topology
support is available for Windows Server 2003, Windows XP, and Windows 2000.
Jack Descriptions for Dynamic Audio Subdevices
10/23/2019 • 2 minutes to read • Edit Online

In Windows Vista and later, the KSPROPERTY_JACK_DESCRIPTION property provides information about a jack
or a collection of jacks on a subdevice in an audio adapter. (In this context, the term subdevice is synonymous with
KS filter.) The property value is an array of one or more KSJACK_DESCRIPTION structures. Each structure
describes the color, connector type, and physical location of a jack. In addition, the structure contains an
IsConnected member that is TRUE if an audio endpoint device such as a microphone or headphones is plugged
into the jack, and is FALSE if the jack is empty. To provide an up-to-date value for IsConnected , the adapter driver
for a dynamic subdevice relies on the jack-presence detection capabilities of the audio hardware. For a static
subdevice (with no jack-presence detection), the IsConnected member should always be TRUE . For more
information, see Jack Description Property.
When the user inserts a plug into a jack on a dynamic subdevice, the adapter driver should call the
PcRegisterSubdevice function to register the subdevice. While the subdevice remains registered, if the adapter
driver receives an IOCTL containing a KSPROPERTY_JACK_DESCRIPTION request for the subdevice, the driver
should set the IsConnected member of the property value to TRUE .
When the user removes the plug from the jack on the dynamic subdevice, the adapter driver should call the
IUnregisterSubdevice::UnregisterSubdevice method to delete the subdevice's registration. While the
subdevice is not registered, if the adapter driver receives an IOCTL containing a KSPROPERTY_JACK_DESCRIPTION
request for the subdevice, the driver should set the IsConnected member of the property value to FALSE .
Multifunction Audio Devices
6/25/2019 • 2 minutes to read • Edit Online

A multifunction device is a single adapter card that incorporates two or more separate functions (or subdevices). A
multifunction device can contain two or more audio subdevices. It may also span device classes. A device
containing audio and modem subdevices, for instance, belongs to both the media class and the modem class. For
more information, see Supporting Multifunction Devices.
The WavePci port driver in PortCls places special requirements on multifunction devices. In particular, an adapter
driver must provide a way to configure each subdevice so that it can be controlled independently of the other
subdevices in a multifunction device. This can be accomplished by setting up the PCI configuration space for your
multifunction device in one of two ways:
1. The preferred method is to assign a separate device ID to each logically distinct subdevice on your
multifunction device. If your multifunction device contains modem, audio, and joystick subdevices, for
example, the system should be able to represent each subdevice as an independent devnode in the device
tree. The subdevice represented by each device ID has its own set of PCI configuration registers and is
orthogonal to and independent of the other subdevices. For instance, enabling or disabling one subdevice
(the audio subdevice, for example) should have no effect on any other subdevice (the modem, for example).
This type of multifunction device requires no special hardware-specific driver support apart from the
proprietary drivers for the subdevices themselves.
2. A second way to design a multifunction device is to assign a single device ID to the device as a whole and to
provide separate PCI base-address registers (BARs) for the individual subdevices. In this scheme, the
subdevices share a common set of configuration registers but each subdevice has its own BAR or BARs. The
system multifunction driver (for example, Mf.sys on Microsoft Windows 2000 and later; see Using the
System-Supplied Multifunction Bus Driver) can configure the base address for each subdevice's status,
command, and data registers independently of the registers for the other functions. If your device's BARs
are not logically separable by subdevice, you cannot use PortCls to manage your device.
The remainder of this section describes the steps necessary to implement approach (2) in the preceding list. The
following topics are discussed:
Multiple Audio Subdevices
Multifunction Device Limits
Multiple Audio Subdevices
6/25/2019 • 2 minutes to read • Edit Online

A multifunction device can contain two or more audio subdevices. For example, an adapter driver might allow an
eight-channel audio device to be exposed to the system as four stereo channels. When writing an adapter driver to
expose multiple subdevices in this way, you should incorporate information about the subdevices into your driver's
startup sequence and INF file.
First, your adapter driver should expose each stereo subdevice as a separate instance of a port/miniport driver pair
during the startup sequence. Several of the sample adapters in the Microsoft Windows Driver Kit (WDK) implement
an InstallSubdevice function that creates and registers a subdevice consisting of a system port driver, a miniport
driver, and a set of resources that are to be bound to this pair. During startup, your driver should call its
InstallSubdevice function once for each stereo subdevice and specify a unique name for each port/miniport
driver pair.
In addition, the unique name you assign to this pair must match the KSNAME string that you specify in your
driver's INF file. For example, your driver might assign the names "Wave1" and "Wave2" to two subdevices during
startup, as shown below:

InstallSubdevice(..., "Wave1",...);
InstallSubdevice(..., "Wave2",...);

In this case, the same names should appear in the INF file:

KSNAME_Wave1="Wave1"
KSNAME_Wave2="Wave2"

Your INF file should add interfaces that contain these names:

AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave1%,Test.Interface.Wave1
AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave2%,Test.Interface.Wave2

The INF file should create AddReg sections (see INF AddReg Directive ) in order to add information about these
interfaces to the registry:

[Test.Interface.Wave1]
AddReg=Test.I.Wave1.AddReg

[Test.Interface.Wave2]
AddReg=Test.I.Wave2.AddReg

The AddReg sections should also specify the registry entries for each subdevice:

[Test.I.Wave1.AddReg]
HKR,,CLSID,,%Proxy.CLSID%
HKR,,FriendlyName,,%Test.Wave1.szName%

[Test.I.Wave2.AddReg]
HKR,,CLSID,,%Proxy.CLSID%
HKR,,FriendlyName,,%Test.Wave2.szName%
Finally, the INF file should define the friendly names for these subdevices:

Test.Wave1.szName="Punch"
Test.Wave2.szName="Judy"

The friendly names show up in the audio control panel to identify the subdevices.
Multifunction Device Limits
10/23/2019 • 2 minutes to read • Edit Online

The number of audio functions per multifunction device is limited by the following factors:
When the adapter driver calls PcAddAdapterDevice , the function's fourth parameter, MaxObjects, specifies the
maximum number of miniport driver objects that the driver can support. The sample adapter drivers in the
Microsoft Windows Driver Kit (WDK) set this parameter to the integer constant MAX_MINIPORTS, which is
typically defined to be a small value (five or less). You might need to increase this value if you plan to support
multiple stereo pairs or other types of audio subdevices.
Supporting Non-PCM Wave Formats
12/5/2018 • 2 minutes to read • Edit Online

This section describes limitations in earlier versions of Windows that prevented clients from playing non-PCM
audio, and presents a set of guidelines for adapting a WDM audio driver to support non-PCM data formats on
more recent versions of Windows.
Additionally, this section describes the new subformat GUIDs in Windows 7 that provide support for compressed
audio formats.
This section includes the following topics:
Background of Non-PCM Support
Requirements for a Non-PCM Pin Factory
Subformat GUIDs for Compressed Audio Formats
Converting Between Format Tags and Subformat GUIDs
KS Topology Considerations
Specifics for waveOut Clients
Specifics for DirectSound Clients
S/PDIF Pass-Through Transmission of Non-PCM Streams
Specifying AC-3 Data Ranges
Specifying WMA Pro Data Ranges
USB Audio Support for Non-PCM Formats
Background of Non-PCM Support
10/23/2019 • 3 minutes to read • Edit Online

Several issues prevented earlier versions of Microsoft Windows from supporting non-PCM formats through the
waveOut and DirectSound APIs. These issues and how they have been resolved are discussed below.
waveOut API
The software layer that separates waveOut applications from VxD wave drivers is fairly thin. Drivers and
applications that support a custom wave format can stream data in that format regardless of whether the
operating system understands the format.
However, in Windows 2000 and Windows 98, the WDM audio framework forces all the audio data that is processed
by the waveOut API (and DirectShow's waveOut renderer) to pass through the KMixer system driver (Kmixer.sys),
which is the kernel audio mixer. A waveOutOpen call succeeds only if KMixer supports the format, regardless of
whether the driver supports the format.
KMixer handles WAVE_FORMAT_PCM on all WDM operating systems. Windows 2000 and later, and Windows 98
SE, extend KMixer to support not only WAVE_FORMAT_IEEE_FLOAT but also WAVEFORMATEXTENSIBLE variants
of PCM and IEEE-float formats. Because KMixer supports no non-PCM formats, an attempt to pass non-PCM data
through KMixer fails.
Windows XP and later, and Windows Me, support non-PCM formats by allowing non-PCM audio data to simply
bypass KMixer. Specifically, waveOut non-PCM data flows directly to PortCls (or USBAudio) instead of first passing
through KMixer. Any mixing of non-PCM data must be done in hardware, but applications that use non-PCM data
in a format such as AC-3 or WMA Pro typically do not require mixing and drivers typically do not support
hardware mixing in that format.
DirectSound API
On legacy waveOut drivers and VxD drivers, DirectSound supports WAVEFORMATEX (but not
WAVEFORMATEXTENSIBLE) PCM formats for both primary and secondary buffers, with 8 or 16 bits per sample,
one or two channels, and a sampling rate between 100 Hz and 100 kHz. VxD drivers can further limit the formats
allowed for primary buffers when the cooperative level is set to DSSCL_WRITEPRIMARY (see the description of the
IDirectSoundBuffer ::SetFormat method in the DirectX SDK). These limitations have not changed in Windows
Me or Windows XP.
WDM drivers can support PCM formats in both WAVEFORMATEX and WAVEFORMATEXTENSIBLE form. For
Windows 2000 and later, Windows Me, and Windows 98 SE, drivers can also support the
WAVE_FORMAT_IEEE_FLOAT format for both primary and secondary DSBCAPS_LOCSOFTWARE buffers (mixed by
KMixer) in both WAVEFORMATEX and WAVEFORMATEXTENSIBLE form.
Calling SetFormat to specify the data format of a primary buffer has only an indirect effect on the final mixing
format chosen by the sound card. The primary buffer object is used to obtain the IDirectSound3DListener
interface and to set the device's global volume and pan, but does not represent the single output stream from the
sound card. Instead, KMixer mixes the primary-buffer data in order to allow several DSSCL_WRITEPRIMARY
DirectSound clients to run simultaneously.
On Windows 2000 and Windows 98, DirectSound supports only PCM data. (The same is true of DirectShow, which
uses DirectSound's renderer.) A call to CreateSoundBuffer with a non-PCM format always fails, even if the driver
supports the format. Failure occurs for two reasons. First, whenever DirectSound creates a KS pin, it automatically
specifies KSDATAFORMAT_SUBTYPE_PCM instead of deriving the subtype from the wFormatTag member of the
WAVEFORMATEX structure that is used to create the IDirectSoundBuffer object. Second, DirectSound requires
every data path to have volume and SRC (sample-rate conversion) nodes (KSNODETYPE_VOLUME and
KSNODETYPE_SRC ), regardless of whether the client requests pan, volume, or frequency controls on the
DirectSound buffer. This requirement is met if either the data passes through KMixer or the device performs
hardware mixing. For non-PCM formats, however, KMixer is not present in the data path and the drivers themselves
typically fail when asked to perform hardware mixing.
Windows XP and later, and Windows Me, remove the limitations that prevented DirectSound applications from
using non-PCM formats. DirectSound 8 (and later versions) uses the correct format subtype and no longer
automatically requires volume and SRC nodes in every data path.
Requirements for a Non-PCM Pin Factory
10/23/2019 • 2 minutes to read • Edit Online

Under Windows XP and later, and Microsoft Windows Me, drivers that play non-PCM WAVEFORMATEX formats
should expose their non-PCM pins according to the following guidelines.
First, define a pin factory for your non-PCM data format that is separate from any PCM pin factories. PCM and non-
PCM cannot share the same single-instance pin factory because the sole pin instance automatically is allocated to
KMixer. If the pin factory supports multiple instances, PCM and non-PCM can coexist on the same pin factory. In
this case, however, you cannot guarantee that these pin instances are available to a non-PCM client at runtime -
PCM clients might already have allocated them. The safest option is to provide a separate pin factory for your non-
PCM format.
In order for the pin to be discovered and used by DirectSound 8, define this non-PCM pin factory on a filter that
already supports PCM. Otherwise, DirectSound will not detect the non-PCM pin. This also means that a device that
does not support PCM at all cannot support a non-PCM format.
Second, implement a data-intersection handler on your non-PCM pin. PortCls provides a built-in handler, but this
default handler always chooses PCM, so you should add your own handler for non-PCM formats. You should not
support WAVE_FORMAT_PCM in the intersection handler for your non-PCM pin. Note that this handler can be
called with an OutputBufferLength of 0, in which case the caller is asking only for the size of the preferred data
range, not for the data itself. In this case, the handler should respond by copying the non-PCM data range's size into
the ResultantFormatLength parameter and returning STATUS_BUFFER_OVERFLOW. The Msvad sample in the
Windows Driver Kit (WDK) contains the code for a DataRangeIntersection routine that you can use as an
example handler. To test your DataRangeIntersection routine, use the KsStudio utility to instantiate your pin--it
first calls your intersection handler in order to determine an acceptable default format. To support a non-PCM
format, your driver must properly handle it in the following locations:
IMinipor t::DataRangeIntersection
Miniport driver methods Init and NewStream (For example, see IMinipor tWavePci::Init and
IMinipor tWavePci::NewStream .)
Miniport-stream method SetFormat (For example, see IMinipor tWavePciStream::SetFormat .)
Subformat GUIDs for Compressed Audio Formats
10/23/2019 • 2 minutes to read • Edit Online

For Windows 7, new subformat GUIDs have been added to the Ksmedia.h header file to provide support for
compressed audio formats. Subformat GUIDs indicate the specific subformat of a data format. These formats are
defined by the Consumer Electronics Association (CEA) standard for uncompressed audio.
As a result of the CEA-861-D standard, you must ensure that audio formats that are not supported by a CEA device
are not transmitted to such a device. High definition multimedia interface (HDMI) and DisplayPort are examples of
CEA devices.
For user-mode access, the GUIDs are specified in the SubFormat member of WAVEFORMATEXTENSIBLE and in the
FormatExt member of WAVEFORMATEXTENSIBLE_IEC61937. For kernel-mode access for audio drivers, the GUIDs
are specified in the DataRange member of the KSDATARANGE_AUDIO structure,
The GUIDs for the available compressed audio formats are listed in the following table.
Note Not all the available formats are supported by the Windows 7 HD audio class driver. The formats supported
by Windows 7 are indicated in the tables with an asterisk (*).

C EA 861 T Y P E SUB F O RM AT GUID DESC RIP T IO N

0x00 Refer to the stream.

0x01 00000000-0000-0010-8000- IEC 60958 PCM


00aa00389b71
KSDATAFORMAT_SUBTYPE_WAVEF
ORMATEX

0x02 00000092-0000-0010-8000- AC-3


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_DOLBY_DIGITAL

0x03 00000003-0cea-0010-8000- MPEG-1 (Layer1 & 2)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_MPEG1

0x04 00000004-0cea-0010-8000- MPEG-3 (Layer 3)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_MPEG3
C EA 861 T Y P E SUB F O RM AT GUID DESC RIP T IO N

0x05 00000005-0cea-0010-8000- MPEG-2 (Multichanel)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_MPEG2

0x06 00000006-0cea-0010-8000- Advanced audio coding* (MPEG-


00aa00389b71 2/4 AAC in ADTS)
KSDATAFORMAT_SUBTYPE_IEC6193
7_AAC

0x07 00000008-0000-0010-8000- Digital Theater Sound (DTS)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_DTS

0x0a 0000000a-0cea-0010-8000- Dolby Digital Plus


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_DOLBY_DIGITAL_PLUS

0x0f Unused. Reserved

The GUIDs for audio formats that are transmitted in high bit-rate audio sample packets are listed in the following
table.

C EA 861 T Y P E SUB F O RM AT GUID DESC RIP T IO N

0x0b 0000000b-0cea-0010-8000- DTS-HD (24-bit, 95KHz)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_DTS_HD

0x0c 0000000c-0cea-0010-8000- MAT(MLP)- Meridian Lossless


00aa00389b71 Packing (Dolby Digital True HD -
24-bit 196KHz/up to 18M bps, 8
KSDATAFORMAT_SUBTYPE_IEC6193 channels)
7_DOLBY_MLP

0x0e 00000164-0000-0010-8000- Windows Media Audio (WMA) Pro


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_WMA_PRO

The GUIDs for compressed audio formats that can be implemented by third-party solutions are listed in the
following table.
C EA 861 T Y P E SUB F O RM AT GUID DESC RIP T IO N

0x08 00000008-0cea-0010-8000- Adaptive Transform Acoustic


00aa00389b71 Coding (ATRAC)
KSDATAFORMAT_SUBTYPE_IEC6193
7_ATRAC

0x09 00000009-0cea-0010-8000- One-bit audio


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_ONE_BIT_AUDIO

0x0d 0000000d-0cea-0010-8000- Direct Stream Transport (DST)


00aa00389b71
KSDATAFORMAT_SUBTYPE_IEC6193
7_DST

The following code example shows how an audio miniport driver defines and initializes a KSDATARANGE_AUDIO
structure for use with an HDMI sink that has a fully functional Dolby Digital Plus decoder. A sink of this type
supports transfer rates of 44.1 and 48 KHz.
For a sampling rate of 48 KHz, an audio miniport driver uses the following code to define and initialize a
KSDATARANGE_AUDIO structure. This code shows the data ranges that the audio miniport driver exposes:

//Define and initialize KSDATARANGE_AUDIO structure


// for use with a sample rate of 48 KHz.
KSDATARANGE_AUDIO drDDPlus48;
drDDPlus48.DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
drDDPlus48.DataRange.Flags = 0; // Ignored.
drDDPlus48.DataRange.SampleSize = 0; // Ignored.
drDDPlus48.DataRange.Reserved = 0;
drDDPlus48.DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
drDDPlus48.DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS;
drDDPlus48.DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
drDDPlus48.MaximumChannels = 2
drDDPlus48.MinimumBitsPerSample = 16; // All encoded data is transmitted at
drDDPlus48.MaximumBitsPerSample = 16; // 16 bits over IEC 60958.
drDDPlus48.MinimumSampleFrequency = 192000; // 48 KHz * 4.
drDDPlus48.MaximumSampleFrequency = 192000;

For a sampling rate of 44.1 KHz, an audio miniport driver uses the following code to define and initialize a
KSDATARANGE_AUDIO structure:
//Define and initialize KSDATARANGE_AUDIO structure
// for use with a sample rate of 41.1 KHz.
KSDATARANGE_AUDIO drDDPlus44;
drDDPlus44.DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
drDDPlus44.DataRange.Flags = 0 // Ignored.
drDDPlus44.DataRange.SampleSize = 0 // Ignored.
drDDPlus44.DataRange.Reserved = 0;
drDDPlus44.DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
drDDPlus44.DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS;
drDDPlus44.DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
drDDPlus44.MaximumChannels = 2
drDDPlus44.MinimumBitsPerSample = 16; // All encoded data is transmitted at
drDDPlus44.MaximumBitsPerSample = 16; // 16 bits over IEC 60958.
drDDPlus44.MinimumSampleFrequency = 176400; // 44.1 KHz * 4
drDDPlus44.MaximumSampleFrequency = 176400;
Converting Between Format Tags and Subformat
GUIDs
10/23/2019 • 2 minutes to read • Edit Online

The guidelines for handling non-PCM WAVE_FORMAT_EXTENSIBLE formats are similar to those for non-PCM
formats that are specified by wave-format tags. Specifically, a WAVE_FORMAT_EXTENSIBLE format should have a
pin factory separate from the factory for PCM formats, and it requires its own data-range intersection handler.
The audio format for a WAVE_FORMAT_EXTENSIBLE format is specified by the GUID in the SubFormat member of
the KSDATAFORMAT structure. Every registered wave-format tag has a corresponding subformat GUID, which is
generated by the DEFINE_WAVEFORMATEX_GUID macro in Ksmedia.h. For example, the GUID corresponding to the
WAVE_FORMAT_DOLBY_AC3_SPDIF tag is defined as
DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF).
This code snippet from Ksmedia.h shows how to define a new GUID as an autoinitialized static variable:

#define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX \
0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX);
#define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX)

These macros from Ksmedia.h convert between wave-format tags and their associated GUIDs:

#if !defined( DEFINE_WAVEFORMATEX_GUID )


#define DEFINE_WAVEFORMATEX_GUID(x) \
(USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
#endif

#define INIT_WAVEFORMATEX_GUID(Guid, x) \
{ \
*(Guid) = KSDATAFORMAT_SUBTYPE_WAVEFORMATEX; \
(Guid)->Data1 = (USHORT)(x); \
}

#define IS_VALID_WAVEFORMATEX_GUID(Guid) \
(!memcmp(((PUSHORT)&KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, \
((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))

#define EXTRACT_WAVEFORMATEX_ID(Guid)(USHORT)((Guid)->Data1)

The sample code below combines these techniques to create a subformat GUID that is based on the wave-format
tag WAVE_FORMAT_AC3_SPDIF, which has the value 0x0092:
#define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF \
DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF)

DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71",
KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF);

#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF \
DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF)
...
INIT_WAVEFORMATEX_GUID(pMyGuid,myWaveFormatTag);
...
if (IS_VALID_WAVEFORMATEX_GUID(aWaveFormatExGuidPtr)) {
aWaveFormatTag = EXTRACT_WAVEFORMATEX_ID(aWaveFormatExGuidPtr);
}
KS Topology Considerations
12/5/2018 • 2 minutes to read • Edit Online

The WDMAud system driver (Wdmaud.sys) translates the KS-filter topology into the legacy mixer lines that are
exposed through the mixer API. A non-PCM pin corresponds to a SRC line
(MIXERLINE_COMPONENTTYPE_SRC_XXX) in the mixer API. If this pin is in a data path that eventually flows into a
bridge pin (the physical connection at the endpoint of a graph) that is dedicated to non-PCM data, the mixer API
exposes the bridge pin as an additional DST line (MIXERLINE_COMPONENTTYPE_DST_XXX), separate from the DST
line for PCM data. This can add unnecessary complexity to the controls that are visible through a mixer -API client
such as a replacement for the SndVol32 utility.
If you prefer not to expose a non-PCM pin in this manner, one approach is to make sure that the data path
containing the pin eventually feeds into a SUM node that is shared by the PCM data path. That is, join the non-PCM
DST line to the main DST line. Unfortunately, this workaround misrepresents the true hardware topology and
might lead to future problems with clients that attempt to control the non-PCM data stream through nodes
downstream from the SUM node. A better approach is to modify the mixer -API client to simply ignore SRC and
DST lines that have no controls.
If you use the KsStudio utility to view your wave filter in KSCATEGORY_AUDIO, you should expect to see a separate
pin for non-PCM data. When viewing the composite system audio graph under KSCATEGORY_AUDIO_DEVICE, you
should see your non-PCM data ranges on the main wave-output pin, alongside any PCM data ranges.
SysAudio (Sysaudio.sys) is the system audio device in Windows Server 2003, Windows XP, Windows 2000, and
Windows Me/98. Note that SysAudio generates KSCATEGORY_AUDIO_DEVICE automatically--a driver should not
register itself manually in this category.
You are not required to connect a non-PCM data path to the Topology miniport driver. This connection is of benefit
only if the non-PCM data path interacts with the rest of the device's topology; for instance, if it feeds into a common
mixer or sample-rate converter. Connecting a streaming pin to a bridge pin, where both pins are on the wave
miniport driver, forms a valid, complete topology for a non-PCM data stream that flows directly to an S/PDIF port,
for example.
Specifics for waveOut Clients
6/25/2019 • 2 minutes to read • Edit Online

A call to waveOutOpen returns WAVERR_BADFORMAT if a driver does not support the specified wave format.
Microsoft Windows does not currently support the looping of a wave header with a non-PCM format. An attempt
to loop a non-PCM format will fail, but the system does not detect the failure until the header-submittal (not
header-preparation) stage because of architectural constraints. Specifically, a call to waveOutPrepareHeader
might accept a non-PCM wave header with WHDR_BEGINLOOP and/or WHDR_ENDLOOP set in dwFlags , but a
subsequent call to waveOutWrite fails and returns MMSYSERR_INVALPARAM. If WHDR_BEGINLOOP and
WHDR_ENDLOOP are not set in dwFlags , however, specifying dwLoops >1 does not cause waveOutWrite to fail.
When non-PCM data is playing, a call to waveOutBreakLoop fails with return code MMSYSERR_INVALPARAM.
Specifics for DirectSound Clients
10/23/2019 • 2 minutes to read • Edit Online

On Microsoft Windows 2000 and Windows 98, DirectSound does not support non-PCM formats, regardless of the
DirectSound version. (However, DirectSound 8 does support non-PCM formats on both Windows 2000 SP2 and
Windows 98 SE + hotfix. Also, the versions of DirectSound that ship with Windows XP and later, and Windows Me,
support non-PCM formats.)
To determine whether a WDM driver supports a particular wave format, a client can attempt to create a
DSBCAPS_LOCHARDWARE buffer in that format on the driver and see whether the attempt succeeds. The
DirectSound API provides no other way to discover which non-PCM data formats are supported.
DirectSound allows secondary DSBCAPS_LOCHARDWARE buffers to have any valid WAVEFORMATEX or
WAVEFORMATEXTENSIBLE format that the selected driver supports. When searching for the format in the
driver's list of supported formats, DirectSound checks only for formats containing the
KSDATAFORMAT_SPECIFIER_DSOUND specifier.
You can extend a DirectSound application to use a non-PCM format by first creating a WAVEFORMATEX or
WAVEFORMATEXTENSIBLE structure that describes the format. Next, load a pointer to the structure into the
lpwfxFormat member of the DSBUFFERDESC structure that is passed to the CreateSoundBuffer method. No
other changes to existing DirectSound code are needed to use a non-PCM format. Note that the controls that a
driver typically supports for PCM data are unlikely to be supported for some non-PCM formats. For example, a
card that supports digital output of data that is encoded in an AC-3 or WMA Pro format is unlikely to support the
DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME controls on that data. Thus, attempting to create the DirectSound
buffer with those flags might fail.
DirectSound playback through VxD drivers or legacy waveOut drivers is still limited to PCM; non-PCM formats are
not supported.
S/PDIF Pass-Through Transmission of Non-PCM
Streams
12/5/2018 • 4 minutes to read • Edit Online

The Sony/Philips digital interface (S/PDIF) format is defined primarily for transmitting PCM audio data, but it can
easily be adapted to transmit non-PCM data. The principle of S/PDIF pass-through transmission is that a non-PCM
data stream can pass through an S/PDIF link as though it were a PCM stream. Pass-through transmission does not
require the S/PDIF sending and receiving ports to understand the encoding of the non-PCM stream.
WMA Pro and AC-3 are both compressed non-PCM formats that transmit digital audio streams in units called
synchronization frames. Each sync frame contains its own header and can be decoded independently of the other
sync frames in the stream. At a 48-kHz sample rate, for example, a WMA Pro sync frame contains enough data to
play for 2048 ticks of the sample clock (42.67 milliseconds). At this same rate, an AC-3 sync frame contains enough
data for 1536 ticks (32 milliseconds).
At a 48-kHz sample rate, a 5.1-channel WMA Pro sync frame never exceeds 8192 bytes, which is the number of
bytes occupied by 2048 stereo (two-channel), 16-bit PCM samples. Similarly, a 5.1-channel AC-3 sync frame never
exceeds 6144 bytes, which is the number of bytes occupied by 1536 stereo, 16-bit PCM samples. (There are
exceptions to this rule, but those types of AC-3 sync frames are very uncommon, cannot be transmitted over
S/PDIF, and can be ignored here.)
When a 48-kHz WMA Pro or AC-3 audio stream passes through an S/PDIF link in digital form without being
decoded, the S/PDIF sending and receiving ports can treat the stream the same as a stereo, 16-bit, 48-kHz PCM
stream. When specifying a data range for a pin that can transmit a WMA Pro-over-S/PDIF or AC-3-over-S/PDIF
stream, the wave-format tag itself is the only thing that differs from a data range for a pin that transmits a PCM
stream through the S/PDIF port. For an example, see the data range declarations in Specifying WMA Pro Data
Ranges.
In order to avoid delivering a WMA Pro compressed stream over the S/PDIF interface faster than real time (that is,
to prevent delivery of 43 milliseconds of audio in less than 43 milliseconds), an audio application must pad a WMA
Pro sync frame with zeros until the sync frame takes up the same number of bytes as 2048 stereo PCM samples.
An AC-3 sync frame must similarly be padded out to the size of 1536 stereo PCM samples.
If you attempt to send unpadded WMA Pro or AC-3 sync frames to a PortCls adapter driver that uses WaveCyclic,
be aware that when the port driver senses data starvation (because the data stream contains fewer bytes than a
two-channel uncompressed stream would), it fills the cyclic buffer with silence. The non-PCM stream decoder will
have problems interpreting these periods of silence, which are in PCM rather than the non-PCM format.
The following figure shows an example application of S/PDIF pass-through transmission.

The figure shows a PC connected to an external audio/visual (A/V) receiver through a coaxial cable. The cable
connects the S/PDIF output port on the PC's audio device to the S/PDIF input port on the A/V receiver.
At the left edge of the figure, an audio application inserts a sync frame from a WMA Pro audio stream into the
beginning of an 8192-byte buffer. (This buffer size is used purely for ease of illustration. In practice, a buffer size of
4096 bytes or 10240 bytes, for example, might be used instead.) The application fills any remaining space in the
buffer with zeros. The audio driver programs the S/PDIF output port to transmit the contents of the buffer as
though they were 8192 bytes of PCM data.
Similarly, the S/PDIF input port on the A/V receiver receives the stream as though it were 8192 bytes of PCM data.
It loads the data into an input buffer, which in this example also has a size of 8192 bytes. The decoder extracts the
WMA Pro sync frame from the input buffer, decodes the sync frame into a 5.1-channel audio stream, and plays the
stream through the surround speakers on the right edge of the figure.
To let the decoder on the other end of the connection know that the audio stream is in a non-PCM format, the
audio driver should set the /AUDIO bit on the S/PDIF transceiver. The decoder reads this bit from the S/PDIF
channel-status block to determine whether the data stream is encoded in a non-PCM format. Setting this bit is the
only thing special that the driver needs to do to accommodate the non-PCM stream. In every other way, the driver
treats the stream as though it contains PCM data.
A number of consumer devices support S/PDIF pass-through transmission, but other digital interfaces such as USB
and 1394 can also be adapted for digital pass-through transmission of non-PCM data to external audio decoders.
Dolby Laboratories introduced the AC-3 (Dolby Digital) compressed audio format in 1992. The first consumer A/V
receivers to support AC-3 over S/PDIF became available in about 1997. Software support for the WMA Pro audio
stream format became available with the release of the Microsoft Windows Media 9 Series technology in 2003.
A/V receivers that support WMA Pro-over-S/PDIF were introduced in 2003.
In Windows XP and later, the waveOut, DirectSound, and DirectShow APIs support non-PCM formats. The
DirectSound and waveOut APIs are implemented in such a way that any PCM or non-PCM format that the driver
exposes is automatically available to clients of these APIs.
Specifying AC-3 Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

The header file Mmreg.h defines the value 0x0092 to be the wave-format tag for AC-3-over-S/PDIF:

#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092

Wave-format tags 0x0240 and 0x0241 are synonymous with 0x0092 and many DVD applications treat the three
tags as identical. However, to eliminate redundancy, drivers and applications should support only tag 0x0092 (and
not support tags 0x0240 and 0x0241).
The corresponding format-subtype GUID can be specified in terms of the wave-format tag by using the
DEFINE_WAVEFORMATEX_GUID macro from the header file Ksmedia.h as follows:

#define KSDATAFORMAT_SUBTYPE_AC3_SPDIF \
DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF)

The following code example shows how a WaveCyclic or WavePci miniport driver can specify the
KSDATARANGE_AUDIO table entries for a pin that supports the AC-3-over-S/PDIF format:
static KSDATARANGE_AUDIO PinDataRangesAC3Stream[] =
{
// 48-kHz AC-3 over S/PDIF
{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
2, // Max number of channels
16, // Minimum number of bits per sample
16, // Maximum number of bits per channel
48000, // Minimum rate
48000 // Maximum rate
},

// If you do not include this second data range (which is identical


// to the first except for the value KSDATAFORMAT_SPECIFIER_DSOUND),
// then your non-PCM pin is not seen by DirectSound on Windows 98 SE
// or Windows 2000, regardless of the DirectX version or whether a
// hotfix or service pack is installed.
{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND)
},
2, // Max number of channels
16, // Minimum number of bits per sample
16, // Maximum number of bits per channel
48000, // Minimum rate
48000 // Maximum rate
}
};

The second data-range entry in the preceding table is necessary to enable DirectSound to handle the non-PCM
AC-3-over-S/PDIF format in Windows 2000 SP2 and in Microsoft Windows 98 SE + hotfix.
For each data range that the miniport driver specifies with KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, the port
driver automatically adds a second data range that is specified with KSDATAFORMAT_SPECIFIER_DSOUND but is
otherwise identical to the first. (You can verify this by using the KsStudio utility to view the list of data ranges.) In
Windows 2000 and Windows 98, the port driver creates KSDATAFORMAT_SPECIFIER_DSOUND versions of data
ranges only for KSDATAFORMAT_SUBTYPE_PCM formats because DirectSound versions before DirectSound 8
support only PCM. This limitation is removed in Windows XP and later and in Windows Me. However, it is not
removed in Windows 2000 SP2 or in the hot-fix package for Windows 98 SE, and to support non-PCM on
DirectSound on these Windows versions, a driver should explicitly list two data ranges for each non-PCM data
format--one with KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, and another with
KSDATAFORMAT_SPECIFIER_DSOUND.
As explained in S/PDIF Pass-Through Transmission of Non-PCM Streams, the two AC-3-over-S/PDIF data ranges
both use the following PCM parameters: two channels and 16 bits per channel.
Specifying WMA Pro Data Ranges
10/23/2019 • 2 minutes to read • Edit Online

The header file Mmreg.h defines the value 0x0164 to be the wave-format tag for WMA Pro-over-S/PDIF:

#define WAVE_FORMAT_WMASPDIF 0x0164

The corresponding format-subtype GUID can be specified in terms of the wave-format tag by using the
DEFINE_WAVEFORMATEX_GUID macro from the header file Ksmedia.h as follows:

#define KSDATAFORMAT_SUBTYPE_WMA_SPDIF \
DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_WMASPDIF)

The following code example shows how a WaveCyclic or WavePci miniport driver can specify the
KSDATARANGE_AUDIO table entries for a pin that supports the WMA Pro-over-S/PDIF and AC-3-over-S/PDIF
formats:
static KSDATARANGE_AUDIO PinDataRangesSpdifOut[] =
{
// 48-kHz WMA Pro over S/PDIF
{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_WMA_SPDIF),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
2, // Max number of channels
16, // Minimum number of bits per sample
16, // Maximum number of bits per channel
48000, // Minimum rate
48000 // Maximum rate
},

// 44.1-kHz WMA Pro over S/PDIF


{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_WMA_SPDIF),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
2, // Max number of channels
16, // Minimum number of bits per sample
16, // Maximum number of bits per channel
44100, // Minimum rate
44100 // Maximum rate
},

// 48-kHz AC-3 over S/PDIF


{
{
sizeof(KSDATARANGE_AUDIO),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_SPDIF),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
},
2, // Max number of channels
16, // Minimum number of bits per sample
16, // Maximum number of bits per channel
48000, // Minimum rate
48000 // Maximum rate
},
};

In this code example, the first and second data ranges specify WMA Pro-over-S/PDIF data formats at sample rates
of 48 kHz and 44.1 kHz. With these two options, an audio application can play a WMA Pro audio stream recorded
at either of these two sample rates, assuming that the external decoder can also handle the sample rate.
The WMA Pro sync frame size is the same at both 48 kHz and 44.1 kHz, and both data ranges use the same PCM
parameter values--two channels and 16 bits per channel. For information about the use of PCM parameters to
specify data ranges for WMA Pro-over-S/PDIF and AC-3-over-S/PDIF formats, see S/PDIF Pass-Through
Transmission of Non-PCM Streams.
The third data range specifies an AC-3-over-S/PDIF data format. For more information, see Specifying AC-3 Data
Ranges.
The preceding example does not enable DirectSound to handle the non-PCM WMA Pro-over-S/PDIF and AC-3-
over-S/PDIF formats on Microsoft Windows 2000 SP2 and Windows 98 SE + hotfix. To enable this capability, the
sample code would need to be modified so that for each of the three data ranges that uses the specifier
KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, a second data range must be included that is identical except that it
uses the specifier KSDATAFORMAT_SPECIFIER_DSOUND instead. For an example, see Specifying AC-3 Data
Ranges.
USB Audio Support for Non-PCM Formats
10/23/2019 • 2 minutes to read • Edit Online

Microsoft's USBAudio class system driver, Usbaudio.sys, does not currently support USB Audio Type III formats
with padded AC-3. For more information, see the Universal Serial Bus Device Class Definition for Audio Data
Formats specification at the USB Implementers Forum website.
USBAudio can accept packed, "raw" AC-3 (as opposed to the padded, AC-3-over-S/PDIF format accepted by the
PortCls driver). USBAudio supports the internal format of DirectShow's DVD-splitter filter (see DVD Decoder
Support in Windows), which can be connected directly to USBAudio under the control of KsProxy (see Kernel
Streaming Proxy). Specifically, the nonpadded AC-3 data range exposed by USBAudio is
KSDATAFORMAT_SUBTYPE_AC3_AUDIO, which is the same GUID value as MEDIASUBTYPE_DOLBY_AC3.
USBAudio currently does not support DirectSound playback of non-PCM audio data.
High Definition Audio DDI
10/23/2019 • 2 minutes to read • Edit Online

In Windows Vista, Microsoft will provide the following two drivers as part of the operating system:
A bus driver for managing an Intel High Definition Audio (HD Audio) bus interface controller.
A Universal Audio Architecture (UAA) class driver for managing a UAA-compliant audio codec (or possibly
more than one codec) that is connected to an HD Audio controller.
Microsoft also will develop a similar HD Audio bus driver and UAA HD Audio class driver for systems that run
Windows Server 2003, and Windows XP. For information about the HD Audio controller architecture, see the Intel
High Definition Audio Specification at the Intel HD Audio website. For an overview of Microsoft's UAA, see the
white paper titled Universal Audio Architecture at the audio technology website.
The HD Audio bus driver implements the HD Audio device driver interface (DDI), which kernel-mode audio and
modem drivers use to communicate with hardware codecs that are attached to the HD Audio controller. The HD
Audio bus driver exposes the HD Audio DDI to its children, which are instances of the audio and modem drivers
that manage the codecs.
The version of the HD Audio bus driver that runs on Windows Server 2003 and Windows XP supports three
variants of the HD Audio DDI:
A DDI that is defined by the HDAUDIO_BUS_INTERFACE structure. This DDI is identical to the HD Audio
DDI in Windows Vista.
A DDI that is defined by the HDAUDIO_BUS_INTERFACE_V2 structure. This DDI is available in Windows
Vista and later versions of Windows.
A DDI that is defined by the HDAUDIO_BUS_INTERFACE_BDL structure. This DDI is available in Windows
XP and later versions of Windows.
The differences between the three DDIs are minor and are discussed in Differences Between the HD Audio DDI
Versions.
In Windows Vista, the HD Audio bus driver supports the DDI that is defined by the HDAUDIO_BUS_INTERFACE and
the HDAUDIO_BUS_INTERFACE_V2 structures.
In Windows Vista, Windows Server 2003 and Windows XP, the UAA class driver uses the DDI defined by the
HDAUDIO_BUS_INTERFACE structure to manage UAA-compliant audio codecs. In addition, hardware vendors can
choose to write custom device drivers that use one or both of these DDIs to manage their audio and modem
codecs.
Hardware vendors should design their audio codecs to conform to the UAA hardware requirements document (to
be published). In the absence of a custom audio driver from the vendor, users can rely on the system-supplied UAA
HD Audio class driver to manage their UAA-compliant audio codecs. However, an audio codec might contain
proprietary features that are accessible only through the vendor's custom driver.
This section describes the following information for both versions of the HD Audio DDI:
A background discussion of Intel's HD Audio architecture and Microsoft's UAA HD Audio class driver.
Programming guidelines for using both versions of the HD Audio DDI to control audio and modem codecs.
This section includes:
HD Audio and UAA
HD Audio DDI Programming Guidelines
HD Audio and UAA
12/5/2018 • 2 minutes to read • Edit Online

This section presents background information about Intel's HD Audio controller architecture and Microsoft's HD
Audio bus driver and UAA HD Audio class driver.
This section includes:
Intel's HD Audio Architecture
UAA Extensions to the HD Audio Architecture
HD Audio Bus Driver
UAA Class Drivers
Communicating Verbs with the HD Audio Codec
Intel's HD Audio Architecture
12/5/2018 • 2 minutes to read • Edit Online

The Intel High Definition Audio Specification (see the Intel HD Audio website) describes an audio hardware
architecture that is being developed as the successor to the Intel AC'97 codec and controller specification. The
operating system's UAA driver components can service an audio solution that exposes the HD Audio register set
and connects to the system's internal bus without requiring a solution-specific driver from the hardware vendor.
The HD Audio architecture provides a uniform programming interface for digital audio controllers. Typically,
today's audio codecs conform to the AC'97 industry standard, and digital controllers connect to one or more AC'97
codecs through another industry standard, AC-Link. Although these standards help to ensure that codecs and links
are implemented consistently, no standard currently exists that defines the interface to the digital audio controller.
Vendors tend to have very similar solutions for their system-integrated AC'97 digital audio controllers, but each
AC'97 solution is likely to be different enough to require a separate driver. The HD Audio architecture is intended to
eliminate the requirement for solution-specific drivers by specifying a base register set that is uniform across all
implementations.
A bus controller that conforms to the HD Audio architecture:
Provides controller hardware version information.
Provides hardware configuration information, including the number of serial data-out (SDO) lines and DMA
engines.
Manages the amount of bus bandwidth available on the HD Audio Link.
Accepts unsolicited responses and wake-up events from codecs.
Queues codec commands and codec responses in separate ring buffers.
Provides a collection of input, output, and bidirectional DMA engines that perform scatter/gather transfers
and can stream data between codecs and cyclic buffers in memory without intervention by the host
processor.
The following figure shows a diagram of the UAA driver architecture for HD Audio devices in Windows Vista. In the
figure, the software components that are labeled UAA HD Audio Class Driver and HD Audio Bus Driver are
provided by Microsoft. The component labeled Modem Driver is provided by an independent hardware vendor.
The UAA HD Audio class driver provides the streaming interface to the operating system audio stack above the
driver (not shown in the preceding figure).
The HD Audio bus driver directly accesses the hardware registers in the HD Audio controller and provides the DDI
that the UAA HD Audio class driver or modem driver uses to manage the DMA engines and to send commands to
the codecs. The HD Audio bus driver handles all interrupts, Plug and Play notifications, and power management
events on behalf of audio devices on the HD Audio Link.
The HD Audio controller provides the DMA engines and command buffers that are used to transfer commands and
data to codecs on the HD Audio Link. The boxes labeled Codec in the preceding figure can be either audio or
modem codecs, and they can be connected either to removable peripherals through external jacks or to fixed
internal peripherals, such as mobile PC speakers.
UAA Extensions to the HD Audio Architecture
12/5/2018 • 2 minutes to read • Edit Online

To be UAA-compliant, a hardware controller must implement the following change to the Intel High Definition
Audio Specification:
A UAA device must support 256 entries each for the command output ring buffer (CORB) and the response
input ring buffer (RIRB).
In addition, the Intel HD Audio architecture includes several features that are not required to implement a UAA-
compliant HD Audio device. As an option, hardware vendors can omit the following features from their HD Audio
devices and remain UAA-compliant:
DMA position lower base address (DPLBASE) and DMA position upper base address (DPUBASE) registers (at
offsets 70h and 74h).
Immediate command output, immediate response input, and immediate command status registers (at
offsets 60h, 64h, and 68h).
Flush control bit in the global control register (at offset 08h).
A bus controller design can omit these features and still be fully compatible with the HD Audio bus driver. However,
a hardware vendor should consider whether these features might be necessary for compatibility with other device-
specific software. For example, a BIOS routine might use the immediate command, response, and status registers.
For UAA version 1.0, the HD Audio hardware version must be 1.0. (The VMAJ and VMIN registers must specify a
major version number of 01h and a minor version number of 00h.)
HD Audio Bus Driver
12/5/2018 • 2 minutes to read • Edit Online

The HD Audio bus driver is the only software component that directly accesses the hardware registers of the HD
Audio bus interface controller. The bus driver exposes the HD Audio DDI that its children--instances of the function
drivers that control the audio and modem codecs--can use to program the HD Audio controller hardware. In
addition, the bus driver manages the HD Audio Link hardware resources, which include the DMA engines and bus
bandwidth. Function drivers allocate and free these resources through the HD Audio DDI.
The HD Audio bus driver:
Queries the codecs on the bus and creates children to manage the codecs.
Handles interrupt service routines (ISRs) for unsolicited responses and propagates the unsolicited responses
to its children.
Passes commands from its children to the codecs and retrieves responses from the codecs.
Sets up the DMA engines that transfer data to or from the cyclic buffers.
Manages bus bandwidth resources on the HD Audio Link.
Provides access to the wall clock register and link position registers.
Provides synchronized starting and stopping of groups of streams.
The HD Audio bus driver does not provide:
An interface for programming a DSP or additional registers that are not defined in the Intel High Definition
Audio Specification.
Prioritized bandwidth management.
During device enumeration, the HD Audio bus driver detects the codecs that are attached to the HD Audio
controller's HD Audio Link. For each codec, the bus driver loads one function driver (if available) for each function
group that it finds within the codec. For information about function groups, see the Intel High Definition Audio
Specification at the Intel HD Audio website.
UAA Class Drivers
12/5/2018 • 2 minutes to read • Edit Online

In Windows Vista, Microsoft provides UAA class drivers for audio devices that connect to either an internal bus
(PCI) or an external bus (IEEE 1394 or USB). To be supported by the UAA class driver for a particular bus, a device
must conform to the UAA hardware specifications for that bus. For a device on an internal bus, the UAA hardware
requirements document specifies the following:
The HD Audio controller's register set with the minor changes that are discussed in UAA Extensions to the
HD Audio Architecture.
The requirements for the HD Audio codec (to be published).
For information about the requirements for UAA devices on external buses or information about UAA class drivers,
see the white paper titled Universal Audio Architecture at the audio technology website.
The remainder of this discussion refers only to the version of the UAA class driver that controls an audio device
that connects to an internal bus, implements the HD Audio hardware registers, and controls a UAA-compliant HD
Audio codec. This class driver is a child of the HD Audio bus driver and uses the bus driver's baseline HD Audio DDI
to program the UAA-compliant hardware.
The UAA class driver for the HD Audio codec:
Provides the system with a device interface for an audio codec or codecs.
Collects information about the digital-to-audio converters, audio-to-digital converters, and jack-presence
detection pins in the codecs that are present on the HD Audio Link.
Initializes the audio codec or codecs with third-party commands on startup.
Gets and sets audio properties in the audio codecs.
Provides a streaming interface (mapping a stream's cyclic buffer to user mode, setting up the codec and
DMA engine, and handling properties such as link position).
Handles power management in the audio codecs.
This class driver does not provide:
A way of dynamically programming audio effects nodes in the codecs.
Combining functions across two or more codecs to form an aggregate audio or modem device.
Handling of general-purpose I/O (GPIO) pins on widgets unless they are explicitly defined in the UAA
hardware requirements document.
A plug-in model for third-party code for either programming the codecs or providing software effects.
Communicating Verbs with the HD Audio Codec
6/25/2019 • 3 minutes to read • Edit Online

The IOCTL_AZALIABUS_SENDVERBS IOCTL is used by the Hdau.exe pin configuration tool when you define sound
topologies for your audio adapters. Do not use this IOCTL for other purposes. This information about
IOCTL_AZALIABUS_SENDVERBS is provided to document its design and implementation only. This IOCTL is
supported in the Windows 7 Hdaudio.sys audio class driver.
High definition (HD) audio codecs are able to receive and respond to verbs. These verbs and the responses of the
codecs to these verbs are documented as part of The HD Audio Specification.
In Windows 7 and later versions of the Windows operating systems, the HD audio class driver uses the
IOCTL_AZALIABUS_SENDVERBS IOCTL to communicate verbs with the audio codec.
IOCTL_AZALIABUS_SENDVERBS is defined as shown in the following example:

#define IOCTL_AZALIABUS_SENDVERBS CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)

For more information about FILE_DEVICE_UNKNOWN, METHOD_BUFFERED, and FILE_ANY_ACCESS, see the
Devioctl.h header file in the Windows SDK.
To initiate communication with the audio codec, the class driver calls the DeviceIoControl function with the
following parameters.

BOOL DeviceIoControl(
(HANDLE) hDevice, // handle to device
IOCTL_AZALIABUS_SENDVERBS, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID) lpOutBuffer, // output buffer
(DWORD) nOutBufferSize, // size of output buffer
(LPDWORD) lpBytesReturned, // number of bytes returned
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
);

If the call to DeviceIoControl is successful, it returns a nonzero value. If the call fails or is pending (not processed
immediately), DeviceIoControl returns a zero value. The class driver can call GetLastError for a more detailed
error message.
When the audio driver must change pin configuration defaults, it can use IOCTL_AZALIABUS_SENDVERBS to send
and receive Set and Get verbs from the audio codec. If communication with the audio codec is not about pin
configuration, the audio codec only responds to the Get verb.
The following example shows a function that takes an AzCorbeEntry structure and a HANDLE as parameters and
returns the AzRirbResponse from the codec.
AzRirbEntry SendVerb(HANDLE handle, AzCorbEntry verb)
{
UserModeCodecCommandPacket c;
UserModeCodecResponsePacket r;
c.NumCommands = 1;
c.Command[0] = verb;
DWORD BytesReturned;

//A nonzero value is returned for a successful call and it is interpreted as TRUE
BOOL rc = DeviceIoControl(handle, IOCTL_AZALIABUS_SENDVERBS, &c, sizeof(c), &r, sizeof(r), &BytesReturned, 0);

if(!rc)
{
printf("Failed to communicate with the device!\n");
return 0;
}

if(BytesReturned != sizeof(r))
{
printf("Wrong number of bytes returned!\n");
return 0;
}

return r.Response[0];
}

The data types and structures that are used in the previous code example are defined in the following example:
AzCorbEntry

struct AzCorbEntry
{
ULONG Verb : 20; // 0:19
ULONG NodeId : 7; // 20:26
ULONG IndirectNID : 1; // 27
ULONG LinkId : 4; // 28:31
enum {Invalid = 0xffffffff};
AzCorbEntry(ULONG x = 0)
:
Verb(x),
NodeId(x >> 20),
IndirectNID(x >> 27),
LinkId(x >> 28) {}
operator ULONG()
{
return Verb | NodeId << 20 | IndirectNID << 27 | LinkId << 28;
}
};

AzRirbEntry
struct AzRirbEntry
{
union
{
struct
{
ULONG Response : 21; // 0 : 20
ULONG SubTag : 5; // 21 : 25
ULONG Tag : 6; // 26 : 31
} UnsolicitedForm;

ULONG Response : 32; // 0:31


};
ULONG Sdi : 4;// 32:35
ULONG Unsolicited : 1;// 36
ULONG Reserved0 : 26;
// 37:62
ULONG Valid : 1;// 63 note this bit only exists
// on the "link". The fact that the response
// got into memory assures that it is valid
AzRirbEntry (ULONGLONG x = 0)
{
Response = x & 0xffffffff;
Sdi = x >> 32;
Unsolicited = x >> 36;
Reserved0 = x >> 37;
Valid = x >> 63;
}
operator ULONGLONG()
{
return (ULONGLONG)Response | (ULONGLONG)Sdi << 32 | (ULONGLONG)Unsolicited << 36 | (ULONGLONG)Reserved0 <<
37 | (ULONGLONG)Valid << 63;
}
};

The following two structures are used together with the verb transfer IOCTL to enable the command and response
transfers between the audio driver and the HD audio codec.
UserModeCodecCommandPacket

typedef struct _UserModeCodecCommandPacket


{
ULONG NumCommands; // number of commands in this packet
AzCorbEntry Command[1]; // variable length array of verbs
} UserModeCodecCommandPacket;

UserModeCodecResponsePacket

typedef struct _UserModeCodecResponsePacket


{
ULONG NumResponses; // on successful IOCTL, this will be updated with the number of responses.
AzRirbEntry Response[1]; // Variable length array of responses. lpOutBuffer param to DeviceIoControl
// must point to sufficient space to hold this IOCTL with all its responses
} UserModeCodecResponsePacket;
HD Audio DDI Programming Guidelines
10/23/2019 • 2 minutes to read • Edit Online

This section presents programming guidelines for using the HD Audio DDI versions (as defined by the
HDAUDIO_BUS_INTERFACE , HDAUDIO_BUS_INTERFACE_V2 and HDAUDIO_BUS_INTERFACE_BDL
structures) to control audio and modem codecs that are connected to an HD Audio bus interface controller.
The HD Audio bus driver exposes one or both versions of the HD Audio DDI to its children, which are kernel-mode
function drivers for the audio and modem codecs. (One of these children might be the UAA HD Audio class driver.)
These drivers call the routines in the DDIs to access the hardware capabilities of the HD Audio controller device.
This section includes:
Differences Between the HD Audio DDI Versions
Synchronous and Asynchronous Codec Commands
Wall Clock and Link Position Registers
Hardware Resource Management
Synchronizing Two or More Streams
Wake Enable
Data Copying and Caching Policy
Querying for an HD Audio DDI
HD Audio DDI Programming Guidelines
10/23/2019 • 2 minutes to read • Edit Online

This section presents programming guidelines for using the HD Audio DDI versions (as defined by the
HDAUDIO_BUS_INTERFACE , HDAUDIO_BUS_INTERFACE_V2 and HDAUDIO_BUS_INTERFACE_BDL
structures) to control audio and modem codecs that are connected to an HD Audio bus interface controller.
The HD Audio bus driver exposes one or both versions of the HD Audio DDI to its children, which are kernel-mode
function drivers for the audio and modem codecs. (One of these children might be the UAA HD Audio class driver.)
These drivers call the routines in the DDIs to access the hardware capabilities of the HD Audio controller device.
This section includes:
Differences Between the HD Audio DDI Versions
Synchronous and Asynchronous Codec Commands
Wall Clock and Link Position Registers
Hardware Resource Management
Synchronizing Two or More Streams
Wake Enable
Data Copying and Caching Policy
Querying for an HD Audio DDI
Differences Between the HD Audio DDI Versions
10/23/2019 • 2 minutes to read • Edit Online

The HD Audio DDI is available in three slightly different versions that are defined as follows:
A baseline version of the HD Audio DDI, which is defined by the HDAUDIO_BUS_INTERFACE structure.
Most function drivers for audio and modem codecs require only the capabilities that this DDI version
provides. This version is available through the HD Audio bus drivers that are provided with Windows XP
and Windows Vista.
An enhanced version of the HD Audio DDI that is defined by the HDAUDIO_BUS_INTERFACE_V2
structure. This version of the DDI provides the additional capability that is required to support DMA-driven
event notification with flexibility. It is available in Windows Vista and later versions of Windows.
A modified version of the HD Audio DDI that is defined by the HDAUDIO_BUS_INTERFACE_BDL
structure. This version accommodates the requirements of a relatively few audio and modem drivers that
must have additional control over the setup of buffer descriptor lists (BDLs) for DMA operations. This
version of the DDI is available for Windows XP and later versions of Windows. However, use either the
HDAUDIO_BUS_INTERFACE or the HDAUDIO_BUS_INTERFACE_V2 DDI version instead. .
In all three structures, the names and types of the first five members match those of the five members of the
INTERFACE structure. For information about the values of these members, see Obtaining an
HDAUDIO_BUS_INTERFACE DDI Object, Obtaining an HDAUDIO_BUS_INTERFACE_V2 DDI Object or Obtaining an
HDAUDIO_BUS_INTERFACE_BDL DDI Object.
The routines in the three versions of the HD Audio DDI perform the following tasks:
Transfer commands to codecs and retrieve the responses to those commands.
Allocate and set up DMA engines to transfer the data in render and capture streams.
Change the stream state of one or more DMA engines to running, paused, stopped, or reset.
Reserve link bandwidth for render and capture streams.
Provide direct access to the wall clock register and link position registers.
Notify clients of unsolicited responses from codecs.
Register kernel events so that they can receive DMA progress notifications.
The HDAUDIO_BUS_INTERFACE and HDAUDIO_BUS_INTERFACE_BDL versions of the DDI have the following
differences:
The HDAUDIO_BUS_INTERFACE structure defines two routines, AllocateDmaBuffer and FreeDmaBuffer ,
that are not present in HDAUDIO_BUS_INTERFACE_BDL.
The HDAUDIO_BUS_INTERFACE_BDL structure defines three routines, SetupDmaEngineWithBdl ,
AllocateContiguousDmaBuffer , and FreeContiguousDmaBuffer , that are not present in
HDAUDIO_BUS_INTERFACE.
When a client calls the AllocateDmaBuffer routine in the first DDI version, the HD Audio bus driver:
Allocates a DMA buffer and BDL for a DMA engine to use.
Initializes the BDL.
Sets up the DMA engine to use the buffer and BDL.
In contrast, the AllocateContiguousDmaBuffer routine in the second DDI version allocates storage for a DMA
buffer and BDL, but relies on the caller to initialize the BDL. The SetupDmaEngineWithBdl routine sets up the
DMA engine to use the buffer and the caller-initialized BDL.
The BDL contains the list of physical memory blocks in the DMA engine's scatter/gather queue. By calling
SetupDmaEngineWithBdl to set up the BDL, the client can specify the points in the data stream at which the
DMA engine generates interrupts. The client does this by setting the interrupt-on-completion (IOC) bit in selected
BDL entries. With this capability, the client can precisely control the timing of the IOC interrupts that occur during
the processing of the audio stream. Audio modem drivers also use the second DDI version to get accurate system
clock information.
For more information, see the Intel High Definition Audio Specification.
However, nearly all clients will use the HDAUDIO_BUS_INTERFACE version of the DDI. Only a few clients that
require precise control over the timing of interrupts will use the HDAUDIO_BUS_INTERFACE_BDL version.
Managing Memory Buffers During Audio Resource
Rebalance and Surprise Removal Operations
12/5/2019 • 3 minutes to read • Edit Online

PnP Rebalance Overview


PnP rebalancing is used in certain PCI scenarios where memory resources need to be reallocated. PnP rebalancing
is available in Windows 10, version 1511 and later versions of Windows. For general information on rebalancing,
see Implement PnP Rebalance for PortCls Audio Drivers.

PnP Surprise Removal Overview


PnP "Surprise Removal" (SR) occurs when a device been unexpectedly removed from the machine and is no longer
available for I/O operations. For additional information, see State Transitions for PnP Devices and Handling an
IRP_MN_SURPRISE_REMOVAL Request.

Managing Memory Buffers During Audio Resource Rebalance and


Surprise Removal Operations
This section describes how to manage memory buffers and the sequence of operations for memory buffer clean up
during audio resource rebalance and PnP SR operations for HD Audio codec drivers.
Note that the operating system support for the buffer management approach described in this topic will be
available in the next major feature release of Windows after the May 2019 Update.
If the allocation and deallocation of the supporting memory buffers is not done properly it can lead to memory
corruption, soft hangs and failures, such as Bug Check 0x9F: DRIVER_POWER_STATE_FAILURE.
Close Stream Handle Behavior
When portcls receives the close stream handle, portcls invokes the functions below to set the stream state to stop
and to free the buffer:
set stream state (If the stream is not already in the stop state.)
IMiniportWaveRTStream::SetState
release buffer
[IMiniportWaveRTStream::FreeAudioBuffer](IMiniportWaveRTStream::SetState or
IMiniportWaveRTStreamNotification::FreeBufferWithNotification
Note that portcls miniport drivers should succeed the state transitions from higher value to lower values (RUN ==
3, PAUSE==2, ACQUIRE==1, STOP==0) when the stream has been already stopped by the driver during a SR/STOP
operation (i.e., when SR/STOP arrives before the close handle request).
Buffer Handling
When a stream is closed during normal operations, portcls invokes the Wave RT’s callbacks to let the driver stop its
DMA operations and release its associated buffers:
IMiniportWaveRTStream::SetState -> SetDmaEngineState (HD Audio Bus DDI). Takes action to start/pause DMA.
IMiniportWaveRTStream::FreeAudioBuffer or IMiniportWaveRTStreamNotification::FreeBufferWithNotification->
FreeDmaBuffer (HD Audio Bus DDI).
IMiniportWaveRTStream[Notification]’s destructor-> FreeDmaEngine (HD Audio Bus DDI).
When a device is surprise removed, the miniport must release all its h/w resources without waiting for the open
stream handles to close. This means that the miniport must stop, reset and free all its allocated DMA engines before
forwarding the PnP request to PortCls with PcDisptachIrp DDI. On the other hand, the miniport must not free the
audio Wave RT buffers until the stream handles are closed and PortCls notifies the miniport with the
FreeAudioBuffer/FreeBufferWithNotification callback.
When a device is stopped because it elected to support rebalance, the miniport must release all its hardware
resources without waiting for the open stream handles to close. This means that the miniport must stop, reset and
free all its allocated DMA engines in the PnP callback invoked by portcls. On the other hand, the miniport must not
free the audio Wave RT buffers until the stream handles are closed and PortCls notifies the miniport with the
FreeAudioBuffer/FreeBufferWithNotification callback.
Note that normal close stream operation can happen at the same time as SR/Stop operation, this means that the
miniport must implement the proper synchronization between these threads.
Examples of operations assuming that the right serialization code exists between the SR/STOP and Close threads:
On Close:

STOP_DMA

FREE_BUFFER

FREE_DMA_ENGINE

On SR/Stop:

STOP_DMA

FREE_DMA_ENGINE

This is the definition for these operations in pseudocode.

STOP_DMA:
if (DmaEngineState != ResetState)
{
\\Set DMA Engine state to not running
SetDmaEngineState(context, StopState, 1, &dma);
SetDmaEngineState(context, ResetState, 1, &dma);
DmaEngineState = ResetState;
}

FREE_BUFFER:
\\Free DMA buffer
FreeDmaEBuffer(context, dma);
FREE_DMA_ENGINE:
if (DMAEngineAllocated==true)
{
\\Free DMA engine
FreeDmaEngine (context, dma);
DMAEngineAllocated=false
}

For more information, see:


PSET_DMA_ENGINE_STATE callback function
HDAUDIO_STREAM_STATE Enumeration
PFREE_DMA_ENGINE callback function
PSET_DMA_ENGINE_STATE callback function
IMiniportWaveRTStreamNotification interface
IMiniportWaveRTStreamNotification::FreeBufferWithNotification method
PcDisptachIrp
Synchronous and Asynchronous Codec Commands
10/23/2019 • 4 minutes to read • Edit Online

The TransferCodecVerbs routine allows function drivers to send commands to audio and modem codecs that are
connected to an HD Audio controller. The codec commands can execute either synchronously or asynchronously:
If a call to TransferCodecVerbs submits a list of commands to be processed synchronously, the routine
returns only after the codec or codecs have processed all of the commands.
If a call to TransferCodecVerbs submits a list of commands to be processed asynchronously, the routine
returns as soon as the HD Audio bus driver adds the commands to its internal command queue, without
waiting for the codec or codecs to process the commands. After the codecs have processed the commands,
the bus driver notifies the function driver by calling a callback routine.
Depending on the nature of the codec commands that it sends, the function driver uses one or more of the
following techniques to retrieve responses from a codec:
If the function driver must have the response from the codec before it can perform any additional
processing, it uses the synchronous mode.
If the function driver does not need to wait for the codec commands to complete, to see the codec
responses, and to know when the commands complete, then it uses the asynchronous mode, ignores the
callback routine (except to free the storage for the codec commands), and discards or ignores the responses
to the codec commands.
If the function driver must know when the codec commands complete, but does not need to see the
responses, then it uses the asynchronous mode and relies on the callback routine for notification. However,
it discards or ignores the responses to the codec commands. The callback routine might use a kernel
streaming (KS) event to send the notification to the main part of the driver.
If the function driver must know both when the codec commands complete and what the responses are, but
must resume processing immediately rather than waiting for the commands to complete, then it uses the
asynchronous mode and avoids reading the responses until it receives the callback routine. Either the
callback routine or the main part of the driver can inspect the responses.
TransferCodecVerbs returns STATUS_SUCCESS if it succeeds in adding the list of commands to the bus driver's
internal command queue. Even though the call succeeds, the responses might still be invalid. The function driver
must check the status bits in the codec responses to determine whether they are valid. This rule applies to both
synchronous and asynchronous mode.
The cause of an invalid response is likely to be one of the following:
The command did not reach the codec.
The codec responded, but the response was lost when a first-in, first-out (FIFO) overrun occurred in the
RIRB.
The latter problem indicates that the RIRB FIFO is of insufficient size.
Each codec response contains an IsValid flag to indicate whether the response is valid and a HasFifoOverrun
flag to indicate whether an RIRB FIFO overrun has occurred. If IsValid = 0, indicating that a response is invalid, the
HasFifoOverrun flag helps identify the source of the failure:
If HasFifoOverrun = 0, then the codec failed to respond within the required time interval. The probable
cause is that the command never reached the codec.
If HasFifoOverrun = 1, then the command probably reached the codec, but the response was lost due to a
FIFO overrun.
During a call to TransferCodecCommands, the caller provides a pointer to an array of
HDAUDIO_CODEC_TRANSFER structures. Each structure contains a command and provides space for a
response. The bus driver always writes each response into the structure that contains the command that triggered
the response.
For each call to TransferCodecCommands, the order in which the commands are processed is determined by the
order of the commands in the array. Processing the first command in the array always completes before
processing the second command begins, and so on.
In addition, if a client makes an asynchronous call to TransferCodecCommands and then calls
TransferCodecCommands a second time without waiting for the callback routine from the first call, the relative
order in which the two groups of commands from the two calls are processed is defined by the order in which the
client submitted the two groups of commands. Thus, the bus driver processes all of the commands from the first
call before it begins processing the commands from the second call.
However, the relative order of commands sent by two different function driver instances is undefined. (Each
instance has its own physical device object.) For example, if instance 1 calls TransferCodecCommands to send
commands A, B, and C in the order A-B-C, and instance 2 calls TransferCodecCommands to send commands X, Y,
and Z in the order X-Y-Z, then the bus driver might execute the commands in the order A-X-Y-B-Z-C.
When separate function driver threads share access to the same set of hardware resources, the relative order of
commands from different driver threads might be important. If so, the function driver is responsible for
synchronizing the sharing of the resources among the threads.
For example, the hardware interface for writing a sequence of data bytes to a codec might consist of an index
register and an 8-bit data register. First, the function driver submits a codec command to load the starting index
into the index register. Next, the driver submits a command to write the first byte of data to the data register. The
index register increments following each successive write to the data register until the transfer is complete.
However, if two driver threads fail to properly synchronize their access of the index and data registers, the relative
order of the individual register access by the two threads is undefined and the probable result is data corruption or
an invalid hardware configuration.
The TransferCodecVerbs routine is available in both versions of the HD Audio DDI.
Wall Clock and Link Position Registers
10/23/2019 • 2 minutes to read • Edit Online

The HD Audio controller contains a 32-bit wall clock counter register that increments at the bit-clock rate of the HD
Audio Link and rolls over approximately every 89 seconds. Software uses this counter to synchronize between two
or more controller devices by measuring the relative drift between the devices' hardware clocks.
In addition, the HD Audio controller contains a set of link position registers. Each DMA engine has a link position
register that indicates the current read or write position of the data that the engine is transmitting over the HD
Audio Link. The position register expresses the current position as a byte offset from the beginning of the cyclic
buffer:
In a render stream, the link position register indicates the cyclic buffer offset of the next byte that the DMA
engine will send over the link to the codec.
In a capture stream, the link position register indicates the cyclic buffer offset of the next byte that the DMA
engine will receive from the codec over the link.
The cyclic buffer offset is simply the offset in bytes of the current read or write position from the start of the cyclic
buffer. Upon reaching the end of the buffer, the position wraps around to the start of the buffer and the cyclic
buffer offset resets to zero. The cyclic buffer resides in system memory. For more information, see the Intel High
Definition Audio Specification at the Intel HD Audio website.
A kernel-mode function driver can read the wall clock and link position registers directly. To enable direct access,
the HD Audio bus driver maps the physical memory that contains the registers into system virtual memory. The
function driver calls the GetWallClockRegister or GetLinkPositionRegister routine to obtain a system virtual
address pointer to the wall clock register or a link position register. These two routines are available in both
versions of the HD Audio DDI.
The HD Audio controller hardware mirrors the wall clock and link position registers into memory pages that do not
contain any of the other registers in the controller. Thus, if the function driver maps the mirrored wall clock or
position registers to user mode, no user-mode programs can access any of the controller's other registers. The
driver never allows a user-mode program to touch these other registers and program the hardware.
Register mirroring must accommodate the host processor's page size. Depending on the host processor
architecture, a typical page size might be 4,096 or 8,192 bytes.
Hardware Resource Management
12/5/2018 • 2 minutes to read • Edit Online

Through the HD Audio DDI, function drivers for audio and modem codecs can allocate and free hardware
resources in the HD Audio controller device. These resources are chiefly:
DMA engines in the HD Audio controller.
Bus bandwidth on the HD Audio Link.
This section includes:
Allocating DMA Engines
Allocating Link Bandwidth
Striping
Allocating DMA Engines
10/23/2019 • 2 minutes to read • Edit Online

The HD Audio controller contains a fixed number of DMA engines. Each engine can perform scatter/gather transfers
for a single render or capture stream.
Three types of DMA engines are available:
Render DMA engines, which can handle only render streams.
Capture DMA engines, which can handle only capture streams.
Bidirectional DMA engines, which can be configured to handle either render or capture streams.
When allocating a DMA engine for a render stream, the AllocateCaptureDmaEngine routine allocates a render
DMA engine if one is available. If the supply of render DMA engines is exhausted, the routine allocates a
bidirectional DMA engine if one is available.
Similarly, when allocating a DMA engine for a capture stream, the AllocateRenderDmaEngine routine allocates a
capture DMA engine if one is available. If the supply of capture DMA engines is exhausted, the routine allocates a
bidirectional DMA engine if one is available.
The AllocateXxxDmaEngine routines are available in both versions of the HD Audio DDI.
Allocating Link Bandwidth
10/23/2019 • 2 minutes to read • Edit Online

The HD Audio Link has a finite amount of bus bandwidth available for render and capture streams to use. To ensure
glitchless audio, the HD Audio bus driver manages bus bandwidth as a shared resource. When a function driver
allocates a DMA engine, it must also allocate a portion of the available bus bandwidth for the DMA engine's render
or capture stream to use.
A fixed amount of bus bandwidth is available on the HD Audio Link's serial data in (SDI) lines and on the serial data
out (SDO) lines. The HD Audio bus driver monitors bandwidth consumption separately on the SDI and SDO lines. If
a request to allocate input or output bus bandwidth exceeds the available bandwidth, the bus driver fails the
request.
When the function driver calls the bus driver's AllocateCaptureDmaEngine and AllocateRenderDmaEngine
routines, it specifies a stream format. The stream format specifies the stream's sample rate, sample size, and
number of channels. From this information, the AllocateXxxDmaEngine routine determines the stream's bus
bandwidth requirements. If sufficient bandwidth is available, the routine allocates the required bandwidth for the
DMA engine to use. Otherwise, the call to AllocateXxxDmaEngine fails.
A function driver can call ChangeBandwidthAllocation to request a change in the bandwidth allocation for an
existing DMA engine allocation.
The AllocateXxxDmaEngine and ChangeBandwidthAllocation routines are available in both versions of the HD
Audio DDI.
Striping
10/23/2019 • 2 minutes to read • Edit Online

The HD Audio architecture supports a technique called striping that can reduce the amount of bus bandwidth that
render streams consume. If the HD Audio hardware interface provides more than one SDO line, striping can
increase the rate at which a render DMA engine can transfer data by alternately distributing the bits in the data
stream among the SDO lines. The first bit (the most significant bit) travels over SDO0, the second bit travels over
SDO1, and so on. For example, with two SDO lines, striping effectively doubles the transfer rate by splitting the
stream between the two SDO lines. A DMA engine that uses striping to transfer a render stream over two SDO lines
consumes only half the bus bandwidth that it would consume if it did not use striping.
The function driver enables striping through the AllocateRenderDmaEngine routine's stripe call parameter.
For more information about striping, see the Intel High Definition Audio Specification at the Intel HD Audio website.
Synchronizing Two or More Streams
10/23/2019 • 2 minutes to read • Edit Online

The SetDmaEngineState routine sets the state of one or more DMA engines to one of the following: running,
paused, stopped, or reset. If a call to this routine specifies more than one DMA engine, then all of the DMA engines
make the state transition synchronously.
The ability to synchronize a group of streams is required for some audio applications. For example, an audio driver
might use codec-combining to create a logical surround-sound audio device that joins two audio codecs: one
codec drives the front speakers and a second audio codec drives the back speakers. Depending on the capabilities
of the codecs, the audio driver might be required to split the original surround-sound audio stream into two
streams, one for each codec. By using the SetDmaEngineState routine to start and stop the streams in unison,
the two streams can remain synchronized.
Allowing the two streams to fall out of synchronization by even a few samples might cause undesirable audio
artifacts.
The SetDmaEngineState routine is available in both versions of the HD Audio DDI.
The UAA HD Audio class driver does not perform codec-combining.
Wake Enable
6/25/2019 • 2 minutes to read • Edit Online

Before powering down a codec, the codec function driver typically enables the codec to wake up the system if a
status-change event occurs while the codec is in the powered-down state. For an audio codec, such an event can be
triggered when the user inserts a plug into an input jack or removes a plug from a jack. For a modem codec, a
status-change event can occur when the phone rings to indicate an incoming call. For more information about
status-change events, see the Intel High Definition Audio Specification at the Intel HD Audio website.
To prepare for powering down, the function driver first configures the codec to signal the HD Audio bus controller
when a status-change event occurs. Next, the function driver sends an IRP_MN_WAIT_WAKE power-management
IRP to the HD Audio bus driver to tell it to enable the wake-up signal from the codec. Later, if the wake-up signal is
enabled, and the codec transmits a status-change event over the codec's SDI line, the controller generates a wake-
up signal to the system and the bus driver notifies the function driver by completing the IRP_MN_WAIT_WAKE IRP.
Following a wake event, the bus driver determines which codec generated the wake-up signal and completes any
pending IRP_MN_WAIT_WAKE IRPs on that codec. However, if the codec contains both audio and modem function
groups, for example, the bus driver has no way to determine which function group is the source of the wake-up
signal. In this case, the function driver must send its own queries to the codec to verify the source of the wake-up
signal.
Data Copying and Caching Policy
10/23/2019 • 2 minutes to read • Edit Online

A WaveCyclic miniport driver copies audio data between the DMA buffer, which the HD Audio controller hardware
accesses, and the client buffer, which the user-mode audio application accesses:
For a playback data stream, the driver copies data from the client buffer to the DMA buffer.
For a capture data stream, the driver copies data from the DMA buffer to the client buffer.
For both playback and capture streams, the driver can achieve the best performance by enabling caching of the
DMA buffer memory (cache type MmCached ) and relying on the PCI controller's bus-snooping mechanism to
ensure cache coherency. However, some PCI Express controller implementations do not snoop the HD Audio
controller's isochronous data transfers (such as Intel's initial PCI Express chipset).
The function driver cannot detect whether the PCI controller hardware supports snooping of DMA buffer transfers
or performs isochronous data transfers. To avoid potential cache coherency problems, the driver disables caching
of the DMA buffer memory by specifying the caching type for that memory as MmWriteCombined .
(MmNonCached would also work, but might not perform as well.) If you write a custom adapter driver that is
based on the sample function driver, your WaveCyclic miniport driver should behave similarly unless you can
verify that the PCI controller does in fact support snooping of DMA buffer transfers.
To support devices and systems that do not perform bus snooping, a custom function driver must follow these
rules:
For a playback stream, specify the DMA buffer's cache type as MmWriteCombined . After copying a block
of data from the client buffer to the DMA buffer, call the KeMemor yBarrier function to make the data
visible to the DMA engine. KeMemor yBarrier flushes the copied data to memory in an efficient way that
leaves the processor's data caches largely undisturbed.
For a capture stream, specify the DMA buffer's cache type as either MmWriteCombined or
MmNonCached . In addition, the function driver should avoid writing to the DMA buffer. If it must perform
in-place processing of audio samples, it should first copy the data elsewhere.
The block of data that the function driver copies to or from the DMA buffer is not required to begin or end on a
write-combining buffer boundary, and its size is not required to be a multiple of the write-combining buffer size
(typically, 32 or 64 bytes).
For codec function drivers that use the HDAUDIO_BUS_INTERFACE_BDL version of the DDI, the
AllocateContiguousDmaBuffer routine performs both the allocation and mapping of the DMA buffer memory.
The routine always sets the buffer's cache type to MmWriteCombined .
For more information about write-combining, see the IA-32 Intel Architecture Software Developer's Manual at the
Intel website.
Querying for an HD Audio DDI
10/23/2019 • 2 minutes to read • Edit Online

To obtain a counted reference to an object with an HD Audio DDI, the function driver for an audio or modem codec
sends an IRP_MN_QUERY_INTERFACE IOCTL to the HD Audio bus driver.
In Windows Vista and later, the HD Audio bus driver supports the HDAUDIO_BUS_INTERFACE and the
HDAUDIO_BUS_INTERFACE_V2 versions of the DDI. It does not support the
HDAUDIO_BUS_INTERFACE_BDL version.
An HD Audio bus driver can be installed as an upgrade in Windows Server 2003 and Windows XP. This bus driver
supports both DDI versions.
The procedures for obtaining references to the HDAUDIO_BUS_INTERFACE, the HDAUDIO_BUS_INTERFACE_V2
and the HDAUDIO_BUS_INTERFACE_BDL versions of the DDI are described in the following sections:
Obtaining an HDAUDIO_BUS_INTERFACE DDI Object
Obtaining an HDAUDIO_BUS_INTERFACE_V2 DDI Object
Obtaining an HDAUDIO_BUS_INTERFACE_BDL DDI Object
Obtaining an HDAUDIO_BUS_INTERFACE DDI
Object
10/23/2019 • 2 minutes to read • Edit Online

The following table shows the input parameter values that the function driver writes into the
IRP_MN_QUERY_INTERFACE IOCTL to obtain an HDAUDIO_BUS_INTERFACE structure and a context object
for the version of the HD Audio DDI that this structure defines.

PA RA M ET ER VA L UE

CONST GUID *InterfaceType GUID_HDAUDIO_BUS_INTERFACE

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE )

USHORT Version 0x0100

PINTERFACE Interface Pointer to HDAUDIO_BUS_INTERFACE structure

PVOID InterfaceSpecificData NULL

The function driver allocates the storage for the HDAUDIO_BUS_INTERFACE structure and includes a pointer to
this structure in the IOCTL. In the preceding table, the pointer to the HDAUDIO_BUS_INTERFACE structure is cast
to type PINTERFACE , which is a pointer to a structure of type INTERFACE . The names and types of the first five
members of HDAUDIO_BUS_INTERFACE match those of the five members of INTERFACE .
HDAUDIO_BUS_INTERFACE contains additional members that are function pointers to the DDI routines. In
response to receiving the IOCTL from the function driver, the HD Audio bus driver fills in the entire
HDAUDIO_BUS_INTERFACE structure.
The following table shows the values that the HD Audio bus driver writes into the first five members of the
HDAUDIO_BUS_INTERFACE structure.

M EM B ER VA L UE

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE )

USHORT Version 0x0100

PVOID Context Context information that must be passed as the first call
parameter to every DDI routine

PINTERFACE_REFERENCE InterfaceReference Pointer to a routine that increments the context object's


reference count
M EM B ER VA L UE

PINTERFACE_DEREFERENCE InterfaceDereference Pointer to a routine that decrements the context object's


reference count

In the preceding table, the Context member points to a context object that contains information that is specific to
the particular instance of the baseline HD Audio DDI that the client obtains from the IOCTL. When calling any of the
routines in the DDI, the client function driver must always specify the Context pointer value as the first call
parameter. The context information is opaque to the client. The HD Audio bus driver creates a different context
object for each client. When the context object is no longer required, the client frees the context object by calling
the InterfaceDereference routine shown in the preceding table. If required, a client can create additional
references to the object by calling the InterfaceReference routine, but the client is responsible for releasing these
references when it no longer requires them.
Obtaining an HDAUDIO_BUS_INTERFACE_V2 DDI
Object
10/23/2019 • 2 minutes to read • Edit Online

The following table shows the input parameter values that the function driver writes into the
IRP_MN_QUERY_INTERFACE IOCTL to obtain an HDAUDIO_BUS_INTERFACE_V2 structure and a context
object for the version of the HD Audio DDI that this structure defines.

PA RA M ET ER VA L UE

CONST GUID *InterfaceType GUID_HDAUDIO_BUS_INTERFACE_V2

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE_V2 )

USHORT Version 0x0100

PINTERFACE Interface Pointer to HDAUDIO_BUS_INTERFACE_V2 structure

PVOID InterfaceSpecificData NULL

The function driver allocates the storage for the HDAUDIO_BUS_INTERFACE_V2 structure and includes a
pointer to this structure in the IOCTL. In the previous table, the pointer to the HDAUDIO_BUS_INTERFACE_V2
structure is cast to type PINTERFACE , which is a pointer to a structure of type INTERFACE . The names and types
of the first five members of HDAUDIO_BUS_INTERFACE_V2 match those of the five members of INTERFACE .
HDAUDIO_BUS_INTERFACE_V2 contains additional members that are function pointers to the DDI routines. In
response to receiving the IOCTL from the function driver, the HD Audio bus driver populates the
HDAUDIO_BUS_INTERFACE_V2 structure.
The following table shows the values that the HD Audio bus driver writes into the first five members of the
HDAUDIO_BUS_INTERFACE_V2 structure.

M EM B ER VA L UE

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE_V2 )

USHORT Version 0x0100

PVOID Context Context information that must be passed as the first call
parameter to every DDI routine.

PINTERFACE_REFERENCE InterfaceReference A pointer to a routine that increments the context object's


reference count.
M EM B ER VA L UE

PINTERFACE_DEREFERENCE InterfaceDereference A pointer to a routine that decrements the context


object's reference count.

In the previous table, the Context member points to a context object that contains information that is specific to
the particular instance of the baseline HD Audio DDI. The client obtains this baseline HD Audio DDI from the IOCTL.
When the client function driver calls any of the routines in the DDI, it must always specify the Context member
value as the first call parameter. The context information is opaque to the client. The HD Audio bus driver creates a
different context object for each client. When the context object is no longer required, the client frees the context
object by calling the InterfaceDereference routine shown in the previous table. If it is required, a client can create
additional references to the object by calling the InterfaceDereference routine, but the client is responsible for
releasing these references when it no longer requires them.
Obtaining an HDAUDIO_BUS_INTERFACE_BDL DDI
Object
10/23/2019 • 2 minutes to read • Edit Online

As explained previously, the function driver for an audio or modem codec obtains a counted reference to an object
with an HD Audio DDI by sending an IRP_MN_QUERY_INTERFACE IOCTL to the HD Audio bus driver.
The following table shows the input parameter values that the function driver writes into the IOCTL to obtain an
HDAUDIO_BUS_INTERFACE_BDL structure and a context object for the version of the HD Audio DDI that this
structure defines.

PA RA M ET ER VA L UE

CONST GUID *InterfaceType GUID_HDAUDIO_BUS_INTERFACE_BDL

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE_BDL )

USHORT Version 0x0100

PINTERFACE Interface Pointer to HDAUDIO_BUS_INTERFACE_BDL structure

PVOID InterfaceSpecificData NULL

The function driver allocates the storage for the HDAUDIO_BUS_INTERFACE_BDL structure and includes a
pointer to this structure in the IOCTL. In the preceding table, the pointer to the HDAUDIO_BUS_INTERFACE_BDL
structure is cast to type PINTERFACE , which is a pointer to a structure of type INTERFACE . The names and types
of the first five members of HDAUDIO_BUS_INTERFACE_BDL match those of the five members of INTERFACE .
HDAUDIO_BUS_INTERFACE_BDL contains additional members that are function pointers to the DDI routines. In
response to receiving the IOCTL from the function driver, the HD Audio bus driver fills in the entire
HDAUDIO_BUS_INTERFACE_BDL structure.
The following table shows the values that the HD Audio bus driver writes into the first five members of the
HDAUDIO_BUS_INTERFACE_BDL structure.

M EM B ER VA L UE

USHORT Size sizeof (HDAUDIO_BUS_INTERFACE_BDL )

USHORT Version 0x0100

PVOID Context Context information that needs to be passed as the first


call parameter to every DDI routine
M EM B ER VA L UE

PINTERFACE_REFERENCE InterfaceReference Pointer to a routine that increments the context object's


reference count

PINTERFACE_DEREFERENCE InterfaceDereference Pointer to a routine that decrements the context object's


reference count

In the preceding table, the Context member points to a context object that contains information that is specific to
the particular instance of the HDAUDIO_BUS_INTERFACE_BDL version of the DDI that the client obtains from the
IOCTL. As explained previously, when calling any of the routines in the DDI, the client function driver must always
specify the Context pointer value as the first call parameter.
WDM Audio Support in Different Versions of
Windows
12/5/2018 • 2 minutes to read • Edit Online

This section describes the operating system support for audio devices and drivers in different versions of Windows.
Implementing Audio Module Communication
Low Latency Audio
Voice Activation
Audio Hardware Resource Management

Bluetooth Bypass Guidelines for Audio Drivers


Hardware-Offloaded Audio Processing
WDM Audio Platform Differences
WDM Audio Components
Typical Audio Configurations
Factors Governing Wave-Output Latency
Implementing Audio Module Communication
10/23/2019 • 6 minutes to read • Edit Online

An Audio Module is a distinct piece of audio processing logic performing a relatively atomic function. An audio
module may reside in the audio driver or in audio DSP. An example audio module would be DSP-based audio
processing.
Starting in Windows 10, release 1703, there are both APIs and DDIs to support communication from Universal
Windows Platform (UWP) apps and kernel mode device drivers.
This topic provides information on Implementing Audio Module Communication in the kernel device driver.
For information on how to send commands and receive change notifications from audio device modules using a
UWP app, see Configure and query audio device modules.

Why Use Audio Modules?


OEMs typically bundle a configuration application on their system that allows the customer to control aspects of
this audio system and tune it to their preference. The audio subsystem can contain various components such as
on-host audio processing objects, hardware DSP processing, and specialized hardware such as a smart amp (all in
addition to the audio codec itself). In most cases these components are created and sold by different vendors.
Historically, IHVs have created their own private APIs to integrate with one another and send information between
the individual components. Existing WIN32 configuration applications then would leverage these private APIs.
The Universal Windows Platform (UWP), provides a set of APIs that enable a single application to run across a
breadth of devices. UWP also introduced a new look-and-feel that has become the customer expectation for
applications running on Windows 10. So many OEMs would like to build their audio configuration applications on
UWP. However, a core security feature of UWP (the AppContainer sandbox) prevents communication from an
application to other components in the audio subsystem. This renders the private APIs previously used by
configuration apps inaccessible in UWP.
Starting in Windows 10, release 1703, the Audio Modules UWP API allows the configuration application and user
mode components to communicate with modules in the kernel and hardware layer that are discoverable through a
new KS property set. Audio IHV and ISVs can write applications and services that can communicate with their
hardware modules using a well-defined interface provided by Windows. For more information about the audio
modules API, see Windows.Media.Devices Namespace

Audio Module Definitions


These definitions are specific to audio modules.

T ERM DEF IN IT IO N

Audio Module A distinct piece of audio processing logic performing a


relatively atomic function. May reside in the audio driver or in
audio DSP. An example audio module would be an Audio
Processing Object (APO).

Common Audio Definitions


These definitions are typically used when working with audio drivers.
T ERM DEF IN IT IO N

OEM Original Equipment Manufacturer

IHV Independent Hardware Vendor

ISV Independent Software Vendor

HSA Hardware Support Application

UWP Universal Windows Platform

APO Audio Processing Object

DSP Digital Signal Processing

Architecture
Audio Modules puts in place a Windows supported mechanism to send messages between user mode and kernel
mode audio components. An important distinction is that Audio Modules standardizes the transport pipeline. It
does not establish the communication protocol over that transport and relies on the ISVs and IHVs to define the
protocol. The intent is to allow existing third party designs to migrate easily to Audio Modules with very little
changes.
The Audio Module API provides access to the modules through two different targeting methods: the KS wave filter
and an initialized KS pin (stream). The placement and access to specific modules is implementation specific.
HSAs and other applications will only be able to access the modules available through the filter handle. The
individual APOs loaded on a stream are the only objects that will have access to the stream targeted audio
modules.
For more information about APOs, see Windows Audio Processing Objects.
Sending Commands
Audio Module client’s avenue to query and change parameters is to send commands to the audio modules in the
kernel and hardware components in the audio subsystem. The command structure of the Audio Modules API is
loosely defined and formalizes the way that modules are discovered and identify themselves. However, the detailed
command structure must be designed and implemented by the involved ISV and IHV to establish the protocol for
what messages can be sent and the expected response.
Module Notifications to Audio Module Clients
The audio miniport also has a way to notify and pass information to Audio Module clients if the client has
subscribed to notifications on a specific module. The information passed in these notifications is not defined by the
Audio Module API, rather it is defined by the ISV and/or IHV.
Enable, Disable and General Topology Information
The Audio Modules APIs define how to enumerate and send commands to the modules. However, the APIs do not
explicitly define how Audio Module clients can enable or disable specific modules. Also, it does not establish a way
for clients to find topology information or the placement of modules in relation to one another. IHVs and ISVs can
determine if this functionality is needed an decide how to implement it.
The recommended approach is exposing a global driver module. The global driver module would handle custom
commands for these topology specific requests.

Audio Module DDIs


Kernel Streaming Audio Module Proper ties
A new KS Property Set, identified by KSPROPSETID_AudioModule, has been defined for three properties specific to
audio modules.
A PortCls miniport driver needs to directly handle the response for each property as no helper interface is
provided.
ksmedia.h:

#define STATIC_KSPROPSETID_AudioModule \
0xc034fdb0, 0xff75, 0x47c8, 0xaa, 0x3c, 0xee, 0x46, 0x71, 0x6b, 0x50, 0xc6
DEFINE_GUIDSTRUCT("C034FDB0-FF75-47C8-AA3C-EE46716B50C6", KSPROPSETID_AudioModule);
#define KSPROPSETID_AudioModule DEFINE_GUIDNAMED(KSPROPSETID_AudioModule)

typedef enum {
KSPROPERTY_AUDIOMODULE_DESCRIPTORS = 1,
KSPROPERTY_AUDIOMODULE_COMMAND = 2,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID = 3,
} KSPROPERTY_AUDIOMODULE;

Audio Module Descriptors


Support for the KSPROPERTY_AUDIOMODULE_DESCRIPTORS property identifies the driver as being Audio
Module aware. The property will be queried through the filter or pin handle and a KSPROPERTY is passed as the
input buffer for the DeviceIoControl call. KSAUDIOMODULE_DESCRIPTOR has been defined to describe each
module within the audio hardware. An array of these descriptors is returned in response to this request
ksmedia.h:

#define AUDIOMODULE_MAX_NAME_SIZE 128

typedef struct _KSAUDIOMODULE_DESCRIPTOR


{
GUID ClassId;
ULONG InstanceId;
ULONG VersionMajor;
ULONG VersionMinor;
WCHAR Name[AUDIOMODULE_MAX_NAME_SIZE];
} KSAUDIOMODULE_DESCRIPTOR, *PKSAUDIOMODULE_DESCRIPTOR;

For more information, see KSAUDIOMODULE_DESCRIPTOR.


Audio Module Command
Support for the KSPROPERTY_AUDIOMODULE_COMMAND property allows Audio Module clients to send custom
commands to query and set parameters on Audio Modules. The property can be sent through the filter or pin
handle and a KSAUDIOMODULE_PROPERTY is passed as the input buffer for the DeviceIoControl call. A client can
optionally send additional information immediately adjacent to the KSAUDIOMODULE_PROPERTY in the input
buffer to send custom commands.
ksmedia.h:
#define AUDIOMODULE_MAX_DATA_SIZE 64000

typedef struct _KSPAUDIOMODULE_PROPERTY


{
KSPROPERTY Property;
GUID ClassId;
ULONG InstanceId;
} KSAUDIOMODULE_PROPERTY, *PKSPAUDIOMODULE_PROPERTY;

For more information, see KSAUDIOMODULE_PROPERTY.


Audio Module Notification Device ID
Support for the KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID is required to enable the miniport to
signal notifications and pass information to Audio Module clients. The lifetime of this ID is tied to the lifetime of the
audio device being exposed and active to the Windows Audio stack. The property can be sent through the filter or
pin handle and a KSPROPERTY is passed as the input buffer for the DeviceIoControl call.
For more information, see KSAUDIOMODULE_PROPERTY.

PortCls Helper - Audio Module Notifications


A new port interface has been added to assist driver developers to send notifications to Audio Module clients.
PortCls.h:
typedef struct _PCNOTIFICATION_BUFFER
{
UCHAR NotificationBuffer[1];
} PCNOTIFICATION_BUFFER, *PPCNOTIFICATION_BUFFER;

DECLARE_INTERFACE_(IPortClsNotifications,IUnknown)
{
DEFINE_ABSTRACT_UNKNOWN() // For IUnknown

STDMETHOD_(NTSTATUS, AllocNotificationBuffer)
( THIS_
_In_ POOL_TYPE PoolType,
_In_ USHORT NumberOfBytes,
_Out_ PPCNOTIFICATION_BUFFER* NotificationBuffer
) PURE;

STDMETHOD_(void, FreeNotificationBuffer)
( THIS_
_In_ PPCNOTIFICATION_BUFFER NotificationBuffer
) PURE;

STDMETHOD_(void, SendNotificationBuffer)
( THIS_
_In_ const GUID* NotificationId,
_In_ PPCNOTIFICATION_BUFFER NotificationBuffer
) PURE;
};

//
// Audio module notification definitions.
//
#define STATIC_KSNOTIFICATIONID_AudioModule \
0x9C2220F0, 0xD9A6, 0x4D5C, 0xA0, 0x36, 0x57, 0x38, 0x57, 0xFD, 0x50, 0xD2
DEFINE_GUIDSTRUCT("9C2220F0-D9A6-4D5C-A036-573857FD50D2", KSNOTIFICATIONID_AudioModule);
#define KSNOTIFICATIONID_AudioModule DEFINE_GUIDNAMED(KSNOTIFICATIONID_AudioModule)

typedef struct _KSAUDIOMODULE_NOTIFICATION {


union {
struct {
GUID DeviceId;
GUID ClassId;
ULONG InstanceId;
ULONG Reserved;
} ProviderId;
LONGLONG Alignment;
};
} KSAUDIOMODULE_NOTIFICATION, *PKSAUDIOMODULE_NOTIFICATION;

For more information, see:


IPortClsNotifications
IPortClsNotifications::AllocNotificationBuffer
IPortClsNotifications::FreeNotificationBuffer
IPortClsNotifications::SendNotificationBuffer
Calling Sequence
The miniport will call into their port to create and send the notification. The general call sequence is shown in this
diagram.
Configure and query audio device modules
12/5/2018 • 4 minutes to read • Edit Online

This article shows how to send commands and receive change notifications from audio device modules from a
UWP app. An audio device module may be a hardware effect processing unit or any other audio configuration
module defined by an audio driver. This feature was designed to enable module providers to create UWP apps that
allow users to control and get status information from an audio processing module running in a DSP. In order to
use the audio device module APIs shown in this article, you must specify the restricted audioDeviceConfiguration
capability in your app package manifest.

Get an instance of the AudioDeviceModulesManager class


All audio device module operations shown in this article begin by obtaining an instance of the
AudioDeviceModulesManager . Do this by first calling the static GetDefaultAudioRenderId method of the
MediaDevice class. This returns the ID of the default audio render device, which is then passed into the
constructor for AudioDeviceModulesManager to create an instance of the class that is associated with the audio
device.
C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);


var audioModuleManager = new AudioDeviceModulesManager(endpointId);

Query for installed audio device modules


Query for all installed audio device modules by calling the FindAll of the AudioDeviceModulesManager class.
Query for a specific set of audio device modules by calling FindAllById and passing in the ID of the requested
modules. The following example defines an ID for a set of modules, calls FindAllById to retrieve a list of
AudioDeviceModule objects, and then prints the details of each module to the debug output.
C#

public const string Contoso_AudioDeviceModuleId = "F72E09C3-FEBA-4C50-93BE-2CA56123AF09";

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);


var audioModuleManager = new AudioDeviceModulesManager(endpointId);
var modules = audioModuleManager.FindAllById(Contoso_AudioDeviceModuleId);

foreach (var module in modules)


{
var classId = module.ClassId;
var name = module.DisplayName;
var minorVersion = module.MinorVersion;
var majorVersion = module.MajorVersion;
var instanceId = module.InstanceId;

Debug.WriteLine($"{classId} : {name} : {minorVersion} : {majorVersion} : {instanceId}");


}
Send a command to an audio device module and receive result data
Send commands to an audio device module by calling SendCommandAsync on the AudioDeviceModule
object. The SendCommandAsync method takes a byte array as an argument. Typically this byte array contains a
command identifier followed by the data associated with the command, but the command format and values are
entirely vendor-defined and are treated as transparent by the system.
The SendCommandAsync method returns an asynchronous operation that, upon completion, returns a
ModuleCommandResult object representing the result of the command. The Status property contains an
enumeration value that indicates whether the system was able to execute the command. This does not necessarily
indicate that the audio device module was able to execute the command successfully. The Result property contains
a byte array that is returned by the audio device module to indicate the status of the command. Typically, this will
be a value that indicates success or failure followed by the data result of the command. As with module commands,
module response formats and values are vendor-defined.
The following example calls FindAllAsync to retrieve a set of audio device modules. A DataWriter is used to
create a byte array containing an example command and data. SendCommandAsync is called to send the
command buffer and, after the asynchronous operation completes, a ModuleCommandResult is returned. If the
command execution was successful, a DataReader is first used to read an integer status value returned from the
module. If this value is the vendor-defined success value, the rest of the result data is read and used by the app,
such as to update the UI.
C#

public const byte Contoso_ReverbLevel_Command = 30;


public const byte Contoso_SendCommand_Success = 99;

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);


var audioModuleManager = new AudioDeviceModulesManager(endpointId);
var modules = audioModuleManager.FindAllById(Contoso_AudioDeviceModuleId);

foreach (var module in modules)


{
var writer = new Windows.Storage.Streams.DataWriter();
writer.WriteByte(Contoso_ReverbLevel_Command);
writer.WriteByte(100);

var command = writer.DetachBuffer();

var result = await module.SendCommandAsync(command);

if (result.Status == SendCommandStatus.Success)
{
using (DataReader reader = DataReader.FromBuffer(result.Result))
{
int bufferStatus = reader.ReadInt32();
if (bufferStatus == Contoso_SendCommand_Success)
{
byte[] data = { 0, 0 };
reader.ReadBytes(data);
// Do something with returned data, such as update UI
}
}
}
}
Receive notifications when audio device modules are modified
Apps can receive notifications when an audio device module has been updated by registering for the
ModuleNotificationReceived event.
C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);


var audioModuleManager = new AudioDeviceModulesManager(endpointId);

audioModuleManager.ModuleNotificationReceived += AudioModuleManager_ModuleNotificationReceived;

ModuleNotificationReceived will be raised when any audio device module associated with the current audio
device is modified. To determine if the event is associated with a particular module, get an instance of
AudioDeviceModule by accessing the Module property of the AudioDeviceModuleNoticiationEventArgs
passed into the event handler, and then checking the ClassId property that identifies the module. The data
associated with the event is passed as a byte array stored in the NotificationData property of the event args. As
with commands and results, the format of the returned byte array is vendor-defined. In the example below, if the
first byte of the notification data contains the example value for the module's reverb level setting, the data is read
and used to update the UI.
C#

public const byte Contoso_ReverbLevel_Data = 25;

C#

private void AudioModuleManager_ModuleNotificationReceived(AudioDeviceModulesManager sender,


AudioDeviceModuleNotificationEventArgs args)
{
if (args.Module.ClassId == Contoso_AudioDeviceModuleId)
{
// Get the coefficient data from the reverb module.
using (DataReader reader = DataReader.FromBuffer(args.NotificationData))
{
// read notification data.
byte item = reader.ReadByte();

// if reverb coefficient data are changed.


if (item == Contoso_ReverbLevel_Data)
{
// read the new value
byte[] data = { 0 };
reader.ReadBytes(data);
ReverbLevelSlider.Value = data[0];
}
}
}
}
Low Latency Audio
10/23/2019 • 24 minutes to read • Edit Online

This topic discusses audio latency changes in Windows 10. It covers API options for application developers as well
as changes in drivers that can be made to support low latency audio.
This topic contains the following sections.
Overview
Definitions
Windows Audio Stack
Audio Stack Improvements in Windows 10
API Improvements
AudioGraph
Windows Audio Session API (WASAPI)
Driver Improvements
Measurement Tools
Samples
FAQ

Overview
Audio latency is the delay between that time that sound is created and when it is heard. Having low audio latency is
very important for several key scenarios, such as the following.
Pro Audio
Music Creation
Communications
Virtual Reality
Games
Windows 10 includes changes to reduce the audio latency. The goals of this document are to:
1. Describe the sources of audio latency in Windows.
2. Explain the changes that reduce audio latency in the Windows 10 audio stack.
3. Provide a reference on how application developers and hardware manufacturers can take advantage of the new
infrastructure, in order to develop applications and drivers with low audio latency. This topic covers these items:
4. The new AudioGraph API for interactive and media creation scenarios.
5. Changes in WASAPI to support low latency.
6. Enhancements in the driver DDIs.

Definitions
Term Description
Render latency Delay between the time that an application submits a
buffer of audio data to the render APIs, until the time that
it is heard from the speakers.

Capture latency Delay between the time that a sound is captured from the
microphone, until the time that it is sent to the capture
APIs that are being used by the application.

Roundtrip latency Delay between the time that a sound is captured from the
microphone, processed by the application and submitted
by the application for rendering to the speakers. It is
roughly equal to render latency + capture latency.

Touch-to-app latency Delay between the time that a user taps the screen until
the time that the signal is sent to the application.

Touch-to-sound latency Delay between the time that a user taps the screen, the
event goes to the application and a sound is heard via the
speakers. It is equal to render latency + touch-to-app
latency.

Windows Audio Stack


The following diagram shows a simplified version of the Windows audio stack.

Here is a summary of the latencies in the render path:


1. The application writes the data into a buffer
2. The Audio Engine reads the data from the buffer and processes it. It also loads audio effects in the form of
Audio Processing Objects (APOs). For more information about APOs, see Windows Audio Processing
Objects.
3. The latency of the APOs varies based on the signal processing within the APOs.
4. Before Windows 10, the latency of the Audio Engine was equal to ~12ms for applications that use floating
point data and ~6ms for applications that use integer data
5. In Windows 10, the latency has been reduced to 1.3ms for all applications
6. The Audio Engine writes the processed data to a buffer.
7. Before Windows 10, this buffer was always set to ~10ms.
8. Starting with Windows 10, the buffer size is defined by the audio driver (more details on this are described
later in this topic).
9. The Audio driver reads the data from the buffer and writes them to the H/W.
10. The H/W also has the option to process the data again (in the form of additional audio effects).
11. The user hears audio from the speaker.
Here is a summary of latency in the capture path:
1. Audio is captured from the microphone.
2. The H/W has the option to process the data (i.e. to add audio effects).
3. The driver reads the data from the H/W and writes the data into a buffer.
4. Before Windows 10, this buffer was always set to 10ms.
5. Starting with Windows 10, the buffer size is defined by the audio driver (more details on this below).
6. The Audio Engine reads the data from the buffer and processes them. It also loads audio effects in the form
of Audio Processing Objects (APOs).
7. The latency of the APOs varies based on the signal processing within the APOs.
8. Before Windows 10, the latency of the Audio Engine was equal to ~6ms for applications that use floating
point data and ~0ms for applications that use integer data.
9. In Windows 10, the latency has been reduced to ~0ms for all applications.
10. The application is signaled that data is available to be read, as soon as the audio engine finishes with its
processing. The audio stack also provides the option of Exclusive Mode. In that case, the data bypasses the
Audio Engine and goes directly from the application to the buffer where the driver reads it from. However, if
an application opens an endpoint in Exclusive Mode, then there is no other application that can use that
endpoint to render or capture audio.
Another popular alternative for applications that need low latency is to use the ASIO (Audio Stream Input/Output)
model, which utilizes exclusive mode. After a user installs a 3rd party ASIO driver, applications can send data
directly from the application to the ASIO driver. However, the application has to be written in such a way that it
talks directly to the ASIO driver.
Both alternatives (exclusive mode and ASIO) have their own limitations. They provide low latency, but they have
their own limitations (some of which were described above). As a result, Audio Engine has been modified, in order
to lower the latency, while retaining the flexibility.

Audio Stack Improvements in Windows 10


Windows 10 has been enhanced in three areas to reduce latency:
1. All applications that use audio will see a 4.5-16ms reduction in round-trip latency (as was explained in the
section above) without any code changes or driver updates, compared to Windows 8.1. a. Applications that use
floating point data will have 16ms lower latency. b. Applications that use integer data will have 4.5ms lower
latency.
2. Systems with updated drivers will provide even lower round-trip latency: a. Drivers can use new DDIs to report
the supported sizes of the buffer that is used to transfer data between the OS and the H/W. This means that
data transfers do not have to always use 10ms buffers (as they did in previous OS versions). Instead, the driver
can specify if it can use small buffers, e.g. 5ms, 3ms, 1ms, etc. b. Applications that require low latency can use
new audio APIs (AudioGraph or WASAPI), in order to query the buffer sizes that are supported by the driver
and select the one that will be used for the data transfer to/from the H/W.
3. When an application uses buffer sizes below a certain threshold to render and capture audio, the OS enters a
special mode, where it manages its resources in a way that avoids interference between the audio streaming
and other subsystems. This will reduce the interruptions in the execution of the audio subsystem and minimize
the probability of audio glitches. When the application stops streaming, the OS returns to its normal execution
mode. The audio subsystem consists of the following resources: a. The audio engine thread that is processing
low latency audio. b. All the threads and interrupts that have been registered by the driver (using the new DDIs
that are described in the section about driver resource registration). c. Some or all of the audio threads from the
applications that request small buffers, as well as from all applications that share the same audio device graph
(e.g. same signal processing mode) with any application that requested small buffers:
4. AudioGraph callbacks on the streaming path.
5. If the application uses WASAPI, then only the work items that were submitted to the Real-Time Work Queue API
or MFCreateMFByteStreamOnStreamEx and were tagged as "Audio" or "ProAudio".

API Improvements
The following two Windows 10 APIs provide low latency capabilities:
AudioGraph
Windows Audio Session API (WASAPI)
This is how an application developer can determine which of the two APIs to use:
Favor AudioGraph, wherever possible for new application development.
Only use WASAPI, if:
You need additional control than that provided by AudioGraph.
You need lower latency than that provided by AudioGraph.
The measurement tools section of this topic, shows specific measurements from a Haswell system using the inbox
HDAudio driver.
The following sections will explain the low latency capabilities in each API. As it was noted in the previous section,
in order for the system to achieve the minimum latency, it needs to have updated drivers that support small buffer
sizes.
AudioGraph
AudioGraph is a new Universal Windows Platform API in Windows 10 that is aimed at realizing interactive and
music creation scenarios with ease. AudioGraph is available in several programming languages (C++, C#,
JavaScript) and has a simple and feature-rich programming model.
In order to target low latency scenarios, AudioGraph provides the
AudioGraphSettings::QuantumSizeSelectionMode property. This property can any of the following values shown in
the table below:
Value Description

SystemDefault Sets the buffer to the default buffer size (~10ms)

LowestLatency Sets the buffer to the minimum value that is supported


by the driver

ClosestToDesired Sets the buffer size to be either equal either to the value
defined by the DesiredSamplesPerQuantum property or
to a value that is as close to DesiredSamplesPerQuantum
as is supported by the driver.

The AudioCreation sample (available for download on GitHub: https://github.com/Microsoft/Windows-universal-


samples/tree/master/Samples/AudioCreation) shows how to use AudioGraph for low latency. The following code
snippet shows how to set the minimum buffer size:

AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);


settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);

Windows Audio Session API (WASAPI )


Starting in Windows 10 , WASAPI has been enhanced to:
Allow an application to discover the range of buffer sizes (i.e. periodicity values) that are supported by the audio
driver of a given audio device. This makes it possible for an application to choose between the default buffer
size (10ms) or a small buffer (<10ms) when opening a stream in shared mode. If an application does not
specify a buffer size, then it will use the default buffer size.
Allow an application to discover the current format and periodicity of the audio engine. This allows applications
to snap to the current settings of the audio engine.
Allow an app to specify that it wishes to render/capture in the format it specifies without any re-sampling by
the audio engine
The above features will be available on all Windows devices. However, certain devices with enough resources and
updated drivers will provide a better user experience than others.
The above functionality is provided by a new interface, called IAudioClient3 , which derives from IAudioClient2 .
IAudioClient3 defines the following 3 methods:

Method Description

GetCurrentSharedModeEnginePeriod Returns the current format and periodicity of the audio


engine

GetSharedModeEnginePeriod Returns the range of periodicities supported by the


engine for the specified stream format

InitializeSharedAudioStream Initializes a shared stream with the specified periodicity


The WASAPIAudio sample (available on GitHub: https://github.com/Microsoft/Windows-universal-
samples/tree/master/Samples/WindowsAudioSession) shows how to use IAudioClient3 for low latency.
The following code snippet shows how a music creation app can operate in the lowest latency setting that is
supported by the system.

// 1. Activation

// Get a string representing the Default Audio (Render|Capture) Device


m_DeviceIdString = MediaDevice::GetDefaultAudio(Render|Capture)Id(
Windows::Media::Devices::AudioDeviceRole::Default );

// This call must be made on the main UI thread. Async operation will call back to
// IActivateAudioInterfaceCompletionHandler::ActivateCompleted, which must be an agile // interface
implementation
hr = ActivateAudioInterfaceAsync( m_DeviceIdString->Data(), __uuidof(IAudioClient3),
nullptr, this, &asyncOp );

// 2. Setting the audio client properties – note that low latency offload is not supported

AudioClientProperties audioProps = {0};


audioProps.cbSize = sizeof( AudioClientProperties );
audioProps.eCategory = AudioCategory_Media;

// if the device has System.Devices.AudioDevice.RawProcessingSupported set to true and you want to use raw
mode
// audioProps.Options |= AUDCLNT_STREAMOPTIONS_RAW;
//
// if it is important to avoid resampling in the audio engine, set this flag
// audioProps.Options |= AUDCLNT_STREAMOPTIONS_MATCH_FORMAT;

hr = m_AudioClient->SetClientProperties( &audioProps ); if (FAILED(hr)) { ... }

// 3. Querying the legal periods

hr = m_AudioClient->GetMixFormat( &mixFormat ); if (FAILED(hr)) { ... }

hr = m_AudioClient->GetSharedModeEnginePeriod(wfx, &defaultPeriodInFrames, &fundamentalPeriodInFrames,


&minPeriodInFrames, &maxPeriodInFrames); if (FAILED(hr)) { ... }

// legal periods are any multiple of fundamentalPeriodInFrames between


// minPeriodInFrames and maxPeriodInFrames, inclusive
// the Windows shared-mode engine uses defaultPeriodInFrames unless an audio client // has specifically
requested otherwise

// 4. Initializing a low-latency client

hr = m_AudioClient->InitializeSharedAudioStream(
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
desiredPeriodInFrames,
mixFormat,
nullptr); // audio session GUID
if (AUDCLNT_E_ENGINE_PERIODICITY_LOCKED == hr) {
/* engine is already running at a different period; call m_AudioClient->GetSharedModeEnginePeriod to
see what it is */
} else if (FAILED(hr)) {
...
}

// 5. Initializing a client with a specific format (if the format needs to be different than the default
format)

AudioClientProperties audioProps = {0};


audioProps.cbSize = sizeof( AudioClientProperties );
audioProps.eCategory = AudioCategory_Media;
audioProps.Options |= AUDCLNT_STREAMOPTIONS_MATCH_FORMAT;
hr = m_AudioClient->SetClientProperties( &audioProps );
if (FAILED(hr)) { ... }

hr = m_AudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, appFormat, &closest);


if (S_OK == hr) {
/* device supports the app format */
} else if (S_FALSE == hr) {
/* device DOES NOT support the app format; closest supported format is in the "closest" output variable
*/
} else {
/* device DOES NOT support the app format, and Windows could not find a close supported format */
}

hr = m_AudioClient->InitializeSharedAudioStream(
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
defaultPeriodInFrames,
appFormat,
nullptr); // audio session GUID
if (AUDCLNT_E_ENGINE_FORMAT_LOCKED == hr) {
/* engine is already running at a different format */
} else if (FAILED(hr)) {
...
}

Also, it is recommended for applications that use WASAPI to also use the Real-Time Work Queue API or the
MFCreateMFByteStreamOnStreamEx to create work items and tag them as Audio or Pro Audio, instead of their
own threads. This will allow the OS to manage them in a way that will avoid interference non-audio subsystems. In
contrast, all AudioGraph threads are automatically managed correctly by the OS. The following code snippet from
the WASAPIAudio sample shows how to use the MF Work Queue APIs.

// Specify Source Reader Attributes


Attributes->SetUnknown( MF_SOURCE_READER_ASYNC_CALLBACK, static_cast<IMFSourceReaderCallback *>(this) );
if (FAILED( hr ))
{
goto exit;
}
Attributes->SetString( MF_READWRITE_MMCSS_CLASS_AUDIO, L"Audio" );
if (FAILED( hr ))
{
goto exit;
}
Attributes->SetUINT32( MF_READWRITE_MMCSS_PRIORITY_AUDIO, 0 );
if (FAILED( hr ))
{
goto exit;
}
// Create a stream from IRandomAccessStream
hr = MFCreateMFByteStreamOnStreamEx (reinterpret_cast<IUnknown*>(m_ContentStream), &ByteStream );
if ( FAILED( hr ) )
{
goto exit;
}
// Create source reader
hr = MFCreateSourceReaderFromByteStream( ByteStream, Attributes, &m_MFSourceReader );

Alternatively, the following code snippet shows how to use the RT Work Queue APIs.

#define INVALID_WORK_QUEUE_ID 0xffffffff


DWORD g_WorkQueueId = INVALID_WORK_QUEUE_ID;
//#define MMCSS_AUDIO_CLASS L"Audio"
//#define MMCSS_PROAUDIO_CLASS L"ProAudio"

STDMETHODIMP TestClass::GetParameters(DWORD* pdwFlags, DWORD* pdwQueue)


{
HRESULT hr = S_OK;
*pdwFlags = 0;
*pdwQueue = g_WorkQueueId;
return hr;
}

//-------------------------------------------------------
STDMETHODIMP TestClass::Invoke(IRtwqAsyncResult* pAsyncResult)
{
HRESULT hr = S_OK;
IUnknown *pState = NULL;
WCHAR className[20];
DWORD bufferLength = 20;
DWORD taskID = 0;
LONG priority = 0;

printf("Callback is invoked pAsyncResult(0x%0x) Current process id :0x%0x Current thread id :0x%0x\n",


(INT64)pAsyncResult, GetCurrentProcessId(), GetCurrentThreadId());

hr = RtwqGetWorkQueueMMCSSClass(g_WorkQueueId, className, &bufferLength);


IF_FAIL_EXIT(hr, Exit);

if (className[0])
{
hr = RtwqGetWorkQueueMMCSSTaskId(g_WorkQueueId, &taskID);
IF_FAIL_EXIT(hr, Exit);

hr = RtwqGetWorkQueueMMCSSPriority(g_WorkQueueId, &priority);
IF_FAIL_EXIT(hr, Exit);
printf("MMCSS: [%ws] taskID (%d) priority(%d)\n", className, taskID, priority);
}
else
{
printf("non-MMCSS\n");
}
hr = pAsyncResult->GetState(&pState);
IF_FAIL_EXIT(hr, Exit);

Exit:
return S_OK;
}
//-------------------------------------------------------

int _tmain(int argc, _TCHAR* argv[])


{
HRESULT hr = S_OK;
HANDLE signalEvent;
LONG Priority = 1;
IRtwqAsyncResult *pAsyncResult = NULL;
RTWQWORKITEM_KEY workItemKey = NULL;;
IRtwqAsyncCallback *callback = NULL;
IUnknown *appObject = NULL;
IUnknown *appState = NULL;
DWORD taskId = 0;
TestClass cbClass;
NTSTATUS status;

hr = RtwqStartup();
IF_FAIL_EXIT(hr, Exit);

signalEvent = CreateEvent(NULL, true, FALSE, NULL);


IF_TRUE_ACTION_EXIT(signalEvent == NULL, hr = E_OUTOFMEMORY, Exit);

g_WorkQueueId = RTWQ_MULTITHREADED_WORKQUEUE;

hr = RtwqLockSharedWorkQueue(L"Audio", 0, &taskId, &g_WorkQueueId);


IF_FAIL_EXIT(hr, Exit);
hr = RtwqCreateAsyncResult(NULL, reinterpret_cast<IRtwqAsyncCallback*>(&cbClass), NULL, &pAsyncResult);
IF_FAIL_EXIT(hr, Exit);

hr = RtwqPutWaitingWorkItem(signalEvent, Priority, pAsyncResult, &workItemKey);


IF_FAIL_EXIT(hr, Exit);

for (int i = 0; i < 5; i++)


{
SetEvent(signalEvent);
Sleep(30);
hr = RtwqPutWaitingWorkItem(signalEvent, Priority, pAsyncResult, &workItemKey);
IF_FAIL_EXIT(hr, Exit);
}

Exit:
if (pAsyncResult)
{
pAsyncResult->Release();
}

if (INVALID_WORK_QUEUE_ID != g_WorkQueueId)
{
hr = RtwqUnlockWorkQueue(g_WorkQueueId);
if (FAILED(hr))
{
printf("Failed with RtwqUnlockWorkQueue 0x%x\n", hr);
}

hr = RtwqShutdown();
if (FAILED(hr))
{
printf("Failed with RtwqShutdown 0x%x\n", hr);
}
}

if (FAILED(hr))
{
printf("Failed with error code 0x%x\n", hr);
}
return 0;
}

Finally, application developers that use WASAPI need to tag their streams with the audio category and whether to
use the raw signal processing mode, based on the functionality of each stream. It is recommended that all audio
streams do not use the raw signal processing mode, unless the implications are understood. Raw mode bypasses
all the signal processing that has been chosen by the OEM, so:
The render signal for a particular endpoint might be sub-optimal.
The capture signal might come in a format that the application cannot understand.
The latency might be improved.

Driver Improvements
In order for audio drivers to support low latency, Windows 10 provides the following 3 new features:
1. [Mandatory] Declare the minimum buffer size that is supported in each mode.
2. [Optional, but recommended] Improve the coordination for the data flow between the driver and the OS.
3. [Optional, but recommended] Register the driver resources (interrupts, threads), so that they can be protected
by the OS in low latency scenarios. HDAudio miniport function drivers that are enumerated by the inbox
HDAudio bus driver hdaudbus.sys do not need to register the HDAudio interrupts, as this is already done by
hdaudbus.sys. However, if the miniport driver creates its own threads, then it needs to register them.
The following three sections will explain each new feature in more depth.
1. Declare the minimum buffer size.
A driver operates under various constraints when moving audio data between the OS, the driver, and the hardware.
These constraints may be due to the physical hardware transport that moves data between memory and hardware,
and/or due to the signal processing modules within the hardware or associated DSP.
In Windows 10 the driver can express its buffer size capabilities using the
DEVPKEY_KsAudio_PacketSize_Constraints device property. This property allows the user to define the absolute
minimum buffer size that is supported by the driver, as well as specific buffer size constraints for each signal
processing mode (the mode-specific constraints need to be higher than the drivers minimum buffer size,
otherwise they are ignored by the audio stack). For example, the following code snippet shows how a driver can
declare that the absolute minimum supported buffer size is 1ms, but default mode supports 128 frames (which
corresponds to 3 ms, if we assume 48 kHz sample rate).

// Describe constraints for small buffers


static struct
{
KSAUDIO_PACKETSIZE_CONSTRAINTS TransportPacketConstraints;
KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT AdditionalProcessingConstraints[1];
} SysvadWaveRtPacketSizeConstraintsRender =
{
{
1 * HNSTIME_PER_MILLISECOND, // 1 ms minimum processing interval
FILE_256_BYTE_ALIGNMENT, // 256 byte packet size alignment
0, // reserved
1, // 1 processing constraint below
{
STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT, // constraint for default processing mode
128, // 128 samples per processing frame
0, // N/A hns per processing frame
},
},
};

See the following topics for more in-depth information regarding these structures:
KSAUDIO_PACKETSIZE_CONSTRAINTS structure
KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT structure
Also, the sysvad sample (https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad) shows
how to use these properties, in order for a driver to declare the minimum buffer for each mode.
2. Improve the coordination between driver and OS.
The DDIs that are described in this section allow the driver to:
Clearly indicate which half (packet) of the buffer is available to the OS, rather than the OS guessing based on a
codec link position. This helps the OS to recover from audio glitches faster.
Optionally optimize or simplify its data transfers in and out of the WaveRT buffer. The amount of benefit here
depends on DMA engine design or other data transfer mechanism between the WaveRT buffer and (possibly
DSP) hardware.
"Burst" captured data faster than real-time if the driver has internally accumulated captured data. This is
primarily intended for voice activation scenarios but can apply during normal streaming as well.
Provide timestamp information about its current stream position rather than the OS guessing, potentially
allowing for extremely accurate position information.
This DDI is very useful in the case, where an DSP is used. However, a standard HD Audio driver or other simple
circular DMA buffer designs might not find much benefit in these new DDIs listed here.
IMiniportWaveRTInputStream
IMiniportWaveRTOutputStream
Several of the driver routines return Windows performance counter timestamps reflecting the time at which
samples are captured or presented by the device.
In devices that have complex DSP pipelines and signal processing, calculating an accurate timestamp may be
challenging and should be done thoughtfully. The timestamps should not simply reflect the time at which samples
were transferred to or from the OS to the DSP.
To calculate the performance counter values, the driver and DSP might employ some of the following methods.
Within the DSP, track sample timestamps using some internal DSP wall clock.
Between the driver and DSP, calculate a correlation between the Windows performance counter and the DSP
wall clock. Procedures for this can range from very simple (but less precise) to fairly complex or novel (but
more precise).
Factor in any constant delays due to signal processing algorithms or pipeline or hardware transports, unless
these delays are otherwise accounted for.
The sysvad sample (https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad) shows how
to use the above DDIs.
3. Register the driver resources
To help ensure glitch-free operation, audio drivers must register their streaming resources with portcls. This allows
the OS to manage resources to avoid interference between audio streaming and other subystems.
Stream resources are any resources used by the audio driver to process audio streams or ensure audio data flow.
At this time, only two type of stream resources are supported: interrupts and driver-owned threads. Audio drivers
should register a resource after creating the resource, and unregister the resource before deleted it.
Audio drivers can register resources at initialization time when the driver is loaded, or at run-time, for example
when there is an I/O resource rebalance. Portcls uses a global state to keep track of all the audio streaming
resources.
In some use cases, such as those requiring very low latency audio, the OS attempts to isolate the audio driver's
registered resources from interference from other OS, application, and hardware activity. The OS and audio
subsystem do this as-needed without interacting with the audio driver, except for the audio driver's registration of
the resources.
This requirement to register stream resources implies that all drivers that are in the streaming pipeline path must
register their resources directly or indirectly with Portcls. The audio miniport driver has these options:
The audio miniport driver is the bottom driver of its stack (interfacing the h/w directly), in this case, the driver
knows its stream resources and it can register them with Portcls.
The audio miniport driver is streaming audio with the help of other drivers (example audio bus drivers). These
other drivers also use resources that must be registered with Portcls. These parallel/bus driver stacks can
expose a public (or private interface, if a single vendor owns all the drivers) that audio miniport drivers use to
collect this info.
The audio miniport driver is streaming audio with the help of other drivers (example hdaudbus). These other
drivers also use resources that must be registered with Portcls. These parallel/bus drivers can link with Portcls
and directly register their resources. Note that the audio miniport drivers must let Portcls know that they
depend on the resources of these other parallel/bus devices (PDOs). The hd-audio infrastructure uses this
option, i.e., the hd-audio-bus driver links with Portcls and automatically performs the following steps:
registers its bus driver's resources, and
notifies Portcls that the children's resources depend on the parent's resources. In the HD audio
architecture, the audio miniport driver just needs to register its own driver-owned thread resources.
Notes:
HDAudio miniport function drivers that are enumerated by the inbox HDAudio bus driver hdaudbus.sys do not
need to register the HDAudio interrupts, as this is already done by hdaudbus.sys. However, if the miniport
driver creates its own threads, then it needs to register them.
Drivers that link with Portcls only for the purpose of registering streaming resources must update their INFs to
include/needs wdmaudio.inf and copy portcls.sys (and dependent files). A new INF copy section is defined in
wdmaudio.inf to only copy those files.
Audio drivers that only run in Windows 10 can hard-link to:
PcAddStreamResource
PcRemoveStreamResource
Audio drivers that must run on a down-level OS can use the following interface (the miniport can call
QueryInterface for the IID_IPortClsStreamResourceManager interface and register its resources only when
PortCls supports the interface).
IPortClsStreamResourceManager
AddStreamResource
RemoveStreamResource
These DDIs, use this enumeration and structure:
PcStreamResourceType
PCSTREAMRESOURCE_DESCRIPTOR
Finally, drivers that link-in PortCls for the sole purpose of registering resources must add the following two lines in
their inf's DDInstall section. Audio miniport drivers do not need this because they already have include/needs in
wdmaudio.inf.

[<install-section-name>]
Include=wdmaudio.inf
Needs=WDMPORTCLS.CopyFilesOnly

The above lines make sure that PortCls and its dependent files are installed.

Measurement Tools
In order to measure roundtrip latency, user can user utilize tools that play pulses via the speakers and capture
them via the microphone. They measure the delay of the following path:
1. The application calls the render API (AudioGraph or WASAPI) to play the pulse
2. The audio is played via the speakers
3. The audio is captured from the microphone
4. The pulse is detected by the capture API (AudioGraph or WASAPI) In order to measure the roundtrip latency for
different buffer sizes, users need to install a driver that supports small buffers. The inbox HDAudio driver has
been updated to support buffer sizes between 128 samples (2.66ms@48kHz) and 480 samples (10ms@48kHz).
The following steps show how to install the inbox HDAudio driver (which is part of all Windows 10 SKUs):
Start Device Manager.
Under Sound video and game controllers , double click on the device that corresponds to your internal
speakers.
In the next window, go to the Driver tab.
Select Update driver -> Browse my computer for driver software -> Let me pick from a list of
device drivers in this computer -> Select High Definition Audio Device and click Next .
If a window titled "Update driver warning" appears, click Yes .
Select close .
If you are asked to reboot the system, select Yes to reboot.
After reboot, the system will be using the inbox Microsoft HDAudio driver and not the 3rd-party codec driver.
Remember which driver you were using before, so that you can fallback to that driver, if you want to use the
optimal settings for your audio codec.

The differences in the latency between WASAPI and AudioGraph are due to the following reasons:
AudioGraph adds one buffer of latency in the capture side, in order to synchronize render and capture (which is
not provided by WASAPI). This addition simplifies the code for applications written using AudioGraph.
There is an additional buffer of latency in AudioGraph's render side when the system is using > 6ms buffers.
AudioGraph does not have the option to disable capture audio effects

Samples
WASAPI Audio sample: https://github.com/Microsoft/Windows-universal-
samples/tree/master/Samples/WindowsAudioSession
AudioCreation sample (AudioGraph): https://github.com/Microsoft/Windows-universal-
samples/tree/master/Samples/AudioCreation
Sysvad driver sample: https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad

FAQ
1. Wouldn't it be better, if all applications use the new APIs for low latency? Doesn't low latency
always guarantee a better user experience for the user?
Not necessarily. Low latency has its tradeoffs:
Low latency means higher power consumption. If the system uses 10ms buffers, it means that the CPU will
wake up every 10ms, fill the data buffer and go to sleep. However, if the system uses 1ms buffers, it means that
the CPU will wake up every 1ms. In the second scenario, this means that the CPU will wake up more often and
the power consumption will increase. This will decrease battery life.
Most applications rely on audio effects to provide the best user experience. For example, media players want to
provide high-fidelity audio. Communication applications want to minimum echo and noise. Adding these types
of audio effects to a stream increases its latency. These applications are more interested in audio quality than in
audio latency.
In summary, each application type has different needs regarding audio latency. If an application does not need low
latency, then it should not use the new APIs for low latency.
2. Will all systems that update to Windows 10 be automatically update to suppor t small buffers?
Also, will all systems suppor t the same minimum buffer size?
No. In order for a system to support small buffers, it needs to have updated drivers. It is up to the OEMs to decide
which systems will be updated to support small buffers. Also, newer systems are more likey to support smaller
buffers than older systems (i.e. the latency in new systems will most likely be lower than older systems).
3. If a driver suppor ts small buffer sizes (<10ms buffers), will all applications in Windows 10
automatically use small buffers to render and capture audio?
No. By default, all applications in Windows 10 will use 10ms buffers to render and capture audio. If an application
needs to use small buffers, then it needs to use the new AudioGraph settings or the WASAPI IAudioClient3
interface, in order to do so. However, if one application in Windows 10 requests the usage of small buffers, then the
Audio Engine will start transferring audio using that particular buffer size. In that case, all applications that use the
same endpoint and mode will automatically switch to that small buffer size. When the low latency application exits,
the Audio Engine will switch to 10ms buffers again.
Multiple Voice Assistant
3/13/2020 • 16 minutes to read • Edit Online

The Multiple Voice Assistant platform provides support for additional voice assistants beyond Cortana. This allows
other assistants be available on Windows devices such as PCs and wearables like HoloLens. Multiple voice
assistants can be active on the same device using a set of supported keyword patterns.
For information on implementing Windows Cortana, see Voice Activation.

NOTE
Multiple Voice Assistant is supported starting with Windows 10 Version 1903.

Voice Activation
Voice activation is a feature that enables users to invoke a speech recognition engine from various device power
states by saying a specific phrase.
Implementing voice activation is a significant project and is a task completed by SoC vendors. OEMs can contact
their SoC vendor for information on their SoC's implementation of voice activation.
Voice activation allows users to quickly engage the voice assistant experience outside of his or her active context
(i.e., what is currently on screen) by using his or her voice. Users often want to be able to instantly access an
experience without having to physically interact with or touch a device. For an Xbox user this may be from not
wanting to find and connect a controller. For PC users, they might want rapid access to an experience without
having to perform multiple mouse, touch and/or keyboard actions, as in the case of a computer in the kitchen.
Voice activation is powered by a keyword spotter (KWS) which reacts if the key phrase is detected. Key phrases may
include key words such as "Hey Contoso." Keyword detection describes the detection of the keyword by either
hardware or software. Key phrases may be uttered by themselves ("Hey Contoso") as a staged command, or
followed by a speech action composing a chained command ("Hey Contoso, where is my next meeting?")
Microsoft provides an OS default keyword spotter (software keyword spotter) to provide voice assistant experience
in cases where hardware keyword detection is unavailable. While this is currently available for Cortana, additional
Microsoft configuration may be needed to onboard other voice assistants to do two-stage keyword detection. For
more information contact [email protected] .
If KWS is to wake the device from a low powered state, the solution is known as Wake-on-Voice (WoV). For more
information, see Wake on Voice.

Glossary of Terms
This glossary summarizes terms related to voice activation.

Staged Command Example: Hey Contoso <pause, wait for assistant UI> What's
the weather? This is sometimes referred to as "two-shot
command" or "keyword-only"

Chained Command Example: Hey Contoso what's the weather? This is sometimes
referred to as a "one-shot command"
Voice Activation Example: "Hey Contoso" The scenario where keyword is
detected in a predefined activation key phrase

Wake-on-Voice (WoV) Technology that enables voice activation from a screen off,
lower power state, to a screen on full power state

WoV from Modern Standby Wake-on-Voice from a Modern Standby (S0ix) screen off state
to a screen on full power (S0) state

Modern Standby Windows Low Power Idle infrastructure - successor to


Connected Standby (CS) in Windows 10. The first state of
modern standby is when the screen is off. The deepest sleep
state is when in DRIPS/Resiliency. For more information, see
Modern Standby

KWS Keyword spotter – the algorithm that provides the detection


of "Hey Contoso"

SW KWS Software keyword spotter – an implementation of KWS that


runs on the host (CPU). For "Hey Cortana", SW KWS is
included as part of Windows.

HW KWS Hardware keyword spotter – an implementation of KWS that


runs offloaded on hardware

Burst buffer A circular buffer used to store PCM data that can be bursted
up in the event of a KWS detection, so that all audio that
triggered a KWS detection is included

Event detector OEM Adapter A user mode component that acts as an intermediary between
the Windows voice assistant stack and driver

Model The acoustic model data file used by the KWS algorithm. The
data file is static. Models are localized, one per locale.

MVA Multiple Voice Agent - new HWKWS DDI which supports


multiple agents

SVA Single Voice Agent - previous HWKWS DDI which only


supports a single agent (Cortana)

Integrating a Hardware Keyword Spotter


To implement a hardware keyword spotter (HW KWS) SoC vendors must complete the following tasks.
Create a custom keyword detector based on the SYSVAD sample described later in this topic. You will implement
these methods in a COM DLL, described in IEvent Detector OEM Adapter Interface.
Implement WAVE RT enhancements described in WAVERT Enhancements.
Provide INF file entries to describe any custom APOs used for keyword detection.
PKEY_FX_KeywordDetector_StreamEffectClsid
PKEY_FX_KeywordDetector_ModeEffectClsid
PKEY_FX_KeywordDetector_EndpointEffectClsid
PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
Review the hardware recommendations and test guidance in Audio Device Recommendation. This topic
provides guidance and recommendations for the design and development of audio input devices intended for
use with Microsoft's Speech Platform.
Support both staged and chained commands.
Meet locale requirements of voice assistants
The APOs (Audio Processing Objects) must provide the following effects:
AEC
AGC
NS
Effects for Speech processing mode must be reported by the MFX APO.
The APO may perform format conversion as MFX.
The APO must output the following format:
16 kHz, mono, FLOAT.
Optionally design any custom APOs to enhance the audio capture process. For more information, see Windows
Audio Processing Objects.
Hardware-offloaded keyword spotter (HW KWS) WoV Requirements
HW KWS WoV is supported during S0 Working state and S0 sleep state also known as Modern Standby.
HW KWS WoV is not supported from S3.
AEC
AEC can be performed by the DSP at the time the burst audio is captured, or it can be done at a later time via a
software APO. In order to perform a software AEC with KWS burst data, it is necessary to have the corresponding
loopback audio from the time the burst data was captured. To do this a custom audio format for the burst output
was created which interleaves the loopback audio into the burst audio data.
Starting with Windows version 20H1, the Microsoft AEC APO is aware of this interleaved format and can use it to
perform the AEC. For more information, see KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION.
Validation
Validate HW support for KSPROPSETID_SoundDetector2 properties with Voice Activation Manager 2 tests.

Sample Code Overview


There is sample code for an audio driver that implements voice activation on GitHub as part of the SYSVAD virtual
audio adapter sample. It is recommended to use this code as a starting point.
For more information about the SYSVAD sample audio driver, see Sample Audio Drivers.

Keyword Recognition System Information


Voice Activation Audio Stack Suppor t
The audio stack external interfaces for enabling Voice Activation serves as the communication pipeline for the
speech platform and the audio drivers. The external interfaces are divided into three parts.
Event detector Device Driver Interface (DDI). The Event detector Device Driver Interface is responsible for
configuring and arming the HW Keyword Spotter (KWS). It is also used by the driver to notify the system of a
detection event.
IEvent Detector OEM Adapter DLL. This DLL implements a COM interface to adapt the driver specific opaque
data for use by the OS to assist with keyword detection.
WaveRT streaming enhancements. The enhancements enable the audio driver to burst stream the buffered
audio data from the keyword detection.
Audio Endpoint Proper ties
Audio endpoint graph building occurs normally. The graph is prepared to handle faster than real time capture.
Timestamps on captured buffers remain true. Specifically, the timestamps will correctly reflect data that was
captured in the past and buffered, and is now bursting.
Theor y of Operation
The driver exposes a KS filter for its capture device as usual. This filter supports several KS properties and a KS
event to configure, enable and signal a detection event. The filter also includes an additional pin factory identified
as a keyword spotter (KWS) pin. This pin is used to stream audio from the keyword spotter.
The property is: KSPROPSETID_SoundDetector2
All KSPROPSETID_SoundDetector2 properties are called with a KSSOUNDDETECTORPROPERTY data structure.
This data structure contains a KSPROPERTY and the event id for the keyword to be armed, reset, detected, etc.
Supported keyword types - KSPROPERTY_SOUNDDETECTOR_PATTERNS . This property is set by the
operating system to configure the keywords to be detected.
List of keyword patterns GUIDs - KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS . This property
is used to get a list of GUIDs that identify the types of supported patterns.
Armed - KSPROPERTY_SOUNDDETECTOR_ARMED . This read/write property is a simply Boolean status
indicating whether the detector is armed. The OS sets this to engage the keyword detector. The OS can clear this
to disengage. The driver automatically clears this when keyword patterns are set and also after a keyword is
detected. (The OS must rearm.)
Match result - KSPROPERTY_SOUNDDETECTOR_RESET is used to reset the sound detector at startup time.
At keyword detection time, a PNP notification containing KSNOTIFICATIONID_SoundDetector is sent. NOTE: this is
not a KSEvent, but rather a PNP event which is sent, with a payload, via IoReportTargetDeviceChangeAsynchronous.
KSNOTIFICATIONID_SoundDetector is defined in ksmedia.h as shown here.

// The payload of this notification is a SOUNDDETECTOR_DETECTIONHEADER


#define STATIC_KSNOTIFICATIONID_SoundDetector\
0x6389d844, 0xbb32, 0x4c4c, 0xa8, 0x2, 0xf4, 0xb4, 0xb7, 0x7a, 0xfe, 0xad
DEFINE_GUIDSTRUCT("6389D844-BB32-4C4C-A802-F4B4B77AFEAD", KSNOTIFICATIONID_SoundDetector);
#define KSNOTIFICATIONID_SoundDetector DEFINE_GUIDNAMED(KSNOTIFICATIONID_SoundDetector)

Sequence of Operation
System Startup
1. The OS sends a KSPROPERTY_SOUNDDETECTOR_RESET to clear any previous detector state, resetting all
detectors to disarmed and clearing previous patterns set.
2. The OS queries KSPROPERTY_SOUNDDETECTOR_PATTERNS to retrieve the clsid for the event detector
OEM adapter.
3. The OS uses the event detector oem adapter to retrieve the list of supported keywords and languages.
4. The OS registers for custom PNP notifications sent by the driver
5. The OS sets the required keyword pattern(s).
6. The OS arms the detector(s)
Internal Driver and Hardware Operation
While the detector is armed, the hardware can be continuously capturing and buffering audio data in a small FIFO
buffer. (The size of this FIFO buffer is determined by requirements outside of this document, but might typically be
hundreds of milliseconds to several seconds.) The detection algorithm operates on the data streaming through this
buffer. The design of the driver and hardware are such that while armed there is no interaction between the driver
and hardware and no interrupts to the "application" processors until a keyword is detected. This allows the system
to reach a lower power state if there is no other activity.
When the hardware detects a keyword, it generates an interrupt. While waiting for the driver to service the
interrupt, the hardware continues to capture audio into the buffer, ensuring no data after the keyword is lost, within
buffering limits.
Keyword Timestamps
After detecting a keyword, all voice activation solutions must buffer all of the spoken keyword, including 1.6s
before the start of the keyword. The audio driver must provide timestamps identifying the start and end of the key
phrase in the stream.
In order to support the keyword start/end timestamps, DSP software may need to internally timestamp events
based on a DSP clock. Once a keyword is detected, the DSP software interacts with the driver to prepare a KS event.
The driver and DSP software will need to map the DSP timestamps to a Windows performance counter value. The
method of doing this is specific to the hardware design. One possible solution is for the driver to read current
performance counter, query the current DSP timestamp, read current performance counter again, and then
estimate a correlation between performance counter and DSP time. Then given the correlation, the driver can map
the keyword DSP timestamps to Windows performance counter timestamps.

IEvent Detector OEM Adapter Interface


The OEM supplies a COM object implementation that acts as an intermediary between the OS and the driver,
helping to compute or parse the opaque data that is written and read to the audio driver through
KSPROPERTY_SOUNDDETECTOR_PATTERNS and KSPROPERTY_SOUNDDETECTOR_MATCHRESULT .
The CLSID of the COM object is a detector pattern type GUID returned by the
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS . The OS calls CoCreateInstance passing the pattern
type GUID to instantiate the appropriate COM object that is compatible with keyword pattern type and calls
methods on the object's IEventDetectorOemAdapter interface.
COM Threading Model requirements
The OEM's implementation may choose any of the COM threading models.
IEventDetectorOemAdapter
The interface design attempts to keep the object implementation stateless. In other words, the implementation
should require no state to be stored between method calls. In fact, internal C++ classes likely do not need any
member variables beyond those required to implement a COM object in general.
Methods
Implement the following methods.
IEventDetectorOemAdapter ::BuildArmingPatternData
IEventDetectorOemAdapter ::ComputeAndAddUserModelData
IEventDetectorOemAdapter ::GetCapabilities
IEventDetectorOemAdapter ::GetCapabilitiesForLanguage
IEventDetectorOemAdapter ::ParseDetectionResultData
IEventDetectorOemAdapter ::Repor tOSDetectionResult
IEventDetectorOemAdapter ::VerifyUserEventData
WAVERT Enhancements
Miniport interfaces are defined to be implemented by WaveRT miniport drivers. These interfaces provide methods
to either simplify the audio driver, improve OS audio pipeline performance and reliability, or support new
scenarios. A new PnP device interface property is defined allowing the driver to provide a static expressions of its
buffer size constraints to the OS.
Buffer Sizes
A driver operates under various constraints when moving audio data between the OS, the driver, and the hardware.
These constraints may be due to the physical hardware transport that moves data between memory and hardware,
and/or due to the signal processing modules within the hardware or associated DSP.
HW-KWS solutions must support audio capture sizes of at least 100ms and up to 200ms.
The driver expresses the buffer size constraints by setting the DEVPKEY_KsAudio_PacketSize_Constraints device
property on the KSCATEGORY_AUDIO PnP device interface of the KS filter that has the KS streaming pin(s). This
property should remain valid and stable while the KS filter interface is enabled. The OS can read this value at any
time without having to open a handle to the driver and call on the driver.
DEVPKEY_KsAudio_PacketSize_Constraints
The DEVPKEY_KsAudio_PacketSize_Constraints property value contains a
KSAUDIO_PACKETSIZE_CONSTRAINTS structure describing the physical hardware constraints (i.e. due to the
mechanics of transferring data from the WaveRT buffer to the audio hardware). The structure includes an array of 0
or more KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT structures describing constraints specific
to any signal processing modes. The driver sets this property before calling PcRegisterSubdevice or otherwise
enabling its KS filter interface for its streaming pins.
IMinipor tWaveRTInputStream
A driver implements this interface for better coordination of audio dataflow from the driver to OS. If this interface is
available on a capture stream, the OS uses methods on this interface to access data in the WaveRT buffer. For more
information see, IMinipor tWaveRTInputStream::GetReadPacket
IMinipor tWaveRTOutputStream
A WaveRT miniport optionally implements this interface to be advised of write progress from the OS and to return
precise stream position. For more information see IMinipor tWaveRTOutputStream::SetWritePacket ,
IMinipor tWaveRTOutputStream::GetOutputStreamPresentationPosition and
IMinipor tWaveRTOutputStream::GetPacketCount .
Performance counter timestamps
Several of the driver routines return Windows performance counter timestamps reflecting the time at which
samples are captured or presented by the device.
In devices that have complex DSP pipelines and signal processing, calculating an accurate timestamp may be
challenging and should be done thoughtfully. The timestamps should not simply reflect the time at which samples
were transferred to or from the OS to the DSP.
Within the DSP, track sample timestamps using some internal DSP wall clock.
Between the driver and DSP, calculate a correlation between the Windows performance counter and the DSP
wall clock. Procedures for this can range from very simple (but less precise) to fairly complex or novel (but more
precise).
Factor in any constant delays due to signal processing algorithms or pipeline or hardware transports, unless
these delays are otherwise accounted for.
Burst Read Operation
This section describes the OS and driver interaction for burst reads. Burst read can happen outside of the voice
activation scenario as long as the driver supports the packet based streaming WaveRT model, including the
IMinipor tWaveRTInputStream::GetReadPacket function.
Two burst example read scenarios are discussed. In one scenario, if the miniport supports a pin having pin category
KSNODETYPE_AUDIO_KEYWORDDETECTOR then the driver will begin capturing and internally buffering data
when a keyword is detected. In another scenario, the driver can optionally internally buffer data outside of the
WaveRT buffer if the OS is not reading data quickly enough by calling
IMinipor tWaveRTInputStream::GetReadPacket .
To burst data that has been captured prior to transition to KSSTATE_RUN, the driver must retain accurate sample
timestamp information along with the buffered capture data. The timestamps identify the sampling instant of the
captured samples.
1. After the stream transitions to KSSTATE_RUN, the driver immediately sets the buffer notification event
because it already has data available.
2. On this event, the OS calls GetReadPacket() to get information about the available data.
a. The driver returns the packet number of the valid captured data (0 for the first packet after the transition
from KSSTATE_STOP to KSSTATE_RUN), from which the OS can derive the packet position within the WaveRT
buffer as well as the packet position relative to start of stream.
b. The driver also returns the performance counter value that corresponds to the sampling instant of the first
sample in the packet. Note that this performance counter value might be relatively old, depending on how
much capture data has been buffered within the hardware or driver (outside of the WaveRT buffer).
c. If there is more unread buffered data available the driver either: i. Immediately transfers that data into the
available space of WaveRT buffer (i.e. space not used by the packet returned from GetReadPacket), returns
true for MoreData, and sets the buffer notification event before returning from this routine. Or, ii. Programs
hardware to burst the next packet into the available space of the WaveRT buffer, returns false for MoreData,
and later sets the buffer event when the transfer completes.
3. The OS reads data from the WaveRT buffer using the information returned by GetReadPacket().
4. The OS waits for the next buffer notification event. The wait might terminate immediately if the driver set the
buffer notification in step (2c).
5. If the driver did not immediately set the event in step (2c), the driver sets the event after it transfers more
captured data into the WaveRT buffer and makes it available for the OS to read
6. Go to (2).
For KSNODETYPE_AUDIO_KEYWORDDETECTOR keyword detector pins, drivers should allocate enough
internal burst buffering for at least 5000ms of audio data. If the OS fails to create a stream on the pin before the
buffer overflows then the driver may end the internal buffering activity and free associated resources.

Wake on Voice
Wake-on-Voice (WoV) enables the user to activate and query a speech recognition engine from a low power state
to a full power state with screen on by saying a certain keyword, such as "Hey Contoso."
This feature allows for the device to be always listening for the user's voice while the device is idle and the screen is
off. This is due to listening mode which uses much less power compared to normal microphone recording. WoV
allows for chained speech phrase like "Hey Contoso, when's my next appointment" to invoke a response from a
voice assistant in a hands-free manner.
The audio stack is responsible for communicating the wake data (speaker ID, keyword trigger, context information
on confidence level) as well as notifying interested clients that the keyword has been detected.
Validation on Modern Standby Systems
WoV from a system idle state can be validated on Modern Standby systems using the Modern Standby Wake on
Voice Basic Test on AC-power Source and the Modern Standby Wake on Voice Basic Test on DC-power Source in the
HLK. These tests check that the system has a hardware keyword spotter (HW-KWS), is able to enter the Deepest
Runtime Idle Platform State (DRIPS) and is able to wake from Modern Standby on voice command with system
resume latency of less than or equal to one second.
Voice Activation
10/23/2019 • 19 minutes to read • Edit Online

Cortana, the personal assistant technology was demonstrated for the first time at the Microsoft BUILD Developer
Conference in 2013. The Windows speech platform is used to power all of the speech experiences in Windows 10
such as Cortana and Dictation. Voice activation is a feature that enables users to invoke a speech recognition
engine from various device power states by saying a specific phrase - "Hey Cortana". To create hardware that
supports voice activation technology, review the information in this topic.
Note
Implementing voice activation is a significant project and is a task completed by SoC vendors. OEMs can contact
their SoC vendor for information on their SoC's implementation of voice activation.

Cortana End User Experience


To understand the voice interaction experience available in Windows, review these topics.

Topic Description

What is Cortana? Provides and overview and usage direction for Cortana

Make Cortana yours Describes customization available through Cortana's Settings


screens.

Introduction to "Hey Cortana" Voice Activation and "Learn my voice"


"Hey Cor tana" Voice Activation
The "Hey Cortana" Voice Activation (VA) feature allows users to quickly engage the Cortana experience outside of
his or her active context (i.e., what is currently on screen) by using his or her voice. Users often want to be able to
instantly access an experience without having to physically interact touch a device. For phone users this may be
due to driving in the car and having their attention and hands engaged with operating the vehicle. For an Xbox
user this may be due not wanting to find and connect a controller. For PC users, this may be due to rapid access to
an experience without having to perform multiple mouse, touch and/or keyboard actions, e.g. a computer in the
kitchen.
Voice activation provides always listening speech input via predefined key phrase(s) or "activation phrases". Key
phrases may be uttered by themselves ("Hey Cortana") as a staged command, or followed by a speech action, for
example, "Hey Cortana, where is my next meeting?", a chained command.
The term Keyword Detection, describes the detection of the keyword by either hardware or software.
Keyword only activation occurs when only the Cortana keyword is said, Cortana starts and plays the EarCon
sound to indicate that it has entered listening mode.
A chained command describes the ability of issuing a command immediately following the keyword (like “Hey
Cortana, call John”) and have Cortana start (if not already started) and follow the command (starting a phone call
with John).
This diagram illustrates chained and keyword only activation.
Microsoft provides an OS default keyword spotter (software keyword spotter) that is used to ensure quality of
hardware keyword detections and to provide the Hey Cortana experience in cases where hardware keyword
detection is absent or unavailable.
The "Learn my voice" feature
The "Learn my voice" feature allows the user to train Cortana to recognize their unique voice. This is accomplished
by the user clicking on Learn how I say "Hey Cortana" in the Cortana settings screen. The user then repeats six
carefully chosen phrases that provide a sufficient variety of phonetic patterns to identify the unique attributes of
the users voice.

When voice activation is paired with "Learn my voice", the two algorithms will work together to reduce false
activations. This is especially valuable for the meeting room scenario, where one person says "Hey Cortana" in a
room full of devices. This feature is available only for Windows 10 version 1903 and earlier.
Voice activation is powered by a keyword spotter (KWS) which reacts if the key phrase is detected. If the KWS is to
wake the device from a low powered state, the solution is known as Wake on Voice (WoV). For more information,
see Wake on Voice.

Glossary of Terms
This glossary summarizes terms related to voice activation.

Staged Command Example: Hey Cortana <pause, wait for earcon> What’s the
weather? This is sometimes referred to as “Two-shot
command” or “Keyword-only”

Chained Command Example: Hey Cortana what’s the weather? This is sometimes
referred to as a “One-shot command”

Voice Activation The scenario of providing keyword detection of a predefined


activation keyphrase. For example, "Hey Cortana" is the
Microsoft Voice Activation scenario.

WoV Wake-on-Voice – Technology that enables Voice Activation


from a screen off, lower power state, to a screen on full power
state.

WoV from Modern Standby Wake-on-Voice from a Modern Standby (S0ix) screen off state
to a screen on full power (S0) state.

Modern Standby Windows Low Power Idle infrastructure - successor to


Connected Standby (CS) in Windows 10. The first state of
modern standby is when the screen is off. The deepest sleep
state is when in DRIPS/Resiliency. For more information, see
Modern Standby

KWS Keyword spotter – the algorithm that provides the detection


of “Hey Cortana”

SW KWS Software keyword spotter – an implementation of KWS that


runs on the host (CPU). For "Hey Cortana", SW KWS is
included as part of Windows.

HW KWS Hardware-offloaded keyword spotter – an implementation of


KWS that runs offloaded on hardware.

Burst Buffer A circular buffer used to store PCM data that can be ‘bursted
up’ in the event of a KWS detection, so that all audio that
triggered a KWS detection is included.

Keyword Detector OEM Adapter A driver-level shim that enables the WoV-enabled HW to
communicate with Windows and the Cortana stack.

Model The acoustic model data file used by the KWS algorithm. The
data file is static. Models are localized, one per locale.

Integrating a Hardware Keyword Spotter


To implement a hardware keyword spotter (HW KWS) SoC vendors must complete the following tasks.
Create a custom keyword detector based on the SYSVAD sample described later in this topic. You will
implement these methods in a COM DLL, described in Keyword Detector OEM Adapter Interface.
Implement WAVE RT enhancements described in WAVERT Enhancements.
Provide INF file entries to describe any custom APOs used for keyword detection.
PKEY_FX_KeywordDetector_StreamEffectClsid
PKEY_FX_KeywordDetector_ModeEffectClsid
PKEY_FX_KeywordDetector_EndpointEffectClsid
PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
Review the hardware recommendations and test guidance in Audio Device Recommendation. This topic
provides guidance and recommendations for the design and development of audio input devices intended for
use with Microsoft’s Speech Platform.
Support both staged and chained commands.
Support “Hey Cortana” for each of the supported Cortana locales.
The APOs (Audio Processing Objects) must provide the following effects:
AEC
AGC
NS
Effects for Speech processing mode must be reported by the MFX APO.
The APO may perform format conversion as MFX.
The APO must output the following format:
16 kHz, mono, FLOAT.
Optionally design any custom APOs to enhance the audio capture process. For more information, see Windows
Audio Processing Objects.
Hardware-offloaded keyword spotter (HW KWS) WoV Requirements
HW KWS WoV is supported during S0 Working state and S0 sleep state also known as Modern Standby.
HW KWS WoV is not supported from S3.
AEC Requirements for HW KWS
For Windows Version 1709
To support HW KWS WoV for S0 sleep state (Modern Standby) AEC is not required.
HW KWS WoV for S0 working state is not supported in Windows Version 1709.
For Windows Version 1803
HW KWS WoV for S0 working state is supported.
To enable HW KWS WoV for S0 working state, the APO must support AEC.

Sample Code Overview


There is sample code for an audio driver that implements voice activation on GitHub as part of the SYSVAD virtual
audio adapter sample. It is recommended to use this code as a starting point. The code is available at this location.
https://github.com/Microsoft/Windows-driver-samples/blob/master/audio/sysvad/
For more information about the SYSVAD sample audio driver, see Sample Audio Drivers.
Keyword Recognition System Information
Voice Activation Audio Stack Suppor t
The audio stack external interfaces for enabling Voice Activation serves as the communication pipeline for the
speech platform and the audio drivers. The external interfaces are divided into three parts.
Keyword detector Device Driver Interface (DDI). The Keyword detector Device Driver Interface is responsible for
configuring and arming the HW Keyword Spotter (KWS). It is also used by the driver to notify the system of a
detection event.
Keyword Detector OEM Adapter DLL. This DLL implements a COM interface to adapt the driver specific opaque
data for use by the OS to assist with keyword detection.
WaveRT streaming enhancements. The enhancements enable the audio driver to burst stream the buffered
audio data from the keyword detection.
Audio Endpoint Proper ties
Audio endpoint graph building occurs normally. The graph is prepared to handle faster than real time capture.
Timestamps on captured buffers remain true. Specifically, the timestamps will correctly reflect data that was
captured in the past and buffered, and is now “bursting”.
Theor y of Operation
The driver exposes a KS filter for its capture device as usual. This filter supports several KS properties and a KS
event to configure, enable and signal a detection event. The filter also includes an additional pin factory identified
as a keyword spotter (KWS) pin. This pin is used to stream audio from the keyword spotter.
The properties are:
Supported keyword types - KSPROPERTY_SOUNDDETECTOR_PATTERNS . This property is set by the
operating system to configure the keywords to be detected.
List of keyword patterns GUIDs - KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS . This property
is used to get a list of GUIDs that identify the types of supported patterns.
Armed - KSPROPERTY_SOUNDDETECTOR_ARMED . This read/write property is a simply Boolean status
indicating whether the detector is armed. The OS sets this to engage the keyword detector. The OS can clear
this to disengage. The driver automatically clears this when keyword patterns are set and also after a keyword
is detected. (The OS must rearm.)
Match result - KSPROPERTY_SOUNDDETECTOR_MATCHRESULT . This read property holds the result data
after detection has occurred.
The event that is fired when a keyword is detected is a KSEVENT_SOUNDDETECTOR_MATCHDETECTED event.
Sequence of Operation
System Startup
1. The OS reads the supported keyword types to verify it has keywords in that format.
2. The OS registers for the detector status change event.
3. The OS sets the keyword patterns.
4. The OS arms the detector.
On Receiving the KS Event
1. The driver disarms the detector.
2. The OS reads the keyword detector status, parses the returned data, and determines which pattern was
detected.
3. The OS rearms the detector.
Internal Driver and Hardware Operation
While the detector is armed, the hardware can be continuously capturing and buffering audio data in a small FIFO
buffer. (The size of this FIFO buffer is determined by requirements outside of this document, but might typically be
hundreds of milliseconds to several seconds.) The detection algorithm operates on the data streaming through
this buffer. The design of the driver and hardware are such that while armed there is no interaction between the
driver and hardware and no interrupts to the “application” processors until a keyword is detected. This allows the
system to reach a lower power state if there is no other activity.
When the hardware detects a keyword, it generates an interrupt. While waiting for the driver to service the
interrupt, the hardware continues to capture audio into the buffer, ensuring no data after the keyword is lost,
within buffering limits.
Keyword Timestamps
After detecting a keyword, all voice activation solutions must buffer all of the spoken keyword, including 250ms
before the start of the keyword. The audio driver must provide timestamps identifying the start and end of the key
phrase in the stream.
In order to support the keyword start/end timestamps, DSP software may need to internally timestamp events
based on a DSP clock. Once a keyword is detected, the DSP software interacts with the driver to prepare a KS
event. The driver and DSP software will need to map the DSP timestamps to a Windows performance counter
value. The method of doing this is specific to the hardware design. One possible solution is for the driver to read
current performance counter, query the current DSP timestamp, read current performance counter again, and then
estimate a correlation between performance counter and DSP time. Then given the correlation, the driver can map
the keyword DSP timestamps to Windows performance counter timestamps.

Keyword Detector OEM Adapter Interface


The OEM supplies a COM object implementation that acts as an intermediary between the OS and the driver,
helping to compute or parse the opaque data that is written and read to the audio driver through
KSPROPERTY_SOUNDDETECTOR_PATTERNS and KSPROPERTY_SOUNDDETECTOR_MATCHRESULT .
The CLSID of the COM object is a detector pattern type GUID returned by the
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS . The OS calls CoCreateInstance passing the pattern
type GUID to instantiate the appropriate COM object that is compatible with keyword pattern type and calls
methods on the object’s IKeywordDetectorOemAdapter interface.
COM Threading Model requirements
The OEM’s implementation may choose any of the COM threading models.
IKeywordDetectorOemAdapter
The interface design attempts to keep the object implementation stateless. In other words, the implementation
should require no state to be stored between method calls. In fact, internal C++ classes likely do not need any
member variables beyond those required to implement a COM object in general.
Methods
Implement the following methods.
IKeywordDetectorOemAdapter ::BuildArmingPatternData
IKeywordDetectorOemAdapter ::ComputeAndAddUserModelData
IKeywordDetectorOemAdapter ::GetCapabilities
IKeywordDetectorOemAdapter ::ParseDetectionResultData
IKeywordDetectorOemAdapter ::VerifyUserKeyword
KEYWORDID
The KEYWORDID enumeration identifies the phrase text/function of a keyword and is also used in the Windows
Biometric Service adapters. For more information, see Biometric Framework Overview - Core Platform
Components

typedef enum {
KwInvalid = 0,
KwHeyCortana = 1,
KwSelect = 2
} KEYWORDID;

KEYWORDSELECTOR
The KEYWORDSELECTOR struct is a set of IDs that uniquely select a particular keyword and language.

typedef struct
{
KEYWORDID KeywordId;
LANGID LangId;
} KEYWORDSELECTOR;

Handling Model Data


Static user independent model - The OEM DLL would typically include some static user independent model data
either built into the DLL or in a separate data file included with the DLL. The set of supported keyword IDs
returned by the GetCapabilities routine would depend on this data. For example, if the list of supported keyword
IDs returned by GetCapabilities includes KwHeyCortana, the static user independent model data would include
data for “Hey Cortana” (or its translation) for all the supported languages.
Dynamic user dependent model - IStream provides a random access storage model. The OS passes an IStream
interface pointer to many of the methods on the IKeywordDetectorOemAdapter interface. The OS backs the
IStream implementation with appropriate storage for up to 1MB of data.
The content and structure of the data within this storage is defined by the OEM. The intended purpose is for
persistent storage of user dependent model data computed or retrieved by the OEM DLL.
The OS may call the interface methods with an empty IStream, particularly if the user has never trained a keyword.
The OS creates a separate IStream storage for each user. In other words, a given IStream stores model data for one
and only one user.
The OEM DLL developer decides how to manage the user independent and user dependent data. However, it shall
never store user data anywhere outside the IStream. One possible OEM DLL design would internally switch
between accessing the IStream and the static user independent data depending on the parameters of the current
method. An alternate design might check the IStream at the start of each method call and add the static user
independent data to the IStream if not already present, allowing the rest of the method to access only the IStream
for all model data.

Training and Operation Audio Processing


As described previously, the training UI flow results in full phonetically rich sentences being available in the audio
stream. Each sentence is individually passed to IKeywordDetectorOemAdapter ::VerifyUserKeyword to verify
it contains the expected keyword and has acceptable quality. After all sentences are gathered and verified by the
UI, they are all passed in one call to IKeywordDetectorOemAdapter ::ComputeAndAddUserModelData .
Audio is processed in a unique way for voice activation training. The following table summarizes the differences
between voice activation training and the regular voice recognition usage.
Voice Training Voice Recognition

Mode Raw Raw or Speech

Pin Normal KWS

Audio Format 32-bit float (Type = Audio, Subtype = Managed by OS audio stack
IEEE_FLOAT, Sampling Rate = 16 kHz,
bits = 32)

Mic Mic 0 All mics in array, or mono

Keyword Recognition System Overview


This diagram provides an overview of the keyword recognition system.

Keyword Recognition Sequence Diagrams


In these diagrams, the speech runtime module is shown as the “speech platform”. As mentioned previously, the
Windows speech platform is used to power all of the speech experiences in Windows 10 such as Cortana and
dictation.
During startup, capabilities are gathered using IKeywordDetectorOemAdapter ::GetCapabilities .
Later when the user selects to "Learn my voice", the training flow is invoked.

This diagram describes the process of arming for keyword detection.


WAVERT Enhancements
Miniport interfaces are defined to be implemented by WaveRT miniport drivers. These interfaces provide methods
to either simplify the audio driver, improve OS audio pipeline performance and reliability, or support new
scenarios. A new PnP device interface property is defined allowing the driver to provide a static expressions of its
buffer size constraints to the OS.
Buffer Sizes
A driver operates under various constraints when moving audio data between the OS, the driver, and the
hardware. These constraints may be due to the physical hardware transport that moves data between memory
and hardware, and/or due to the signal processing modules within the hardware or associated DSP.
HW-KWS solutions must support audio capture sizes of at least 100ms and up to 200ms.
The driver expresses the buffer size constraints by setting the DEVPKEY_KsAudio_PacketSize_Constraints device
property on the KSCATEGORY_AUDIO PnP device interface of the KS filter that has the KS streaming pin(s). This
property should remain valid and stable while the KS filter interface is enabled. The OS can read this value at any
time without having to open a handle to the driver and call on the driver.
DEVPKEY_KsAudio_PacketSize_Constraints
The DEVPKEY_KsAudio_PacketSize_Constraints property value contains a
KSAUDIO_PACKETSIZE_CONSTRAINTS structure describing the physical hardware constraints (i.e. due to the
mechanics of transferring data from the WaveRT buffer to the audio hardware). The structure includes an array of
0 or more KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT structures describing constraints
specific to any signal processing modes. The driver sets this property before calling PcRegisterSubdevice or
otherwise enabling its KS filter interface for its streaming pins.
IMinipor tWaveRTInputStream
A driver implements this interface for better coordination of audio dataflow from the driver to OS. If this interface
is available on a capture stream, the OS uses methods on this interface to access data in the WaveRT buffer. For
more information see, IMinipor tWaveRTInputStream::GetReadPacket
IMinipor tWaveRTOutputStream
A WaveRT miniport optionally implements this interface to be advised of write progress from the OS and to return
precise stream position. For more information see IMinipor tWaveRTOutputStream::SetWritePacket ,
IMinipor tWaveRTOutputStream::GetOutputStreamPresentationPosition and
IMinipor tWaveRTOutputStream::GetPacketCount .
Performance counter timestamps
Several of the driver routines return Windows performance counter timestamps reflecting the time at which
samples are captured or presented by the device.
In devices that have complex DSP pipelines and signal processing, calculating an accurate timestamp may be
challenging and should be done thoughtfully. The timestamps should not simply reflect the time at which samples
were transferred to or from the OS to the DSP.
Within the DSP, track sample timestamps using some internal DSP wall clock.
Between the driver and DSP, calculate a correlation between the Windows performance counter and the DSP
wall clock. Procedures for this can range from very simple (but less precise) to fairly complex or novel (but
more precise).
Factor in any constant delays due to signal processing algorithms or pipeline or hardware transports, unless
these delays are otherwise accounted for.
Burst Read Operation
This section describes the OS and driver interaction for burst reads. Burst read can happen outside of the voice
activation scenario as long as the driver supports the packet based streaming WaveRT model, including the
IMinipor tWaveRTInputStream::GetReadPacket function.
Two burst example read scenarios are discussed. In one scenario, if the miniport supports a pin having pin
category KSNODETYPE_AUDIO_KEYWORDDETECTOR then the driver will begin capturing and internally
buffering data when a keyword is detected. In another scenario, the driver can optionally internally buffer data
outside of the WaveRT buffer if the OS is not reading data quickly enough by calling
IMinipor tWaveRTInputStream::GetReadPacket .
To burst data that has been captured prior to transition to KSSTATE_RUN, the driver must retain accurate sample
timestamp information along with the buffered capture data. The timestamps identify the sampling instant of the
captured samples.
1. After the stream transitions to KSSTATE_RUN, the driver immediately sets the buffer notification event
because it already has data available.
2. On this event, the OS calls GetReadPacket() to get information about the available data.
a. The driver returns the packet number of the valid captured data (0 for the first packet after the transition
from KSSTATE_STOP to KSSTATE_RUN), from which the OS can derive the packet position within the
WaveRT buffer as well as the packet position relative to start of stream.
b. The driver also returns the performance counter value that corresponds to the sampling instant of the
first sample in the packet. Note that this performance counter value might be relatively old, depending on
how much capture data has been buffered within the hardware or driver (outside of the WaveRT buffer).
c. If there is more unread buffered data available the driver either: i. Immediately transfers that data into the
available space of WaveRT buffer (i.e. space not used by the packet returned from GetReadPacket), returns
true for MoreData, and sets the buffer notification event before returning from this routine. Or, ii. Programs
hardware to burst the next packet into the available space of the WaveRT buffer, returns false for MoreData,
and later sets the buffer event when the transfer completes.
3. The OS reads data from the WaveRT buffer using the information returned by GetReadPacket().
4. The OS waits for the next buffer notification event. The wait might terminate immediately if the driver set
the buffer notification in step (2c).
5. If the driver did not immediately set the event in step (2c), the driver sets the event after it transfers more
captured data into the WaveRT buffer and makes it available for the OS to read
6. Go to (2). For KSNODETYPE_AUDIO_KEYWORDDETECTOR keyword detector pins, drivers should
allocate enough internal burst buffering for at least 5000ms of audio data. If the OS fails to create a stream
on the pin before the buffer overflows then the driver may end the internal buffering activity and free
associated resources.

Wake on Voice
Wake On Voice (WoV) enables the user to activate and query a speech recognition engine from a screen off, lower
power state, to a screen on, full power state by saying a certain keyword, such as "Hey Cortana".
This feature allows for the device to be always listening for the user’s voice while the device is in a low power
state, including when the screen is off and the device is idle. It does this by using a listening mode, which is lower
power when compared to the much higher power usage seen during normal microphone recording. The low
power speech recognition allows a user to simply say a pre-defined key phrase like "Hey Cortana", followed by a
chained speech phrase like "when’s my next appointment" to invoke speech in a hands-free manner. This will work
regardless of whether the device is in use or idle with the screen off.
The audio stack is responsible for communicating the wake data (speaker ID, keyword trigger, confidence level) as
well as notifying interested clients that the keyword has been detected.
Validation on Modern Standby Systems
WoV from a system idle state can be validated on Modern Standby systems using the Modern Standby Wake on
Voice Basic Test on AC-power Source and the Modern Standby Wake on Voice Basic Test on DC-power Source in
the HLK. These tests check that the system has a hardware keyword spotter (HW-KWS), is able to enter the
Deepest Runtime Idle Platform State (DRIPS) and is able to wake from Modern Standby on voice command with
system resume latency of less than or equal to one second.
USB Audio 2.0 Drivers
12/20/2019 • 11 minutes to read • Edit Online

Starting with Windows 10, release 1703, a USB Audio 2.0 driver is shipped with Windows. It is designed to support
the USB Audio 2.0 device class. The driver is a WaveRT audio port class miniport. For more information about the
USB Audio 2.0 device class, see https://www.usb.org/documents?
search=&type%5B0%5D=55&items_per_page=50.
The driver is named: usbaudio2.sys and the associated inf file is usbaudio2.inf.
The driver will identify in device manager as "USB Audio Class 2 Device." This name will be overwritten with a USB
Product string, if it is available.
The driver is automatically enabled when a compatible device is attached to the system. However, if a third-party
driver exists on the system or Windows Update, that driver will be installed and override the class driver.

Architecture
USBAudio.Sys fits within the wider architecture of Windows USB Audio as shown.

Related USB specifications


The following USB specifications define USB Audio and are referenced in this topic.
USB-2 refers to the Universal Serial Bus Specification, Revision 2.0
ADC-2 refers to the USB Device Class Definition for Audio Devices, Release 2.0.
FMT-2 refers to the Audio Data Formats specification, Release 2.0.
The USB-IF is a special interest group that maintains the Official USB Specification, test specifications and tools.

Audio formats
The driver supports the formats listed below. An alternate setting which specifies another format defined in FMT-2,
or an unknown format, will be ignored.
Type I formats (FMT-2 2.3.1):
PCM Format with 8..32 bits per sample (FMT20 2.3.1.7.1)
PCM8 Format (FMT-2 2.3.1.7.2)
IEEE_FLOAT Format (FMT-2 2.3.1.7.3)
Type III formats (FMT-2 2.3.3 and A.2.3):
IEC61937_AC-3
IEC61937_MPEG-2_AAC_ADTS
IEC61937_DTS-I
IEC61937_DTS-II
IEC61937_DTS-III
TYPE_III_WMA

Feature descriptions
This section describes the features of the of the USB Audio 2.0 driver.
Audio function topology
The driver supports all entity types defined in ADC-2 3.13.
Each Terminal Entity must have a valid clock connection in compatible USB Audio 2.0 hardware. The clock path may
optionally include Clock Multiplier and Clock Selector units and must end in a Clock Source Entity.
The driver supports one single clock source only. If a device implements multiple clock source entities and a clock
selector, then the driver will use the clock source that is selected by default and will not modify the clock selector’s
position.
A Processing Unit (ADC-2 3.13.9) with more than one input pin is not supported.
An Extension Unit (ADC-2 3.13.10) with more than one input pin is not supported.
Cyclic paths in the topology are not allowed.
Audio streaming
The driver supports the following endpoint synchronization types (USB-2 5.12.4.1):
Asynchronous IN and OUT
Synchronous IN and OUT
Adaptive IN and OUT
For the asynchronous OUT case the driver supports explicit feedback only. A feedback endpoint must be
implemented in the respective alternate setting of the AS interface. The driver does not support implicit feedback.
There is currently limited support for devices using a shared clock for multiple endpoints.
For the Adaptive IN case the driver does not support a feedforward endpoint. If such an endpoint is present in the
alternate setting, it will be ignored. The driver handles the Adaptive IN stream in the same way as an Asynchronous
IN stream.
The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1.
This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot (audio slot
= channel count samples).

Descriptors
An audio function must implement exactly one AudioControl Interface Descriptor (ADC-2 4.7) and one or more
AudioStreaming Interface Descriptors (ADC-2 4.9). A function with an audio control interface but no streaming
interface is not supported.
The driver supports all descriptor types defined in ADC20, section 4. The following subsections provide comments
on some specific descriptor types.
Class-Specific AS interface descriptor
For details on this specification, refer to ADC-2 4.9.2.
An AS interface descriptor must start with alternate setting zero with no endpoint (no bandwidth consumption) and
further alternate settings must be specified in ascending order in compatible USB Audio 2.0 hardware.
An alternate setting with a format that is not supported by the driver will be ignored.
Each non-zero alternate setting must specify an isochronous data endpoint, and optionally a feedback endpoint. A
non-zero alternate setting without any endpoint is not supported.
The bTerminalLink field must refer to a Terminal Entity in the topology and its value must be identical in all alternate
settings of an AS interface.
The bFormatType field in the AS interface descriptor must be identical to bFormatType specified in the Format Type
Descriptor (FMT-2 2.3.1.6).
For Type I formats, exactly one bit must be set to one in the bmFormats field of the AS interface descriptor.
Otherwise, the format will be ignored by the driver.
To save bus bandwidth, one AS interface can implement multiple alternate settings with the same format (in terms
of bNrChannels and AS Format Type Descriptor) but different wMaxPacketSize values in the isochronous data
endpoint descriptor. For a given sample rate, the driver selects the alternate setting with the smallest
wMaxPacketSize that can fulfill the data rate requirements.
Type I format type descriptor
For details on this specification, refer to FMT-2 2.3.1.6.
The following restrictions apply:

Type I PCM format: 1 <= bSubslotSize <= 4 8 <= bBitResolution <= 32

Type I PCM8 format: bSubslotSize == 1 bBitResolution == 8

Type I IEEE_FLOAT format: bSubslotSize == 4 bBitResolution == 32

Type III IEC61937 formats: bSubslotSize == 2 bBitResolution == 16

Class-Specific AS isochronous audio data endpoint descriptor


For details on this specification, refer to ADC-2 4.10.1.2.
The MaxPacketsOnly flag in the bmAttributes field is not supported and will be ignored.
The fields bmControls, bLockDelayUnits and wLockDelay will be ignored.

Class requests and interrupt data messages


The driver supports a subset of the control requests defined in ADC-2, section 5.2, and supports interrupt data
messages (ADC-2 6.1) for some controls. The following table shows the subset that is implemented in the driver.
EN T IT Y C O N T RO L GET C UR SET C UR GET RA N GE IN T ERRUP T

Clock Source Sampling x x x


Frequency
Control

Clock Selector Clock Selector x


Control

Clock Multiplier Numerator x


Control

Denominator x
Control

Terminal Connector x x
Control

Mixer Unit Mixer Control x x x

Selector Unit Selector Control x x

Feature Unit Mute Control x x x

Volume Control x x x x

Automatic Gain x x
Control

Effect Unit –

Processing Unit –

Extension Unit –

Additional information on the controls and requests is available in the following subsections.
Clock source entity
For details on this specification, refer to ADC-2 5.2.5.1.
At a minimum, a Clock Source Entity must implement Sampling Frequency Control GET RANGE and GET CUR
requests (ADC-2 5.2.5.1.1) in compatible USB Audio 2.0 hardware.
The Sampling Frequency Control GET RANGE request returns a list of subranges (ADC-2 5.2.1). Each subrange
describes a discrete frequency, or a frequency range. A discrete sampling frequency must be expressed by setting
MIN and MAX fields to the respective frequency and RES to zero. Individual subranges must not overlap. If a
subrange overlaps a previous one, it will be ignored by the driver.
A Clock Source Entity which implements one single fixed frequency only does not need to implement Sampling
Frequency Control SET CUR. It implements GET CUR which returns the fixed frequency, and it implements GET
RANGE which reports one single discrete frequency.
Clock selector entity
For details on this specification, refer to ADC-2 5.2.5.2
The USB Audio 2.0 driver does not support clock selection. The driver uses the Clock Source Entity which is selected
by default and never issues a Clock Selector Control SET CUR request. The Clock Selector Control GET CUR request
(ADC-2 5.2.5.2.1) must be implemented in compatible USB Audio 2.0 hardware.
Feature unit
For details on this specification, refer to ADC-2 5.2.5.7.
The driver supports one single volume range only. If the Volume Control GET RANGE request returns more than
one range, then subsequent ranges will be ignored.
The volume interval expressed by the MIN and MAX fields should be an integer multiple of the step size specified in
the RES field.
If a feature unit implements single channel controls as well as a master control for Mute or Volume, then the driver
uses the single channel controls and ignores the master control.

Additional Information for OEM and IHVs


OEMs and IHVs should test their existing and new devices against the supplied in-box driver.
There is not any specific partner customization that is associated with the in-box USB Audio 2.0 driver.
This INF file entry (provided in a update to Windows Release 1703), is used to identify that the in-box driver is a
generic device driver.

GenericDriverInstalled,,,,1

The in-box driver registers for the following compatible IDs with usbaudio2.inf.

USB\Class_01&SubClass_00&Prot_20
USB\Class_01&SubClass_01&Prot_20
USB\Class_01&SubClass_02&Prot_20
USB\Class_01&SubClass_03&Prot_20

See the USB audio 2.0 specification for subclass types.


USB Audio 2.0 Devices with MIDI (subclass 0x03 above) will enumerate the MIDI function as a separate multi-
function device with usbaudio.sys (USB Audio 1.0 driver) loaded.
The USB Audio 1.0 class driver registers this compatible ID with wdma_usb.inf.

USB\Class_01

And has these exclusions:

USB\Class_01&SubClass_00&Prot_20
USB\Class_01&SubClass_01&Prot_20
USB\Class_01&SubClass_02&Prot_20
USB\Class_01&SubClass_03&Prot_20

An arbitrary number of channels (greater than eight) are not supported in shared mode due to a limitation of the
Windows audio stack.

IHV USB Audio 2.0 drivers and updates


For IHV provided third party driver USB Audio 2.0 drivers, those drivers will continue to be preferred for their
devices over our in-box driver unless they update their driver to explicitly override this behavior and use the in-box
driver.

Audio Jack Registry Descriptions


Starting in Windows 10 release 1703, IHVs that create USB Audio Class 2.0 devices having one or more jacks have
the capability to describe these jacks to the in-box Audio Class 2.0 driver. The in-box driver uses the supplied jack
information when handling the KSPROPERTY_JACK_DESCRIPTION for this device.
Jack information is stored in the registry in the device instance key (HW key).
The following describes the audio jack information settings in the registry:

REG_DWORD T<tid>_NrJacks # of the jack on this device


REG_DWORD T<tid>_J<n>_ChannelMapping Channel mask. The value is defined in ksmedia.h. e.g.
SPEAKER_FRONT_RIGHT or KSAUDIO_SPEAKER_5POINT1_SURROUND
REG_DWORD T<tid>_J<n>_ConnectorType The enum value is define in EPcxConnectionType.
REG_DWORD T<tid>_J<n>_GeoLocation The enum value is define in EPcxGeoLocation.
REG_DWORD T<tid>_J<n>_GenLocation The enum value is define in EPcxGenLocation.
REG_DWORD T<tid>_J<n>_PortConnection The enum value is define in EPxcPortConnection.
REG_DWORD T<tid>_J<n>_Color The color needs to be represent by RGB like this: 0x00RRGGBB (NOT a
COLORREF).

<tid> = terminal ID (As defined in the descriptor)


<n> = Jack number (1 ~ n).
Convention for <tid> and <n> is:
Base 10 (8, 9, 10 rather than 8, 9, a)
No leading zeros
n is 1-based (first jack is jack 1 rather than jack 0)
For example:
T1_NrJacks, T1_J2_ChannelMapping, T1_J2_ConnectorType
For additional audio jack information, see KSJACK_DESCRIPTION structure.
These registry values can be set in various ways:
By using custom INFs which wrap the in-box INF for the purpose to set these values.
Directly by the h/w device via a Microsoft OS Descriptors for USB devices (see example below). For more
information about creating these descriptors, see Microsoft OS Descriptors for USB Devices.
Microsoft OS Descriptors for USB Example
The following Microsoft OS Descriptors for USB example contains the channel mapping and color for one jack. The
example is for a non-composite device with single feature descriptor.
The IHV vendor should extend it to contain any other information for the jack description.
UCHAR Example2_MSOS20DescriptorSetForUAC2 [0x76] = {
//
// Microsoft OS 2.0 Descriptor Set Header
//
0x0A, 0x00, // wLength - 10 bytes
0x00, 0x00, // MSOS20_SET_HEADER_DESCRIPTOR
0x00, 0x00, 0x0?, 0x06, // dwWindowsVersion – 0x060?0000 for future Windows version
0x76, 0x00, // wTotalLength – 118 bytes // update later

//
// Microsoft OS 2.0 Registry Value Feature Descriptor
//
0x42, 0x00, // bLength - 66 bytes
0x04, 0x00, // wDescriptorType – 5 for Registry Property
0x04, 0x00, // wPropertyDataType - 4 for REG_DWORD
0x34, 0x00, // wPropertyNameLength – 52 bytes
0x54, 0x00, 0x30, 0x00, // Property Name - “T01_J01_ChannelMapping”
0x31, 0x00, 0x5f, 0x00,
0x4a, 0x00, 0x30, 0x00,
0x31, 0x00, 0x5f, 0x00,
0x43, 0x00, 0x68, 0x00,
0x61, 0x00, 0x6e, 0x00,
0x6e, 0x00, 0x65, 0x00,
0x6c, 0x00, 0x4d, 0x00,
0x61, 0x00, 0x70, 0x00,
0x70, 0x00, 0x69, 0x00,
0x6e, 0x00, 0x67, 0x00,
0x00, 0x00
0x04, 0x00, // wPropertyDataLength – 4 bytes
0x02, 0x00, 0x00, 0x00 // PropertyData - SPEAKER_FRONT_RIGHT

//
// Microsoft OS 2.0 Registry Value Feature Descriptor
//
0x2A, 0x00, // bLength - 42 bytes
0x04, 0x00, // wDescriptorType – 5 for Registry Property
0x04, 0x00, // wPropertyDataType - 4 for REG_DWORD
0x1C, 0x00, // wPropertyNameLength – 28 bytes
0x54, 0x00, 0x30, 0x00, // Property Name - “T01_J01_Color”
0x31, 0x00, 0x5f, 0x00,
0x4a, 0x00, 0x30, 0x00,
0x31, 0x00, 0x5f, 0x00,
0x43, 0x00, 0x6f, 0x00,
0x6c, 0x00, 0x6f, 0x00,
0x72, 0x00, 0x00, 0x00,
0x04, 0x00, // wPropertyDataLength – 4 bytes
0x00, 0x00, 0xff, 0x00 // PropertyData - 0xff0000 - RED }

Troubleshooting
If the driver does not start, the system event log should be checked. The driver logs events which indicate the
reason for the failure. Similarly, audio logs can be manually collected following the steps described in this blog
entry. If the failure may indicate a driver problem, please report it using the Feedback Hub described below, and
include the logs.
For information on how to read logs for the USB Audio 2.0 class driver using supplemental TMF files, see this blog
entry. For general information on working with TMF files, see Displaying a Trace Log with a TMF File.
For information on "Audio services not responding" error and USB audio device does not work in Windows 10
version 1703 see, USB Audio Not Playing

Feedback Hub
If you run into a problem with this driver, collect audio logs and then follow steps outlined in this blog entry to
bring it to our attention via the Feedback Hub.

Driver development
This USB Audio 2.0 class driver was developed by Thesycon and is supported by Microsoft.
See also
Windows Driver Model (WDM)
Audio Drivers Overview
WaveRT Port Driver
Low Latency Audio
Audio Hardware Resource Management
12/5/2018 • 18 minutes to read • Edit Online

Windows 10 includes the ability to express concurrency constraints using and XML file. On resource constrained
mobile devices the ability to specify priority for specific audio streams can enhance the customer experience.
Note This mechanism is only available in phones and tablets.
One challenge with creating a good audio experience on a low cost mobile device, is that some devices have
various concurrency constraints. For example, it is possible that the device can only play up to 6 audio streams
concurrently and supports only 2 offload streams. When there is an active phone call on a mobile device, it is
possible that the device supports only 2 audio streams. When the device is capturing audio, the device can only
play up to 4 audio streams.
Windows 10 includes a mechanism to express concurrency constraints to insure that high-priority audio streams
and cellular phone calls will be able to play. If the system does not have enough resources, then low priority
streams are terminated. This mechanism is only available in phones and tablets not on desktops or laptops.
To specify constraints complete these two steps.
Create a concurrency constraints XML file as described in Specify Concurrency Constraints.
Configure a registry entry to use the custom concurrency constraints XML file as described in
Registry_Key_Configuration.

Specify Concurrency Resource Constraints


The XML constraints file is made up of three sections. The first required section is defined by <Limits> </Limits>.
This section can be used to define up to fifteen resource restraints. For example you could define constraints for
the maximum number of rendering stream and the maximum number of streams that can be off loaded.

<?xml version="1.0" encoding="utf-8"?>


<ConstraintModel>

<Limits>
<Resource>
<ID>MaxRender</ID>
<Consumption>6</Consumption>
</Resource>
<Resource>
<ID>MaxOffLoad</ID>
<Consumption>2</Consumption>
</Resource>
...

</Limits>

The next section of the XML file defines one or more lists of exclusive endpoints, with each list containing two or
more endpoints. These are endpoints that, that cannot be active at the same time. This section is optional.
For example, if the audio hardware has both HandsetSpeaker and WiredHeadsetSpeaker wired to the same DAC,
that cannot be active at the same time, these should be in the same ExclusiveEndpoints list.
This section can have multiple <ExclusiveEndpoints> nodes. Each ExclusiveEndpoints node contains two or more
Endpoint nodes. Each Endpoint node contains HWID, TopologyName, and PinId.
<ExclusiveEndpoints>
<Endpoint>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
</Endpoint>
<Endpoint>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
</Endpoint>
</ExclusiveEndpoints>

The last required section of the XML file defines various resource consumers. This section of the file contains
multiple <ResourceConsumer> entries. Each entry identifies information about a resource consumer and their
associated resources use. Each resource that is used, must be previously defined in the <Limits> section.

<ResourceConsumer>
<!-- Active Phone call -->
<ConsumerInfo>
<PhoneCall>
<CallState>Active</CallState>
</PhoneCall>
</ConsumerInfo>
<Resource>
<ID>MaxRender</ID>
<Consumption>2</Consumption>
</Resource>
<Resource>
<ID>MaxOffLoad</ID>
<Consumption>2</Consumption>
</Resource>
...
</ResourceConsumer>

As audio resources are used, the audio service tracks the resources. When insufficient resources are available,
either lower priority streams are terminated or the current resource request fails if existing resource consumers
are higher priority.
These are the valid <ConsumerInfo> entries.
<PhoneCall> - The <Phonecall> node contains a with CallState child node, that can be "Active" or "Hold".
<Stream> - Audio streams. The <Stream> node contains the following child nodes.
<HWID- The hardware ID (hw-id) of the resource consumer as specified in the driver’s INF file.
<TopologyName> - The topology filter reference string of the resource consumer.
<PinId> - The pin ID of the resource consumer.
<Mode> - The GUID of the associated mode. For more information, see Audio Signal Processing Modes.
<ConnectorType> - The connector type of the resource consumer. Valid values are: Host, Loopback, or
Offload.
<FM> - FM Radio.
<KeywordDetector> - Keyword detector used to support Cortana voice interactions.
The following table summarizes the render audio stream priorities, listed from highest to lowest priority.

Communications 1

Game Chat 2

Screen Reader 3

Camera Shutter 4

Push To Talk 5

In Call Notification 6

Personal Assistant 6

Speech 7

Ringtone 8

Alarm 9

Movie 10

Foreground Only Media 10

Background Capable Media 11

Media 11

Sound Effects 12

DTMF 12

Game Media 12

System 12

Game Effects 12

Other 13

Alerts 14

The following table summarizes the capture audio stream priorities, listed from highest to lowest priority.

Communications 1
Game Chat 2

Push To Talk 4

Personal Assistant 6

Speech 7

Background Capable Media 8

Media 8

Other 13

Game Media 15

Screen Reader 15

Alerts 15

Foreground Only Media 15

Game Effects 15

Sound Effects 15

DTMF 15

In Call Notification 15

Alarm 15

Camera Shutter 15

Movie 15

Ringtone 15

System 15

Examples
Example 1: The user is talking over Skype, using Communications Render and Capture streams. They start a
game, which attempts to create a Game Effects stream. If there aren’t enough resources available, the Game
Effects stream creation will fail.
Example 2: The user is playing music. They start an application that creates a Speech stream. If there aren’t
enough resources available, the music stream will be terminated and the Speech stream creation will
succeed.

Registry Key Configuration


The full path to the concurrency constraints XML file needs to be specified in the following registry key.

HKR\SYSTEM\MultiMedia\DeviceCapability\ResourceSettings\XMLConfig

The path is relative to the driver install. In the driver INF installation the constraint XML file needs to be copied and
the following line would be added to register it with the system:

HKR,SYSTEM\MultiMedia\DeviceCapability\ResourceSettings\XMLConfig,<Name of the constraint>,,<Path to the


constraint>

In this registry key, provide a value containing the path to the XML. It is recommended that the name of the XML
file and regkey value name be unique since there is potential for other subsystems/audio devices providing their
own set of constraints in XML files. The regkey can be set in the audio driver INF file.

Example XML Constraints File


This is an example XML constraints file from the SYSVAD virtual audio driver sample.

<?xml version="1.0" encoding="utf-8"?>


<ConstraintModel>

<Limits>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>3</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>2</Consumption>
</Resource>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>2</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>127</Consumption>
</Resource>
</Limits>

<ExclusiveEndpoints>
<Endpoint>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
</Endpoint>
<Endpoint>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
</Endpoint>
</ExclusiveEndpoints>
<ResourceConsumer>
<!-- Phone call -->
<ConsumerInfo>
<PhoneCall>
<CallState>Active</CallState>
</PhoneCall>
</ConsumerInfo>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>2</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>26</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- FM -->
<ConsumerInfo>
<FM />
</ConsumerInfo>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- Keyword Detector -->
<ConsumerInfo>
<KeywordDetector />
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, default mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!--Signal processing mode default-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Communications mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<!--Signal processing mode Communications-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Speech mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<!--Signal processing mode Speech-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Notification mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<!--Signal processing mode Notification-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Media mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{4780004E-7133-41D8-8C74-660DADD2C0EE}</Mode>
<!--Signal processing mode Media-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Movie mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}</Mode>
<!--Signal processing mode Movie-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, raw mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<!--Signal processing mode raw-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, default mode, offload -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!--Signal processing mode default-->
<ConnectorType>Offload</ConnectorType>
<!-- Offload -->
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Media mode, Offload -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{4780004E-7133-41D8-8C74-660DADD2C0EE}</Mode>
<!--Signal processing mode Media-->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, Movie mode, offload -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}</Mode>
<!--Signal processing mode Movie-->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to speaker, default mode, loopback -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeaker</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!--Signal processing mode default-->
<ConnectorType>Loopback</ConnectorType>
<!-- Loopback -->
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Communications mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<!--Signal processing mode Communications-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Speech mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<!--Signal processing mode Speech-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Notification mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<!--Signal processing mode Notification-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Media mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{4780004E-7133-41D8-8C74-660DADD2C0EE}</Mode>
<!--Signal processing mode Media-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Movie mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}</Mode>
<!--Signal processing mode Movie-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, default mode, offload -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!-- Offload -->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>
<ResourceConsumer>
<!-- AudioStream to wired headset, Media mode, Offload -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{4780004E-7133-41D8-8C74-660DADD2C0EE}</Mode>
<!--Signal processing mode Media-->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, Movie mode, offload -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}</Mode>
<!--Signal processing mode Movie-->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to wired headset, default mode, loopback -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologySpeakerHeadset</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!-- Loopback -->
<ConnectorType>Loopback</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to BT speaker, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyBthHfpSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to BT speaker, raw mode, offload -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyBthHfpSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<!-- Offload -->
<ConnectorType>Offload</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxTwoOffload</ID>
<Consumption>1</Consumption>
</Resource>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to BT speaker, default mode, loopback -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyBthHfpSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!-- Loopback -->
<ConnectorType>Loopback</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to handset speaker, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to handset speaker, Communications mode, host -->
<ConsumerInfo>
<Stream>
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- Topology filter reference string-->
<!-- Topology filter reference string-->
<PinId>1</PinId>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<!--Signal processing mode Communications-->
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to handset speaker, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream to handset speaker, default mode, loopback -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetSpeaker</TopologyName>
<!-- KSPIN_TOPO_LINEOUT_DEST -->
<PinId>1</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<!-- Loopback -->
<ConnectorType>Loopback</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxThreeRender</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneLoopback</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicIn</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic, communications mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicIn</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode communications-->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic, speech mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicIn</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode speech-->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic, notification mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicIn</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode notification-->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicIn</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from wired headset mic, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicHeadset</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from wired headset mic, communications mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicHeadset</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode communications-->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from wired headset mic, speech mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicHeadset</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode speech-->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from wired headset mic, notification mode, host -->
<ConsumerInfo>
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicHeadset</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode notification-->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from wired headset mic, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicHeadset</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic array, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicArray1</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic array, communications mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicArray1</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode communications-->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic array, speech mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicArray1</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode speech-->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic array, notification mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicArray1</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode notification-->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from mic array, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyMicArray1</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from BT mic, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyBthHfpMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from BT mic, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyBthHfpMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<PinId>0</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from handset mic, default mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode default-->
<Mode>{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from handset mic, communications mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode communications-->
<Mode>{98951333-B9CD-48B1-A0A3-FF40682D73F7}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from handset mic, speech mode, host -->
<ConsumerInfo>
<Stream>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode speech-->
<Mode>{FC1CFC9B-B9D6-4CFA-B5E0-4BB2166878B2}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from handset mic, notification mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode notification-->
<Mode>{9CF2A70B-F377-403B-BD6B-360863E0355C}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>2</Consumption>
</Resource>
</ResourceConsumer>

<ResourceConsumer>
<!-- AudioStream from handset mic, raw mode, host -->
<ConsumerInfo>
<Stream>
<!-- Example of h/w id specified in phoneaudiosample.inf -->
<HWID>Root\sysvad_PhoneAudioSample</HWID>
<!-- Topology filter reference string-->
<TopologyName>TopologyHandsetMic</TopologyName>
<!-- KSPIN_TOPO_MIC_ELEMENTS -->
<PinId>0</PinId>
<!--Signal processing mode raw-->
<Mode>{9E90EA20-B493-4FD1-A1A8-7E1361A956CF}</Mode>
<ConnectorType>Host</ConnectorType>
</Stream>
</ConsumerInfo>
<Resource>
<ID>MaxTwoCapture</ID>
<Consumption>1</Consumption>
</Resource>
<Resource>
<ID>MaxOneRawStreamInPhoneCall</ID>
<Consumption>1</Consumption>
</Resource>
</ResourceConsumer>

</ConstraintModel>
Bluetooth Bypass Guidelines for Audio Drivers
12/5/2018 • 2 minutes to read • Edit Online

The Bluetooth bypass design guidelines presented in this section show audio driver developers how audio data can
be rerouted past the Bluetooth host controller interface (HCI) to be processed in system-on-a-chip (SoC) solution.
Support for Bluetooth bypass audio data streaming was introduced with Windows 8.1.
This section contains the following topics.
Architectural Overview
Theory of Operation
Bluetooth Bypass DDI Reference
Related Design Guidelines
Windows Bluetooth host controller interface (HCI)
Architectural Overview
12/5/2018 • 2 minutes to read • Edit Online

This topic presents an architectural overview of the Windows 8.1 support for rerouting audio data to bypass the
Bluetooth host controller interface (HCI).
Starting with Windows 8.1, the Microsoft operating system has been updated to be compatible with low power
system-on-a-chip (SoC) design solutions. The new Windows support is compatible with either Intel-based or ARM-
based SoC designs. These new low-power devices will be optimized for “always on” scenarios, so low battery
consumption will be a key factor for success.
SoC architectures use the Universal Asynchronous Receiver/Transmitter (UART) transport mode to transmit data to
and from the Bluetooth host controller.
Because UARTs cannot provide time sensitive data transmission, a synchronous connection oriented (SCO) bypass
channel must be implemented in addition to a UART, to transfer audio data via I2S or some other connection
between the audio codec and the Bluetooth radio. This means that audio data must be rerouted to bypass the
Bluetooth HCI. The Bluetooth HCI which would normally be used on PCs to transmit audio data.
It is important to note that this feature is simply offloading the same functionality that exists in versions of
Windows prior to Windows 8.1, so from a user perspective there are no use cases that are different between the
Bluetooth hands-free profile (HFP) on SoC and Bluetooth HFP in Windows on a PC or laptop.
The following diagram shows the software and hardware components that work together to provide this new
support in Windows 8.1.

Note that this Windows feature does not support bypass audio streaming using advanced audio distribution
profile (A2DP). Windows 8 provides a separate A2DP profile driver that completely supports audio functionality
through the standard Bluetooth HCI without requiring any additional audio drivers.
Theory of Operation
12/5/2018 • 2 minutes to read • Edit Online

This theory of operation topic explains the theory behind the inner working of the new Windows 8.1 support for
Bluetooth bypass audio streaming.
When Bluetooth audio is in bypass mode, the audio control path flows through some other hardware connection
to the Bluetooth controller, rather than through the host controller interface (HCI). This other hardware connection
is often I2S, but can be any interface determined by the Bluetooth host controller. This set of topics refers to this
connection as a “bypass” or “sideband” connection.
While audio I/O occurs through the bypass connection, the over-the-air synchronous connection oriented (SCO)
audio stream is still managed through the HCI. Windows 8 provides a Bluetooth Hands-Free profile (HFP) driver to
hide most of the complexities of managing the SCO connection and other aspects of the Hands-Free profile.
However a custom audio driver controls audio data I/O between Windows and the bypass connection.
The separation of roles between the HFP driver and the custom control driver for audio I/O data, means that
efficient communication must be established between the Windows HFP driver and the custom audio driver. This
communication is handled by a set of IOCTLs that are passed from the custom audio driver to the Windows HFP
driver.
Typically the bypass connection itself is always present. The PnP service always enumerates the hardware that
includes this connection, and then loads the required audio driver. However, the audio system may or may not
have any HFP headsets paired and the bypass connection is only useful if at least one HFP headset is paired.
For each paired HFP device, the Windows HFP driver registers and enables a device interface in the
GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interface class. So the following conditions are true for
HFP devices:
When Windows activates the HFP driver (normally during boot up), the HFP driver registers and enables an
interface for each paired HFP device.
When an HFP device is first paired, with Windows already up and running, the HFP driver registers and
enables an interface for the device.
If there are n paired HFP devices, the Windows HFP driver registers n instances of the device interface.
When a paired HFP device is removed, the Windows HFP driver disables the device interface.
When Windows stops the HFP driver (normally during shutdown or reboot), the HFP driver disables the
interface for each paired HFP device.
The audio driver must handle multiple arrivals and removals of interfaces at any time, not just during
startup or shutdown.
The following topics provide more information about the connection life cycle and some design features of an HFP
device and its audio driver.
HFP Device Startup
HFP Device Connection
HFP Device Removal
Kernel Streaming Considerations
Audio Endpoint Container ID
Management of I2S and SCO Resources
HFP Device Startup
10/23/2019 • 4 minutes to read • Edit Online

The HFP Device startup topic discusses what happens when a Bluetooth hands-free profile (HFP) device arrives in
the audio system.
For each paired HFP device that arrives in the audio system, the Windows HFP driver registers a device interface in
the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS class. The audio driver uses device interface
notifications to stay informed of all instances of the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS
interfaces. The audio driver calls IoRegisterPlugPlayNotification from within its AVStrMiniDevicePostStart driver
routine (or from an equivalent Portcls routine) to register a callback to discover the currently installed HFP devices,
and to be notified of new HFP devices.
When the audio driver calls IoRegisterPlugPlayNotification, the call is made using the following parameters.
EventCategory is set to EventCategoryDeviceInterfaceChange.
EventCategoryFlags is typically set to PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES in
order to receive immediate notifications of existing interfaces. However some alternate audio driver designs
might find existing interfaces through other means.
EventCategoryData is set to GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS.
DriverObject is set to the audio driver’s DriverObject.
CallbackRoutine is set to a routine in the audio driver that will receive the notifications.
The following sections outline the tasks that the audio driver can performs for each registered instance of a paired
HFP device.

Handling interface instances


For each interface instance that is registered in the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS class,
the audio driver must use the following protocol for communication:
When Windows calls the audio driver’s callback routine that was registered when the audio driver called
IoRegisterPlugPlayNotification, Windows passes a symbolic link for the HFP interface, using
DEVICE_INTERFACE_CHANGE_NOTIFICATION.SymbolicLinkName.
When the audio driver calls IoGetDeviceObjectPointer, the driver uses the symbolic link to get the HFP FileObject
and the DeviceObject for the HFP device.
When the audio driver sends IOCTLs to the HFP driver, the driver uses the HFP FileObject and the DeviceObject for
the HFP device.

Retrieving static information


The audio driver can retrieve static information from the HFP driver. For example, the HFP driver can provide the
ksnodetype, the container id and the friendly name of the paired HFP device. The audio driver can use this
information to create and initialize a KS filter or filters representing the paired HFP device. The audio driver uses
IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR to get this information.
The audio driver can also retrieve the Bluetooth address of the paired HFP device. Each paired HFP device has a
unique Bluetooth address, and this can be useful as a unique identifier string. For more information, see Obtaining
Bluetooth Address of HF Device.

Creating, initializing audio-specific filter factory context


To create and initialize an audio-specific filter factory context, the audio driver must store the HFP DeviceObject and
the HFP FileObject in the filter factory context, and then initialize the IsConnected field to false.

Creating the KS filter factory


For each device instance in the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interface class, the audio
driver creates and enables one or more filter factories.
If the audio driver is an AVStream driver, the audio driver calls KsCreateFilterFactory to add the new filter factory
and KsFilterFactorySetDeviceClassesState to enable the factory. If the audio driver is a PortCls driver, then it
indirectly creates and enables KS filter factories by calling PcRegisterSubdevice. For many PortCls audio driver
designs, there are two sub-devices registered for a given paired HFP device.
Each filter factory (or, for PortCls audio drivers, each pair of filter factories) represents the audio functionality of a
single paired HFP device. The audio driver creates separate filter factories for each paired HFP device represented
by unique instances of GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interfaces. For each paired HFP
device, the audio driver must use unique strings for the RefString parameter of KsCreateFilterFactory, or the Name
parameter of PcRegisterSubdevice. The driver developer might find it useful to use the paired HFP device’s
Bluetooth address string as a unique string. See Obtaining Bluetooth Address of HF Device for information about
how to retrieve the unique string.
Note that there is no specific maximum number of possible paired HFP devices, so the audio driver should avoid
hard coding specific limitations. Instead, the audio driver must correctly handle dynamic arrival and removal of
multiple GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interfaces.
As a practical matter, however, a PortCls driver must specify a maximum number of sub-devices when it calls
PcAddAdapterDevice. PcAddAdapterDevice pre-allocates extra memory for each potential sub-device. The audio
driver developer should select a number high enough to accommodate many paired devices, but at the same time
select a number that doesn't result in a waste of resources. For example, supporting only 2 HFP devices might be
inadequate, and supporting 2000 would certainly result in overextended resources. However, supporting 16 is
likely to be reasonable.
If at runtime the audio driver is notified of another GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS
interface, but has already registered its maximum number of sub-devices, then the audio driver can invoke some
algorithm to choose a paired HFP device whose sub-devices it can unregister to make room for the new HFP
device. For example, the audio driver could keep track of the HFP device with the oldest connection. Whereas a
simpler but perhaps less user-friendly audio driver could simply ignore additional
GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interface after reaching its maximum.

Sending the get connection status IOCTL


The audio driver sends the get connection status IOCTL to get information about any changes that have occurred in
the connection.

Sending the get volume status IOCTL


The audio driver sends the get volume status IOCTL to get information about any changes in volume level that
have occurred in the volume status of the headset.

Related topics
IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR
Theory of Operation
Obtaining Bluetooth Address of HF Device
HFP Device Connection
10/23/2019 • 3 minutes to read • Edit Online

The HFP Device connection topic discusses how the audio system determines and handles connection status
information for a Bluetooth hands-free profile (HFP) device.
As required for all audio drivers, the audio driver must support KSPROPERTY_JACK_DESCRIPTION . The audio
driver maintains an IsConnected field in the filter factory context. The audio driver uses this value when handling
the KSPROPERTY_JACK_DESCRIPTION property.
When IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE completes successfully, then the audio
driver updates IsConnected with the new connection status. If the status has changed, the audio driver raises the
KSEVENT_PINCAPS_JACKINFOCHANGE event, which causes the audio system to reevaluate the connection
state. The audio driver then calls another instance of
IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE to receive the next status change. If there is an
earlier status change request that is still pending, then this second call will fail, the audio driver doesn't update its
connection status, and doesn't make another request for status change information.
As discussed in Kernel Streaming Considerations, the audio driver must support
KSPROPERTY_ONESHOT_RECONNECT and KSPROPERTY_ONESHOT_DISCONNECT , and the handlers for
these properties must send REQUESTCONNECT and REQUESTDISCONNECT IOCTLs respectively, to the HFP driver.
These IOCTLs complete quickly, and the audio driver needs to be ready to respond to the returned results.
Here are some other Bluetooth audio device connection-related factors that the audio driver developer must be
aware of.

Stream channel
The Stream Channel represents the audio driver’s allocation of over-the-air bandwidth. For the most part, this is the
SCO channel. However, some of the details of managing the SCO channel status are handled entirely within the
HFP driver. This includes for example remote disconnects which may be due to call scenarios where the HF initiates
an audio transfer to the AG (where the PC plays the role of the AG in this case).

Audio filter pin states


The audio driver implements a KS pin state handlers (similar to AVStrMiniPinSetDeviceState) for two KS pins. The
SCO stream channel is required for either of these pins to transfer data over the air. When either of these pins
transitions to KSSTATE_ACQUIRE, the audio driver opens the channel by sending
IOCTL_BTHHFP_STREAM_OPEN to the HFP driver. This is an asynchronous call and may take several seconds to
complete. The audio driver does not need to implement its own timeout mechanism and should wait for the IOCTL
to complete before completing the transition to KSSTATE_ACQUIRE.
When both KS pins transition to KSSTATE_STOP, the audio driver sends IOCTL_BTHHFP_STREAM_CLOSE to the
HFP driver. This completes quickly.
To determine when to send IOCTL_BTHHFP_STREAM_OPEN and IOCTL_BTHHFP_STREAM_CLOSE , the audio
driver can use a simple reference counting mechanism to track the number of pins that require the SCO stream
channel. The audio driver would open and close the SCO stream channel when the reference count changes from 0
to 1.
On IOCTL_BTHHFP_STREAM_OPEN , the HFP driver requests an SCO channel, if one is not already open, and
completes the request with the results from the SCO request. On IOCTL_BTHHFP_STREAM_CLOSE the HFP
driver requests a SCO channel disconnect, if one is open.

Remote SCO connect and disconnect


On a remote SCO disconnect, if the Stream Channel is closed, the HFP driver does nothing. If the Stream Channel is
opened the HFP driver will start a reconnect timer. When the timer expires, if SCO is still disconnected and Stream
Channel is still open then the driver will request a SCO channel. Note that no audio data transfers over the air while
SCO is disconnected so there will be a gap in audio during this period. If the SCO request fails then the HFP driver
will signal a Stream Channel status change to the audio driver by completing any invoking
IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE . This should be rare, as remote SCO disconnect is normally
associated with the HF device requesting transfer of call audio to the audio gateway. The audio driver should
consider this a mid-stream error condition.
This procedure allows time for a VoIP application to receive an audio transfer callback from the CallButtons API and
cleanly release its audio resources on the HFP endpoint, instead of causing streaming errors.
On a remote SCO connect, if the Stream Channel is open the driver simply accepts the connection. If the Stream
Channel is closed, then the HFP driver accepts the connection and also starts a disconnect timer. When the
disconnect timer expires, if SCO is still connected and the Stream channel is still closed, then the driver will break
the SCO connection.
This procedure allows time for a VoIP application to receive an audio transfer callback from the CallButtons API and
establish audio resources on the HFP endpoint, without prematurely rejecting or closing the SCO connection.

Related topics
Theory of Operation
HFP Device Removal
12/5/2018 • 2 minutes to read • Edit Online

The HFP device removal topic discusses what happens when a Bluetooth hands-free profile (HFP) device is
removed from (leaves) the audio system.
To remove the registered device interface for a paired HFP device, the audio driver:
1. Cancels any pending IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE IOCTLs.
2. Cancels any pending IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE IOCTLs.
3. Cancels any pending IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE IOCTLs.
4. De-references the HFP FileObject (which also de-references the DeviceObject).
5. Calls KsDeleteFilterFactory to remove the filter factory that represents the HFP device associated with the
removed interface.

Related topics
Theory of Operation
Kernel Streaming Considerations
10/23/2019 • 3 minutes to read • Edit Online

The Kernel Streaming considerations topic clarifies the requirements and other special considerations beyond
those for all audio drivers. These are kernel streaming considerations that are more related to Bluetooth bypass
audio streaming.
The audio driver should fully support the WaveRT port driver, including “pull mode.” For more information, see
Introducing the WaveRT Port Driver. And although there is no requirement to implement a hardware audio engine
for the synchronous connection oriented (SCO) bypass output, there is no harm in doing so.
The Windows logo requirements for format support include an exception for Bluetooth.
The audio driver should support the formats that are possible through the sideband hardware. This is typically
8KHz mono audio streaming.

Topology
All Bluetooth Hands-Free devices support both capture and render. So the audio driver should expose a kernel
streaming (KS) topology for the Hands-Free device as shown in the following diagram, to support both render and
capture.

Note The audio driver developer can choose whether or not to implement a single filter for both capture and
render paths, or separate filters. However, the HFP device only allows a single file object on the
GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS device interface. Therefore a design that uses two filters
needs to allow both filters to share the single file object.
The DAC and ADC nodes represent the analog/digital conversions, but do not support any KS properties.
The volume nodes support KSPROPERTY_AUDIO_VOLUMELEVEL and KSEVENT_CONTROL_CHANGE by
sending the SETVOLUME and GETVOLUMESTATUSUPDATE IOCTLs to the HFP driver.
The volume node should be implemented as follows:
If the Bluetooth headset supports volume control, then the audio driver should include a volume node in its
KS topology. The audio driver's volume property handlers send the above IOCLTs to the Bluetooth HFP
driver to handle the volume.
If the Bluetooth headset does not implement a hardware volume, and the codec (or DSP) has a hardware
volume, the audio driver should handle the volume control on the codec (or DSP).
If the Bluetooth headset and the audio device do not have hardware volume controls, no volume node
should be presented and Windows will insert a software volume control node.
The mute node is optional. The audio driver should implement the mute node, if and only if the DSP or audio codec
provides the capability to mute the bypass PCM signal before passing it to the Bluetooth controller. The mute
nodes support KSPROPERTY_AUDIO_MUTE .

Property requests
The audio driver uses the following KS properties to obtain information about any audio jack or jacks in the audio
path. And the audio driver can also use the appropriate property request to make or break a connection to any
Bluetooth audio device in the audio path.
KSPROPERTY_JACK_DESCRIPTION
This property returns a KSJACK_DESCRIPTION structure. The audio driver should set the
KSPROPERTY_JACK_DESCRIPTION fields as follows. ChannelMapping = KSAUDIO_SPEAKER_MONO Color = 0
ConnectionType = eConnTypeOtherDigital GeoLocation = eGeoLocNotApplicable GenLocation = eGenLocOther
PortConnection = ePortConnUnknown IsConnected = <BOOL for current connection status>
KSPROPERTY_JACK_DESCRIPTION2
This property returns a KSJACK_DESCRIPTION2 structure. The audio driver should set the
KSPROPERTY_JACK_DESCRIPTION2 fields as follows. DeviceStateInfo = 0 JackCapabilities =
JACKDESC2_PRESENCE_DETECT_CAPABILITY KSPROPERTY_ONESHOT_RECONNECT
The audio driver’s filter should support KSPROPERTY_ONESHOT_RECONNECT . To create and initialize this
structure, the audio driver sends IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT to the HFP driver. The HFP
driver completes this request, and then attempts to connect to the Bluetooth audio device asynchronously.
KSPROPERTY_ONESHOT_DISCONNECT
The audio driver’s filter should support KSPROPERTY_ONESHOT_DISCONNECT . To create and initialize this
structure, the audio driver sends IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT to the HFP driver. The HFP
driver completes this request, and then attempts to disconnect from the Bluetooth audio device asynchronously.
When an audio driver supports these properties, the Sound dialog box in the Control Panel exposes Connect and
Disconnect commands for the HFP endpoint.

Related topics
Theory of Operation
Audio Endpoint Container ID
6/25/2019 • 2 minutes to read • Edit Online

The Audio Endpoint Container ID topic discusses the reliable methods available for obtaining the container ID of an
audio endpoint associated with a Bluetooth audio device.
The audio endpoint builder uses an enumeration algorithm to determine the container IDs of audio endpoints, and
then stores these IDs as properties in the MMDEVAPI endpoint property store. In certain cases, the logic used by
the endpoint builder is not sufficient to handle Bluetooth I2S designs where the container ID of an audio endpoint
exposed by the audio driver is determined by another enumerator - the Bluetooth enumerator.
This scenario involving a Bluetooth I2S design that uses its own Bluetooth enumerator is rare. But regardless, you
can develop your audio driver to provide support for such a scenario. In this case, your audio driver can support a
new container ID property for endpoints. The new property is KSPROPERTY_JACK_CONTAINERID and it's been
added to the existing KSPROPSETID_Jack property set. The value is a GUID, which is the data type for a container ID.
An audio driver supports KSPROPERTY_JACK_CONTAINERID , if and only if, it can reliably obtain the correct
container ID through some other means; For example, from a Bluetooth enumerator.
If your audio driver supports the KSPROPERTY_JACK_CONTAINERID property, the audio system reads this
property's value from the driver, and then stores the value as the container ID for the audio endpoint.
For more information about container IDs and about the algorithm mentioned in the preceding section, see
Container ID and Audio Endpoint Builder Algorithm.

Related topics
Theory of Operation
Management of I2S and SCO Resources
12/5/2018 • 2 minutes to read • Edit Online

The Management of I2S and SCO Resources topic discusses the assumptions that were made in the design of this
new support for Bluetooth bypass audio streaming in Windows 8.1.
At this time Windows assumes that there is only one Bluetooth host controller. And also, the HFP synchronous
connection oriented (SCO) bypass support assumes that there is only one bypass connection and that, any channel
opened through the HFP device driver interface is associated with that single connection.
Audio drivers should arbitrate this channel and the single bypass connection for a single consumer on a first-come
first-serve basis. The simplest way to achieve this is for the driver to allow only a single filter to transition its pins to
the ACQUIRE state.

Related topics
Theory of Operation
Bluetooth Bypass DDI Reference
6/25/2019 • 2 minutes to read • Edit Online

The Bluetooth bypass device driver interface (DDI) reference is a set of topics that show the structures and IOCTLs
introduced with Windows 8.1 to provide support for a Bluetooth Hands-free profile (HFP) driver.
For detailed information about the DDI members, see Bluetooth HFP DDI Reference.

Related topics
Theory of Operation
Related Design Guidelines
12/5/2018 • 2 minutes to read • Edit Online

The topics in the Related Design Guidelines section show how a port class audio driver and the audio driver for a
Bluetooth Hands-free device can set device-related values and register audio processing objects.
This section contains the following topics.
Setting Properties and Registry Values
Setting Friendly Names, Registering APOs
Obtaining Bluetooth Address of HF Device
Setting Properties and Registry Values
12/5/2018 • 2 minutes to read • Edit Online

The Setting Properties and Registry Values topic describes how a Port Class audio driver can set properties and
registry values for a PnP device interface.
The port class audio driver, Portcls must perform the following steps to properly register the device interface and
set required values.

1. Register the device interface


Before calling PcRegisterSubdevice for the sub-device, the driver can directly call IoRegisterDeviceInterface to
register the KSCATEGORY_AUDIO interface. This gives the driver a chance to set interface properties and registry
values on the device interfaces before PcRegisterSubdevice registers and enables the interfaces.
The audio driver sets the parameters for IoRegisterDeviceInterface as follows.
The PhysicalDeviceObject parameter is the PDEVICE_OBJECT that the audio driver can retrieve from the
PcGetPhysicalDeviceObject function.
The InterfaceClassGuid is set to the interface’s class GUID.
The ReferenceString is the same as the Name parameter that the audio driver passes to
PcRegisterSubdevice.
After the preceding tasks are completed successfully, IoRegisterDeviceInterface returns a SymbolicLinkName for
the registered interface.

2. Set registry values


The audio driver calls IoOpenDeviceInterfaceRegistryKey to obtain a handle to the device interface registry key. The
audio driver sets the parameters to IoOpenDeviceInterfaceRegistryKey as follows.
The SymbolicLinkName is the string returned from IoRegisterDeviceInterface in the previous step.
The DesiredAccess is set to KEY_WRITE (or other values if needed by the driver).
After the preceding steps are completed successfully, DeviceInterfaceKey returns the opened registry key handle.
The audio driver:
Calls ZwSetValueKey to set registry values
Closes the registry key handle by calling ZwClose
Note If the driver needs to set values in a registry subkey, then the driver calls ZwCreateKey to create the subkey.
When preparing to call ZwCreateKey, the driver:
Calls InitializeObjectAttributes, and sets the ObjectName to the subkey path
Sets Attributes to OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE
Sets RootDirectory to the handle returned by IoOpenDeviceInterfaceRegistryKey
Calls ZwClose to close any handle created by calling ZwCreateKey
3. Set properties
The audio driver calls IoSetDeviceInterfacePropertyData to set properties. The audio driver sets the parameters to
IoSetDeviceInterfacePropertyData as follows:
The SymbolicLinkName is the string returned from IoRegisterDeviceInterface.
The remaining parameters depend on the specific property being set.

Related topics
Related Design Guidelines
Setting Friendly Names, Registering APOs
10/23/2019 • 2 minutes to read • Edit Online

The Setting Friendly Names, Registering APOs topic describes how a Port Class Bluetooth sideband audio driver
can set the friendly name for a device interface, and register any audio processing object (APO) that is used by the
Bluetooth device.
For each enabled GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS interface, the Port Class audio driver
(PortCls) normally calls the PcRegisterSubdevice function, which registers PnP device interfaces that represent a
sub-device on an audio adapter. In typical audio driver designs, the audio driver calls PcRegisterSubdevice for
“wave” and “topology” sub-devices, which are then connected by calling other Port Class functions.
Before calling PcRegisterSubdevice for the “topology” sub-device, the driver follows the procedure described in
Setting Properties and Registry Values to set properties and registry values on the interface in the
KSCATEGORY_AUDIO interface class. The specific properties and registry values are described in the following
sections.

DEVPKEY_DeviceInterface_FriendlyName
The audio driver sends an IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR request to the Hands-free profile (HFP)
audio driver. The requested information is returned in the form of a BTHHFP_DESCRIPTOR structure, plus an
other data referenced by the structure. The audio driver then calls IoSetDeviceInterfacePropertyData to set
DEVPKEY_DeviceInterface_FriendlyName to the value in the FriendlyName field of the BTHHFP_DESCRIPTOR
structure.
The audio driver sets the parameters to IoSetDeviceInterfacePropertyData as follows:
SymbolicLinkName = the string returned from IoRegisterDeviceInterface
PropertyKey = DEVPKEY_DeviceInterface_FriendlyName
Lcid = LOCALE_NEUTRAL
Flags = PLUGPLAY_PROPERTY_PERSISTENT
Type = DEVPROP_TYPE_STRING_INDIRECT
Size = BTHHFP_DESCRIPTOR.FriendlyName.Length + sizeof(UNICODE_NULL)
Data = BTHHFP_DESCRIPTOR.FriendlyName.Buffer

APO registration
As described in Setting Properties and Registry Values, the driver can set registry values for a device interface. To
register an APO, the audio driver sets several values on the device interface. These values are the same as those
that are often set for APO registration in an INF, and the specific values will change from one audio driver to the
next.
Here is an example of INF file syntax for registering an APO:

HKR,"EPFX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
HKR,"EPFX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_DISCOVER_EFFECTS_APO_CLSID%
Note The syntax shown in the preceding snippet doesn't include instructions for registering the COM server of the
APO.

Related topics
Related Design Guidelines
Obtaining Bluetooth Address of HF Device
12/5/2018 • 2 minutes to read • Edit Online

The Obtaining Bluetooth Address of HF Device topic demonstrate how the audio driver can obtain the Bluetooth
address of a paired Hands-free (HF) device.
The address string can be useful for uniquely identifying a particular paired HF device. For example, the address
string can be used as the ReferenceString parameter that is passed to IoRegisterDeviceInterface, the RefString
parameter that is passed to KsCreateFilterFactory, or the Name parameter that is passed to PcRegisterSubdevice.
Note that the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS device interface symbolic link is also
unique for each paired HF device, but this string can be too long for some purposes.
The IoHelperGetDevicePdo routine shown in the following code example is a utility function used by
IoHelperGetDeviceBluetoothAddress. Such functions can be called while the audio driver is handling a PnP
interface arrival notification. The audio driver gets the device object from IoGetDeviceObjectPointer and passes it
to IoHelperGetDeviceBluetoothAddress.

_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
IoHelperGetDevicePdo(
_In_ PDEVICE_OBJECT DeviceObject,
_Out_ PDEVICE_OBJECT *PhysicalDeviceObject
)

/*++

Routine description:
Returns a pointer to the physical device object in a driver stack and
increments the reference count on that object.

Parameters:
DeviceObject
Pointer to the device object for which the physical device object is
retrieved.

PhysicalDeviceObject
Returns a pointer to the physical device object in a stack of device
objects after incrementing the reference count on the object.

Return value:
A status code.

Remarks:
This routine uses IRP_MN_QUERY_DEVICE_RELATIONS TargetDeviceRelation to
get the physical device object from the device stack.

Requirements:
IRQL = PASSIVE_LEVEL

--*/

{
NTSTATUS status;
PIRP irp = NULL;
PDEVICE_RELATIONS deviceRelations = NULL;
PIO_STACK_LOCATION ioStack;
KEVENT completionEvent;

PAGED_CODE();
PAGED_CODE();

irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);


if (irp == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

ioStack = IoGetNextIrpStackLocation(irp);
ioStack->MajorFunction = IRP_MJ_PNP;
ioStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
ioStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;

KeInitializeEvent(&completionEvent, SynchronizationEvent, FALSE);

IoSetCompletionRoutine(irp, OnRequestComplete, &completionEvent, TRUE, TRUE, TRUE);

status = IoCallDriver(DeviceObject, irp);


if (status == STATUS_PENDING) {
// wait for irp to complete
KeWaitForSingleObject(
&completionEvent,
Suspended,
KernelMode,
FALSE,
NULL);
status = irp->IoStatus.Status;
}

if (NT_SUCCESS(status))
{
deviceRelations = (PDEVICE_RELATIONS)irp->IoStatus.Information;
*PhysicalDeviceObject = deviceRelations->Objects[0];
}

Exit:
if (deviceRelations != NULL)
{
ExFreePool(deviceRelations);
}
if (irp != NULL)
{
IoFreeIrp(irp);
}
return status;
}

_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS IoHelperGetDeviceBluetoothAddress(
_In_ PDEVICE_OBJECT DeviceObject,
_Outptr_ PWSTR *BluetoothAddress,
_In_ ULONG Tag
)

/*++

Routine description:
Returns the Bluetooth address string for the physical device object in the
device stack.

Parameters:
DeviceObject
Pointer to a device object in a device stack whose physical object has
a Bluetooth address property.

BluetoothAddress
Returns a string allocated from NonPagedPoolNx pool.
Returns a string allocated from NonPagedPoolNx pool.

Tag

Return value:
A status code.

Remarks:
This routine retrieves the DEVPKEY_Bluetooth_DeviceAddress property from
the physical device object in the device stack containing the specified
device object.

Requirements:
IRQL = PASSIVE_LEVEL

--*/

{
NTSTATUS status;
PDEVICE_OBJECT physicalDeviceObject = NULL;
PWSTR bluetoothAddress = NULL;
ULONG requiredSize;
DEVPROPTYPE devPropType;

PAGED_CODE();

status = IoHelperGetDevicePdo(DeviceObject, &physicalDeviceObject);


if (!NT_SUCCESS(status))
{
goto Exit;
}

status = IoGetDevicePropertyData(physicalDeviceObject, &DEVPKEY_Bluetooth_DeviceAddress, LOCALE_NEUTRAL,


0, 0, NULL, &requiredSize, &devPropType);
if (NT_SUCCESS(status) || devPropType != DEVPROP_TYPE_STRING)
{
status = STATUS_UNSUCCESSFUL;
goto Exit;
}
if (status != STATUS_BUFFER_TOO_SMALL)
{
goto Exit;
}

bluetoothAddress = (PWCH)ExAllocatePoolWithTag(NonPagedPoolNx, requiredSize, Tag);


if (bluetoothAddress == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

status = IoGetDevicePropertyData(physicalDeviceObject, &DEVPKEY_Bluetooth_DeviceAddress, LOCALE_NEUTRAL,


0, requiredSize, bluetoothAddress, &requiredSize, &devPropType);
if (!NT_SUCCESS(status))
{
goto Exit;
}

*BluetoothAddress = bluetoothAddress;
bluetoothAddress = NULL;
status = STATUS_SUCCESS;

Exit:
if (bluetoothAddress != NULL)
{
ExFreePoolWithTag(bluetoothAddress, Tag);
}
if (physicalDeviceObject != NULL)
{
ObDereferenceObject(physicalDeviceObject);
ObDereferenceObject(physicalDeviceObject);
}
return status;
}

Related topics
Related Design Guidelines
Hardware-Offloaded Audio Processing
12/5/2018 • 2 minutes to read • Edit Online

Hardware-offloaded audio processing allows the main audio processing tasks to be performed outside the
computer's main CPU.
Audio processing can be very computationally intensive. So in many scenarios, it may be beneficial to allow a
dedicated processor to take care of processing tasks like, for example, mixing, and applying effects. But Windows 7
and earlier versions of Windows did not provide support for hardware-offloaded audio processing.
With Windows 8 and later operating systems, the audio driver model has been updated to provide support for
hardware-offloaded audio processing, and the following sections provide information about how to develop an
audio driver that can expose its ability to handle offloaded audio for processing.
Architectural Overview
Driver Implementation for Offloaded Audio
PortCls Power Management Updates for SoC
Architectural Overview
12/5/2018 • 3 minutes to read • Edit Online

This topic provides an overview of the audio architecture that was introduced in Windows 8, to provide support for
a combined hardware/software audio engine.

The software audio engine


The audio engine in Windows 7 and some earlier versions of Windows, supported a software audio engine that
allowed third-party developers to plug in software decoders, encoders, and other generic audio effects at specific
points in the processing pipeline.
The following diagram shows the Windows 8 software audio engine.

As you can see in the preceding diagram, audio streams arrive in the software audio engine from the Windows
audio session API (WASAPI) layer, and possibly through a higher-level API such as Media Foundation. In the
software audio engine local effects (LFX), like volume control and muting are applied on a per-stream basis before
the separate streams are mixed, and then passed through any available global effects (GFX) and sent to the
speakers.

The hardware audio engine


The hardware audio engine is implemented in the audio adapter, and largely mirrors the functionality of the
software audio engine. And although Windows 8 supports hardware-offloaded audio processing, the audio driver
for a given audio adapter is responsible for exposing the underlying capabilities of the audio hardware, using the
topology shown in the following diagram.
As shown in the diagram, the hardware audio engine must accept a single host process stream and up to n
offloaded streams. These offloaded streams are routed directly from the application layer to be processed in
hardware. In other words, the offloaded streams will not be passed through the software audio engine. The
diagram shows an implementation that was designed to handle up to three offloaded streams. The host process
stream is the final output from the software mixer of all the streams that were processed in the software audio
engine. Each hardware audio engine must also contain a hardware mixer.
In order to maintain parity with the software audio engine and the WASAPI interface, it is necessary for the
hardware audio engine to provide the final audio output stream back to the audio stack in the form of a loopback
stream. This is especially critical for applications and scenarios that rely on Acoustic Echo Cancellation, which
requires knowledge of the final output stream to cancel echoes and prevent feedback.
In order to implement a path for a loopback stream, the audio driver is responsible for exposing a loopback pin.
This pin will return the audio data from the final audio engine output, if the data is encoded to a PCM format.
Otherwise, the post-mixing (but pre-encoding) result will be returned. This means that in the case of audio data
that is processed with a hardware GFX that encodes to a non-PCM format, the loopback stream is taken directly
after the hardware mixer, before the GFX stage in the hardware audio engine. For information about the new KS-
filter topology that represents the hardware audio engine, see Implementation Overview.

The overall architecture


The following diagram shows an overview of the resulting architecture when a hardware audio engine works in
concert with the Windows 8 software audio engine.
This means that in a scenario where the audio driver has indicated its support for offloaded audio processing, the
first n (in this case, three) streams that are initialized will be routed directly from the WASAPI layer to the hardware
audio engine, bypassing the software audio engine. Any new audio streams subsequent to the n supported by the
hardware audio engine will be routed through the software audio engine for processing. The resulting stream from
the software audio engine is then sent to the hardware audio engine as a host process stream. The host process
stream is mixed with the first n streams, GFX processing is applied, and the resulting stream is then sent to the
speakers.
Note In general, GFX processing is applied before volume adjustment. But there is an exception in cases where the
GFX is encoded to a non-PCM format; in this case the GFX/volume control order is reversed so that volume control
can be applied to uncompressed data before GFX processing takes place. The Windows 7 software audio engine
follows the same model.
Driver Implementation for Offloaded Audio
12/5/2018 • 2 minutes to read • Edit Online

When you implement a driver for offloaded audio, you develop a driver that is able to process offloaded audio
streams, and to expose that ability to the Windows audio system.
The following topics in this section discuss the UI considerations, the application impact and other issues that you
should be aware of when you develop an audio driver for an audio adapter that implements a hardware audio
engine to handle offloaded audio streams.
Implementation Overview
Driver Implementation Details
Helper Interfaces for Offloaded Audio Processing
Glitch Reporting for Offloaded Audio
Implementation Overview
6/25/2019 • 3 minutes to read • Edit Online

This topic is an overview of the implementation key points that you must be aware of, when you develop a driver
for an audio adapter that is capable of processing hardware-offloaded audio streams.

The New KS Filter Topology


In Windows 8 and later operating systems, support has been provided for a new type of audio adapter that can use
an on-board hardware audio engine to process audio streams. When you develop such an audio adapter, the
associated audio driver must expose this fact to the user mode audio system in a specific manner, so that the audio
system can discover, use and properly expose the features of this adapter and its driver.
To make it possible for audio drivers to expose the hardware capabilities of these new audio adapters, Windows 8
introduces a new KS-filter topology that the driver must use:

As you can see in the preceding figure, a KS-filter topology represents the data paths through the hardware, and
also shows the functions that are available on those paths. In the case of an audio adapter that can process
offloaded audio, there are the following inputs and outputs (called pins) on the KS-filter:
One Host Process pin. This represents the input into the KS-filter from the software audio engine.
One Loopback pin. This represents an output from the hardware audio engine to the Windows audio
session API (WASAPI) layer.
A number of Offloaded-audio pins. Although the figure shows only one pin of this type, an IHV is free to
implement any number (n) of pins.
For more information about the pins in this new type of KS-filter topology, see Architectural Overview. The actual
service in the user mode audio system that "leads" to the discovery of the audio adapter and its driver, is the
AudioEndpointBuilder. The AudioEndpointBuilder service monitors the KSCATEGORY_AUDIO class for device
interface arrivals and removals. When an audio device driver registers a new instance of the
KSCATEGORY_AUDIO device interface class, a device interface arrival notification is fired off. The
AudioEndpointBuilder service detects the device interface arrival notification and uses an algorithm to examine the
topology of the audio devices in the system so that it can take appropriate action.
So when you develop your audio driver to support an adapter that is capable of processing offloaded-audio, your
driver must use the newly-defined KSNODETYPE_AUDIO_ENGINE audio endpoint to expose the capabilities of
the hardware audio engine. For more information about the audio endpoint discovery process, see Audio Endpoint
Builder Algorithm.
User Interface Considerations
You developed your audio driver to control the underlying hardware capabilities of an audio adapter that is
capable of processing offloaded-audio. This means that your driver has the best knowledge about how to control
the adapter's features. So you must develop a UI that will expose the features of the adapter to the end user in the
form of options that they can select, enable and/or disable.
If however, you already have a UI that is used for controlling audio processing objects (APOs) that you developed,
this UI could be extended to work with your new audio adapter. In this case, your extensions to the UI would
provide software control for the APOs, and hardware control for the adapter.

Application Impact
The functionality described for this new type of audio adapter and its associated driver, can be used by UWP apps
via WASAPI, Media Foundation, Media Engine, or the HTML 5 <audio> tags. Note that Wave and DSound cannot
be used, as they are not available to UWP apps. Also note that Desktop applications cannot use the offloading
capabilities of audio adapters that support hardware-offloaded audio. These applications can still render audio, but
only through the host pin which makes use of the software audio engine.
If a UWP app streams media content and uses Media Foundation, Media Engine, or the HTML 5 <audio> tags, the
app is automatically opted-in for hardware offloading as long as the proper audio category has been set for the
stream. Opting-in for hardware offloading is done on a per stream basis.
UWP apps that use WASAPI or streaming communications have to explicitly opt-in for hardware offloading.
Driver Implementation Details
6/25/2019 • 2 minutes to read • Edit Online

This topic presents the implementation details for an audio driver that is developed for an audio adapter that is
capable of processing hardware-offloaded audio streams.
In other words, this topic explains what Microsoft has done (starting with Windows 8) to support a driver that
works with an audio adapter that is capable of processing hardware-offloaded audio. In the following sections, this
topic also shows you what the driver must be capable of to support such an adapter.

A new Type GUID for node descriptors


If an audio adapter is capable of processing offloaded audio streams, the adapter’s audio driver exposes this
capability by using a newly introduced node in the KS-filter for the adapter.
Each node in the path of the audio stream has a node descriptor, so for this new node the driver must set the Type
GUID to KSNODETYPE_AUDIO_ENGINE . Here’s an example of how the driver could configure the node
descriptor for this new node:

typedef struct _KSNODE_DESCRIPTOR {


const KSAUTOMATION_TABLE *AutomationTable; // drv specific
const GUID *Type; // must be set to KSNODETYPE_AUDIO_ENGINE
const GUID *Name; // drv specific (KSNODETYPE_AUDIO_ENGINE?)
} KSNODE_DESCRIPTOR, *PKSNODE_DESCRIPTOR;

If the Name GUID is set to KSNODETYPE_AUDIO_ENGINE , then you must create a default name string for this
node. You then add that string to ks.inf, so that during installation of the driver, the string can be used to populate
the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MediaCategories registry key.
The definition of the GUID for the new node type, KSNODETYPE_AUDIO_ENGINE , is as follows:

Code style
#define STATIC_KSNODETYPE_AUDIO_ENGINE\
0x35caf6e4, 0xf3b3, 0x4168, 0xbb, 0x4b, 0x55, 0xe7, 0x7a, 0x46, 0x1c, 0x7e
DEFINE_GUIDSTRUCT("35CAF6E4-F3B3-4168-BB4B-55E77A461C7E", KSNODETYPE_AUDIO_ENGINE);
#define KSNODETYPE_AUDIO_ENGINE DEFINE_GUIDNAMED(KSNODETYPE_AUDIO_ENGINE)

For more information, see the ksmedia.h header file.


And based on the preceding information, a descriptor for a miniport node could look like the following:

PCNODE_DESCRIPTOR MiniportNodes[] =
{
// KSNODE_WAVE_AUDIO_ENGINE
{
0, // Flags
NULL, // AutomationTable
&KSNODETYPE_AUDIO_ENGINE, // Type KSNODETYPE_AUDIO_ENGINE
NULL // Name
}
};
A new KS property set for audio engines
Starting with Windows 8, the KSPROPSETID_AudioEngine property set has been introduced to support hardware
audio engines and hardware-offloaded audio processing. So the driver for an adapter that can process offloaded
audio streams must support the properties in this new property set.
The new property set, KSPROPSETID_AudioEngine , is defined as follows:

#define STATIC_KSPROPSETID_AudioEngine\
0x3A2F82DCL, 0x886F, 0x4BAA, 0x9E, 0xB4, 0x8, 0x2B, 0x90, 0x25, 0xC5, 0x36
DEFINE_GUIDSTRUCT("3A2F82DC-886F-4BAA-9EB4-082B9025C536", KSPROPSETID_AudioEngine);
#define KSPROPSETID_AudioEngine DEFINE_GUIDNAMED(KSPROPSETID_AudioEngine)

The names of the properties in this new property set are defined in the KSPROPERTY_AUDIOENGINE enum, and
the driver must support these names.
Here are the new properties in the KSPROPSETID_AudioEngine property set:
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
KSPROPERTY_AUDIOENGINE_DESCRIPTOR
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT
KSPROPERTY_AUDIOENGINE_GFXENABLE
KSPROPERTY_AUDIOENGINE_LFXENABLE
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION
KSPROPERTY_AUDIOENGINE_MIXFORMAT
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL

Updates to the KSPROPSETID_ Audio property set


In addition to supporting the properties in the new KSPROPSETID_AudioEngine property set, the driver must
also support the following existing properties in the KSPROPSETID_Audio property set:
KSPROPERTY_AUDIO_MUTE
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_VOLUMELEVEL
And to complete the implementation of driver support for hardware-offloaded audio processing, new properties
have been added to the KSPROPSETID_ Audio property set.
Here are the new KSPROPSETID_ Audio properties:
KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION
KSPROPERTY_AUDIO_PRESENTATION_POSITION
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION

Port-class driver updates and glitch reporting


In addition to the support described in the preceding sections for hardware-offloaded audio processing, the
Windows port-class driver has also been updated with "helper interfaces" to make it simple to develop a driver
that can work with offloaded audio streams. And when such a driver detects glitches, there is a mechanism in place
to allow the driver to report the glitch errors. The following topics provide more details about the helper interfaces
and glitch reporting:
Helper Interfaces for Offloaded Audio Processing
Glitch Reporting for Offloaded Audio
Helper Interfaces for Offloaded Audio Processing
10/23/2019 • 2 minutes to read • Edit Online

This topic presents the helper interfaces that Microsoft has added to its audio port-class driver (PortCls), to simplify
the implementation of drivers that support offloaded-audio processing.
When you develop your WaveRT miniport driver that will work with an audio adapter that is capable of processing
hardware-offloaded audio streams, your miniport driver works with PortCls to stream and/or process audio data.
PortCls has been updated to handle all the offload-related kernel streaming (KS) properties, and that is what
makes it simple to develop a WaveRT miniport driver to expose support for processing hardware-offloaded audio
streams. As a result of the updates, PortCls only calls the underlying miniport driver for hardware and/or driver-
specific operations via two newly defined interfaces:
IMinipor tAudioEngineNode
IMinipor tStreamAudioEngineNode
You must develop two classes to work with these interfaces, one for each interface.

Working with IMiniportAudioEngineNode


The class that you develop to work with IMinipor tAudioEngineNode , must also inherit from IMiniportWaveRT.
The methods defined in IMinipor tAudioEngineNode allow your driver to use KS properties that access the
audio engine via a KS filter handle. The class/interface hierarchy is as follows:

So if, for example, you develop a class called CYourMiniportWaveRT, then as you can see from the preceding
diagram, CYourMiniportWaveRT must implement all the methods (shown as Operations) defined for the two
parent interfaces.
A skeletal template for such a class would contain the following code:
class CMiniportWaveRT :
public IMiniportWaveRT,
public IMiniportAudioEngineNode,
public CUnknown
{
...

IMP_IMiniportWaveRT;
IMP_IMiniportAudioEngineNode;
...

};

The Portcls.h header file defines these interfaces.

Working with IMiniportStreamAudioEngineNode


The class that you develop to work with the second interface, IMinipor tStreamAudioEngineNode , must also
inherit from IMiniportWaveRTStreamNotification. The methods defined in IMinipor tStreamAudioEngineNode
allow your driver to use KS properties that access the audio engine via a pin instance handle. The class/interface
hierarchy is as follows:

So if, for example, you develop a class called CYourMiniportWaveRTStream, then as you can see from the preceding
diagram, CYourMiniportWaveRTStream must implement all the methods defined for the two parent interfaces.
A skeletal template for such a class would contain the following code:

class CMiniportWaveRTStream :
public IMiniportWaveRTStreamNotification,
public IMiniportStreamAudioEngineNode,
public CUnknown
{
...
IMP_IMiniportWaveRTStream;
IMP_IMiniportWaveRTStreamNotification;
IMP_IMiniportStreamAudioEngineNode;
...

};

The Portcls.h header file defines these interfaces. And for more information about how to develop a driver that can
handle hardware-offloaded audio streams, see Driver Implementation Details.
Glitch Reporting for Offloaded Audio
10/23/2019 • 2 minutes to read • Edit Online

This topic explains the mechanism that an audio driver must use when it has to report glitching errors in
connection with hardware-offloaded audio streams.
When an audio driver detects glitching errors, it must raise an Event Tracing for Windows (ETW) event to report the
errors. This event should include the reason for the glitch, along with information about the DMA buffer in use for
the audio streams.
The following enum shows the events that have been defined for the audio driver to use for glitch error reporting.

typedef enum
{
eMINIPORT_IHV_DEFINED = 0,
eMINIPORT_BUFFER_COMPLETE,
eMINIPORT_PIN_STATE,
eMINIPORT_GET_STREAM_POS,
eMINIPORT_SET_WAVERT_BUFFER_WRITE_POS,
eMINIPORT_GET_PRESENTATION_POS,
eMINIPORT_PROGRAM_DMA,
eMINIPORT_GLITCH_REPORT
} EPcMiniportEngineEvent;

For more information about this enum, see EPcMinipor tEngineEvent .


And for more information about how to develop a driver that can handle hardware-offloaded audio streams, see
Driver Implementation Details.
PortCls Power Management Updates for SoC
12/5/2018 • 2 minutes to read • Edit Online

The following topics discuss the power management updates that have been introduced in Windows 8 in the port-
class driver (PortCls) to support the system-on-a-chip (SoC) platform.
PortCls Registry Power Settings
Immediate Idle Timeout Opt-in
PortCls Private PEP Context Sharing
PortCls D3 Exit Latency Requirement
PortCls Registry Power Settings
1/15/2020 • 2 minutes to read • Edit Online

This topic explains the PortCls registry power settings for Windows 8.
In Windows 8, (PortCls) miniport drivers can use registry values in the driver’s registry key to do the following:
Determine whether or not PortCls enables idle power management
Determine the idle timeout values for battery conservation mode, versus high performance mode
By default, Windows 8 has power settings that PortCls uses to determine whether to register for "device idle"
detection with the power manager, when the runtime power framework indicates that power is no longer required.
The parameters that are used to describe the power setting profile are defined as follows.

REGIST RY VA L UE DATA T Y P E DEFA ULT VA L UE DESC RIP T IO N

ConservationIdleTime REG_BINARY 0 0-second timeout.

IdlePowerState REG_BINARY 3 (D3) Specifies the power state


Valid values: that the device will enter,
when power is no longer
1 - D1 2 - D2 3 - D3 needed.

PerformanceIdleTime REG_BINARY 0 0-second timeout.

The following Windows registry fragment shows the syntax that is used for providing the power setting
information.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96C-E325-11CE-BFC1-
08002BE10318}\0000\PowerSettings]
"ConservationIdleTime"=hex:1e,00,00,00
"PerformanceIdleTime"=hex:00,00,00,00
"IdlePowerState"=hex:03,00,00,00

The preceding fragment shows a hexadecimal (hex) value of "1e" for the ConservationIdleTime, and this equates to
a 30-second idle timeout. The hex value of "0" shown for PerformanceIdleTime means that idle management has
been disabled. And the value of "03" shown for the IdlePowerState means that when power is no longer needed,
the device associated with this power setting profile will enter the D3 power state.
Immediate Idle Timeout Opt-in
10/23/2019 • 2 minutes to read • Edit Online

This topic discusses the ImmediateIdle registry value that a Windows 8 driver can use to opt-in to an immediate
power down state, when power is no longer needed.
In addition to the default power settings discussed in PortCls Registry Power Settings, Windows 8 introduces a new
registry value that is also located in the PowerSettings registry key for the associated driver. For example, if you
have a driver whose key is <UVXYZ>, then the power settings information for the driver would be found in the
following path in the Windows registry:
HKLM\System\CurrentControlSet\Control\Class\{4D36E96C-E325-11CE-BFC1-08002BE10318}\
<UVXYZ>\PowerSettings.
And in addition to the default power setting values shown in PortCls Registry Power Settings, you would also
include the following line for ImmediateIdle:

"ImmediateIdle"=hex:00,00,00,00

ImmediateIdle has a data type of REG_DWORD and its default value is "0" which equates to FALSE. In the preceding
syntax fragment, the hexadecimal value of "0" means that the device will not immediately power down when
power is no longer needed.
For your driver to opt-in to an immediate power down state, when power is no longer needed, you must use the
following syntax:

"ImmediateIdle"=hex:01,00,00,00

In the preceding syntax fragment, the hex value of "1" equates to TRUE, and it means that the device will
immediately power down when power is no longer needed.
When the runtime power management framework invokes a callback for the DevicePowerRequired method,
indicating that the device no longer requires power, PortCls then requests a Device Power IRP for the D-State
indicated by the IdlePowerState registry value. If no state is supplied, then the default value of D3 is used.
If a driver opts-in to immediate idle power management, it must ensure that the Power Engine Plug-in (PEP) for the
system contains the logic needed to prevent unnecessarily and continuously powering the adapter up and down
for IRPs received in immediate succession. Some residency rules should be applied in order to keep the device
powered up for batches of I/O requests.
In addition, the new interface introduced in Windows 7 that allows drivers to programmatically enable or disable
idle power management, continues to be honored when the driver has not opted-in to immediate idle power
management. This is done via the IPor tClsPower ::SetIdlePowerManagement method and would override the
settings in the registry, except for the case in which ImmediateIdle is set to 1 (TRUE).
PortCls Private PEP Context Sharing
10/23/2019 • 2 minutes to read • Edit Online

Starting with Windows 8, a miniport driver can use IPortClsRuntimePower, a new interface, for private context
sharing with the Windows Power Engine Plug-in (PEP).
The audio port class driver (PortCls) has been updated to expose the new interface, IPortClsRuntimePower, on the
WaveRT port. In order for a miniport driver to send private power controls to the operating system's PEP, the
miniport driver first has to gain access to the IPortClsRuntimePower interface of its associated port. The miniport
driver then registers a callback that is invoked at the appropriate time, allowing the miniport driver to send the
private power controls.

Accessing IPortClsRuntimePower
The miniport driver gains access to its port's IPortClsRuntimePower via the following sequence of events:
1. The miniport driver calls PcNewPor t and supplies IID_IPortWaveRT as the REFID.
2. PcNewPor t creates a port interface (Pport) of type IPortWaveRT.
3. The miniport driver then calls QueryInterface in the newly created IPor tWaveRT port interface, and
specifies IID_IPortClsRuntimePower as the interface GUID.
4. The IPor tWaveRT port interface provides the miniport driver with a pointer to its IPor tClsRuntimePower
interface.
The Portcls.h header file defines the GUID for the IPortClsRuntimePower as follows:

// {E057C351-0430-4DBC-B172-C711D40A2373}
DEFINE_GUID(IID_IPortClsRuntimePower,
0xe057c351, 0x430, 0x4dbc, 0xb1, 0x72, 0xc7, 0x11, 0xd4, 0xa, 0x23, 0x73);

Registering a callback
The miniport driver uses the IPor tClsRuntimePower ::RegisterPowerControlCallback method to register a
callback. This method is invoked either when the PEP initiates a private request, or in response to a private request
that is initiated by the miniport driver itself. The callback registration should typically be performed while the driver
is handling the IRP_MN_START_DEVICE PNP Irp.
Aside from the Context pointer that is supplied in the callback, the other parameters are defined identically to the
definitions for the runtime power framework’s PowerControlCallback. Additionally, the miniport’s callback must be
of type PCPFNRUNTIME_POWER_CONTROL_CALLBACK, as defined in the following snippet from the Portcls.h
header file.
typedef
NTSTATUS
_IRQL_requires_max_(DISPATCH_LEVEL)
(*PCPFNRUNTIME_POWER_CONTROL_CALLBACK)
(
_In_ LPCGUID PowerControlCode,
_In_opt_ PVOID InBuffer,
_In_ SIZE_T InBufferSize,
_Out_opt_ PVOID OutBuffer,
_In_ SIZE_T OutBufferSize,
_Out_opt_ PSIZE_T BytesReturned,
_In_opt_ PVOID Context
);

When the driver is stopped or removed, it must use the


IPor tClsRuntimePower ::UnregisterPowerControlCallback method to unregister any registered callbacks.

Sending private power controls


After the miniport establishes access to an IPor tClsRuntimePower interface, and uses the interface's
RegisterPowerControlCallback method to register a callback, it is now ready to send private power controls.
When the callback method is invoked, the miniport driver uses the IPor tClsRuntimePower ::SendPowerControl
method to send the private power controls to the Windows PEP.
With the exception of the DeviceObject parameter, all other parameters are defined identically to those for the
runtime power framework’s PoFxPowerControl method.
PortCls D3 Exit Latency Requirement
10/23/2019 • 2 minutes to read • Edit Online

This topic discusses how the Windows port class driver (PortCls) can use a new Windows 8 interface to manipulate
the exit latency requirement for the D3 sleep state.
When a system enters a platform power state other than fully working (for example, sleep or connected standby),
the required exit latency for the audio adapter to return to D0 (fully working) can be relaxed. This makes it possible
for the audio adapter to use sleep states deeper than D3, even if these deeper states could result in longer exit
latencies (exit times).
PortCls can now use a new power management interface to generate a new D3 exit latency tolerance, and then
communicate it dynamically to the audio miniport driver. These tolerances are represented as PC_EXIT_L ATENCY
enumeration values.
For more information about the new power management interface, see IAdapterPowerManagement3
WDM Audio Platform Differences
6/25/2019 • 2 minutes to read • Edit Online

This section discusses the levels of support for Microsoft Windows Driver Model (WDM) audio drivers that are
provided in the various versions of Windows.
The following topics describe the support for WDM audio in the different Windows releases that are available:
Windows Vista Support for WDM Audio
Additional information about WDM platform differences is available elsewhere in the Windows Driver Kit (WDK)
documentation:
For information about how the support for PortCls functions and interfaces differs among Windows
versions, see PortCls Support by Operating System.
For information about how version numbers for PortCls adapter drivers differ among Windows versions,
see Version Numbers for Audio Drivers.
For information about how the support for WDM drivers in general differs among Windows versions,
including a discussion of floating-point issues for drivers, see Differences in WDM Versions.
Windows Vista Support for WDM Audio
6/25/2019 • 2 minutes to read • Edit Online

Windows Vista supports the following WDM audio capabilities:


WDM version 1.40
All the features that Windows XP supports, with the following exceptions.
Hardware peak meters are supported, except when the Windows Vista mixer API runs in per-application
mode.
Wave and MIDI NT4 drivers function normally, but they are not supported by the new audio user
interface.
AUX devices are not supported, and the auxGetNumDevs function in Mmsystem.h will always return a
count of zero.
Windows NT4-style mixer drivers (DRIVERS32) are not supported.
WDM Audio Components
12/5/2018 • 2 minutes to read • Edit Online

This section describes the system-supplied Microsoft Windows Driver Model (WDM) audio components. These are
software components that are included with the operating system. These components support ISA, PCI, and USB
audio devices and provide the software interfaces through which application programs control and monitor these
devices. The following topics are discussed:
User-Mode WDM Audio Components
Kernel-Mode WDM Audio Components
Wave and DirectSound Components
MIDI and DirectMusic Components
Virtual Audio Devices
User-Mode WDM Audio Components
12/5/2018 • 2 minutes to read • Edit Online

The user-mode Microsoft Windows Driver Model (WDM) audio components are:
WinMM System Component
WDMAud System Driver
DirectSound System Component
DirectMusic System Component
Windows Audio Services
WinMM System Component
The WinMM system components (Winmm.dll and its 16-bit counterpart, Mmsystem.dll) implement the Microsoft
Windows multimedia APIs waveXxx, midiXxx, mixerXxx, and auxXxx (see Microsoft Windows SDK documentation).
The WinMM components use the WDMAud system driver to translate the WinMM API calls into kernel-streaming
I/O requests.
WDMAud System Driver
The user-mode WDMAud system driver (Wdmaud.drv) is paired with the kernel-mode WDMAud system driver
(Wdmaud.sys). Together, the WDMAud system drivers translate between WinMM API calls and kernel-streaming
I/O requests. The kernel-mode mode WDMAud driver is a client of the SysAudio system driver.
DirectSound System Component
The DirectSound system component (Dsound.dll) supports the DirectSound API (see Microsoft Windows SDK
documentation). The DirectSound component is a client of the SysAudio driver. If hardware mixing is available, the
SysAudio driver connects DirectSound hardware buffers directly to the rendering device. Otherwise, the SysAudio
driver connects DirectSound software buffers to the KMixer system driver. For more information, see Rendering
Wave Content Using DirectSound Software and Hardware Buffers.
DirectMusic System Component
The DirectMusic system component (DMusic.dll) supports the DirectMusic API (see Microsoft Windows SDK
documentation). This component converts calls made to the DirectMusic API into I/O requests to WDM audio
devices. The DirectMusic component is a client of the SysAudio system driver.
Windows Audio Services
In Windows XP and later, the Windows Audio Services component (Audiosrv.dll) manages audio devices for
Windows-based programs. Stopping Windows Audio Services prevents audio devices and effects from functioning
properly. If audio services are disabled, any other services (including WDM audio drivers) that explicitly depend on
them will fail to start. In the Home Edition, Professional, and Server versions of Windows XP and later, audio
services are by default configured to start automatically. However, in the Advanced Server, Data Center, and Web
Server versions of Windows Server 2003 and later, audio services are disabled by default. When audio services are
disabled, installing an audio device does not enable them -- audio services are enabled to run automatically only if
an administrator explicitly configures them to do so. For information about starting and stopping Windows
services, see the help file in the Ser vices dialog box (look in the Windows Control Panel under Administrative
Tools ).
Kernel-Mode WDM Audio Components
10/23/2019 • 6 minutes to read • Edit Online

The kernel-mode Microsoft Windows Driver Model (WDM) audio components are:
WDMAud System Driver
SysAudio System Driver
KMixer System Driver
Redbook System Driver
SBEmul System Driver
SWMidi System Driver
DMusic System Driver
AEC System Driver
DRMK System Driver
Splitter System Driver
Port Class Adapter Driver and PortCls System Driver
USB Audio Class System Driver (Usbaudio.sys)
AVCAudio Class System Driver
WDMAud System Driver
The kernel-mode WDMAud system driver (Wdmaud.sys) is paired with the user-mode WDMAud system driver
(Wdmaud.drv). The pair of WDMAud drivers translate between user-mode Microsoft Windows multimedia system
calls and kernel-streaming I/O requests. WDMAud performs I/O for the following APIs: waveIn , waveOut , midiIn ,
midiOut , mixer , and aux (described in the Microsoft Windows SDK documentation). The kernel-mode WDMAud
driver is a kernel streaming (KS) filter and a client of the SysAudio system driver.
SysAudio System Driver
The SysAudio system driver (Sysaudio.sys) builds the filter graphs that render and capture audio content. The
SysAudio driver represents audio filter graphs as virtual audio devices and registers each virtual audio device as
an instance of a KSCATEGORY_AUDIO_DEVICE device interface. (Adapter drivers should not register themselves in
this category, which is reserved exclusively for SysAudio.) For example, a virtual MIDI device might represent a
filter graph that is created by connecting the SWMidi driver, the KMixer driver, and a port/miniport driver. The client
communicates only with the virtual audio device rather than with the individual devices that make up the virtual
audio device. Transparent to the client, the SysAudio driver configures all the KS filters in the filter graph that are
connected together to form the virtual audio device. The following audio stream sources use the graphs that
SysAudio builds:
DirectSound (See Microsoft Windows SDK documentation.)
Windows multimedia APIs waveIn , waveOut , midiIn , midiOut , mixer , and aux (See Windows SDK
documentation.)
Redbook CD digital audio (See Redbook System Driver.)
Sound Blaster emulator (See SBEmul System Driver.)
Kernel-mode software synthesizers (See SWMidi System Driver and DMusic System Driver.)
DRMK System Driver
KMixer System Driver
The KMixer system driver (Kmixer.sys) is the KS filter that does the following:
Mixing of multiple PCM audio streams
High-quality format conversion
Bit-depth conversion
Speaker configuration and channel mapping
In addition to simple 8- and 16-bit, mono and stereo data formats, the KMixer driver supports:
PCM and IEEE floating-point data
Bit depths greater than 16 bits, and multichannel formats with more than two channels
Head-related transfer function (HRTF) 3-D processing
For information about the volume ranges and the default volume levels in the various versions of Windows, see
Default Audio Volume Settings.
Redbook System Driver
The Redbook system driver (Redbook.sys) is the KS filter that manages the rendering of CD digital audio. The
Redbook driver is a client of the SysAudio system driver. The system routes CD digital audio through the file
system to the Redbook driver and then to the SysAudio driver. The CD digital audio is rendered on the preferred
wave output device (as set in the Multimedia property pages in Control Panel).
SBEmul System Driver
The SBEmul system driver (Sbemul.sys) provides Sound Blaster emulation for MS-DOS applications. The SBEmul
driver is a client of the SysAudio system driver. To render and capture content, the SysAudio driver uses the
preferred wave and MIDI devices (as set in the Multimedia property pages in Control Panel).
Sound Blaster emulation is supported only in Windows 98/Me.
SWMidi System Driver
The SWMidi system driver (Swmidi.sys) is the KS filter that provides software-emulated General MIDI (GM) and
high-quality Roland GS wavetable synthesis. A midiOut Xxx application uses SWMidi when a hardware synthesizer
is unavailable. The SWMidi filter receives as input a time-stamped MIDI stream from the WDMAud system driver
and outputs a PCM wave stream to the KMixer system driver. SWMidi mixes all of its voices internally to form a
single two-channel output stream with a PCM wave format.
DMusic System Driver
The DMusic system driver (Dmusic.sys) is the KS filter that supports software-emulated, high-quality,
downloadable sound (DLS) synthesis. The DMusic driver is a system-supplied port class miniport driver. It exposes
a single DirectMusic pin, which supports a DirectMusic stream data range. The DMusic filter receives as input a
time-stamped MIDI stream from the DirectMusic system component and outputs a PCM wave stream to the
KMixer system driver. The DMusic driver mixes all of its voices internally to form a single two-channel output
stream with a PCM wave format. A DirectMusic application must explicitly select the kernel-mode software synth,
Dmusic.sys, to use it in place of DirectMusic's default, user-mode synth.
AEC System Driver
The AEC system driver (Aec.sys) supports full-duplex DirectSound applications by implementing AEC (acoustic
echo cancellation) and noise-suppression algorithms in software. For more information, see DirectSound Capture
Effects.
DRMK System Driver
The DRMK system driver (Drmk.sys) is the KS filter that decrypts audio streams containing DRM-protected content.
For more information, see Digital Rights Management.
Splitter System Driver
The Splitter system driver (Splitter.sys) is the KS filter that creates two or more output streams from a single input
capture stream. The Splitter driver transparently copies the input stream to two more output streams
independently of the format of the input stream.
The Splitter driver is supported by Windows Me, and Microsoft Windows XP and later. For more information, see
AVStream Splitters.
Port Class Adapter Driver and PortCls System Driver
A port class adapter driver uses the port/miniport driver architecture to support an audio device. The PortCls
driver includes built-in driver support for ISA and PCI audio devices. Although the PortCls system driver
(Portcls.sys) also provides the framework for vendor-supplied port class adapter drivers, Microsoft recommends
that vendors use a system-supplied port class adapter driver to support ISA and PCI audio devices. The PortCls
framework might also be useful for constructing drivers for audio devices on other hardware buses or for
software-only devices. For more information, see Introduction to Port Class.
USB Audio Class System Driver (Usbaudio.sys)
The USBAudio class system driver (Usbaudio.sys) provides driver support for USB Audio devices that comply with
the Universal Serial Bus Device Class Definition for Audio Devices. For more information about this class system
driver, see USB Audio Class System Driver (Usbaudio.sys).
AVCAudio Class System Driver
The AVCAudio class system driver (Avcaudio.sys) is an AVStream minidriver that provides driver support for audio
devices that reside on an IEEE 1394 bus. The AVCAudio driver and associated support for IEEE 1394 audio devices
are available in Windows XP and later.
To work with the system-supplied drivers, hardware vendors should design their audio devices to comply with the
appropriate sections of the following specifications:
IEC 61883-1 and IEC 61883-6 (IEC 60958)
AV/C Digital Interface Command Set General Specification Ver. 3.0
AV/C Audio Subunit Specification 1.0
Connection and Compatibility Management Specification 1.0
AV/C Media Stream Format Information and Negotiation
Updates to the AV/C Audio Subunit Specifications currently in process
These specifications are available at the 1394 Trade Association website. The AVCAudio driver supports a subset of
the features that are described in these specifications.
When an audio device identifies itself as an IEEE 1394-compliant audio device during Plug and Play device
enumeration, the system automatically loads the AVCAudio driver to drive the device. AVCAudio drives the device
directly, without the aid of a proprietary adapter driver. This means that a device that complies with the appropriate
IEEE 1394 specifications requires no proprietary adapter driver.
Microsoft recommends that hardware vendors use the AVCAudio driver for their IEEE 1394 audio devices instead
of writing proprietary adapter drivers.
The following figure shows the driver hierarchy for an IEEE 1394 audio device in Windows XP. In Windows XP and
later, all of the driver components shown in this figure are provided by Microsoft with the operating system.

For more information about the driver components in the figure, see the following sections:
AVStream Overview
AV/C Client Drivers
IEEE 1394 Bus
USB Audio Class System Driver (Usbaudio.sys)
10/23/2019 • 2 minutes to read • Edit Online

The USB Audio class system driver (Usbaudio.sys) is an AVStream minidriver that provides driver support for audio
devices that comply with the Universal Serial Bus (USB) Device Class Definition for Audio Devices.

The USB Device Class Definition for Audio Devices specification (release 1.0) is available at the USB Implementers
Forum website. Usbaudio.sys supports a subset of the features that are described in the USB Audio specification. In
addition to Usbaudio.sys, there are several other kernel-mode audio components in the Windows Driver Model
(WDM). For more information, see Kernel-Mode WDM Audio Components.
In Windows 98 Usbaudio.sys introduced support for USB devices such as speakers and microphones. Support for
MIDI devices was added in Windows Me.
When an audio device identifies itself as USB Audio-compliant during Plug and Play device enumeration, the
system automatically loads the USBAudio driver to drive the device. USBAudio drives the device directly, without
the aid of a proprietary adapter driver. This means that a device that complies with the USB audio specifications
requires no proprietary adapter driver.
Microsoft recommends that hardware vendors use the USBAudio driver for their USB Audio devices instead of
writing proprietary adapter drivers.
In Windows 98, the USBAudio driver supports the following features:
All Type I formats (except 8-bit signed PCM)
AC-3 Type II format
Synchronization types synchronous and adaptive
Multichannel devices
However, USBAudio in Windows 98 does not support:
8-bit signed PCM format
MPEG Type II format
Type III formats
USB MIDI
WAVEFORMATEXTENSIBLE wave format (USBAudio uses packed WAVE_FORMAT_PCM for 24-bit data
instead.)
In Windows 98 Second Edition (SE), Windows Me, and Windows 2000 and later, USBAudio supports all the same
features as Windows 98, with one exception: USBAudio supports WAVEFORMATEXTENSIBLE but does not support
packed WAVE_FORMAT_PCM for 24-bit data.
In Windows Me, and Windows XP and later, USBAudio supports all the features that are supported in Windows 98
SE and Windows 2000. In addition, Windows Me and Windows XP support USB MIDI but do not support USB MIDI
Elements.
The following figure shows the driver hierarchy for a USB audio device. All of the driver components shown in the
figure are provided by Microsoft with the operating system.
For more information about the driver components in the figure, see the following sections:
AVStream Overview
System-Supplied USB Drivers
Wave and DirectSound Components
10/23/2019 • 6 minutes to read • Edit Online

Application programs rely on a combination of user-mode and kernel-mode components to capture (input) and
render (output) wave streams. A wave stream is a digital-audio stream whose data format is described by a
WAVEFORMATEX or WAVEFORMATEXTENSIBLE structure.
An application can use either of the following software interfaces for wave rendering and capture:
Microsoft Windows Multimedia waveOutXxx and waveInXxx functions
DirectSound and DirectSoundCapture APIs
The behavior of the waveOutXxx and waveInXxx functions is based on the capabilities of legacy wave drivers and
devices. Beginning with Windows 98, the WDMAud system driver translates calls to these functions into
commands to WDM audio drivers. However, by emulating the behavior of older software and hardware, the
waveOutXxx functions sacrifice the 3-D sound effects and hardware acceleration that are now available through the
DirectSound API. For more information about DirectSound and the Windows Multimedia wave functions, see the
Microsoft Windows SDK documentation.
DirectSound and the Windows Multimedia wave functions are clients of the SysAudio system driver, which builds
the audio filter graphs that process the wave and DirectSound streams. Graph building is transparent to the
applications that use these software interfaces.
Wave Components
The following figure shows the user-mode and kernel-mode components that a wave application uses to render or
capture a digital audio stream consisting of wave PCM data.
The rendering components appear on the left side of the preceding figure, and the capture components appear on
the right. The boxes representing the wave miniport driver are darkened to indicate that these are vendor-supplied
components. The other components in the figure are system-supplied.
At the top left of the figure, the wave-rendering (or "wave-out") application interfaces to the WDM audio drivers
through the waveOutXxx functions, which are implemented in the user-mode WinMM system component,
Winmm.dll. The application reads blocks of wave audio samples from a file and calls the waveOutWrite function
to render them.
WDMAud, which consists of both user-mode and kernel-mode components (Wdmaud.drv and Wdmaud.sys),
buffers the wave data from the waveOutWrite call and outputs the wave stream to the KMixer system driver,
which appears below WDMAud in the figure.
KMixer is a system component that receives wave PCM streams from one or more sources and mixes them
together to form a single output stream, which is also in wave PCM format.
KMixer outputs a wave stream to a WaveCyclic or WavePci device, whose port and miniport drivers appear below
KMixer on the left side of the preceding figure. The miniport driver binds itself to the port driver to form the wave
filter that represents the underlying audio rendering device. A typical rendering device outputs an analog signal
that drives a set of speakers or an external audio unit. A rendering device might also output digital audio through
an S/PDIF connector. For more information about WaveCyclic and WavePci, see Wave Filters.
Alternatively, KMixer can pass its output stream to a USB audio device, which is controlled by the USBAudio class
system driver (not shown in figure), instead of a WaveCyclic or WavePci device.
An adapter driver creates an instance of a WaveCyclic or WavePci port driver by calling PcNewPor t with a GUID
value of CLSID_Por tWaveCyclic or CLSID_Por tWavePci , respectively.
The right side of the preceding figure shows the components that are needed to support an application that
captures wave data to a file. The wave-capture (or "wave-in") application communicates with the WDM audio
drivers through the waveInXxx functions, which are implemented in the WinMM system component.
At the lower right corner of the figure, the wave-capture device is controlled by wave miniport and port drivers.
The port and miniport drivers, which can be of type WaveCyclic or WavePci, bind together to form a wave filter that
represents the capture device. This device typically captures an analog signal from a microphone or other audio
source and converts it to a wave PCM stream. The device might also input a digital audio stream through an S/PDIF
connector.
The wave port driver outputs its wave stream either to KMixer or to WDMAud directly. The stream must pass
through KMixer if it needs to be sample-rate converted before WDMAud receives it. A system that performs
simultaneous rendering and capture of audio streams might require two instances of KMixer, as shown in the
figure. Note that SysAudio automatically creates these instances as they are needed.
Alternatively, the source of the captured wave stream can be a USB audio device instead of a WaveCyclic or
WavePci device. In this case, the USBAudio driver (not shown in figure) passes the stream to KMixer.
Regardless of whether the wave stream is captured by a USB device or by a WaveCyclic or WavePci device, KMixer
performs sample-rate conversion on the stream, if needed, but does no mixing with other streams. KMixer outputs
the resulting stream to Wdmaud.sys, the kernel-mode half of the WDMAud system driver. The user-mode half,
Wdmaud.drv, outputs the wave stream to the application program through the waveInXxx functions, which are
implemented in Winmm.dll. Finally, at the top of the figure, the wave-capture application writes the wave data to a
file.
At the time that the wave-capture application calls the waveInOpen function to open the capture stream, it passes
in a pointer to its callback routine. When a wave-capture event occurs, the operating system calls the callback
routine with a buffer containing the next block of wave samples from the capture device. In response to the
callback, the application writes the next block of wave data to the file.
DirectSound Components
The following figure shows the user-mode and kernel-mode components that are used by a DirectSound
application program to render or capture wave data.

The rendering components are shown in the left half of the preceding figure, and the capture components appear
on the right. The wave miniport drivers are shown as darkened boxes to indicate that they are vendor-supplied
components. The other components in the figure are system-supplied.
At the top left of the figure, a DirectSound application loads wave data from a file to a sound buffer that the user-
mode DirectSound system component (Dsound.dll) manages. This component sends a wave stream to a
WaveCyclic or WavePci device, whose port and miniport drivers appear at the lower left in the figure. If a hardware
mixer pin is available on the device, the stream passes directly to the wave port driver, bypassing KMixer.
Otherwise, the stream first passes through KMixer, which mixes it with any other simultaneously playing streams.
KMixer outputs the mixed stream to the port driver.
As before, the miniport driver binds itself to the port driver to form the wave filter that represents the underlying
audio rendering device. This device might play the stream through a set of speakers, for example.
Alternatively, the wave stream can be rendered by a USB audio device instead of a WaveCyclic or WavePci device. In
this case, the stream cannot bypass KMixer; the USBAudio class system driver (not shown in figure) always passes
the stream to KMixer.
The right side of the preceding figure shows the components that support a DirectSoundCapture application. The
application records wave data that is receives from a WaveCyclic or WavePci capture device. This device converts
an analog signal from a microphone, for example, to a wave stream. The device's wave port and miniport drivers
appear at the lower-right corner of the figure. As shown in the figure, the port driver receives as input the stream
from the miniport driver and outputs it either directly to the user-mode DirectSound component, Dsound.dll, or
indirectly through KMixer. This depends on whether a hardware capture pin is available from the capture device.
Alternatively, the source of the captured wave stream can be a USB audio device. In this case, the stream cannot
bypass KMixer; the USBAudio driver (not shown in figure) always passes the stream to KMixer.
If KMixer is inserted into the path of the capture stream, it performs sample-rate conversion on the stream, if
needed, but does no mixing with other streams.
At the top-right corner of the preceding figure, the application reads the wave data from the DirectSoundCapture
buffer and writes it to the file.
MIDI and DirectMusic Components
10/23/2019 • 8 minutes to read • Edit Online

Application programs rely on a combination of user- and kernel-mode components to capture and play back MIDI
and DirectMusic streams.
An application can use either of the following software interfaces for MIDI playback and capture:
Microsoft Windows Multimedia midiOut Xxx and midiIn Xxx functions
DirectMusic API
The behavior of the midiOut Xxx and midiIn Xxx functions is based on the capabilities of legacy MIDI drivers and
devices. Beginning with Windows 98, the WDMAud system driver translates calls to these functions into
commands to WDM audio drivers. However, by emulating the behavior of older software and hardware, the
midiOut Xxx and midiIn Xxx functions sacrifice the precision timing and enhanced functionality that are now
available through the DirectMusic API. For more information about DirectMusic and the Windows Multimedia MIDI
functions, see the Microsoft Windows SDK documentation.
DirectMusic and the Windows Multimedia MIDI functions are clients of the SysAudio system driver, which builds
the audio filter graphs that process the MIDI and DirectMusic streams. Graph building is transparent to the
applications that use these software interfaces.
MIDI Components
The following figure shows the user-mode and kernel-mode components that a MIDI application uses to play back
MIDI data. This application interfaces to the WDM audio drivers through the midiOut Xxx functions, which are
implemented in the WinMM system component, Winmm.dll.

The MIDI application in the preceding figure reads time-stamped MIDI events from a MIDI file and plays them. The
MIDI and DMus miniport drivers are shown as darkened boxes to indicate that they can be vendor-supplied
components. If appropriate, a vendor might choose to use one of the system-supplied miniport drivers--FMSynth,
UART, or DMusUART--instead of writing a custom miniport driver. All of the other components in the figure are
system-supplied.
The main loop of a typical MIDI-playback application calls timeSetEvent to schedule the next note-on or note-off
event. This call takes as one of its parameters a function pointer to the application's callback routine. When the
event occurs and the operating system calls the callback routine, this routine calls midiOutShor tMsg to turn on
or turn off one or more scheduled notes. The midiOutShor tMsg function stores the MIDI messages in page-
locked data buffers to eliminate the need to page-in this memory during a call. For more information about the
timeSetEvent and midiOutShor tMsg calls, see the Microsoft Windows SDK documentation.
WDMAud, which consists of both user- and kernel-mode components (Wdmaud.drv and Wdmaud.sys), records the
times at which the raw MIDI messages from the midiOutShor tMsg calls arrive. WDMAud combines these time
stamps with the MIDI messages to generate the MIDI stream that it sends to one of the kernel-mode components
that appear below WDMAud in the figure.
When building the audio filter graph for the MIDI application, SysAudio selects only one of the three possible
connections -- to SWMidi, the MIDI port, or the DMus port driver -- that appear in the preceding figure. If the
application selects the default MIDI device, SysAudio first looks for a synthesizer device whose MIDI or DMus
miniport driver has a MIDI pin. If it finds no such device in the registry, SysAudio will instead use the SWMidi
system driver (Swmidi.sys). SWMidi is a KS filter that implements a wavetable synth in software, and it requires
only a device that can render a wave audio stream.
SWMidi mixes all of its voices together to produce a single wave PCM stream, which it outputs to the KMixer
system driver. KMixer, in turn, passes a PCM-formatted wave stream to a WaveCyclic or WavePci device, whose port
and miniport drivers appear at the lower-left corner of the figure. Alternatively, KMixer can pass its output stream
to a USB audio device that is controlled by the USBAudio class system driver (not shown in figure).
In the preceding figure, the MIDI port driver takes the time-stamped MIDI stream from WDMAud and converts it to
raw MIDI messages, which the MIDI miniport driver plays through the synthesizer device. The MIDI port driver
contains a sequencer, which is implemented in software and is able to schedule the raw MIDI messages with a
timer resolution of one millisecond.
The DMus port driver is able to achieve a much higher timing accuracy than the MIDI port driver if the synthesizer
device contains a hardware sequencer. In this case, the DMus miniport driver should specify a hardware buffer that
is large enough to absorb the jitter resulting from competition for CPU time with ISRs (interrupt service routines)
and other high-priority operations. The time stamps in the MIDI stream that the DMus port driver outputs to the
miniport driver are 64-bit values with 100-nanosecond resolution.
If the DMusic synth does not have a hardware sequencer, it must rely on the DMus port driver's software
sequencer, which, like the MIDI port driver's, has a timer resolution of one millisecond.
An adapter driver creates a MIDI or DMus port driver by calling PcNewPor t with a GUID value of
CLSID_Por tMidi or CLSID_Por tDMus , respectively. In Windows XP and later, the MIDI and DMus port drivers
share the same software implementation.
Appearing at the bottom of the preceding figure are the names of the system-supplied miniport drivers FMSynth,
UART, and DMusUART, which are included in Portcls.sys. An adapter driver creates one of these miniport drivers by
calling PcNewMinipor t . FMSynth and UART provide IMiniportMidi interfaces, and DMusUART provides an
IMiniportDMus interface. Note that UART is now obsolete (after Windows 98 Gold) and is supported only for
existing drivers. New adapter drivers should instead use DMusUART (in Windows 98 SE and later, and in Windows
2000 and later), which implements a superset of UART's functionality. DMusUART is an example of a DMus
miniport driver that supports neither DLS downloads nor hardware sequencing. The source code for the FMSynth
and DMusUART miniport drivers is available in the sample audio drivers in the Windows Driver Kit (WDK).
The following figure shows the user-mode and kernel-mode components that a MIDI application program uses to
capture MIDI data. This application interfaces to the WDM audio drivers through the midiIn Xxx functions.

In the preceding figure, the MIDI and DMus miniport drivers are shown as darkened boxes to indicate that they can
be vendor-supplied components. If appropriate, a vendor might instead choose to use one of the system-supplied
miniport drivers, UART or DMusUARTCapture. All of the other components in the figure are system-supplied.
The source of the MIDI data is typically an MPU-401 device. By calling PcNewMinipor t , an adapter driver can
create one of the system-supplied miniport drivers, UART or DMusUARTCapture, to capture MIDI data from a MPU-
401 device. Again, UART is obsolete, and new drivers instead should use DMusUARTCapture (in Windows 98 SE
and later, and in Windows 2000 and later).
Each time a MIDI note-on or note-off event occurs, the MIDI or DMusic capture miniport driver (at the bottom of
the preceding figure) adds a time stamp to the MIDI message before adding it to the MIDI stream that flows to the
MIDI or DMus port driver.
The MIDI or DMusic capture port driver outputs a time-stamped MIDI stream to Wdmaud.sys, the kernel-mode half
of the WDMAud system driver. The user-mode half, Wdmaud.drv, outputs the time-stamped MIDI stream to the
application program through the midiIn Xxx functions, which are implemented in Winmm.dll.
The MIDI application at the top of the figure writes time-stamped MIDI events to a MIDI file. At the time that the
application calls midiInOpen to open the MIDI input stream, it passes in a function pointer to its callback routine.
When a note-on or note-off event occurs, the operating system calls the callback routine with a data block that
includes one or more time-stamped MIDI messages. The time stamps on these messages are essentially the same
ones that the MIDI or DMus miniport driver originally generated.
DirectMusic Components
The following figure shows the user- and kernel-mode components that are used by a DirectMusic application
program to play back or capture MIDI data.
The playback components are shown in the left half of the preceding figure, and capture components appear on
the right. The DMus miniport drivers are shown as darkened boxes to indicate that they can be vendor-supplied
components. If appropriate, a vendor can instead use one of the system-supplied miniport drivers, DMusUART or
DMusUARTCapture. The other components in the figure are system-supplied.
In the top left corner of the figure, a DirectMusic application directs a time-stamped MIDI stream from a file to the
user-mode DirectMusic system component (DMusic.dll), which in turn directs the stream to a DMus port driver.
This driver can be bound to the miniport driver for a DirectMusic synth or MPU-401 device, if one is available.
Alternatively, the port driver can be bound to the DMusic system driver (Dmusic.sys), which is a system-supplied
DMus miniport driver that implements a DLS-capable wavetable synth in software, and that only requires a device
that can render a wave audio stream.
Like SWMidi, the DMusic driver, Dmusic.sys, mixes all of its voices together to produce a single PCM-formatted
wave stream, which it outputs to KMixer. KMixer, in turn, can pass a wave stream to a wave device, whose port and
miniport drivers appear at the lower-left corner of the figure, or to a USB audio device that is controlled by the
USBAudio system driver, which does not appear in the figure.
The DirectMusic capture components appear in the right half of the preceding figure. The DMusic capture miniport
driver in the lower-right corner of the figure controls the capture hardware and time-stamps each MIDI message
that it records. The DMus port driver directs the time-stamped MIDI stream to the user-mode DirectMusic
component, DMusic.dll. The application accesses this stream through the DirectMusic API and writes the time-
stamped MIDI data to a file.
An adapter driver can use the system-supplied DMusUARTCapture miniport driver to control an MPU-401 capture
device. The adapter driver creates this miniport driver by calling PcNewMinipor t with GUID value
CLSID_DMusUARTCapture . The resulting miniport driver object supports an IMinipor tDMus interface. The
source code for the DMusUARTCapture miniport driver is available in the sample audio drivers in the Windows
Driver Kit (WDK).
A DirectMusic application can also run through a midiOut Xxx device such as SWMidi (Swmidi.sys) if it chooses to.
For simplicity, this path is omitted from the preceding figure. The DMusic driver (Dmusic.sys) requires an initial DLS
download in order to operate correctly; using SWMidi avoids this requirement.
Virtual Audio Devices
12/5/2018 • 2 minutes to read • Edit Online

Virtual audio devices represent the filter graphs that render and capture audio content. The system audio driver
(SysAudio) uses the available hardware and software components to determine the filter graphs to build.
For more information about the system audio driver, see SysAudio System Driver.

SysAudio's clients include DirectSound and the WDMAud system driver, which serves as the interface between
WDM audio drivers and the audio-specific Microsoft Windows Multimedia APIs waveIn, waveOut, midiIn, midiOut,
mixer, and aux (described in Microsoft Windows SDK documentation).
The KsStudio utility in the Windows Driver Kit (WDK) is an example of an application that bypasses SysAudio and
allows users to construct filter graphs manually.
Following PnP device enumeration, SysAudio takes stock of the registered audio hardware and software
components in order to determine how to construct the various audio filter graphs that its clients might require.
After determining the list of filter graphs that it can build from the available hardware and software components,
SysAudio registers these graphs as virtual audio devices for playback, recording, MIDI input/output, and mixing.
SysAudio reserves the registry category KSCATEGORY_AUDIO_DEVICE exclusively for its virtual audio devices.
Adapter drivers should not register themselves in this category.
A SysAudio client can treat a filter factory for a virtual audio device similarly to a filter factory for a hardware or
software component. When asked by a client to instantiate a particular pin on a virtual device, SysAudio constructs
the graph automatically and manages the graph's internal pin connections transparently to the client. This allows
the client to treat a filter graph as a single filter, thereby avoiding complexities of graph management such as inter-
filter communication.
Typical Audio Configurations
12/5/2018 • 2 minutes to read • Edit Online

This section presents a collection of typical audio configurations for rendering and capturing audio content. The
following configurations are shown:
Rendering and Capturing Wave Content
Rendering and Capturing MIDI Content
Rendering and Capturing Audio Content by Using a Port Class Audio Adapter
Rendering and Capturing Audio Content by Using the USBAudio Driver
Rendering Wave Content Using DirectSound Software and Hardware Buffers
Rendering and Capturing Wave Content
12/5/2018 • 2 minutes to read • Edit Online

The following figure shows the configuration of Microsoft Windows Driver Model (WDM) audio components that
render and capture wave content.

See the following for a description of the WDM audio components:


DirectSound System Component
WDMAud System Driver
SBEmul System Driver
SysAudio System Driver
KMixer System Driver
Redbook System Driver
Splitter System Driver
Port Class Adapter Driver and PortCls System Driver
USBAudio Class System Driver
See the following for more information about the configuration of the port class adapter driver and the USBAudio
driver:
Rendering and Capturing Audio Content by Using a Port Class Audio Adapter
Rendering and Capturing Audio Content by Using the USBAudio Driver
Rendering and Capturing MIDI Content
12/5/2018 • 2 minutes to read • Edit Online

The following diagram shows the relationship between the system-supplied Microsoft Windows Driver Model
(WDM) audio components that support rendering and capturing MIDI content.

See the following for a description of the Microsoft Windows Driver Model (WDM) audio components:
DirectMusic System Component
WDMAud System Driver
SBEmul System Driver
SysAudio System Driver
KMixer System Driver
SWMidi System Driver
DMusic System Driver
Port Class Adapter Driver and PortCls System Driver
USBAudio Class System Driver
See the following for more information about the configuration of the port class adapter driver and the USBAudio
driver:
Rendering and Capturing Audio Content by Using a Port Class Audio Adapter
Rendering and Capturing Audio Content by Using the USBAudio Driver
Rendering and Capturing Audio Content by Using a
Port Class Audio Adapter
12/5/2018 • 2 minutes to read • Edit Online

The following figure shows a configuration of a port class audio adapter driver that renders and captures audio
content.

See the following for a description of the Microsoft Windows Driver Model (WDM) audio components:
DirectSound System Component
DirectMusic System Component
WDMAud System Driver
SBEmul System Driver
KMixer System Driver
Redbook System Driver
Splitter System Driver
Port Class Adapter Driver and PortCls System Driver
See the following for information about wave, MIDI, DirectMusic, and topology filters:
Wave Filters
MIDI and DirectMusic Filters
Topology Filters
See the following for more detail about the filter graphs located above the port class audio adapter:
Rendering and Capturing Wave Content
Rendering and Capturing MIDI Content
Rendering and Capturing Audio Content by Using
the USBAudio Driver
12/5/2018 • 2 minutes to read • Edit Online

The following figure shows how the USBAudio class system driver is configured to render and capture audio
content. In this figure, the USBAudio driver sprouts pins to represent the terminals on the USB Audio device. Audio
components such as KMixer, WDMAud, and DirectSound connect to these pins to render output streams or capture
input streams.

See the following for a description of the Microsoft Windows Driver Model (WDM) audio components:
DirectSound System Component
WDMAud System Driver
SBEmul System Driver
KMixer System Driver
Redbook System Driver
Splitter System Driver
SWMidi System Driver
DMusic System Driver
See the following for more detail about the filter graphs located above the USBAudio driver:
Rendering and Capturing Wave Content
Rendering and Capturing MIDI Content
Rendering Wave Content Using DirectSound
Software and Hardware Buffers
12/5/2018 • 2 minutes to read • Edit Online

The following figure shows a configuration of Microsoft Windows Driver Model (WDM) components that renders
to DirectSound software and hardware buffers.

See the following for a description of the WDM audio components:


DirectSound System Component
SysAudio System Driver
KMixer System Driver
Port Class Adapter Driver and PortCls System Driver
USBAudio Class System Driver
Factors Governing Wave-Output Latency
12/5/2018 • 2 minutes to read • Edit Online

This section describes the sources of latency for a wave-output stream. Some of the factors that affect latency are:
Whether the stream is output to a WaveCyclic or WavePci device
Whether the stream is generated by DirectSound or the waveOut API
The following topics are discussed:
WaveCyclic Latency
WavePci Latency
Avoiding Data Copying
WaveCyclic Latency
10/23/2019 • 2 minutes to read • Edit Online

If your WaveCyclic miniport driver provides hardware mixing of an audio playback stream, DirectSound submits an
IRP to the WaveCyclic port driver that contains the entire DirectSound wave stream in a single cyclic buffer. The
WaveCyclic port driver receives the IRP and feeds the wave data piece-by-piece into the DMA buffer that your
driver exposes. WaveCyclic attempts to keep the DMA buffer's write pointer about 40 milliseconds ahead of the
read pointer. Even when your driver is doing hardware mixing with DirectSound, it can expect about 40
milliseconds of extra data in the DMA buffer.
The fact that the WaveCyclic port driver tries to accumulate up to 40 milliseconds of data in the cyclic buffer does
not mean that the WaveCyclic port driver adds 40 milliseconds to the latency of the stream. In fact, the port driver
adds very little latency. Just before a new stream begins playing, while the port driver is still writing the initial data
into the beginning of the cyclic buffer, the port driver continues writing until either no more data is available or the
buffer contains a full 40 milliseconds of data. However, if less than this amount of data is immediately available, the
port driver will not force the miniport driver to wait. Instead, it allows the miniport driver to begin playing the
already buffered data immediately. Later, as more data becomes available, the port driver continues writing the
data to the buffer until either no more data is available or the amount of data buffered between the read and write
pointers reaches 40 milliseconds.
After a period of near starvation, a KMixer stream can contain intervals of silence. If WaveCyclic has received only
enough wave data from KMixer to maintain thirty rather than forty milliseconds of extra data in the DMA buffer,
WaveCyclic begins writing silence into the DMA buffer following the end of the valid data from KMixer. This policy
ensures that if starvation occurs and the device reads past the end of the valid data, the audio device renders
silence instead of stale or uninitialized data.
The amount of silence written to the DMA buffer is kept fairly small, and if KMixer does succeed in supplying the
WaveCyclic port driver with additional data before the silence has been played, that data overwrites the silence in
the buffer. In the absence of starvation, the audio device receives a continuous stream of mixed data without
intervals of forced silence. When you are debugging your driver, however, you might see your miniport driver's
IMinipor tWaveCyclicStream::Silence method being called even though your audio renderer is not starving.
WavePci Latency
10/23/2019 • 4 minutes to read • Edit Online

The WavePci port driver handles buffering of an audio stream differently from the WaveCyclic driver.
If your WavePci miniport driver provides hardware mixing, DirectSound submits an IRP to the WavePci port driver
that contains the entire DirectSound wave stream in a single cyclic buffer. DirectSound allocates the buffer as a
contiguous block of virtual memory. To avoid copying the DirectSound buffer, the kernel-streaming layer maps the
buffer into kernel-mode virtual memory and generates a MDL (memory descriptor list) that specifies both the
virtual and physical addresses of the memory pages in the cyclic buffer. The WavePci port driver partitions the
cyclic buffer into a sequence of allocator frames (see KS Allocators). The miniport driver specifies its preferred
allocator-frame size when its IMinipor tWavePciStream::GetAllocatorFraming method is called by the port
driver during stream initialization. However, SysAudio, the system graph builder, can override the miniport driver's
preferences in order to accommodate the requirements of the other components in the audio filter graph.
The WavePci port driver exposes the cyclic buffer to the miniport driver as a sequence of mappings. A mapping is
either an entire allocation frame or a portion of a frame. If a particular allocation frame lies completely within a
page, the port driver presents that frame to the miniport driver as a single mapping. If an allocation frame
straddles one or more page boundaries, the port driver splits the frame at each page boundary and presents it as
two or more mappings. Each call to IPor tWavePciStream::GetMapping yields the next successive mapping in
the sequence.
In contrast to the WaveCyclic case, where the miniport driver has little control over how many milliseconds of data
are buffered at the hardware, the WavePci miniport driver has considerable control over the number of mappings
that it has open at any time. The number of open mappings increases by one with each call to GetMapping and
decreases by one with each call to ReleaseMapping . (A GetMapping call can fail, of course, so the driver has less
than total control over the number of mappings.) By controlling the number of open mappings and keeping track
of the cumulative the size of the mappings, the miniport driver can determine (within a tolerance dependent on the
mapping size) the number of milliseconds of buffering that are available to the hardware. Your WavePci miniport
driver should request enough page mappings to reduce the chances of starvation to acceptable levels.
If your miniport driver's policy is to buffer up to 50 milliseconds of data, for example, between the read and write
pointers, remember that this limit represents the maximum amount of data that your driver will accumulate, but it
does not and should not represent your driver's contribution to the latency of the stream. Your driver should be
designed to keep its latency as small as possible. When a miniport driver obtains its initial set of mappings before
starting to play a new stream, the miniport driver can continue to request mappings until it either reaches its
buffer limit (50 milliseconds in this example) or no more mappings are immediately available. In the latter case,
however, the miniport driver must not wait until more mappings become available before it begins playing the
stream. Instead, the driver should immediately begin playing the mappings it has already obtained. Later, as more
mappings become available, the driver can continue to acquire additional mappings until either it reaches its
buffer-size limit or no more mappings are immediately available.
In general, a WavePci device's DMA hardware should be designed to directly access audio frames that are stored at
arbitrary byte alignments and that straddle boundaries between noncontiguous pages of physical memory. If you
have a device that requires that the mappings be an integral number of audio frames, that device is limited in the
kinds of audio formats that it supports. Of course, a device with this limitation should still be able to handle an
audio frame size that is a power of two.
For example, a device with four channels and a 16-bit sample size requires an audio-frame size of eight bytes. An
integral number of audio frames fits neatly within a page (or any other allocation-frame size that is a multiple of
eight bytes). However, in the case of a 5.1-channel stream with 16-bit samples, the audio frame size is 12 bytes and
a stream that exceeds the size of a single page necessarily contains audio frames that straddle page boundaries.
(The figures in Wave Filters illustrate this problem.) Hardware that cannot handle arbitrary byte alignments and
arbitrary byte-length mappings must depend on the driver to perform an intermediate copy, which degrades
performance.
The Ac97 sample adapter driver in the Microsoft Windows Driver Kit (WDK) implements a GetAllocatorFraming
method. The miniport driver uses this method to communicate its preferred frame-allocation size. In Windows
2000 and Windows Me, the port driver calls this method only when the Splitter system driver (Splitter.sys) is
instantiated above the output pin. In Windows XP and later, the port driver calls this method for input streams as
well. Remember that SysAudio might choose to ignore the miniport driver's preferences when deciding on a
frame-allocation size.
Avoiding Data Copying
12/5/2018 • 2 minutes to read • Edit Online

You can improve driver performance by designing your audio hardware to avoid unnecessary data copying.
You can achieve the best results by implementing your hardware to perform true scatter/gather DMA and by
writing a WavePci miniport driver to manage the hardware. Your device can then directly access playback data
buffers or empty record buffers wherever they are located in system memory. This eliminates a lot of unnecessary
software intervention and time-consuming data copying.
If you are designing a WaveCyclic device, however, you can improve its performance by making its hardware buffer
directly accessible as system memory. This eliminates the overhead of copying data from an intermediate buffer in
system memory.
Also, if your device requires an audio format with a channel ordering that is incompatible with the standard WDM
audio formats, the driver might have to perform in-place conversion of each audio frame in an intermediate buffer
before the hardware can process it. This can degrade performance. For additional information, see the white paper
titled Multiple Channel Audio Data and WAVE Files at the audio technology website.
Exploring the Windows Vista Audio Engine
12/5/2018 • 3 minutes to read • Edit Online

This topic presents an overview of the Windows Vista audio engine. It focuses on concepts that will help you
understand how APOs and sAPOs work together.
The following diagram presents a simplified layout of the internal structure of the audio engine.

As the diagram shows, system-supplied APOs and sAPOs are the basic building blocks of the audio engine. The
audio engine configures the system-supplied APOs and sAPOs into components called pipes. There are two types
of pipes in the audio engine:
Stream pipes are made up of APOs and sAPOs that perform digital audio processing that is local to the
stream from a single application. The sAPO in this type of pipe is referred to as local effects sAPO (LFX
sAPO).
Device pipes are made up of APOs and sAPOs that perform digital audio processing that affects all the
streams globally. The sAPO in this type of pipe is called a global effects sAPO (GFX sAPO).
The following table shows the sAPOs that are available in the Windows Vista audio engine and the type of system
effects that they apply.

W IN DO W S VISTA SA P O SY ST EM EF F EC T

Bass Boost LFX

Bass Management LFX

Loudness Equalization LFX

Low Frequency Protection LFX


W IN DO W S VISTA SA P O SY ST EM EF F EC T

Speaker Fill LFX

Speaker Phantoming LFX

Virtual Surround LFX

Virtualized Surround over Headphones LFX

Enhanced Sound for Portable Computers GFX

Room Correction GFX

When an audio application initiates audio processing, the audio engine configures the system-supplied APOs and
the sAPOs into an audio graph to process the digital audio data. The mechanism the audio engine uses for building
the audio graph is a system detail and will not be discussed.
The audio application can initiate the connection in shared mode or exclusive mode. Although a default set of
sAPOs is installed with Windows Vista, sAPOs are not considered to be system components and are therefore
customizable.
Shared mode
In shared mode, an audio application shares the audio hardware with other audio applications that are running in
other processes. The audio engine mixes the streams from these applications and plays the resulting mix through
the hardware. Any application that opens a stream in shared mode must select the mix format that is used by the
audio engine. The advantage of using shared mode is that the Windows Vista audio engine provides a built-in
Audio Processing Object (APO) to provide the necessary supporting functionality. The disadvantage of using
shared mode is that audio stream latency is higher than it is in exclusive mode. The following code example shows
the syntax for initializing an audio stream in shared mode.

hResult = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
0,
0,
pWfx,
&m_SubmixGuid);

Exclusive mode
In contrast, when an application opens a stream in exclusive mode, the application has exclusive access to the
audio hardware. In this mode the application can select any audio format that the endpoint supports. The
advantage of using exclusive mode is that audio stream latency is lower than it is in shared mode. The
disadvantage of using exclusive mode is that you must provide your own APO to handle the supporting
functionality of the audio engine. Only a small number of professional level applications require this mode of
operation. The following code example shows the syntax for initializing an audio stream in exclusive mode.
hResult = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
0,
0,
0,
pWfxEx,
&m_SubmixGuid);

After an application initiates audio processing, the graph builder configures the sAPOs into an audio graph and
also initializes the sAPOs. The audio service then negotiates with the LFX sAPO to establish the format for the
audio data at the input and output of the sAPO. For more information, see Format Negotiation.
Format Negotiation
12/5/2018 • 2 minutes to read • Edit Online

After an application initiates audio processing, the graph builder configures the sAPOs into an audio graph and
also initializes the sAPOs. The audio service then negotiates with the LFX sAPO to establish the format for the audio
data at the input and output of the sAPO. This negotiation process is known as format negotiation.
All sAPOs that provide audio systems effects for Windows Vista must have certain interfaces and methods. The
methods used by the sAPO and the audio engine to negotiate the data format are: the IsInputFormatSuppor ted
method of the IAudioProcessingObject interface and the LockForProcess and UnlockForProcess methods of
the IAudioProcessingObjectConfiguration interface.
To initiate format negotiation, the audio service first sets the output of the LFX sAPO to the default float32-based
format. The audio service then calls the IAudioProcessingObject::IsInputFormatSuppor ted method of the LFX
sAPO, suggests the default format, and monitors the HRESULT response of this method. If the LFX sAPO can
support the suggested format, it returns S_OK, together with a reference to the supported format. If the LFX sAPO
cannot support the suggested format, it returns S_FALSE together with a reference to a format that is the closest
match to the suggested one. If the LFX sAPO cannot support the suggested format and does not have a close
match, it returns APOERR_FORMAT_NOT_SUPPORTED. The GFX sAPO works with the output format of the LFX
sAPO. So the GFX sAPO is not involved in the format negotiation process.
After a data format is selected to process the audio data, the audio processing graph builder calls the
IAudioProcessingObjectConfiguration::LockForProcess method of the sAPOs, causing the format selection
to be finalized.
If the Windows Vista sAPO returns an error to the wrapping custom sAPO in response to a call to the
LockForProcess method, the custom sAPO must handle the error the same way it handles an error from
CoCreateInstance when an attempt to instantiate an sAPO fails. Refer to the Spkrfill.cpp file for details about how
to overwrite the system-supplied LockForProcess method.
Because of the way that the audio service operates, the LFX and GFX sAPOs must be able to respond independently
of each other to queries from the audio service regarding data formats.
Impor tant When you implement a custom sAPO that wraps a Windows Vista LFX sAPO, do not specify the
APO_FLAG_FRAMESPERSECOND_MUST_MATCH flag in the registration properties of the custom sAPO. If you
specify this flag, the Windows Vista LFX sAPO will be unable to perform speaker fill, headphone virtualization, or
virtual surround. Additionally, your custom sAPO will not be able to down-mix any audio streams. For example,
your custom sAPO will not be able to mix a 5.1 audio stream down to a two-channel stereo audio stream.
Dynamic Format Change
12/5/2018 • 3 minutes to read • Edit Online

Dynamic format change is a feature in Windows 7 and later versions of the Windows operating system that allows
the format used to stream audio data between an audio application and an audio adapter to be changed
dynamically. Dynamic format change accommodates the behavior of audio streaming in high definition multimedia
interface (HDMI) devices. This topic provides an overview of dynamic format change and describes how it works.
The following list shows the scenarios in which dynamic format change is used.
HDMI devices present new capabilities. When an HDMI device streams audio or video data or both, the
total HDMI bandwidth used for the audio and video transfer is fixed and the video signal is given preference
in capacity allocation. This means that if you have an HDMI display device connected to a computer and you
change the display resolution, this affects the size of the bandwidth that remains for audio data transfer to
the computer.
Assume, for example, that your HDMI device is initially configured with the data format set to 192 KHz, 16-
bit stereo with a particular display mode. When you change to a different display mode, the remaining
bandwidth for streaming audio data might not be enough for the 192 KHz format. So the device driver
notifies the audio service for the connected computer about the change in display mode, and this causes the
audio driver and the audio service to renegotiate the audio data format. If the currently selected 192 KHz
format cannot be streamed within the remaining bandwidth, a new format is selected. For more information
about the format negotiation process, see Format Negotiation.
In another HDMI-related dynamic format change scenario, an audio device is unplugged and a new, HDMI-
capable device is plugged in. The device driver for the HDMI device generates a format change event and the
audio service renegotiates the audio data format with the device driver.
Some stand-alone audio devices provide hardware controls that a user can use to change the
audio data format. In this scenario, the user manipulates a control knob on a surround sound amplifier, for
example, to select an audio data format. If there is a computer connected to the stand-alone audio device,
this newly selected data format causes the audio driver on the connected computer to renegotiate the data
format and, possibly, change it.
Third-par ty UI for the Sound applet in the Control Panel provides options for enabling or
disabling system effects. When you develop your own system effects audio processing objects (sAPOs),
you can also provide a custom UI for the Sound applet in the Control Panel. This custom UI can include
modifications to the Enhanced or the Advanced tabs of the Sound applet or both. In this scenario, a user
selects a check box in the Enhanced tab to enable or disable a global system effects (GFX) feature that
requires the audio data format to be changed. The selection made by the user causes the HDMI driver to
generate a format change event. The audio service receives the notification about this event and
renegotiates with the audio driver to select a new format for the audio data.
To provide support for HDMI and IEC61937-compliant compressed audio formats such as Dolby Digital and digital
theater sound (DTS), Windows 7 and later Windows operating systems provide a new set of subtype GUIDs for use
by the kernel streaming (KS) properties and structures. The International Electrotechnical Commission (IEC)
standard, IEC 61937, applies to digital audio interfaces that transfer non-linear PCM encoded bit streams. For more
information about the subtype GUIDs, see the KSDATAFORMAT_SUBTYPE_IEC61937_Xxx GUIDs in Ksmedia.h.
Note When the audio endpoint builder receives the dynamic format change notification, and the proposed data
format is not supported by the device driver, the endpoint builder will then recalculate a new default device data
format.
And in the case where a redesigned audio driver now supports a new format, it can force the endpoint builder to
select the new format as the default format for the device. To force a changeover to the new format as the default
for the device, the audio driver must fail the format support query that it receives regarding the old format. The
failed format support query triggers a format change notification, and the endpoint builder then calculates a new
default format for the device.
Windows Audio Processing Objects
10/18/2019 • 2 minutes to read • Edit Online

Audio processing objects (APOs), provide customizable software based digital signal processing for Windows
audio streams.
This section contains the following topics.
Audio Processing Object Architecture
Implementing Audio Processing Objects
Implementing Hardware Offloaded APO Effects
APOs were first introduced in Windows Vista and you may see references to the earlier system APOs - sAPOs.
For more information, see Custom Audio Effects in Windows Vista. This white paper may reference older COM
and UI development topics.
Audio Processing Object Architecture
12/6/2019 • 6 minutes to read • Edit Online

Audio processing objects (APOs), provide customizable software based digital signal processing for Windows
audio streams.

Audio Processing Objects Overview


Windows allows OEMs and third-party audio hardware manufacturers to include custom digital signal processing
effects as part of their audio driver's value-added features. These effects are packaged as user-mode system effect
Audio Processing Objects (APOs).
Audio processing objects (APOs), provide software based digital signal processing for Windows audio streams. An
APO is a COM host object that contains an algorithm that is written to provide a specific Digital Signal Processing
(DSP) effect. This capability is known informally as an "audio effect." Examples of APOs include graphic equalizers,
reverb, tremolo, Acoustic Echo Cancellation (AEC) and Automatic Gain Control (AGC). APOs are COM-based, real-
time, in-process objects.
Note The descriptions and terminology in this documentation refers mostly to output devices. However, the
technology is symmetric and works essentially in reverse for input devices.
Software APOs vs. Hardware DSP
A hardware digital signal processor (DSP) is a specialized microprocessor (or a SIP block), with its architecture
optimized for the operational needs of digital signal processing. There can be significant advantages to implement
audio processing in purpose built hardware vs. using a software APO. One advantage is that the CPU use and
associated power consumption may be lower with a hardware implemented DSP.
There are other advantages and disadvantages to consider, specific to your projects goals and constraints that you
will want to consider before implementing a software based APO.
Software based effects are inserted in the software device pipe on stream initialization. These solutions do all their
effects processing on the main CPU and do not rely on external hardware. This type of solution is best for
traditional Windows audio solutions such as HDAudio, USB and Bluetooth devices when the driver and hardware
only support RAW processing. For more information about RAW processing, see Audio Signal Processing Modes.
Proxy APO for Hardware DSP
Any effects applied in hardware DSP need to be advertised via a proxy APO. Microsoft provides a default proxy
APO (MsApoFxProxy.dll). To use the Microsoft provided APO, this property set and property must be supported.
KSPROPSETID_AudioEffectsDiscovery
KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST
Optionally, you can implement your own proxy APO.
Windows Provided (System) APOs
Windows installs a default set of APOs, that provide a number of different audio effects. For a list of the system
provided APO effects, see Audio Signal Processing Modes.
OEMs can include all of the system supplied APOs or replace some or all of them with custom APOs.
Custom APOs
It is possible to create custom APOs to enhance the Windows audio experience by adding additional audio effects.
The OEM can include any combination of the provided Windows APOs and custom APOs when they ship
Windows.
A custom APO can be installed by an OEM or a third-party to enhance the audio experience after the device has
been purchased. When users install an audio device driver by using the standard INF file, they automatically have
access to the system's APOs. Independent hardware vendors (IHVs) and original equipment manufacturers (OEMs)
can provide additional custom system effects while still using the Microsoft class drivers. They do so by packaging
their DSP algorithms as APOs and modifying the standard INF file to insert their APOs into the audio engine’s
signal processing graph.
For more information on creating custom APOs see, Implementing Audio Processing Objects.
Custom APO Suppor t App
To allow the user to configure settings associated with your custom APO the recommended approach is to create a
Hardware Support App. For more information, see Hardware Support App (HSA): Steps for Driver Developers.
Custom APO Tests and Requirements
The Microsoft HLK provides tests that can be used with APOs. For more information about audio tests see,
Device.Audio Testing and Device.Audio Tests.
These two tests can be particularly useful when working with APOs.
Verify Audio EffectsDiscovery (Manual) - Certification
SysFX Test
For information on audio requirements to support APOs, see Device.Audio Requirements.
Custom APO Tools and Utilities
You can use the "Audio Effects Discovery Sample" to explore the available audio effects. This sample demonstrates
how to query audio effects on render and capture audio devices and how to monitor changes with the audio
effects. It is included as part of the SDK samples and can be downloaded using this link:
Audio effects discovery sample
Application Audio Effect Awareness
Applications have the ability to call APIs to determine which audio effects are currently active on the system. For
more information on the audio effects awareness APIs, see AudioRenderEffectsManager class.

Audio Processing Objects Architecture


Placement of Audio Effects
There are three different locations for audio effects implemented as APOs. They are in Stream effects (SFX), Mode
effects (MFX), and Endpoint effects (EFX).
Stream Effect (SFX)
A stream effect APO has an instance of the effect for every stream. Stream effects are before the mix (render) or
after the tee (capture) for a given mode and can be used for changing channel count before the mixer. Stream
effects are not used for raw streams.
Some versions of Windows, as an optimization, do not load SFX or MFX APOs in RAW mode.
Windows 8.1 does not load RAW SFX or RAW MFX
Windows 10 loads RAW MFX but not RAW SFX
Mode Effect (MFX)
Mode effects (MFX) are applied to all streams that are mapped to the same mode. Mode effects are applied after
the mix (render) or before the tee (capture) for a given mode, but before the mix (render) or after the tee (capture)
of all modes. Any scenario specific effect or effect that doesn’t need the specifics of the stream effect should be
placed here. It is more power efficient to use a mode effect since there is one instance for multiple streams that
share the same characteristics like periodicity and format.
Endpoint Effect (EFX)
Endpoint Effect (EFX) are applied to all streams that use the same endpoint. An endpoint effect is always applied,
even to raw streams. That is, it is after the mix (render) or before the tee (capture) of all modes. The endpoint
effects should be used with care and when in doubt an effect should be place in the Mode area. Some effects that
should be placed in the endpoint area are speaker protection and speaker compensation.
This diagram shows the possible locations for stream (SFX), mode (MFX) and endpoint (EFX) effects for
Windows 10.

Multiple Custom APO Effects


It is possible to configure multiple APO based effects to work with different applications.
This diagram illustrates how multiple applications can access multiple combinations of stream, mode and endpoint
APO effects. All of the APOs are COM based and run in user mode. In this scenario, none of the effects are running
in hardware or in kernel mode.
Note You can use the scroll bar at the very bottom of this page to view all of this diagram.
Software Mode Effects and Hardware Endpoint Effects for Render and Capture
This diagram illustrates software mode effects and hardware endpoint effects for render and capture.
DSP Equipped System with Hardware Effects
This diagram illustrates a DSP equipped system that implements effects in hardware. In this scenario, a Proxy APO
should be created to inform the apps of the effects that are implemented in hardware.
Related topics
Windows Audio Processing Objects
Implementing Audio Processing Objects
3/27/2020 • 17 minutes to read • Edit Online

This topic describes how to implement an audio processing object (APO). For general information about APOs, see
Audio Processing Object Architecture.

Implementing Custom APOs


Custom APOs are implemented as in-process COM objects, so they run in user mode and are packaged in a
dynamic-link library (DLL). There are three types of APO, based on where they are inserted in the signal
processing graph.
Stream effects (SFX)
Mode effects (MFX)
Endpoint effects (EFX)
Each logical device can be associated with one APO of each type. For more information on modes and effects, see
Audio Signal Processing Modes.
You can implement an APO by basing your custom class on the CBaseAudioProcessingObject base class, which is
declared in the Baseaudioprocessingobject.h file. This approach involves adding new functionality into the
CBaseAudioProcessingObject base class to create a customized APO. The CBaseAudioProcessingObject base class
implements much of the functionality that an APO requires. It provides default implementations for most of the
methods in the three required interfaces. The primary exception is the
IAudioProcessingObjectRT::APOProcess method.
Perform the following steps to implement your custom APOs.
1. Create custom APO com objects to provide the desired audio processing.
2. Optionally create a user interface for configuring the custom APOs using a.
3. Create an INF file to install and register the APOs and the custom user interface.

Design Considerations for Custom APO Development


All custom APOs must have the following general characteristics:
The APO must have one input and one output connection. These connections are audio buffers and can
have multiple channels.
An APO can modify only the audio data that is passed to it through its
IAudioProcessingObjectRT::APOProcess routine. The APO cannot change the settings of the underlying
logical device, including its KS topology.
In addition to IUnknown, APOs must expose the following interfaces:
IAudioProcessingObject. An interface that handles setup tasks such as initialization and format
negotiation.
IAudioProcessingObjectConfiguration. The configuration interface.
IAudioProcessingObjectRT. A real-time interface that handles audio processing. It can be called from
a real-time processing thread.
IAudioSystemEffects. The interface that makes the audio engine recognize a DLL as a systems effects
APO.
All APOs must have real-time system compatibility. This means that:
All methods that are members of real-time interfaces must be implemented as nonblocking
members. They must not block, use paged memory, or call any blocking system routines.
All buffers that are processed by the APO must be nonpageable. All code and data in the process
path must be nonpageable.
APOs should not introduce significant latency into the audio processing chain.
Custom APOs must not expose the IAudioProcessingObjectVBR interface.
Note For detailed information about the required interfaces, see the Audioenginebaseapo.h and
Audioenginebaseapo.idl files in the Windows Kits\<build number>\Include\um folder.

Using Sample Code to Accelerate the Development Process


Using the SYSVAD Swap APO code sample as a template can accelerate the custom APO development process.
The Swap sample is the sample that was developed to illustrate some features of audio processing objects. The
Swap APO sample swaps the left channel with the right channel and implements both SFX and MFX effects. You
can enable and disable the channel swap audio effects using the properties dialog.
The SYSVAD audio sample is available on the Windows Driver Samples GitHub.
You can browse the Sysvad audio sample here:
https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad
Download and extract the Sysvad audio sample from GitHub
Follow these steps to download and open the SYSVAD sample.
a. You can use GitHub tools to work with the samples. You can also download the universal driver samples in one
zip file.
https://github.com/Microsoft/Windows-driver-samples/archive/master.zip
b. Download the master.zip file to your local hard drive.
c. Right click Windows-driver-samples-master.zip, and choose Extract All . Specify a new folder, or browse to an
existing one that will store the extracted files. For example, you could specify C:\DriverSamples\ as the new folder
into which the files will be extracted.
d. After the files are extracted, navigate to the following subfolder.
C:\DriverSamples\Audio\Sysvad
Open the driver solution in Visual Studio
In Microsoft Visual Studio, Click File > Open > Project/Solution... and navigate to the folder that contains the
extracted files (for example, C:\DriverSamples\Audio\Sysvad). Double-click the Sysvad solution file to open it.
In Visual Studio locate the Solution Explorer. (If this is not already open, choose Solution Explorer from the View
menu.) In Solution Explorer, you can see one solution that has six projects.
SwapAPO Example Code
There are five projects in the SYSVAD sample, one of which is of primary interest to the APO developer.
Project Description

SwapAPO Sample code for an example APO.

The other projects in the Sysvad sample are summarized below.

Project Description

PhoneAudioSample Sample code for a mobile audio driver.

TabletAudioSample Sample code for an alternate audio driver.

KeywordDetectorAdapter Sample code for a keyword detector adapter

EndpointsCommon Sample code for common endpoints.

The primary header files for the SwapAPO sample is swapapo.h. The other primary code elements are
summarized below.

File Description

Swap.cpp C++ code that contains the implementation of the Swap APO.

SwapAPOMFX.cpp Implementation of CSwapAPOMFX

SwapAPOSFX.cpp Implementation of CSwapAPOSFX

SwapAPODll.cpp Implementation of DLL Exports.

SwapAPODll.idl Definition of COM interfaces and coclasses for the DLL.

SwapAPOInterface.idl The interface and type definitions for Swap APO functionality.

swapapodll.def COM exports definitions

Implementing the COM Object Audio Processing Code


You can wrap a system-supplied APO by basing your custom class on the CBaseAudioProcessingObject base
class, which is declared in the Baseaudioprocessingobject.h file. This approach involves introducing new
functionality into the CBaseAudioProcessingObject base class to create a customized APO. The
CBaseAudioProcessingObject base class implements much of the functionality that an APO requires. It
provides default implementations for most of the methods in the three required interfaces. The primary exception
is the IAudioProcessingObjectRT::APOProcess method.
By using CBaseAudioProcessingObject , you can more easily implement an APO. If an APO has no special
format requirements and operates on the required float32 format, the default implementations of the interface
methods that are included in CBaseAudioProcessingObject should be sufficient. Given the default
implementations, only three main methods must be implemented:
IAudioProcessingObject::IsInputFormatSuppor ted , IAudioProcessingObjectRT::APOProcess , and
ValidateAndCacheConnectionInfo .
To develop your APOs based on the CBaseAudioProcessingObject class, perform the following steps:
1. Create a class that inherits from CBaseAudioProcessingObject .
The following C++ code example shows the creation of a class that inherits from
CBaseAudioProcessingObject . For an actual implementation of this concept, follow instructions in the
Audio Processing Objects Driver Sample section to go to the Swap sample, and then refer to the
Swapapo.h file.

// Custom APO class - LFX


Class MyCustomAPOLFX: public CBaseAudioProcessingObject
{
public:
//Code for custom class goes here
...
};

Note Because the signal processing that is performed by an SFX APO is different from the signal
processing that is performed by an MFX or an EFX APO, you must create separate classes for each.
2. Implement the following three methods:
IAudioProcessingObject::IsInputFormatSuppor ted . This method handles format negotiation
with the audio engine.
IAudioProcessingObjectRT::APOProcess . This method uses your custom algorithm to perform
signal processing.
ValidateAndCacheConnectionInfo . This method allocates memory to store format details, for
example, channel count, sampling rate, sample depth, and channel mask.
The following C++ code example shows an implementation of the APOProcess method for the sample class that
you created in step 1. For an actual implementation of this concept, follow instructions in the Audio Processing
Objects Driver Sample section to go to the Swap sample, and then refer to the Swapapolfx.cpp file.

// Custom implementation of APOProcess method


STDMETHODIMP_ (Void) MyCustomAPOLFX::APOProcess (...)
{
// Code for method goes here. This code is the algorithm that actually
// processes the digital audio signal.
...
}

The following code example shows an implementation of the ValidateAndCacheConnectionInfo method. For
an actual implementation of this method, follow instructions in the Audio Processing Objects Driver Sample
section to go to the Swap sample, and then refer to the Swapapogfx.cpp file.

// Custom implementation of the ValidateAndCacheConnectionInfo method.


HRESULT CSwapAPOGFX::ValidateAndCacheConnectionInfo( ... )
{
// Code for method goes here.
// The code should validate the input/output format pair.
...
}

Note The remaining interfaces and methods that your class inherits from CBaseAudioProcessingObject are
described in detail in the Audioenginebaseapo.idl file.
For desktop PCs, you can provide a user interface to configure the features that you added to the custom APO. For
more information about this, see Implementing a UI for Configuring APOs.

Replacing System-supplied APOs


When implementing the APO interfaces, there are two approaches: you can write your own implementation, or
you can call into the inbox APOs.
This pseudocode illustrates wrapping a system APO.

CMyWrapperAPO::CMyWrapperAPO {
CoCreateInstance(CLSID_InboxAPO, m_inbox);
}

CMyWrapperAPO::IsInputFormatSupported {
Return m_inbox->IsInputFormatSupported(…);
}

This pseudocode illustrates creating your own custom APO.

CMyFromScratchAPO::IsInputFormatSupported {
my custom logic
}

When you develop your APOs to replace the system-supplied ones, you must use the same names in the following
list, for the interfaces and methods. Some of the interfaces have more methods in addition to the listed required
methods. See the reference pages for those interfaces to determine if you want to implement all the methods or
only the required ones.
The rest of the implementation steps are the same as a custom APO.
Implement the following interfaces and methods for the COM component:
IAudioProcessingObject. The required methods for this interface are: Initialize and
IsInputFormatSuppor ted.
IAudioProcessingObjectConfiguration. The required methods for this interface are: LockForProcess and
UnlockForProcess
IAudioProcessingObjectRT. The required method for this interface is APOProcess and it is the method that
implements the DSP algorithm.
IAudioSystemEffects. This interface makes the audio engine recognize a DLL as an APO.

Working with Visual Studio and APOs


When working with APOs in Visual Studio, perform these tasks for each APO project.
Link to the CRT
Drivers that are targeting Windows 10 should dynamically link against the universal CRT.
If you need to support Windows 8,1, enable static linking by setting the project properties in C/C++, Code
Generation. Set "Runtime Library" to /MT for release builds or /MTd for debug builds. This change is made,
because for a driver it is difficult to redistribute the MSVCRT<n>.dll binary. The solution is to statically link
libcmt.dll. For more information see /MD, /MT, /LD (Use Run-Time Library) .
Disable Use of an Embedded Manifest
Disable Use of an Embedded Manifest by setting project properties for your APO project. Select Manifest Tool ,
Input and Output . Then change "Embed Manifest" from the default of Yes to No. If you have an embedded
manifest, this triggers the use of certain APIs which are forbidden within a protected environment. This means that
your APO will run with DisableProtectedAudioDG=1, but when this test key is removed, your APO will fail to load,
even if it is WHQL-signed.

Packaging your APO with a Driver


When you develop your own audio driver and wrap or replace the system-supplied APOs, you must provide a
driver package for installing the driver and APOs. For Windows 10, please see Universal Windows Drivers for
Audio. Your audio related driver packages should follow the policies and packaging model detailed there.
The custom APO is packaged as a DLL, and any configuration UI is packaged as a separate UWP or Desktop Bridge
app. The APO device INF copies the DLLs to the system folders that are indicated in the associated INF CopyFile
directive. The DLL that contains the APOs must register itself by including an AddReg section in the INF file.
The following paragraphs and INF file fragments show the modifications that are necessary to use the standard
INF file to copy and register APOs.
The inf files included with the Sysvad sample illustrate how the SwapApo.dll APOs are registered.

Registering APOs for Processing Modes and Effects in the INF File
You can register APOs for specific modes using certain allowable combinations of registry keys. For more
information on which effects are available and general information about APOs, see Audio Processing Object
Architecture.
Refer to these reference topics for information on each of the APO INF file settings.
PKEY_FX_StreamEffectClsid
PKEY_FX_ModeEffectClsid
PKEY_FX_EndpointEffectClsid
PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_MFX_ProcessingModes_Supported_For_Streaming
PKEY_EFX_ProcessingModes_Supported_For_Streaming
The following INF file samples show how to register audio processing objects (APOs) for specific modes. They
illustrate the possible combinations available from this list.
PKEY_FX_StreamEffectClsid with PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid with PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
PKEY_FX_ModeEffectClsid without PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
PKEY_FX_EndpointEffectClsid without PKEY_EFX_ProcessingModes_Supported_For_Streaming
There is one additional valid combination that is not shown in these samples.
PKEY_FX_EndpointEffectClsid with PKEY_EFX_ProcessingModes_Supported_For_Streaming
SYSVAD Tablet Multi-Mode Streaming Effect APO INF Sample
This sample shows a multi-mode streaming effect being registered using AddReg entries in the SYSVAD Tablet INF
file.
This sample code is from the SYSVAD audio sample and is available on GitHub:
https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad.
This sample illustrates this combination of system effects:
PKEY_FX_StreamEffectClsid with PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid with PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

[SWAPAPO.I.Association0.AddReg]
; Instruct audio endpoint builder to set CLSID for property page provider into the
; endpoint property store
HKR,EP\0,%PKEY_AudioEndpoint_ControlPanelPageProvider%,,%AUDIOENDPOINT_EXT_UI_CLSID%

; Instruct audio endpoint builder to set the CLSIDs for stream, mode, and endpoint APOs
; into the effects property store
HKR,FX\0,%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,FX\0,%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,FX\0,%PKEY_FX_UserInterfaceClsid%,,%FX_UI_CLSID%

; Driver developer would replace the list of supported processing modes here
; Concatenate GUIDs for DEFAULT, MEDIA, MOVIE
HKR,FX\0,%PKEY_SFX_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT
%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%

; Concatenate GUIDs for DEFAULT, MEDIA, MOVIE


HKR,FX\0,%PKEY_MFX_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT
%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%

;HKR,FX\0,%PKEY_EFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%

Note that in the sample INF file, the EFX_Streaming property is commented out because the audio processing has
transitioned to kernel mode above that layer, so that streaming property is not necessary and would not be used.
It would be valid to specify a PKEY_FX_EndpointEffectClsid for discovery purposes, but it would be an error to
specify PKEY_EFX_ProcessingModes_Supported_For_Streaming. This is because the mode mix / tee happens lower
in the stack, where it is not possible to insert an endpoint APO.
Componentized APO Installation
Starting with Windows 10, release 1809, APO registration with the audio engine uses the componentized audio
driver model. Using audio componentization creates a smoother and more reliable install experience and better
supports component servicing. For more information, see Creating a componentized audio driver installation.
The following example code is extracted from the public ComponentizedAudioSampleExtension.inf and
ComponentizedApoSample.inf. Refer to the SYSVAD audio sample which is available on GitHub here:
https://github.com/Microsoft/Windows-driver-samples/tree/master/audio/sysvad.
The registration of the APO with the audio engine is done using a newly created APO device. For the audio engine
to make use of the new APO device it must be a PNP child of the audio device, sibling of the audio endpoints. The
new componentized APO design does not allow for an APO to be registered globally and used by multiple
different drivers. Each driver must register its own APO's.
The installation of the APO is done in two parts. First, the driver extension INF will add an APO device to the
system:

[DeviceExtension_Install.Devices]
AddDevice = SwapApo,,Apo_AddDevice

[Apo_AddDevice]
HardwareIds = APO\VEN_SMPL&CID_APO
Description = "Audio Proxy APO Sample"
Capabilities = 0x00000008 ; SWDeviceCapabilitiesDriverRequired

This APO device triggers the second part, the installation of the APO INF, in the SYSVAD sample this is done in
ComponentizedApoSample.inf. This INF file is dedicated to the APO device. It specifies the device class as
AudioProcessingObject and adds all of the APO properties for CLSID registration and registering with the audio
engine.

NOTE
The INF file samples shown support state separation by using in most cases the HKR registry key. Earlier samples used the
HKCR to store persistent values. The exception is that registration of Component Object Model (COM) objects, a key may be
written under HKCR. For more information, see Using a Universal INF File.

[Version]
Signature = "$WINDOWS NT$"
Class = AudioProcessingObject
ClassGuid = {5989fce8-9cd0-467d-8a6a-5419e31529d4}

[ApoComponents.NT$ARCH$]
%Apo.ComponentDesc% = ApoComponent_Install,APO\VEN_SMPL&CID_APO

[Apo_AddReg]
; CLSID registration
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%,,,%SFX_FriendlyName%
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,,0x00020000,%%SystemRoot%%\System32\swapapo.dll
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,ThreadingModel,,"Both"

;Audio engine registration
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"FriendlyName",,%SFX_FriendlyName%
...

When this INF installs the componentized APO, on a desktop system "Audio Processing Objects" will be shown in
Windows Device Manager.
Bluetooth Audio Sample APO INF Sample
This sample illustrates this combination of system effects:
PKEY_FX_StreamEffectClsid with PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid with PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
This sample code supports Bluetooth hands-free and stereo devices.
; wdma_bt.inf – example usage
...
[BthA2DP]
Include=ks.inf, wdmaudio.inf, BtaMpm.inf
Needs=KS.Registration,WDMAUDIO.Registration,BtaMPM.CopyFilesOnly,mssysfx.CopyFilesAndRegister
...
[BTAudio.SysFx.Render]
HKR,"FX\\0",%PKEY_ItemNameDisplay%,,%FX_FriendlyName%
HKR,"FX\\0",%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,"FX\\0",%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,"FX\\0",%PKEY_FX_UiClsid%,,%FX_UI_CLSID%
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
HKR,"FX\\0",%PKEY_SFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%
HKR,"FX\\0",%PKEY_MFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%
...
[Strings]
FX_UI_CLSID = "{5860E1C5-F95C-4a7a-8EC8-8AEF24F379A1}"
FX_STREAM_CLSID = "{62dc1a93-ae24-464c-a43e-452f824c4250}"
PKEY_FX_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},5"
PKEY_FX_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},6"
PKEY_SFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},5"
PKEY_MFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},6"
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"

APO INF Audio Sample


This sample INF file illustrates the following combination of system effects:
PKEY_FX_StreamEffectClsid with PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid with PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
PKEY_FX_EndpointEffectClsid without PKEY_EFX_ProcessingModes_Supported_For_Streaming

[MyDevice.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,%MyFilterName%,MyAudioInterface

[MyAudioInterface]
AddReg=MyAudioInterface.AddReg

[MyAudioInterface.AddReg]
;To register an APO for discovery, use the following property keys in the .inf (or at runtime when registering
the KSCATEGORY_AUDIO device interface):
HKR,"FX\\0",%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,"FX\\0",%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,"FX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_MODE_CLSID%

;To register an APO for streaming and discovery, add the following property keys as well (to the same
section):
HKR,"FX\\0",%PKEY_SFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDI
O_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the modes:
HKR,"FX\\0",%PKEY_MFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDI
O_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Define a custom APO and CLSID APO INF Sample


This sample shows how to define your own CLSID for a custom APO. This sample uses the MsApoFxProxy CLSID
{889C03C8-ABAD-4004-BF0A-BC7BB825E166}. CoCreate-ing this GUID instantiates a class in MsApoFxProxy.dll
which implements the IAudioProcessingObject interfaces and queries the underlying driver via the
KSPROPSETID_AudioEffectsDiscovery property set.
This INF file sample shows the [BthHfAud] section, which pulls in [MsApoFxProxy.Registration] from wdmaudio.inf
[BthHfAud.AnlgACapture.AddReg.Wave], which then registers PKEY_FX_EndpointEffectClsid as the well-known
CLSID for MsApoFxProxy.dll.
This INF file sample also illustrates the use of this combination of system effects:
PKEY_FX_EndpointEffectClsid without PKEY_EFX_ProcessingModes_Supported_For_Streaming

;wdma_bt.inf
[BthHfAud]
Include=ks.inf, wdmaudio.inf, BtaMpm.inf
Needs=KS.Registration, WDMAUDIO.Registration, BtaMPM.CopyFilesOnly, MsApoFxProxy.Registration
CopyFiles=BthHfAud.CopyList
AddReg=BthHfAud.AddReg

; Called by needs entry in oem inf


[BthHfAudOEM.CopyFiles]
CopyFiles=BthHfAud.CopyList

[BthHfAud.AnlgACapture.AddReg.Wave]
HKR,,CLSID,,%KSProxy.CLSID%
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
HKR,"FX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_DISCOVER_EFFECTS_APO_CLSID%
#endif

Sample APO Effect Registration


This sample shows the [Apo_AddReg] section from the Sysvad ComponentizedApoSample.inx. This section
registers the swap stream GUID with COM and registers the Swap Stream APO effect. The [Apo_CopyFiles] section
copies the swapapo.dll into C:\Windows\system32.
; ComponentizedApoSample.inx

...

[ApoComponent_Install]
CopyFiles = Apo_CopyFiles
AddReg = Apo_AddReg

[Apo_CopyFiles]
swapapo.dll

...

[Apo_AddReg]
; Swap Stream effect APO COM registration
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%,,,%SFX_FriendlyName%
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,,0x00020000,%13%\swapapo.dll
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,ThreadingModel,,"Both"

'''
; Swap Stream effect APO registration
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"FriendlyName",,%SFX_FriendlyName%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"Copyright",,%Copyright%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MajorVersion",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinorVersion",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"Flags",0x00010001,%APO_FLAG_DEFAULT%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinInputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxInputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinOutputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxOutputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxInstances",0x00010001,0xffffffff
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"NumAPOInterfaces",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"APOInterface0",,"{FD7F2B29-24D0-4B5C-B177-
592C39F9CA10}"
...

[Strings]
; Driver developers would replace these CLSIDs with those of their own APOs
SWAP_FX_STREAM_CLSID = "{B48DEA3F-D962-425a-8D9A-9A5BB37A9904}"

...

APO Registration
APO registration is used to support a process that dynamically matches the effects to endpoints using a weighted
calculation. The weighted calculation uses the following property stores. Every audio interface has zero or more
endpoint property stores and effects property stores registered either via the .inf or at runtime. The most specific
endpoint property store and the most specific effects property store have the highest weights and are used. All
other property stores are ignored.
Specificity is calculated as follows:
Endpoint property stores weighting
1. FX with specific KSNODETYPE
2. FX with KSNODETYPE_ANY
3. MSFX with specific KSNODETYPE
4. MSFX with KSNODETYPE_ANY
Effects property stores weighting
1. EP with specific KSNODETYPE
2. EP with KSNODETYPE_ANY
3. MSEP with specific KSNODETYPE
4. MSEP with KSNODETYPE_ANY
Numbers must start at 0 and increase sequentially: MSEP\0, MSEP\1, …, MSEP\n If (for example) EP\3 is missing,
Windows will stop looking for EP\n and will not see EP\4, even if it exists
The value of PKEY_FX_Association (for effects property stores) or PKEY_EP_Association (for endpoint property
stores) is compared against the KSPINDESCRIPTOR.Category value for the pin factory at the hardware end of the
signal path, as exposed by Kernel Streaming.
Only Microsoft inbox class drivers (which can be wrapped by a third-party developer) should use MSEP and MSFX;
all third-party drivers should use EP and FX.
APO Node Type Compatibility
The following INF file sample illustrates setting the PKEY_FX_Association key to a GUID associated with the APO.

;; Property Keys
PKEY_FX_Association = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},0"
"

;; Key value pairs


HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%

Because an audio adapter is capable of supporting multiple inputs and outputs, you must explicitly indicate the
type of kernel streaming (KS) node type that your custom APO is compatible with. In the preceding INF file
fragment, the APO is shown to be associated with a KS node type of %KSNODETYPE_ANY%. Later in this INF file,
KSNODETYPE_ANY is defined as follows:

[Strings]
;; Define the strings used in MyINF.inf
...
KSNODETYPE_ANY = "{00000000-0000-0000-0000-000000000000}"
KSNODETYPE_SPEAKER = "{DFF21CE1-F70F-11D0-B917-00A0C9223196}"
...

A value of NULL for KSNODETYPE_ANY means that this APO is compatible with any type of KS node type. To
indicate, for example, that your APO is only compatible with a KS node type of KSNODETYPE_SPEAKER, the INF file
would show the KS node type and APO association as follows:

;; Key value pairs


...
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_SPEAKER%
...

For more information about the GUID values for the different KS node types, see the Ksmedia.h header file.

Troubleshooting APO Load Failures


The following information is provided to help you understand how failure is monitored for APOs. You can use this
information to troubleshoot APOs that fail to get incorporated into the audio graph.
The audio system monitors APO return codes to determine whether APOs are being successfully incorporated into
the graph. It monitors the return codes by tracking the HRESULT values that are returned by any one of the
designated methods. The system maintains a separate failure count value for each SFX, MFX and EFX APO that is
being incorporated into the graph.
The audio system monitors the returned HRESULT values from the following four methods.
CoCreateInstance
IsInputFormatSupported
IsOutputFormatSupported
LockForProcess
The failure count value is incremented for an APO every time one of these methods returns a failure code. The
failure count is reset to zero when an APO returns a code that indicates that it was successfully incorporated into
the audio graph. A successful call to the LockForProcess method is a good indication that the APO was
successfully incorporated.
For CoCreateInstance in particular, there are a number of reasons why the returned HRESULT code could
indicate a failure. The three primary reasons are as follows:
The graph is running protected content, and the APO is not properly signed.
The APO is not registered.
The APO has been renamed or tampered with.
Also, if the failure count value for an SFX, MFX or EFX APO reaches a system-specified limit, the SFX, MFX and EFX
APOs are disabled by setting the PKEY_Endpoint_Disable_SysFx registry key to '1'. The system-specified limit is
currently a value of 10.

Related topics
Windows Audio Processing Objects
Using a Universal INF File
Creating a componentized audio driver installation
Implementing Hardware Offloaded APO Effects
6/25/2019 • 2 minutes to read • Edit Online

In Windows 10, version 1511 and later, offloading of audio processing objects (APOs) is supported. In addition to
possible performance enhancements, there are significant possible power savings available when using hardware
offloaded APOs.
Two types of APOs can be loaded during hardware offload playback.
1. Offload Stream Effects (OSFX)
2. Offload Mode Effects (OMFX)

Hardware Offloaded APO Effects Overview


Hardware Offloaded Audio Processing and Hardware Offloaded APOs
In Windows 8, the audio engine has been redesigned to work with audio streams that have been offloaded to a
hardware device that is separate from, but connected to, the computer's main audio system. This is referred to as
hardware offloading. For more information, see Hardware-Offloaded Audio Processing.
The hardware offloading feature is primarily targeted for low power scenarios with larger buffer sizes. For
example, during Low Power Audio (LPA) playback in the capable systems, the audio buffer size or periodicity is set
to 1 second so that the CPU doesn’t wake up frequently to process small buffers (e.g., at every 10 milliseconds).
Implementing hardware offloaded APOs along with hardware offloaded audio processing provides the ability to
maximize power efficiency.
The following diagram shows the audio processing objects architecture. The right side of the diagram shows an
application communicating down to hardware offloaded OSFX and OMFX effects.

Implementing Hardware Offloaded APO Effects


A hardware offloaded APO must follow the same basic requirements and design principles described in Audio
Processing Object Architecture and Implementing Audio Processing Objects.
Suppor ted Audio Format Implementation Guidelines
For hardware offloaded APOs, some additional consideration must be given to supported audio formats.
Each APO implements IAudioProcessingObject::IsInputFormatSuppor ted method which is used during audio
graph building to determine the output audio format and whether any format conversion is needed.

HRESULT IsInputFormatSupported(
[in, optional] IAudioMediaType *pOppositeFormat,
[in, optional] IAudioMediaType *pRequestedInputFormat,
[out, optional] IAudioMediaType **ppSupportedInputFormat
);

Offload render endpoint can support a variety of formats including the default format supported by the
host/system pin rendering. An Offload APO should support all of these formats so that rendering streams (with
the supported formats) don’t have to go through any additional format conversion.
An offload SFX can implement format conversions and accept a broader range of formats. For example, if the
Offload SFX provides headphone virtualizations (i.e., convert 5.1 channel audio to stereo), then it should return
S_OK for the appropriate input/output pair in this method.
An offload SFX should review the offload pin supported formats and support/extend the capabilities together.
Offload MFX cannot change the format of the input stream, but it still needs to support the variety of formats
offered by the offload endpoint and eliminate any unnecessary format conversion.
During rendering in the offload pin, only one stream is active on that pin and therefore there is no mixing of
streams. So, processing the audio at both stream-level and mode-level is not necessary. Thus audio effects may not
need to be enabled as both a stream effect and mode effect. Offloaded endpoints will support more streams, and
depending on the processing architecture for a system, Offload processing may need to be factored into SFX/MFX.
INF file entries
Implement the following INF file entries to define the effects that will be loaded during offload playback. The INF
file property key instructs the audio endpoint builder to set the CLSIDs for offloaded APOs into the effects property
store. This information is used to build the audio graph that will be used to inform upper level apps what effects
are in place.

Proper ty Key GUID

PKEY_FX_Offload_StreamEffectClsid {D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},11

PKEY_FX_Offload_ModeEffectClsid {D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},12

PKEY_SFX_Offload_ProcessingModes_Supported_For_Streamin {D3993A3F-99C2-4402-B5EC-A92A0367664B},11
g

PKEY_MFX_Offload_ProcessingModes_Supported_For_Streami {D3993A3F-99C2-4402-B5EC-A92A0367664B},12
ng

Related topics
Implementing Audio Processing Objects
Windows Audio Processing Objects
Windows Default APOs
12/5/2018 • 2 minutes to read • Edit Online

With Windows Vista the audio driver does not provide digital audio system effects. All digital signal processing for
creating system effects is provided by real-time in-process COM objects called system effects audio processing
objects (APOs).
Windows provides an Enhancements tab with the Sound applet on the Control Panel for configuring these system
effects. The APOs provided by default with Windows are shown in the following list.
Bass Boost
Bass Management
Enhanced Sound for Laptop Computers
Loudness Equalization DSP
Low Frequency Protection
Room Correction
Speaker Fill
Speaker Phantoming
Virtual Surround
Virtualized Surround Sound over Headphones
Bass Boost
12/5/2018 • 2 minutes to read • Edit Online

In systems such as laptops that have speakers with limited bass capability, it is sometimes possible to increase the
perceived quality of the audio by boosting the bass response in the frequency range that is supported by the
speaker. Bass boost improves sound on mobile devices with very small speakers by increasing gain in the mid-bass
range.
Bass Management
12/5/2018 • 2 minutes to read • Edit Online

There are two bass management modes: forward bass management and reverse bass management.
Forward bass management filters out the low frequency content of the audio data stream. The forward bass
management algorithm redirects the filtered output to the subwoofer or to the front-left and front-right
loudspeaker channels, depending on the channels that can handle deep bass frequencies. This decision is
based on the setting of the LRBig flag.
To set the LRBig flag, the user uses the Sound applet in Control Panel to access the Bass Management
Settings dialog box. The user selects a check box to indicate, for example, that the front-right and front-left
speakers are full range and this action sets the LRBig flag. To clear this flag, click the check box to clear it.
Reverse bass management distributes the signal from the subwoofer channel to the other output channels.
The signal is directed either to all channels or to the front-left and front-right channels, depending on the
setting of the LRBig flag. This process uses a substantial gain reduction when mixing the subwoofer signal
into the other channels.
The bass management mode that is used depends on the availability of a subwoofer and the bass-handling
capability of the main speakers. In Windows, the user provides this information via the Sound applet in
Control Panel.
Enhanced Sound for Laptop Computers
12/5/2018 • 2 minutes to read • Edit Online

This Windows feature allows laptop computer users to experience the quality of audio sound that is normally
associated with home theater stereo sound systems.
Loudness Equalization DSP
12/5/2018 • 2 minutes to read • Edit Online

The loudness equalization DSP ensures that the volume level across different sources of audio signal stays
constant. A TV program, for example, might be at just the right volume level whereas the commercial breaks within
the program can vary widely in volume. This requires users to adjust the volume setting accordingly. Some of
today's expensive HD-capable TVs can equalize volume so that the sound stays at a somewhat constant level. That
works well if you rely on your TV for sound playback, but most home theater and home audio enthusiasts connect
the TV audio directly to their stereo sound systems. In addition, today's loudness equalization solutions are often
not effective for different audio content and sources.
Versions of Windows with this audio effect can maintain a more uniform perceived loudness across different digital
audio files or sources than earlier Windows technologies. This means that loudness always stays within a specified
range, even for different digital signals.
Low Frequency Protection
12/5/2018 • 2 minutes to read • Edit Online

Low frequency protection is a form of forward bass management. It is used when there is no subwoofer and all the
speakers are small and lack bass capability. When you apply the low frequency protection APO, the result is the
removal of the part of the audio signal that falls below the cut-off frequency that is specified by the algorithm of
the APO.
Room Correction
12/5/2018 • 2 minutes to read • Edit Online

Windows Vista provides a new feature called room correction processing. This form of processing optimizes the
listening experience for a particular location in the room, for example, the center cushion of your couch, by
automatically calculating the optimal combination of delay, frequency response, and gain adjustments.
The room correction feature better matches sound to the image on the video screen and is also useful in cases
where desktop speakers are placed in nonstandard locations. room correction processing is an improvement over
similar features in high-end receivers because it better accounts for the way in which the human ear processes
sound.
Calibration is performed with the help of a microphone, and the procedure can be used with both stereo and
multichannel systems. The user places the microphone where the user intends to sit and then activates a wizard
that measures the room response. The wizard plays a set of specially designed tones from each loudspeaker in
turn, and measures the distance, frequency response, and overall gain of each loudspeaker from the microphone's
location.
Speaker Fill
12/5/2018 • 2 minutes to read • Edit Online

Most music is produced with only two channels and is, therefore, not optimized for the multichannel audio
equipment of the typical audio or video enthusiast. So having music emanate from only the front-left and front-
right loudspeakers is a less-than-ideal audio experience. Speaker fill simulates a multichannel loudspeaker setup. It
allows music that would otherwise be heard on only two speakers to be played on all of the loudspeakers in the
room, enhancing the spatial sensation.
Speaker Phantoming
12/5/2018 • 2 minutes to read • Edit Online

Usually, all the loudspeakers in a multichannel system, including the center and satellite loudspeakers, are always
present. However, users might not have all the expected loudspeakers or they might choose to turn one or more of
them off. A common example is a multichannel system that lacks a center loudspeaker. Speaker phantoming
reproduces the sound from the missing loudspeaker, typically by splitting it between the adjacent loudspeakers.
However, phantoming can also use other combinations such as the rear-left and rear-right or side-left and side-
right speakers.
Virtual Surround
12/5/2018 • 2 minutes to read • Edit Online

Virtual surround uses simple digital methods to combine a multichannel signal into two channels. This is done in a
way that allows the transformed signal to be restored to the original multichannel signal, using the Pro Logic
decoders that are available in most modern audio receivers. Virtual surround is ideal for a system with a two-
channel sound card and a receiver that has a surround sound enhancement mechanism.
Virtualized Surround Sound over Headphones
12/5/2018 • 2 minutes to read • Edit Online

Virtualized surround sound allows users who are wearing headphones to distinguish sound from front to back as
well as from side to side. This is done by transmitting spatial cues that help the brain localize the sounds and
integrate them into a sound field. This has the effect of making the sound feel like it transcends the headphones,
creating an "outside-the-head" listening experience. This effect is achieved by using an advanced technology called
Head Related Transfer Functions (HRTF). HRTF generates acoustic cues that are based on the shape of the human
head. These cues not only help listeners to locate the direction and source of sound but it also enhances the type of
acoustic environment that is surrounding the listener.
Audio Miniport Drivers
6/25/2019 • 2 minutes to read • Edit Online

This section describes audio miniport driver interfaces and explains how to develop adapter drivers for audio
hardware whose registers are directly accessible to the system processor over a system bus. This class of
hardware includes all ISA/DMA, PCMCIA, and PCI audio adapters.
This documentation does not discuss how to support audio devices that reside on an external bus. For information
about supporting audio devices on external buses, see USBAudio Class System Driver and AVCAudio Class System
Driver.
The following discussion assumes that the reader is familiar with kernel streaming (KS) concepts. For background
information, see Kernel Streaming.
The WDM audio driver model divides the implementation of a KS filter into port and miniport drivers that are
complementary but separate. This division makes audio hardware drivers easier to write by isolating generic filter-
implementation issues from device-specific hardware-interface issues. Hardware vendors write miniport drivers to
directly control their hardware devices, but the port drivers that implement the KS filters are provided with the
operating system. The port and miniport drivers communicate with each other through well-defined software
interfaces.
Various aspects of miniport driver development are discussed in the following topics:
Introduction to Port Class
Supporting a Device
COM in the Kernel
Adapter Driver Construction
Miniport Driver Types by Operating System
Miniport Interfaces
Installing a Port Class Audio Adapter
Port Driver Helper Objects
Power Management for Audio Devices
Version Numbers for Audio Drivers
Other Implementation Issues for Audio Drivers
Introduction to Port Class
10/23/2019 • 4 minutes to read • Edit Online

Most hardware drivers for PCI and DMA-based audio devices are based on the Port Class library, which is
accessible through the PortCls system driver (Portcls.sys). PortCls is an audio port-class driver that Microsoft
includes as part of the operating system. PortCls supplies a set of port drivers that implement most of the generic
kernel streaming (KS) filter functionality. Therefore, PortCls simplifies the task of the audio driver developer. The
hardware vendor only has to supply a set of miniport drivers to handle the hardware-specific functions of an
audio adapter.
Although hardware vendors have the option to implement their own KS filters for their audio devices, this option
is both difficult and unnecessary for typical audio devices. You can develop a KS filter to conform to either
Stream.sys, the Stream class driver, or Avstream.sys, the AVStream class driver. But a KS filter that is based on
Stream.sys cannot take advantage of the improvements that are only available in AVStream. For more information
about KS filters and PortCls, see Getting Started with WDM Audio Drivers.
The internal implementation of PortCls can evolve to take advantage of kernel streaming improvements in
successive Windows releases while it maintains compatibility with existing drivers.
PortCls is implemented in the Portcls.sys system file as an export driver (a kernel-mode DLL) and contains the
following items:
A set of helper functions that can be called by the adapter driver
A collection of audio port drivers
It is the responsibility of the hardware vendor of an audio device, to provide an adapter driver. The adapter driver
includes initialization and miniport driver-management code (including the DriverEntr y function) and a
collection of audio miniport drivers.
When the operating system loads the adapter driver, the adapter driver creates a set of miniport driver objects
and prompts the PortCls system driver to create a corresponding set of port driver objects. (The code example in
Subdevice Creation illustrates this process.) These port drivers are typically a subset of those that are available in
the Portcls.sys file. Each miniport driver binds itself to a matching port driver from Portcls.sys to form a complete
subdevice driver. The combination port-and-miniport subdevice driver is a KS filter (see Audio Filters). For
example, a typical adapter driver might contain three miniport drivers: WaveRT, DMusUART, and Topology (with
IMiniportWaveRT, IMiniportDMus, and IMiniportTopology interfaces). During initialization, these miniport drivers
are bound to the WaveRT, DMus, and Topology port drivers (with IPortWaveRT, IPortDMus, and IPortTopology
interfaces) that are contained in the Portcls.sys file. Each of these three subdevice drivers takes the form of a KS
filter. The three filters together expose the complete functionality of the audio adapter.
Typically, the port drivers provide the majority of the functionality for each class of audio subdevice. For example,
the WaveRT port driver does most of the work that is required to stream audio data to a DMA-based audio device,
whereas the miniport driver provides device-specific details such as the DMA address and device name.
Audio adapter drivers and miniport drivers are typically written in Microsoft C++ and make extensive use of COM
interfaces. The port-miniport driver architecture promotes modular design. Miniport driver writers should
implement their driver as a C++ class derived from the IMiniport interface, which is defined in the header file
Portcls.h. Hardware initialization takes place at driver load time--typically in the Init method of the IMinipor t -
derived class (for example, IMinipor tWaveRT::Init ). For more information about COM implementations of audio
miniport drivers, see COM in the Kernel.
The following diagram illustrates the relationship between port and miniport drivers and their position in the
audio stack.

In the preceding diagram, the KSEndpoint component is a system-supplied file that is provided with Windows
Vista and later versions of Windows. This component is provided in the form of a DLL (Audiokse.dll). KSEndpoint
abstracts the kernel-mode device endpoint, and provides the audio engine with access to the abstracted endpoint.
For more information about the audio engine, see Exploring the Windows Vista Audio Engine.
The legend in the preceding diagram shows the boxes that represent driver components that the vendor provides.
Note that the upper edge of each miniport driver interfaces to the lower edge of each port driver. For example, the
WaveRT port driver exposes an IPor tWaveRT interface to the WaveRT miniport driver, which exposes an
IMinipor tWaveRT interface to the port driver. These interfaces are sometimes referred to as upper-edge and
lower-edge interfaces.
The port class and AVStream class drivers are similar in that they are both WDM drivers and they both support
the WDM kernel streaming architecture. However, port class drivers differ from AVStream class drivers in the
areas of multiprocessor handling and reentrancy. Port class drivers do the following:
Use a three-tiered approach that combines the class driver, port drivers, and vendor-supplied miniport
drivers.
Have a restricted number of audio functions, allowing miniport drivers to operate closer to the audio
hardware.
Allow several port or miniport drivers to be linked for a specific device. This feature allows for better
support for multifunction cards.
Do not support external buses (for example, USB). All port drivers support devices that reside on the
system buses (PCMCIA, and PCI).
The terminology for describing WDM audio ports and miniport drivers differs in some respects from the terms
that are used for other classes of Windows drivers. These differences are explained in WDM Audio Terminology.
This section discusses the following topics:
Implementation of Function-Specific Interfaces
PortCls Support by Operating System
Implementation of Function-Specific Interfaces
10/23/2019 • 2 minutes to read • Edit Online

A typical audio adapter card contains a collection of audio hardware functions, which the adapter driver can expose
to the WDM audio system through a corresponding collection of IMiniportXxx interfaces. All IMiniportXxx
interfaces inherit from IMiniport. Each type of miniport interface--wave, MIDI, topology, and so on--encapsulates a
miniport driver for controlling a particular type of audio function on an adapter card. A driver can also expose
several instances of the same miniport interface to represent multiple instances of the same (or similar) hardware
functions.
For more information, see Miniport Interfaces.
PortCls Support by Operating System
10/23/2019 • 2 minutes to read • Edit Online

The following lists contain all the functions and interfaces that the PortCls system driver (Portcls.sys) supports. If a
list item is preceded by an asterisk (*), then PortCls supports that item only in Windows XP and later. If a list item is
preceded by a double asterisk (**), then PortCls supports that item only in Windows Vista and later. All other list
items are supported by all versions of PortCls (Windows 2000 and later, and Windows Me/98).
Audio Port Class Functions
PcAddAdapterDevice
* PcAddContentHandlers
PcCompleteIrp
PcCompletePendingProper tyRequest
* PcCreateContentMixed
* PcDestroyContent
PcDispatchIrp
* PcFor wardContentToDeviceObject
* PcFor wardContentToFileObject
* PcFor wardContentToInterface
PcFor wardIrpSynchronous
* PcGetContentRights
PcGetDeviceProper ty
PcGetTimeInter val
PcInitializeAdapterDriver
PcNewDmaChannel
PcNewInterruptSync
PcNewMinipor t
PcNewPor t
PcNewRegistr yKey
PcNewResourceList
PcNewResourceSublist
PcNewSer viceGroup
PcRegisterAdapterPowerManagement
PcRegisterIoTimeout
PcRegisterPhysicalConnection
PcRegisterPhysicalConnectionFromExternal
PcRegisterPhysicalConnectionToExternal
PcRegisterSubdevice
PcRequestNewPowerState
PcUnregisterIoTimeout
Audio Helper Object Interfaces
IDmaChannel
IDmaChannelSlave
* IDrmPort
* IDrmPort2
IInterruptSync
IMasterClock
* IPortClsVersion
IPortEvents
* IPreFetchOffset
IRegistryKey
IResourceList
IServiceGroup
IServiceSink
** IUnregisterPhysicalConnection
** IUnregisterSubdevice
Audio Port Object Interfaces
IPort
IPortDMus
IPortMidi
IPortTopology
IPortWaveCyclic
IPortWavePci
** IPortWaveRT
Audio Miniport Object Interfaces
IMiniport
IMiniportDMus
IMiniportMidi
IMiniportTopology
IMiniportWaveCyclic
IMiniportWavePci
** IMiniportWaveRT
Audio Miniport Auxiliary Interfaces
* IMusicTechnology
* IPinCount
Audio Stream Object Interfaces
IAllocatorMXF
* IDrmAudioStream
IMiniportMidiStream
IMiniportWaveCyclicStream
IMiniportWavePciStream
** IMiniportWaveRTStream
IMXF
IPortWavePciStream
** IPortWaveRTStream
ISynthSinkDMus
Audio Power Management Interfaces
IAdapterPowerManagement
IPowerNotify
Supporting a Device
10/23/2019 • 2 minutes to read • Edit Online

The PortCls system driver (Portcls.sys) provides several built-in port drivers to support audio devices that render
and capture wave and MIDI streams.
All port drivers expose interfaces that derive from base interface IPort. IPor t inherits the methods from base
interface IUnknown . IPor t provides the following additional methods:
IPor t::GetDeviceProper ty
Retrieves an audio adapter's Plug and Play properties from the registry. IPor t::Init
Initializes the port object. IPor t::NewRegistr yKey
Creates a new registry key or opens an existing key. PortCls implements the following port drivers:
WaveCyclic Port Driver
WavePci Port Driver
WaveRT Port Driver
Topology Port Driver
MIDI Port Driver
DMus Port Driver
WaveRT Port Driver
12/5/2018 • 2 minutes to read • Edit Online

This section provides information about the wave real-time (WaveRT) port driver for Windows Vista and later
versions of the Microsoft Windows operating system.
This section includes the following topics:
Introducing the WaveRT Port Driver
Understanding the WaveRT Port Driver
Introducing the WaveRT Port Driver
10/23/2019 • 2 minutes to read • Edit Online

In Windows Vista and later operating systems, support is provided for a wave real-time (WaveRT) port driver that
achieves improved performance but uses a simple cyclic buffer for rendering and capturing audio streams.
The improved performance of the WaveRT port driver includes the following characteristics:
Low-latency during wave-capture and wave-rendering
A glitch-resilient audio stream
Like the WaveCyclic and WavePci port drivers in earlier versions of Microsoft Windows, the WaveRT port driver
provides the generic functionality for a kernel streaming (KS) filter. The WaveRT port driver provides support for
audio devices that can do the following:
They can connect to a system bus, for example the PCI Express bus.
They can playback or record wave data (audio data that is described by a WAVEFORMATEX or
WAVEFORMATEXTENSIBLE structure).
They can use the improved scheduling support that is available in Windows Vista, to reduce the latency of
an audio stream.
If you want your audio device to take advantage of the improvements in audio offered in Windows, your audio
device must be able to play or capture audio data with little or no intervention by the driver software during
streaming. A properly designed audio device that uses the WaveRT port driver requires little or no help from the
driver software from the time the audio stream enters the run state until it exits from that state.
The main client of the WaveRT port driver is the audio engine running in shared mode. For more information
about the Windows Vista audio engine, see the Exploring the Windows Vista Audio Engine topic.
Understanding the WaveRT Port Driver
6/25/2019 • 3 minutes to read • Edit Online

The WaveRT port driver combines the simplicity of the previous WaveCyclic port driver with the hardware-
accelerated performance of the WavePci port driver.
The WaveRT port driver eliminates the need to continually map and copy audio data by providing its main client
(typically, the audio engine) with direct access to the data buffer. This direct access also eliminates the need for the
driver to manipulate the data in the audio stream. The WaveRT port driver thus accommodates the needs of the
direct memory access (DMA) controllers that some audio devices have.
To distinguish itself from other wave-render and wave-capture devices, the WaveRT port driver registers itself
under KSCATEGORY_REALTIME in addition to KSCATEGORY_AUDIO , KSCATEGORY_RENDER and
KSCATEGORY_CAPTURE . This self-registration occurs during the installation of the adapter driver.
In Windows Vista and later operating systems, when the operating system starts and the audio engine is initialized,
the audio engine enumerates the KS filters that represent the audio devices. During the enumeration, the audio
engine instantiates the drivers for the audio devices that it finds. This process results in the creation of filter objects
for these devices. For WaveRT audio devices, the resulting filter object has the following components:
An instance of the WaveRT port driver to manage the generic system functions for the filter
An instance of the WaveRT miniport driver to handle all the hardware-specific functions of the filter
After the filter object is created, the audio engine and the WaveRT miniport driver are ready to open an audio
stream for the type of audio processing needed. To prepare the KS filter for audio rendering (playback), for
example, the audio engine and the WaveRT miniport driver do the following to open a playback stream:
1. The audio engine opens a pin on the KS filter, and the WaveRT miniport driver creates an instance of the pin.
When the audio engine opens the pin, it also passes the wave format of the stream to the driver. The driver
uses the wave format information to select the proper buffer size in the next step.
2. The audio engine sends a request to the miniport driver for a cyclic buffer of a particular size to be created.
The term cyclic buffer refers to the fact that when the buffer position register reaches the end of the buffer
in a playback or record operation, the position register can automatically wrap around to the beginning of
the buffer. Unlike the WaveCyclic miniport driver that sets up a contiguous block of physical memory, the
WaveRT miniport driver does not need a buffer that is contiguous in physical memory. The driver uses the
KSPROPERTY_RTAUDIO_BUFFER property to allocate space for the buffer. If the hardware of the audio
device cannot stream from a buffer of the requested size, the driver works within the resource limitations of
the audio device to create a buffer that is the closest in size to the originally requested size. The driver then
maps the buffer into the DMA engine of the audio device and makes the buffer accessible to the audio
engine in user-mode.
3. The audio engine schedules a thread to periodically write audio data to the cyclic buffer.
4. If the hardware of the audio device does not provide direct support for cyclic buffers, the miniport driver
periodically reprograms the audio device to keep using the same buffer. For example, if the hardware does
not support buffer looping, the driver must set the DMA address back to the start of the buffer each time it
reaches the end of the buffer. This update can be done in either an interrupt service routine (ISR) or a high-
priority thread.
The resulting configuration supplies a glitch-resilient audio signal on audio device hardware that either supports
cyclic buffers or works with the miniport driver to regularly update its hardware.
To prepare a KS filter for audio capture (recording), the audio engine and the WaveRT miniport driver use similar
steps to open a record stream.
One of the performance improvements provided by the WaveRT port driver is a reduction in the delay in the end-
to-end processing of the audio stream during wave-render or wave-capture. This delay is referred to as stream
latency.
For more information about these two types of stream latency, see the following topics.
Stream Latency during Playback
Stream Latency during Recording
For information about how to develop a WaveRT miniport driver that complements the WaveRT port driver, see the
Developing a WaveRT Miniport Driver topic.
Stream Latency During Playback
6/25/2019 • 3 minutes to read • Edit Online

While an audio playback stream is in the Run state, the role of the WaveRT port driver is minimal. As shown in the
following diagram, during playback the client of the WaveRT port driver writes its data to the cyclic buffer and the
audio device then reads this data from the buffer. This activity requires no intervention from the port driver. In
other words, audio data flows directly between the user-mode application and the audio hardware without being
touched by any kernel-mode software components.
In the diagram, the write and play positions continually progress from left to right as the audio data stream flows
through the cyclic buffer. The buffer is described as cyclic because when the play position or the write position
reaches the end of the buffer it automatically wraps around to the start of the buffer.
Stream latency during playback has two main sources, designated in the following diagram as A and B.

In the preceding diagram, the Write Position is the location just past the last sample that the client wrote to the
buffer. The Play Position is the sample that the audio device is currently playing through the speaker.
The latency from the time that the client writes an audio sample to the buffer until the audio device plays it is
simply the separation between the write and play positions. This separation is the sum of the following two sources
of latency (marked as A and B in the diagram):
Latency A : After the audio device reads data from the buffer, the data resides in a hardware "first in, first out"
(FIFO) buffer until the audio device clocks the data through the digital-to-analog converter (DAC).
Latency B : After the client writes data to the cyclic buffer, the data resides in the buffer until the audio device reads
the data.
The client has no control over latency A, which depends entirely on the hardware. A typical FIFO might store
enough samples to feed the DAC for roughly 64 ticks of the sample clock. However, the client does control latency
B. Making latency B too large introduces unnecessary delays into the system; however, making it too small risks
depleting the audio device.
Although the client can set up a timer to periodically activate its buffer-writing thread, this method does not
achieve the smallest latency. To further reduce latency, the client can configure the device to generate a hardware
notification each time the device finishes reading a new block of playback data from the buffer. In this case, the
client thread is activated by hardware notifications instead of by a timer.
By having the audio device notify the client each time it finishes reading a block of data from the buffer, the client
can make the latency smaller than would otherwise be practical.
The client can obtain a summary of the delays that contribute to stream latency by sending a
KSPROPERTY_RTAUDIO_HWL ATENCY request to the WaveRT port driver.
After the client determines the amount of separation to maintain between the write and play positions, the client
monitors changes in the play position to determine how far to advance the write position. In Windows Server 2008
and later operating systems, the client sends out a KSPROPERTY_RTAUDIO_POSITIONREGISTER property
request to determine the play position. Support for this feature is provided by improvements in the PortCls system
driver.
If the audio device has a position register as shown in the preceding diagram, the property request maps the
register to a virtual memory address that is accessible to the user-mode client. After the position register is
mapped, the client can read the contents of the memory address to determine the current play position.
Stream Latency During Recording
6/25/2019 • 2 minutes to read • Edit Online

While an audio record stream is in the Run state, the role of the WaveRT port driver is minimal. As shown in the
following diagram, during the recording process, the audio device captures audio data and writes it to the cyclic
buffer. The audio engine then reads this data from the buffer. This activity requires no intervention from the port
driver. In other words, audio data flows directly between the audio hardware and the user-mode application
without being touched by any kernel-mode software components.
In the following diagram, the record and read positions continually progress from left to right as the stream flows
through the buffer. When the record or the read position reaches the end of the buffer, it wraps around to the start
of the buffer.

The preceding diagram identifies the Record Position as the buffer location of the sample that the audio device is
currently recording (capturing from the microphone through the analog-to-digital converter, or ADC). Note that the
record position is the future buffer location into which the audio device writes the sample after it passes through
the FIFO. The Read Position is the buffer position from which the audio engine reads the next sample.
The latency from the time that the audio device captures an audio sample in the ADC until the client reads it is
simply the separation between the record and read positions. This separation is the sum of the following sources of
latency (marked as A and B in the diagram):
Latency A : After capturing data from the ADC, the audio device stores the data in a hardware FIFO until it can
write the data to the cyclic buffer.
Latency B : After the audio device writes data to the cyclic buffer, the data resides in the buffer until the client reads
the data.
The client has no control over latency A, which depends entirely on the hardware. A typical FIFO might store
roughly 64 samples from the ADC. However, the client does control latency B. Making latency B too large
introduces unnecessary delays into the system, but making it too small risks reading data too early, before the
audio device has written into the buffer.
Although the client can set up a timer to periodically activate its buffer-reading thread, this method does not
achieve the smallest latency. To further reduce latency, the client can configure the audio device to generate a
hardware notification each time the device finishes writing a new block of capture data to the buffer. In this case,
the client thread is activated by hardware notifications instead of by a timer.
By having the audio device periodically notify the audio engine, the client can make the latency smaller than would
otherwise be practical.
The client (typically the audio engine) can obtain a summary of the delays that the audio device contributes to
stream latency by sending a KSPROPERTY_RTAUDIO_HWL ATENCY request to the WaveRT port driver.
After the client determines the amount of separation to maintain between the record and read positions, the client
monitors changes in the record position to determine how much the read position should lag. In Windows Server
2008 and later operating systems, the client sends out a KSPROPERTY_AUDIO_POSITION or a
KSPROPERTY_RTAUDIO_POSITIONREGISTER property request to determine the record position. The latter
request method is more efficient because it allows the client to read the record position directly without the
transition to a kernel-mode routine for the information.
Topology Port Driver
10/23/2019 • 2 minutes to read • Edit Online

The Topology port driver exposes the topology of the audio adapter's mixing hardware. For example, the hardware
that mixes the playback streams from the wave renderer and MIDI synthesizer in a typical adapter can be modeled
as a set of control nodes (volume, mute, and sum) plus the data paths that connect the nodes. This topology is
exposed as a set of controls and mixer lines by the Windows multimedia mixer API (see Kernel Streaming Topology
to Audio Mixer API Translation). The adapter driver provides a corresponding Topology miniport driver that binds
to the Topology port driver to form a topology filter.
The Topology port driver exposes an IPortTopology interface to the miniport driver. IPortTopology inherits the
methods from base interface IPort; it provides no additional methods.
The Topology port and miniport driver objects communicate with each other through their respective
IPortTopology and IMiniportTopology interfaces.
MIDI Port Driver
10/23/2019 • 2 minutes to read • Edit Online

The MIDI port driver manages a MIDI synthesizer or capture device. The adapter driver provides a corresponding
MIDI miniport driver that binds to the MIDI port driver object to form a MIDI filter (see MIDI and DirectMusic
Filters) that can capture or render a MIDI stream.
The MIDI port driver exposes an IPortMidi interface to the miniport driver. IPor tMidi inherits the methods in base
interface IPort. IPor tMidi provides the following additional methods:
IPor tMidi::Notify
Notifies the port driver that the MIDI synthesizer or capture device has advanced to a new position in the MIDI
stream. IPor tMidi::RegisterSer viceGroup
Registers a service group object with the port driver. A service group contains a list of one or more service routines
that are to be called when the miniport driver calls Notify ; for more information, see Service Sink and Service
Group Objects.
The MIDI port and miniport driver objects communicate with each other through their respective IPor tMidi and
IMiniportMidi interfaces. The miniport driver uses the port driver's IPor tMidi interface to notify the port driver of
hardware interrupts. In addition, the port driver communicates with the miniport driver's stream objects through
their IMiniportMidiStream interfaces.
In Windows XP and later, the IPor tMidi and IPortDMus interfaces are both implemented in a single internal driver
module. This consolidation is facilitated by the similarity of these two interfaces. For example, the same methods
are defined for both interfaces. Applications written for previous versions of Windows should see no change in the
behavior of the IPor tMidi and IPor tDMus interfaces resulting from consolidation of the MIDI and DMus port
drivers.
DMus Port Driver
10/23/2019 • 2 minutes to read • Edit Online

The DMus port driver manages a Microsoft DirectMusic synthesizer or capture device. In contrast to the MIDI port
driver, which supports only simple MIDI devices, the DMus port driver supports devices with advanced MIDI
capabilities such as precision sequencer timing, downloadable sounds (DLS), and channel groups. The adapter
driver implements a corresponding DMus miniport driver that binds to the DMus port driver to form a
DirectMusic filter (see MIDI and DirectMusic Filters) that can render or capture a MIDI stream.
The DMus port driver exposes an IPortDMus interface to the miniport driver. IPor tDMus inherits the methods in
base interface IPort. IPor tDMus provides the following additional methods:
IPor tDMus::Notify
Notifies the port driver that the MIDI synthesizer or capture device has advanced to a new position in the MIDI
stream.
IPor tDMus::RegisterSer viceGroup
Registers a service group object with the port driver. The registered service group contains a list of one or more
service routines that are called by the port driver when the miniport driver calls Notify ; for more information, see
Service Sink and Service Group Objects.
The DMus port driver also creates a memory allocator for each stream and exposes the allocator's IAllocatorMXF
interface to the miniport driver's stream object. IAllocatorMXF inherits the methods in base interface IMXF.
IAllocatorMXF provides the following additional methods:
IAllocatorMXF::GetBuffer
Gets a buffer for a MIDI event or list of events that is too large to fit within a DMUS_KERNEL_EVENT structure.
IAllocatorMXF::GetBufferSize
Gets the size in bytes of the buffer retrieved by the GetBuffer method.
IAllocatorMXF::GetMessage
Gets a message buffer containing storage for a single structure of type DMUS_KERNEL_EVENT.
IAllocatorMXF::PutBuffer
Not used. The DMus port and miniport driver objects communicate with each other through their respective
IPor tDMus and IMiniportMidi interfaces. In addition, the port driver communicates with the miniport driver's
stream objects through their IMXF interfaces, and a miniport driver's stream object communicates with the port
driver's allocator through its IAllocatorMXF interface.
For more information about driver support for DirectMusic, see Synthesizer Miniport Driver Overview.
In Windows XP and later, the IPor tDMus and IPortMidi interfaces are both implemented in a single internal driver
module. This consolidation is facilitated by the similarity of these two interfaces. For example, the same methods
are defined for both interfaces. Applications written for previous versions of Windows should see no change in the
behavior of the IPor tMidi and IPor tDMus interfaces resulting from consolidation of the MIDI and DMus port
drivers.
Adapter Driver Construction
10/23/2019 • 2 minutes to read • Edit Online

Driver support for a particular audio adapter card takes the form of an adapter driver. An adapter driver consists of
the following:
General adapter code that performs driver startup and initialization, and that implements any operations
that are common to all audio functions on the adapter card.
A set of miniport drivers that manage specific audio functions on the adapter card.
The hardware vendor supplies both the general adapter code and the code for any miniport drivers that are not
provided by the system.
For an example of the general adapter code, see the implementation of the CAdapterCommon interface in the
Sb16, Msvad, and Ac97 sample audio drivers in the Microsoft Windows Driver Kit (WDK).
By using a layered approach, the vendor can write an adapter driver that operates on one of several levels,
depending on the adapter's hardware functionality. When determining the level of support that a given hardware
function requires, the vendor should first determine whether a system-supplied miniport driver already exists that
supports the function (see the PcNewMinipor t function's list of system-supplied miniport drivers). If not, the
vendor must implement a proprietary miniport driver but might still be able to use one of the system-supplied
port drivers (see the PcNewPor t function's list of system-supplied port drivers).
To implement WDM support for a device, follow these steps:
1. If a system-supplied miniport driver already supports the hardware function, use the existing miniport
driver to manage the function.
2. If the hardware function is not compatible with a system-supplied miniport driver, then determine whether
the function is compatible with at least one of the system-supplied port drivers. If a system-supplied port
driver supports the hardware function, write the portion of the miniport driver that manages the function.
That miniport driver should comply with the specification for the miniport interface that the owning port
driver expects.
3. If no system-supplied port driver supports the hardware function, write a minidriver to support the
function. The minidriver should comply with the interface specification for the streaming class driver.
This section discusses the following topics:
Startup Sequence
Subdevice Creation
Startup Sequence
10/23/2019 • 2 minutes to read • Edit Online

Because the adapter driver is installed as a kernel-mode driver service, the operating system loads the adapter
driver at system-startup time and calls the driver's DriverEntr y routine. The DriverEntr y routine receives two
parameters: a driver object and a registry path name. DriverEntr y should call the PortCls function
PcInitializeAdapterDriver with the driver-object and registry-path name parameters plus a third parameter,
which is a pointer to the adapter driver's AddDevice function.
In the following example, the driver's DriverEntr y function passes the function pointer MyAddDevice , which points
to the driver's AddDevice function, as the third parameter to the PcInitializeAdapterDriver routine.

NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
return PcInitializeAdapterDriver(DriverObject, RegistryPath, MyAddDevice);
}

The PcInitializeAdapterDriver routine installs the supplied AddDevice routine in the driver object's driver
extension and installs the PortCls driver's IRP handlers in the driver object itself.
The following code is an example implementation of the driver's MyAddDevice function.

#define MAX_MINIPORTS 6 // maximum number of miniports


NTSTATUS
MyAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
)
{
return PcAddAdapterDevice(DriverObject, PhysicalDeviceObject, MyStartDevice,
MAX_MINIPORTS, 0);
}

This function calls the PortCls function PcAddAdapterDevice and associates it with the physical device object
(PDO) that is supplied by the system. The new FDO is created with an extension that PortCls uses to store context
information about the device. This context includes the MyStartDevice function pointer that is supplied by
MyAddDevice .

After the operating system determines what resources (interrupts, DMA channels, I/O port addresses, and so on)
to assign to the device, it sends the device a request to start (IRP_MN_START_DEVICE ). In response to this
request, the request handler in the PortCls driver calls the adapter driver's MyStartDevice function, which is shown
in the following example code:
NTSTATUS
MyStartDevice(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PRESOURCELIST ResourceList
)
{
...
}

The request handler supplies MyStartDevice with pointers to the device object, IRP_MN_START_DEVICE request,
and resource list (see IResourceList). The MyStartDevice function partitions the resource list into the resources that
are required for each miniport driver that needs to be started. The function then starts each miniport driver and
returns control to PortCls, which completes the IRP and returns control to the operating system.
For more examples of driver startup code, see the sample audio adapter drivers in the Microsoft Windows Driver
Kit (WDK).
Subdevice Creation
10/23/2019 • 2 minutes to read • Edit Online

The term subdevice is used to describe the binding of the four components that are listed in the following table.

C O M P O N EN T DESC RIP T IO N

Miniport object An object that exposes the miniport driver's


IMiniportXxx interface

Port object An object that exposes the port driver's IPortXxx


interface

Resource list object An object containing a list of adapter driver resources


that are assigned to the subdevice

Reference string A name added to the device path name to specify a


subdevice during filter creation

A subdevice's IMiniportXxx and IPortXxx interfaces inherit from base interfaces IMiniport and IPort, respectively.
The PortCls system driver does not distinguish between the port driver and the miniport driver. It simply
requires an object, such as the port object, with an interface that can handle system-generated requests.
Similarly, PortCls is not directly involved in managing resources. It only needs to bind the request handler (the
port driver) to a resource list. The adapter driver is responsible for binding the port, miniport, and resource list
objects together.
The following code example shows how the adapter driver performs these actions:
//
// Instantiate the port by calling a function supplied by PortCls.
//
PPORT port;
NTSTATUS ntStatus = PcNewPort(&port, PortClassId);

if (NT_SUCCESS(ntStatus))
{
PUNKNOWN miniport;
//
// Create the miniport object.
//
if (MiniportCreate) // a function to create a proprietary miniport
{
ntStatus = MiniportCreate(&miniport,
MiniportClassId, NULL, NonPagedPool);
}
else // Ask PortCls for one of its built-in miniports.
{
ntStatus = PcNewMiniport((PMINIPORT*)&miniport,
MiniportClassId);
}

if (NT_SUCCESS(ntStatus))
{
//
// Bind the port, miniport, and resources.
//
ntStatus = port->Init(DeviceObject,
Irp, miniport, UnknownAdapter, ResourceList);
if (NT_SUCCESS(ntStatus))
{
//
// Hand the port driver and the reference
// string to PortCls.
//
ntStatus = PcRegisterSubdevice(DeviceObject,
Name, port);
}

//
// We no longer need to reference the miniport driver.
// Either the port driver now references it,
// or binding failed and it should be deleted.
//
miniport->Release();
}

//
// Release the reference that existed when PcNewPort() gave us
// the pointer in the first place. This reference must be released
// regardless of whether the binding of the port and miniport
// drivers succeeded.
//
port->Release();
}

For information about the PortCls function calls in the preceding code example, see PcNewPor t ,
PcNewMinipor t , and PcRegisterSubdevice .
Miniport Driver Types by Operating System
6/25/2019 • 2 minutes to read • Edit Online

When you develop your own audio driver, you must determine whether your driver will work in conjunction with
the PortCls system driver (Portcls.sys) or with the AVStream class system driver. If a video stream is not necessary,
you will probably want a driver that works with the PortCls system driver. For more information about these two
types of system drivers, see the Introduction to Port Class and AVStream Overview topics.
The PortCls system driver (Portcls.sys) provides several built-in port drivers to support audio devices that render
and capture wave and MIDI streams. Typically, a port driver provides the majority of the functionality for each class
of audio subdevice.
Each port driver works in conjunction with a miniport driver. The miniport driver manages the hardware-
dependent functions of a wave-rendering or wave-capture device. In other words, the miniport driver provides
support for functionality that is specific to the hardware of the third party audio device.
The type of miniport driver that you develop is determined by your target Windows operating system and the
features that are provided by your audio device. The following table shows the different types of miniport drivers
and the Windows operating systems that support them.

M IN IP O RT DRIVER W IN DO W S XP W IN DO W S VISTA W IN DO W S 7

WaveCyclic x x x

WavePci x x x

WaveRT x x

Topology x x x

MIDI x x x

DMus x x x

Each port driver implements an interface, which it presents to the miniport driver. To communicate with the port
driver, the miniport driver must also implement an interface. For more information about the interfaces that are
implemented by the miniport drivers, see Miniport Interfaces.
Note When you develop audio drivers for Windows Vista and later operating systems, be aware of the following:
You cannot obtain a logo qualification for a WaveCyclic- or a WavePci -based audio driver.
There is no support for kernel-mode software synthesizers for DMus. However, support is provided for
hardware MIDI I/O.
COM in the Kernel
12/5/2018 • 2 minutes to read • Edit Online

Audio port and miniport drivers export device driver interfaces (DDIs) that conform to the Component Object
Model (COM). For background information about COM interfaces, see the COM section of the Microsoft Windows
SDK documentation.
All COM interfaces inherit from the IUnknown interface, which has the methods AddRef , Quer yInterface , and
Release . Because these methods are common to all COM interfaces, the reference pages for the WDM audio
driver interfaces do not explicitly describe them.
This section discusses the following topics:
Function Tables for Miniport Drivers
Creating Audio Driver Objects
Reference-Counting Conventions for COM Objects
Function Tables for Miniport Drivers
12/5/2018 • 2 minutes to read • Edit Online

A generic miniport driver's upper-edge interfaces (see WDM Audio Terminology) consist of function tables. Some
non-audio miniport drivers supply the function table to the port driver during registration, at which time the
miniport driver informs the port driver of the size of the context structure that the miniport driver will require. The
port driver copies the function table to some private location, allocates the context structure, and calls an
initialization function in the function table, passing a pointer to the context structure.
Similarly, audio miniport drivers use function tables, but they are statically allocated and do not need to be copied
by the port driver. The port driver also retrieves its context ("object") memory from a specified pool and installs a
pointer to the function table into the context. Because the function table pointer is always the first field in the
context, the port driver needs only a context pointer and can access the function table through the context.
This approach was taken because COM supplies a solid, efficient, widely-understood model for creating abstracted
objects. The audio miniport driver model leverages industry experience with COM and the body of COM literature.
Objects can be implemented and used in C or C++. Assembly language can also be used, but should only be used
where portability is not required.
Creating Audio Driver Objects
10/23/2019 • 2 minutes to read • Edit Online

In user mode, COM objects are created using a function such as CoCreateInstance (described in the Microsoft
Windows SDK documentation), where the client is unaware of how the memory required for the object is allocated.
In kernel mode, however, where the allocation of memory tends to be tightly controlled, a different method of
object creation is necessary.
The audio driver model uses the concept of the COM interface, as defined by the IUnknown interface. Audio
drivers, however, are not required to access the registry or to use mechanisms such as in-process servers. Miniport
drivers are not required to support aggregation.
By convention, the function used to create a particular class of objects always takes the same form:

NTSTATUS CreateMyObject(
OUT PUNKNOWN *Unknown,
IN REFGUID ClassId,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType
);

Parameters
Unknown
Pointer to a pointer to an IUnknown interface. The function outputs a reference to the newly created object
through Unknown.
ClassId
Specifies the class GUID, which is passed by reference. This parameter is used only if the function creates objects of
multiple classes. Otherwise, it is set to NULL .
OuterUnknown
Specifies the IUnknown interface for aggregating the new object. This parameter can be set to NULL to indicate
that no aggregation is required.
PoolType
Specifies the type of memory pool from which the object is to be allocated (see POOL_TYPE ).
The first three parameters are identical to the parameters of the COM CoCreateInstance function. For an example
of a creation function of this type, see the CreateMinipor tMidiFM function in the Fmsynth sample audio driver in
the Microsoft Windows Driver Kit (WDK).
Another convention is to supply a New Xxx function for a class. Such functions provide an easy way to instantiate
(create and initialize) an object, as shown in the following example:

NTSTATUS NewMyObject(
OUT PMYINTERFACE *InterfacePointer,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
// ...more parameters
);

The NewMyObject function creates and initializes an object, and then passes a pointer back to the interface.
Because the initialization parameters are class-specific, so is the prototype of a New Xxx function. The New Xxx
function provides convenient access to the constructor for the object.
For an example of a New Xxx function of this type, see PcNewDmaChannel .
Reference-Counting Conventions for COM Objects
10/23/2019 • 2 minutes to read • Edit Online

The methods in the audio interfaces follow a general set of rules for counting references on the COM objects that
they take as input parameters or return as output parameters. These rules, and their exceptions, are summarized
below. For more information about COM interfaces, see the COM section of the Microsoft Windows SDK
documentation.
Reference Counting on Input Parameters
When calling a method that takes a reference to an object X as an input parameter, the caller must hold its own
reference on the object for the duration of the call. This behavior is necessary to ensure that the method's pointer
to object X remains valid until it returns. If the object Y that implements this method needs to hold a reference to
object X beyond the return from this method, the method should call AddRef on object X before returning. When
object Y later finishes using object X, it should call Release on object X.
For example, the ISer viceGroup::AddMember method calls AddRef on the IServiceSink object that it adds to its
service group. To complement this behavior, the ISer viceGroup::RemoveMember method calls Release on the
IServiceSink object that it removes from the service group.
Reference Counting on Output Parameters
A method that passes an object reference to the caller through an output parameter should call AddRef on the
object before it returns (or before it releases its own reference to the object). This behavior is necessary to ensure
that the caller holds a valid reference upon return from the call. The caller is responsible for calling Release on the
object when it has finished using it.
For example, the IMinipor tWaveCyclic::NewStream method calls AddRef on the stream, service group, and
DMA channel objects that it outputs to the caller (the WaveCyclic port driver). The caller is responsible for releasing
these references when it no longer needs them. For an implementation of the
IMinipor tWaveCyclic::NewStream method that shows this behavior, see the Sb16 sample adapter in the
Microsoft Windows Driver Kit (WDK).
Exceptions to the Rules
For a description of the unconventional reference counting that this method performs on its DmaChannel output
parameter, see IMinipor tWavePci::NewStream .
Miniport Interfaces
10/23/2019 • 2 minutes to read • Edit Online

As described in Supporting a Device, the PortCls system driver provides a set of built-in port drivers for managing
wave and MIDI devices. To use one of these port drivers to manage a particular type of audio device, the adapter
driver must provide a corresponding miniport driver that complements the port driver by managing all the
device's hardware-dependent functions.
This section discusses the following miniport driver types:
WaveRT Miniport Driver
Complements the WaveRT port driver by managing the hardware-dependent functions of a wave rendering or
capture device that uses a cyclic buffer for audio data.
Topology Miniport Driver
Complements the Topology port driver by managing the various hardware controls (for example, volume level) in
the audio adapter's mixer circuitry.
MIDI Miniport Driver
Complements the MIDI port driver by managing the hardware-dependent functions of a simple MIDI device.
DMus Miniport Driver
Complements the DMus port driver by managing the hardware-dependent functions of an advanced MIDI device.
Each port driver implements an IPor tXxx interface, which it presents to the miniport driver. In turn, the miniport
driver must implement an IMinipor tXxx interface, which the port driver uses to communicate with the miniport
driver. The following table shows the IPor tXxx interface and the corresponding IMinipor tXxx interface for each
device type.

DEVIC E T Y P E P O RT DRIVER IN T ERFA C E M IN IP O RT DRIVER IN T ERFA C E

WaveCyclic IPortWaveCyclic IMiniportWaveCyclic

WavePci IPortWavePci IMiniportWavePci

WaveRT IPortWaveRT IMiniportWaveRT

Topology IPortTopology IMiniportTopology

MIDI IPortMidi IMiniportMidi

DirectMusic IPortDMus IMiniportDMus

In the preceding table, all IPor tXxx interfaces are derived from base interface IPort, and all IMinipor tXxx
interfaces are derived from IMiniport.
WaveRT Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

The WaveRT miniport driver is supported in Windows Vista and later Windows operating systems, and it manages
the hardware-dependent functions of a wave-rendering or wave-capture audio device. A WaveRT-friendly audio
device has scatter/gather DMA hardware that can transfer audio data to or from any location in physical memory.
A WaveRT miniport driver must implement two interfaces:
IMiniportWaveRT. This interface performs miniport driver initialization, channel enumeration, and stream
creation.
IMiniportWaveRTStream. This interface manages a wave stream and exposes most of the functionality of the
miniport driver.
For information about how to design a WaveRT miniport driver that complements the WaveRT port driver, see the
Developing a WaveRT Miniport Driver topic.
IMiniportWaveRT
The IMiniportWaveRT interface provides the following methods:
IMinipor tWaveRT::Init
Initializes the miniport object.
IMinipor tWaveRT::NewStream
Creates a new stream object.
IMinipor tWaveRT::GetDeviceDescription
Returns a pointer to a DEVICE_DESCRIPTION structure describing the device.
IMiniportWaveRTStream
The IMiniportWaveRTStream interface inherits the methods from the IUnknown interface.
IMiniportWaveRTStream provides the following additional methods:
IMinipor tWaveRTStream::AllocateAudioBuffer
Allocates a cyclic buffer for audio data.
IMinipor tWaveRTStream::FreeAudioBuffer
Frees an audio buffer previously allocated with a call to IMinipor tWaveRTStream::AllocateAudioBuffer .
IMinipor tWaveRTStream::GetClockRegister
Retrieves the information that the port driver must have to expose the clock register to the audio subsystem and
its clients.
IMinipor tWaveRTStream::GetHWLatency
Retrieves information about sources of stream latency in the audio hardware.
IMinipor tWaveRTStream::GetPosition
Retrieves the current play or record position as a byte offset from the beginning of the buffer.
IMinipor tWaveRTStream::GetPositionRegister
Retrieves the information that the port driver must have to expose the position register to the audio subsystem
and its clients.
IMinipor tWaveRTStream::SetFormat
Sets the data format of the wave stream.
IMinipor tWaveRTStream::SetState
Changes the transport state of the audio stream.
Developing a WaveRT Miniport Driver
6/25/2019 • 6 minutes to read • Edit Online

This topic presents the software and hardware-related points you must consider when you decide to develop your
own WaveRT miniport driver.
Microsoft has developed a set of hardware design guidelines for a Universal Audio Architecture (UAA) and the
guidelines incorporate the features we recommend for a WaveRT audio device. The UAA guidelines are closely
based on the High Definition (HD) Audio specification developed by Intel.
Windows Vista and later Windows operating systems provide an HD audio driver for UAA-compliant audio
devices. So if your audio device is UAA-compliant, you do not have to develop your own WaveRT miniport driver.
But for audio devices that have some proprietary, non-UAA hardware features, you must develop your own
WaveRT miniport driver to support the proprietary features.
To help you to develop your own WaveRT miniport driver, we recommend that you first review the sample adapter
driver, and then review the WaveRT-friendly UAA features.
The sample adapter driver
For information on the sample driver, see Sample Audio Drivers.
The WaveRT -friendly features
After you review the sample adapter driver and start to design your WaveRT miniport driver, you must verify that
it supports the following software and hardware features. As a result, the miniport driver that you build then
becomes compatible with the system-supplied WaveRT port driver and with the mode of operation of the
Windows Vista audio engine.
Low hardware latency. A WaveRT miniport driver must provide a fully functioning implementation of the
IMinipor tWaveRTStream::GetHWLatency method. This method is necessary to support the
KSPROPERTY_RTAUDIO_HWL ATENCY property.
FIFO interrupts. A WaveRT miniport driver must automatically generate interrupts when FIFO overruns
and underruns occur. This feature allows the detection of glitches in the audio stream when you run tests on
the audio device and driver software. Without hardware support (in other words, FIFO interrupts), no
convenient and reliable method exists for obtaining glitch information.
Scatter-Gather DMA and Buffer Looping. When your miniport driver supports a DMA controller that
has scatter-gather capabilities, it allows data to be moved into and out of the cyclic buffer without the need
for intervention from your miniport driver.
When your miniport driver supports a DMA controller that can perform buffer loops, the DMA controller
can automatically wrap around to the start of the buffer after it reaches the end of the buffer with a read or
write operation. It can perform the wrap around without intervention from your miniport driver.
Note that the WaveRT port driver supports existing hardware designs that lack the ability to perform
scatter-gather transfers or automatic buffer loops.
If an audio device lacks scatter-gather capability, the WaveRT miniport driver must first allocate cyclic
buffers that consist of pages that are physically contiguous in memory. The miniport driver then uses
helper functions in the WaveRT port driver to perform the data transfers and automatic buffer looping. The
drawback is that as the nonpaged memory pool of a system becomes increasingly fragmented, a request to
allocate a large block of contiguous physical memory is more likely to fail. A device with scatter-gather
capability is not affected by memory fragmentation.
If an audio device cannot automatically perform buffer loops when the DMA channel reaches the end of the
cyclic buffer, the WaveRT miniport driver must intervene and configure the channel to begin the transfer of
data at the beginning of the buffer.
Position Registers. For new designs, hardware implementers should include a position register for each
DMA channel. A position register indicates the current buffer position as a byte offset from the beginning of
the cyclic buffer. The position register reading is zero at the beginning of the buffer. When the position
register reaches the end of the cyclic buffer, it automatically wraps around to the beginning of the buffer
(resets to zero) and continues to increment as the buffer position advances.
Position registers can be mapped to virtual memory so that clients can read the registers directly.
Ideally, position registers should indicate the buffer position of the samples that are currently moving
through the digital-to-analog and analog-to-digital converters (DACs and ADCs) of the audio device.
However, this information might not be directly available from an audio chipset that divides the digital and
analog functions into separate bus-controller and encoder/decoder (codec) chips. Typically, the position
registers are located in the bus-controller chip, and each register indicates the position of the audio data
that the controller is writing to or reading from the codecs.
After obtaining a reading from this type of position register, the client can estimate the current position of
the samples that are moving through the DACs or ADCs by adding or subtracting the delay through the
codec. The client obtains the codec delay from the KSPROPERTY_RTAUDIO_HWL ATENCY property
request. For this reason, a WaveRT miniport driver must accurately report the codec delay when the port
driver calls the IMinipor tWaveRTStream::GetHardwareLatency method in response to this type of
property request.
Note that the WaveRT port driver supports existing hardware designs that lack position registers. For a
device with this limitation, the WaveRT miniport driver must fail calls to the
IMinipor tWaveRTStream::GetPositionRegister method by returning the STATUS_NOT_SUPPORTED
error code, which forces the port driver to fail KSPROPERTY_RTAUDIO_POSITIONREGISTER property
requests. In this case, clients must obtain the current position through the
KSPROPERTY_AUDIO_POSITION property, which incurs the overhead of a transition between user mode
and kernel mode for each position reading.
Clock Register. A clock register is an optional but useful hardware feature for a WaveRT-compatible audio
device. Audio application programs can use clock registers to synchronize audio streams in two or more
independent audio devices that have separate and unsynchronized hardware clocks. Without clock
registers, an application is unable to detect and compensate for the drift between the hardware clocks.
The sample clock that the audio hardware uses to clock audio data through the digital-to-analog or analog-
to-digital converters should be derived from the internal clock that increments the clock register. A clock
register that increments at a rate that is asynchronous with respect to the sample clock is of no use for
synchronization and should not be exposed.
Similar to the position registers, the clock register can be mapped to virtual memory so that clients can
read the register directly.
Audio Processing Objects. A well-designed WaveRT miniport driver must never touch the audio data in
the cyclic buffer of an audio device. The hardware should be designed so that audio data flows directly
between the client and audio hardware with no intervention by the audio driver software. However,
Windows Vista supports two types of audio processing objects (APOs) that perform software processing of
audio data without violating this rule:
Local effects (LFX) APOs
LFX APOs perform generic audio processing functions (for example, equalization) that are not
specific to a particular audio device. An LFX APO processes an audio stream from an application
before the stream is added to the global mix.
Global effects (GFX) APOs
GFX APOs perform hardware-specific processing of an audio stream. A GFX APO is tied to a
particular audio device by the INF file that installs the device. The effect of a GFX APO is global
because it affects the global mix that plays through the audio device.
Global mixing is performed by the audio engine, which is the user-mode system component that is
responsible for mixing the audio streams from all audio applications. Typically, the audio engine is the client
that directly exchanges data with the WaveRT audio device through the cyclic buffer.
When the user enables an LFX APO, the audio system inserts the APO into one of the input streams to the
audio engine. When the user enables a GFX APO, the system inserts that APO into the output stream from
the audio engine. For more information about LFX and GFX APOs and the audio engine, see the Exploring
the Windows Vista Audio Engine topic.
APOs are available for use only with shared-mode audio streams. For exclusive-mode streams, applications
exchange data directly with WaveRT hardware devices through cyclic buffers, and no other components can
touch the data in the buffers.
Topology Miniport Driver
10/23/2019 • 4 minutes to read • Edit Online

A Topology miniport driver manages the various hardware controls (for example, volume and muting) in the audio
adapter's mixer circuitry. This driver enumerates the controls as nodes in the mixer topology, allowing clients to
discover the interconnections between nodes, and to query and set the control parameters at each node.
The SysAudio system driver looks at the adapter's topology when it builds an audio filter graph. The mixer API
(described in the Windows multimedia section of the Microsoft Windows SDK documentation) represents the
topology nodes as mixer-line controls and exposes them to user-mode applications such as SndVol32. For more
information, see SysTray and SndVol32.
A Topology miniport driver should implement a Topology miniport interface, which the port driver uses to
initialize the miniport driver. The miniport interface, IMiniportTopology, inherits the methods in the IMiniport
interface; it provides no additional methods. An audio adapter driver forms a topology filter by binding a miniport
object's IMiniportTopology interface to a port object's IPortTopology interface.
Typically, a topology filter encompasses most of an adapter's topology nodes, although other devices within the
adapter might contain additional topology nodes. For example, a wave device, which is represented as a wave filter,
might contain DAC (KSNODETYPE_DAC ) and ADC (KSNODETYPE_ADC ) nodes.
The querying and setting of control parameters on topology nodes is accomplished through property requests.
Each node type is associated with a specific property or set of properties. A node might support only one control
value. For example, a volume node (KSNODETYPE_VOLUME ) has a value indicating its current volume setting.
Other nodes might support multiple control values. For example, a 3D node (KSNODETYPE_3D_EFFECTS )
supports a number of 3D buffer and 3D listener properties. A sum node (KSNODETYPE_SUM ), on the other
hand, has no control values.
A Topology miniport driver uses a connection descriptor (PCCONNECTION_DESCRIPTOR ) to describe a
connection between two topology nodes. Each connection is directed and specifies both a from-node and a to-
node. A node might have several pins, and the function performed by one pin might differ from that of the other
pins. To distinguish one pin from another, the miniport driver numbers the pins on a node. These pin numbers
appear in the connection descriptors. For example, a state-variable filter might have three output pins - one each
for the high, middle, and low frequencies - numbered 1, 2, and 3. Pin numbering allows clients of the miniport
driver to determine which connections are associated with which pins.
A connection descriptor uses a distinguished node identifier, PCFILTER_NODE , to distinguish a pin on the filter
from a pin on a node within the filter. Each of the mixer circuitry's hardwired connections to the audio rendering
and capture devices in the audio adapter is represented as a pin on the topology filter. Other topology filter pins
represent external physical connections, such as a lineout jack on the adapter card. The pins on a topology filter
represent physical, hardwired connections of the adapter hardware. Thus, the pins cannot provide explicit control
over whether a connection is made, and they cannot be used to manage the flow of data over that connection.
A single connection descriptor can describe a connection between any two pin types in a topology. The pins on the
two sides of a connection can both be pins on the filter or pins on nodes within the filter, or the connection can
have a filter pin on one side and a node pin on the other. A miniport driver specifies its topology as an array of
connection descriptors. A single pin can have more than one connection, which means that the same pin can
appear in more than one connection descriptor in the array.
The topology description that a client obtains from a miniport driver is not designed to support open-ended
discovery of how to interpret node types that are unknown to the client. Node pin numbering alone does not
provide the client with the information needed to discover the functions of the pins. Although the miniport driver
identifies the type of a node (by means of a GUID), it does not provide any standardized list of parameters for
describing either the node type or the pins supported by the node type.
For example, if a client enumerates a node that uses the node-type GUID KSNODETYPE_VOLUME to identify
itself, the client can make use of the node only if it knows the conventions for dealing with volume nodes. By
convention, a volume node, for example, supports the KSPROPERTY_AUDIO_VOLUMELEVEL property and
assigns node pin numbers 0 and 1 to the output (source) pin and input (sink) pin, respectively. In addition, a client
that is able to control a volume node usually performs a directed search that limits its exploration to a relatively
small number of node types (volume and mute nodes, for example). The client typically explores only portions of a
filter graph that are likely to contain volume nodes (for example, mixer lines).
The miniport interface supports the delivery of unsolicited control value changes from the miniport driver to the
port driver. This feature accommodates devices with control knobs, sliders, or switches that can be physically
manipulated by the user. Each time the user changes a node's control value, a hardware interrupt notifies the port
driver that a hardware event has occurred.
MIDI Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

A MIDI miniport driver manages the hardware-dependent functions of simple MIDI devices that lack advanced
capabilities such as hardware sequencing and downloadable sounds (DLS). The MIDI port driver handles the
timing of the delivery of MIDI messages to synthesizers. The MIDI miniport driver is responsible only for
transporting the MIDI messages to the synthesizer in response to requests from the port driver. Devices with
advanced MIDI capabilities should use a DMus miniport driver instead.
A MIDI miniport driver should implement two interfaces:
The miniport interface initializes the miniport object and creates MIDI streams.
The stream interface manages a MIDI stream and exposes most of the miniport driver's functionality.
The miniport interface, IMiniportMidi, inherits the methods in the IMiniport interface. IMinipor tMidi provides the
following additional methods:
IMinipor tMidi::Init
Initializes the miniport object.
IMinipor tMidi::NewStream
Creates a new stream object.
IMinipor tMidi::Ser vice
Notifies the miniport driver of a request for service.
The stream interface, IMiniportMidiStream, inherits the methods in the IUnknown interface.
IMinipor tMidiStream provides the following additional methods:
IMinipor tMidiStream::Read
Reads input data from a MIDI capture device.
IMinipor tMidiStream::SetFormat
Sets the data format of the MIDI stream.
IMinipor tMidiStream::SetState
Sets the state of the MIDI stream.
IMinipor tMidiStream::Write
Writes output data to a MIDI synthesizer.
The MIDI port driver handles all timing issues in both directions and relies on the miniport driver to promptly
move data on and off the adapter in response to the port driver's calls to the IMinipor tMidiStream read and
write methods.
PortCls contains built-in MIDI miniport drivers for MIDI devices that have FM synth and UART functions. For more
information, see PcNewMinipor t .
DMus Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

A DMus miniport driver manages the hardware-dependent functions of advanced MIDI devices. These devices
support DirectMusic capabilities such as precision sequencer timing, downloadable sounds (DLS), and channel
groups. DMus miniport drivers can achieve high performance with devices such as MPU-401. Timing can be
handled by either the miniport driver or the port driver, depending on the capabilities of the hardware. A DMus
miniport driver can also support a software synthesizer that generates a wave output stream.
A DMus miniport driver for a MIDI hardware device should support two interfaces:
The miniport interface initializes the miniport object and creates MIDI streams.
The stream interface manages a MIDI stream and exposes most of the miniport driver's functionality.
The miniport interface, IMiniportDMus, inherits the methods in the IMiniport interface. IMinipor tDMus provides
the following additional methods:
IMinipor tDMus::Init
Initializes the miniport object.
IMinipor tDMus::NewStream
Creates a new stream object.
IMinipor tDMus::Ser vice
Notifies the miniport driver of a request for service.
The stream interface, IMXF, inherits the methods in the IUnknown interface. IMXF provides the following
additional methods:
IMXF::ConnectOutput
Connects this stream object, which is a data source, to the IMXF interface of another stream object, which is a data
sink.
IMXF::DisconnectOutput
Disconnects this stream object from the IMXF interface of another stream object that is a data sink.
IMXF::PutMessage
Passes a DMUS_KERNEL_EVENT structure to the data sink.
IMXF::SetState
Sets the state of the stream.
In addition, the DMus miniport driver's ISynthSinkDMus interface provides DLS functionality for software
synthesizers. ISynthSinkDMus inherits the methods in base interface IMXF . ISynthSinkDMus provides the
following additional methods:
ISynthSinkDMus::RefTimeToSample
Converts a reference time to a sample time.
ISynthSinkDMus::Render
Renders wave data into a buffer for the wave sink.
ISynthSinkDMus::SampleToRefTime
Converts a sample time to a reference time.
ISynthSinkDMus::SyncToMaster
Synchronizes the sample clock to the master clock.
The port driver's wave sink calls ISynthSinkDMus::Render to read the wave PCM data that the synthesizer
generates from its MIDI input stream. For more information about the wave sink, see A Wave Sink for Kernel-
Mode Software Synthesizers.
The miniport driver calls the following interfaces on the DMus port driver:
IPortDMus
IAllocatorMXF
IMasterClock
PortCls contains a built-in DMus miniport driver for a MIDI device with a UART function. For more information, see
PcNewMinipor t .
Installing a Port Class Audio Adapter
6/25/2019 • 2 minutes to read • Edit Online

This section describes the device-class-specific information that a vendor should include in an INF file to install a
port-class audio adapter. For a description of the general INF file requirements and options for all device classes,
see Device Installation Overview.
The description of the required INF file entries in this section is based on a hypothetical XYZ Audio Device. The
driver for this device is contained in a file named Xyzaudio.sys. Example Manufacturer and Models sections for
the device are shown in the following:

[VendorName] ; Manufacturer section


%XYZ-Audio-Device-Description%=XYZ-Audio-Device, <Plug and Play hardware ID>
[XYZ-Audio-Device] ; Models section
AddReg=XYZ-Audio-Device.AddReg

For more information, see INF AddReg Directive .


For additional examples, see the INF files included in the SYVAD audio sample. For more information, see Sample
Audio Drivers and Universal Windows Drivers for Audio.
The following topics present examples of the key sections in the INF file that installs the device:
Specifying Version Information for an Audio Adapter
Installing Device Interfaces for an Audio Adapter
Installing Core System Components for an Audio Adapter
Installing Windows Multimedia System Support for an Audio Adapter
Installing an Audio Adapter Service in Windows
Customizing Control Panel
Miscellaneous Installation Issues for an Audio Adapter
Specifying Version Information for an Audio Adapter
6/25/2019 • 2 minutes to read • Edit Online

A vendor should specify the following entries in the Version section of an INF file for a port-class audio adapter:

Signature="$CHICAGO$"
Class=MEDIA
ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318}

For a description of additional version requirements and options for all device classes, see INF Version Section .
Installing Device Interfaces for an Audio Adapter
6/25/2019 • 3 minutes to read • Edit Online

A client accesses an audio device through a set of device interfaces that a vendor specifies in the adapter's INF file.
The device interfaces specified in the INF file have a one-to-one correspondence with the subdevices that the
adapter driver creates when it initializes the device (see Subdevice Creation). For each device interface, the INF file
specifies a FriendlyName entry value, which is accessible in user mode, under the interface's registry key.
In the kernel-streaming architecture, topology categories (see KSPROPERTY_TOPOLOGY_CATEGORIES )
represent device interface classes.
The following table lists the topology categories that audio adapters are most likely to use to describe the
capabilities of their subdevices.

C AT EGO RY DESC RIP T IO N

KSCATEGORY_ACOUSTIC_ECHO_CANCEL An audio device that can perform acoustic echo cancellation


(see DirectSound Capture Effects) registers itself under this
category.

KSCATEGORY_AUDIO All audio devices register themselves under this category.

KSCATEGORY_CAPTURE An audio device that can capture a data stream registers itself
under this category.

KSCATEGORY_DATATRANSFORM An audio device that performs a data transformation on a


stream registers itself under this category.

KSCATEGORY_MIXER An audio device that can mix data streams registers itself
under this category.

KSCATEGORY_RENDER An audio device that can render a data stream registers itself
under this category.

KSCATEGORY_SYNTHESIZER An audio device that can convert MIDI messages to either


wave audio samples or an analog output signal registers itself
under this category (see Synthesizers and Wave Sinks).

KSCATEGORY_TOPOLOGY A device's Topology miniport driver registers itself under this


category.

KSCATEGORY_DRM_DESCRAMBLE An audio device that can unscramble a DRM-protected wave


stream registers itself under this category (see Digital Rights
Management).

For a complete list of topology categories, see the KSCATEGORY_XXX GUIDs that are defined in the header files
Ks.h and Ksmedia.h.
All audio devices are classified under KSCATEGORY_AUDIO, but an audio device might also be classified under
additional categories such as KSCATEGORY_RENDER (for an audio rendering device) or
KSCATEGORY_SYNTHESIZER (for a synthesizer). For each category that the INF file specifies for a device, the
Windows Installer builds a set of registry entries for that device under the category name (see Filter Factories).
Only a device that contains a built-in synthesizer should register itself under the category
KSCATEGORY_SYNTHESIZER. Note that this category excludes a pure MPU-401 device. A pure MPU-401 device,
which can output or input raw MIDI to or from a UART, should register itself under these categories:
KSCATEGORY_AUDIO
KSCATEGORY_RENDER
KSCATEGORY_CAPTURE
Note that the SysAudio system driver reserves the registry category KSCATEGORY_AUDIO_DEVICE exclusively for
its virtual audio devices. Adapter drivers should not register themselves in this category.
The following example installs four common system-defined device interfaces that an adapter typically supports
for an audio device.
Example: Installing Audio Device Interfaces
In this example, the device-install section for the XYZ Audio Device uses the INF AddInterface directive to install
four audio adapter interfaces. In the following, each of the four directives assigns a unique reference string to an
interface, which the adapter driver can use to distinguish between instances of each interface class.

[XYZ-Audio-Device.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,%KSName_Wave%,XYZ-Audio-Device.Wave
AddInterface=%KSCATEGORY_RENDER%,%KSName_Wave%,XYZ-Audio-Device.Wave
AddInterface=%KSCATEGORY_CAPTURE%,%KSName_Wave%,XYZ-Audio-Device.Wave
AddInterface=%KSCATEGORY_TOPOLOGY%,%KSName_Topology%,XYZ-Audio-Device.Topology

The first three AddInterface directives specify an add-interface section named XYZ-Audio-Device.Wave. The last
specifies an add-interface section named XYZ-Audio-Device.Topology. Each add-interface section adds the
following registry entries to a device interface subkey, which is accessible in user mode under the \DeviceClasses\
<InterfaceGUID> registry key:
A FriendlyName registry entry specifies a friendly name for each device interface.
Microsoft DirectShow requires a CLSID registry entry, set to a proxy GUID value, which indicates that the
adapter can be accessed and controlled by the KSProxy system driver.
The two add-interface sections appear in the following example, which contains INF file entries that add each
interface's FriendlyName and CLSID to the registry:

[XYZ-Audio-Device.Wave]
AddReg=XYZ-Audio-Device.Wave.AddReg
[XYZ-Audio-Device.Wave.AddReg]
HKR,,FriendlyName,,%WaveDeviceName%
HKR,,CLSID,,%Proxy.CLSID%

[XYZ-Audio-Device.Topology]
AddReg=XYZ-Audio-Device.Topology.AddReg
[XYZ-Audio-Device.Topology.AddReg]
HKR,,FriendlyName,,%WaveDeviceMixerName%
HKR,,CLSID,,%Proxy.CLSID%

The keyword HKR in this example denotes the system-supplied registry path for the device. For more information,
see INF AddReg Directive .
The following is the Strings section for this example.
[Strings]
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
KSCATEGORY_RENDER="{65E8773E-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_TOPOLOGY="{DDA54A40-1E4C-11D1-A050-405705C10000}"
Proxy.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
WaveDeviceName="XYZ Audio Device"
WaveDeviceMixerName="XYZ Audio Device Super Mixer"

The string name that an AddInterface directive specifies for a KSCATEGORY_XXX device interface cannot be
localized because the adapter driver uses the same name internally as a string constant. The sample adapter
drivers in the Windows Driver Kit (WDK) use the following string names for their audio device interfaces:

KSNAME_Wave="Wave"
KSNAME_UART="UART"
KSNAME_FMSynth="FMSynth"
KSNAME_Topology="Topology"
KSNAME_Wavetable="Wavetable"
KSNAME_DMusic="DMusic"

For the sake of uniformity, your proprietary driver should assign these same names to its corresponding device
interfaces. If your driver supports additional device interfaces that are proprietary, you can invent your own
proprietary names for these interfaces. Make sure that the names that the driver uses match those in your INF file.
If the strings do not match, system setup will not load the driver.
Installing Core System Components for an Audio
Adapter
6/25/2019 • 2 minutes to read • Edit Online

This section includes the following topics about installing the core system components for a port-class audio
adapter:
Installing in Windows
The INF DDInstall section for each hardware ID specified in the manufacture's MODEL section should specify
the inclusion of the KS.Registration section in Ks.inf and the WDMAUDIO.Registration section in Wdmaudio.inf.
The Ks.inf file installs the core kernel streaming components. The Wdmaudio.inf file installs the core WDM audio
components. Vendors should not modify or replace these system INF files.
Installing in Windows
6/25/2019 • 2 minutes to read • Edit Online

In the following example of an INF device-driver-installation section, the two directives add the system-driver
information that installs the core system components for an audio adapter in Windows:

[XYZ-Audio-Device.Registration.NTX86]
Include=ks.inf, wdmaudio.inf
Needs=KS.Registration, WDMAUDIO.Registration

For information about the Include and Needs directives, see INF DDInstall Section .
Installing Windows Multimedia System Support for
an Audio Adapter
6/25/2019 • 2 minutes to read • Edit Online

An INF add-registry section creates or modifies driver-specific information in the system registry. The add-registry
section for a PortCls audio adapter contains information that makes the adapter accessible to the Windows
multimedia system components.
The following example presents the add-registry section, XYZ-Audio-Device.AddReg, that was named in an INF
AddReg directive in a previous example (see Installing a Port Class Audio Adapter):

[XYZ-Audio-Device.AddReg]
HKR,,AssociatedFilters,,"wdmaud,swmidi,redbook"
HKR,,Driver,,xyzaud.sys
HKR,Drivers,SubClasses,,"wave,midi,mixer,aux"

HKR,Drivers\wave\Wdmaud.drv,Driver,,Wdmaud.drv
HKR,Drivers\midi\Wdmaud.drv,Driver,,Wdmaud.drv
HKR,Drivers\mixer\Wdmaud.drv,Driver,,Wdmaud.drv
HKR,Drivers\aux\Wdmaud.drv,Driver,,Wdmaud.drv

HKR,Drivers\wave\Wdmaud.drv,Description,,%XYZ-Audio-Device-Description%
HKR,Drivers\midi\Wdmaud.drv,Description,,%XYZ-Audio-Device-Description%
HKR,Drivers\mixer\Wdmaud.drv,Description,,%XYZ-Audio-Device-Description%
HKR,Drivers\aux\Wdmaud.drv,Description,,%XYZ-Audio-Device-Description%

The add-registry section adds the registry entries that specify the components that the system needs to load so
that the Windows multimedia system can use the audio adapter. These components include both the adapter driver,
Xyzaud.sys, and the system drivers WDMAud, SWMidi, and Redbook (see Kernel-Mode WDM Audio Components).
The AssociatedFilters keyword in the example add-registry section indicates that the directive contains the
names of one or more auxiliary driver files whose loading is to be deferred until they are needed by the adapter
driver. The alternative is to load the auxiliary files at the same time that the device driver is loaded.
Installing an Audio Adapter Service in Windows
6/25/2019 • 2 minutes to read • Edit Online

The following INF AddSer vice directive installs the adapter driver Xyzaud.sys for the XYZ Audio Device:

[XYZ-Audio-Device.Services.NTX86]
AddService = XYZ-Audio-Device, 0x00000002, XYZ-Audio-Device.Service.Install

[XYZ-Audio-Device.Service.Install]
DisplayName = %XYZ-Audio-Device.ServiceDescription%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\system32\drivers\xyzaud.sys
Customizing Control Panel
12/5/2018 • 2 minutes to read • Edit Online

In Windows XP and later versions of Windows, you can customize the sound application in Control Panel. To do
this, you add a custom bitmap or icon. Or, if you develop a third-party digital audio format that is streamed over
SPDIF, you can make this digital audio format available in Control Panel.
For more information about how to add a bitmap or an icon, or how to use an INF file to add a third-party digital
audio format to Control Panel, see the following topics:
Branding Control Panel with Bitmaps or Icons
Adding New Digital Formats to Control Panel
Branding Control Panel with Bitmaps or Icons
6/25/2019 • 3 minutes to read • Edit Online

In Windows XP and later versions of Windows, the sound application in Control Panel supports third-party
branding of audio-device controls. Independent hardware vendors (IHVs) can display the following items next to
the controls for their audio devices:
Company logo
Proprietary device name
The INF file that installs the device driver also loads the Control Panel customization data into the registry.
Bitmapped images of company logos are contained in the installed driver files themselves.
In Windows XP, branding information is visible to users in the following program locations:
The Volume page of the Sounds and Audio Devices application in Control Panel (Mmsys.cpl)
The SndVol32 program (Sndvol32.exe)
In Windows Vista, branding information is visible to users in the Playback and Recording pages of the Sound
application in Control Panel (Mmsys.cpl).
The branding information is stored in the registry in a Branding subkey under the audio device's root key, which is
located under the media-class key. The Branding subkey can contain one or more of the REG_SZ values that are
shown in the following table.

VA L UE N A M E M EA N IN G

icon Name of the file that contains the icon that is used by the
SndVol32 control menu.

bitmap Name of the file that contains the 32-by-32 bitmap that is
displayed in the Volume page of the Sound and Audio
Devices application in Control Panel.

These values are added to the registry by directives within the add-registry-section (see INF AddReg Directive )
of the INF file that installs the device driver. Control Panel uses defaults for any values that are missing from the
Branding subkey.
The "bitmap" logo appears to the left of the proprietary device name at the top of the Volume page. The "icon"
logo appears in the top-left corner of the SndVol32 control menu.
The proprietary device name that appears in the previously mentioned pages is the friendly name of the device.
This friendly name is specified by a directive in the add-registry-section of the INF file that installs the device. This
directive contains the keyword "FriendlyName", as shown in the example in INF AddReg Directive . In Windows
XP, the Volume page and SndVol32 display only the first 31 characters of the name string. Longer strings are
truncated. In Windows Vista and later versions of Windows, this 31-character restriction is removed when the
device name is displayed in Control Panel. When you use APIs that were supported in versions of Windows earlier
than Windows Vista, for example MCI_GetDevCaps, the 31-character limit still applies to the device name that you
provide to the API.
Impor tant In Windows Vista and later versions of Windows, the use of bitmap images for third-party branding is
no longer supported. Third-party audio driver developers who want to brand their audio device controls must use
icons. The supported pixel dimensions for these icons are 32x32 or 48x48.
Example 1
The following example shows a couple of directives from the add-registry-section of a vendor's INF file:

[XYZ-Audio-Device.AddReg]
HKR,Branding,icon,,"foo.sys,102"
HKR,Branding,bitmap,,"c:\mydir\myimage.bmp"

These directives add control-panel branding information to the registry. HKR represents the audio device's root key
in the registry; the Branding subkey is specified relative to the path name for the root key. The string value for the
icon or bitmap key can be specified in one of two formats: "file,resourceid" or "imagefile". The first directive in the
preceding example uses the "file,resourceid" format. The directive assigns to the icon key a string value that
contains a file name, foo.sys, and a resource ID of 102. The file name and resource ID are separated by a comma
(with no spaces). The file foo.sys contains the icon resource. The second directive in the preceding example assigns
an "imagefile" formatted string to the bitmap key; the string contains the full path name of a .bmp file that
contains the bitmap.
The example directive for the icon value can be changed to use the "imagefile" format, but in this case the string
value should contain the path name of a file with an .ico file name extension.
In the case of the "file,resourceid" format, the control-panel software searches the same list of the search paths as
the LoadLibrar y function (described in the Microsoft Windows SDK documentation). If this path list does not
contain the file, the software also searches the drivers directory (see INF DestinationDirs Section ). This format
allows the images to be easily stored in the driver file itself without requiring that absolute path names be specified
in the INF file.
Example 2
The following example applies to Windows Vista and later versions of Windows. This example shows a directive
from the add-registry-section of a vendor's INF file. This example uses the "imagefile" format:

[ABC-Audio-Device.AddReg]
HKR,Branding,icon,,"c:\mydir\myicon.ico"
Adding New Digital Formats to Control Panel
12/5/2018 • 2 minutes to read • Edit Online

In Windows Vista and later versions of Windows, you can develop a third-party digital audio format that streams
over SPDIF and make this format available in Control Panel.
After you develop your digital audio format, define a new GUID for the format and use an INF file to install the
associated audio driver. The following code from an INF file shows how to add the necessary information about
your new digital audio format to the registry:

[Version]
Signature=$WindowsNT$
...
[DDInstall]
AddReg = AddReg.NewDigitalFormat
...
...
[AddReg.NewDigitalFormat]
HKLM, %My_SubKey%, "DisplayName",,"ABC Audio"
HKLM, %My_SubKey%, "CustomIcon",,"c:\Program Files\MyVendor\myicon.ico"
HKLM, %My_SubKey%, "TestFile",,"c:\Program Files\MyVendor\testfile.wav"
...
[Strings]
My_SubKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\SPDIF_Formats\{00000682-0000-0010-8000-
00aa00389b71}"
...
...

In the preceding example, the GUID shown in the [Strings] section is used to illustrate the placement of the GUID
that you define for your new digital format. HKLM is used as the standard abbreviation for HKEY_LOCAL_MACHINE.
Impor tant The two HKLM line entries for Mycion.ico and Testfile.wav are required. The "c:\Program
Files\MyVendor\" folder has been used to show that you must create an appropriate folder for your driver-related
icon and test wave files.
Miscellaneous Installation Issues for an Audio
Adapter
6/25/2019 • 2 minutes to read • Edit Online

Listed are the most common installation issues for an audio adapter:
During initial installation of an audio device or when undergoing an operating system upgrade that destroys
existing audio settings, the driver should ensure that the settings are initialized to reasonable default values.
For more information, see Default Audio Volume Settings.
Sometimes during installation, an OEM would like to override the default audio volume level, or the default
microphone boost level that is hard-coded by the Audio Class driver. This was not possible in earlier
versions of Windows up to Windows 7. In Windows 8 and later, you can now customize the default values
for these settings. For more information about how to do this, see Customizing Default Audio Volume
Settings.
In Windows Vista and later operating systems, the default setting for the master volume level of an audio
device is six decibels of attenuation, and it is set at the time of installation. This default master volume level
setting, or any other level that you choose after installation, is maintained no matter how often you restart
your computer. To opt out of volume level persistence you can use the AddProperty registry directive via an
INF file, to set the value of the PKEY_AudioDevice_DontPersistControls registry key. For more information
about how to do this, see Opting Out of Volume Level Persistence.
During an operating system upgrade, an audio device's installed driver and registry settings can frequently
be preserved. For guidelines on how to make this process transparent to users, see Operating System
Upgrades.
An audio driver is easily designed to allow multiple identical instances of an audio adapter card to be
plugged into the same system. For more information, see System-Wide Unique Device IDs.
For a list of INF file keywords that are common to all device classes, see INF File Sections and Directives.
However, this list does not contain several media-specific keywords. For more information, see Media-
Specific INF File Keywords.
For information about how an adapter driver or miniport driver can obtain setup information from the
registry, see Retrieving Device Setup Information.
For information about Windows Vista support for an audio adapter which does not have a physical volume
control knob, see the Windows Vista Software Volume Control Support topic.
Default Audio Volume Settings
6/25/2019 • 2 minutes to read • Edit Online

The SndVol program (see SysTray and SndVol32) displays a set of volume sliders. The sliders indicate the volume-
level settings for the various audio devices and applications such as speakers and system sounds. There is an
endpoint volume for each audio output and input, and an application volume for each application. The audio driver
has control only over its own endpoint volumes, via KSPROPERTY_AUDIO_VOLUMELEVEL. If the driver does not
explicitly initialize these volume settings at the time that it is installed, the operating system chooses its own
default values for these settings. The defaults that the operating system chooses are not the same across all
Windows releases, and vendors might need to take these differences into account to ensure that the volume levels
are set neither too high nor too low immediately following driver installation.
As a general rule, if the audio adapter drives a set of analog speakers that have their own physical volume control,
the INF file should not set the default volume level too low. Otherwise, a user might try to compensate by
increasing the volume on the speakers instead of increasing the master volume on the sound card. The result of
amplifying a low signal level is loss of audio quality.
If the audio adapter does not have a hardware amplifier, see Software Volume Control Support for information
about the software support provided.
Note If there is a hardware amplifier, then the driver sets the range and the default level via the
KSPROPERTY_AUDIO_VOLUMELEVEL kernel streaming property. If there is not a hardware amplifier, Windows
will create a software volume control APO. If there is a physical volume knob on an active set of speakers, it should
appear to Windows as a HID control. This will function similarly to the volume up and volume down buttons on a
keyboard; Windows will see the volume knob turn and will program the volume control correspondingly (whether
it is a hardware or software volume.)
Ideally, if a set of active speakers ships in the same box with the audio adapter card, the factory should adjust the
volume knob on the speakers to the position that works best with the adapter's default volume setting. If the audio
adapter does not have a physical volume control knob, see the Software Volume Control Support topic for
information about the software support provided by Windows.
Note If the audio hardware exposes a hardware volume control (like a volume knob), then the driver sets the
range and the default level via the KSPROPERTY_AUDIO_VOLUMELEVEL Kernel Streaming property.
The following table shows the volume ranges and default volume levels for audio in the different versions of
Windows.

W IN DO W S VERSIO N M IC RO P H O N E DEFA ULT VA L UES N O N - M IC RO P H O N E* DEFA ULT VA L UES

Windows Vista SP1 Default level: 0.0db Default level: 0.0db


Volume Range : -192.0 dB ~ Volume Range : -192.0 dB ~ 0dB
+12.0dB

Windows 7 Default level: +30.0dB Default level: 0 dB


Volume Range : -192 dB ~ +30.0 Volume Range : -192 dB ~ 0 dB
dB
W IN DO W S VERSIO N M IC RO P H O N E DEFA ULT VA L UES N O N - M IC RO P H O N E* DEFA ULT VA L UES

Windows 8 Default level: 0.0 dB Default level: 0.0 dB


Volume Range: -96 dB ~ +30 dB Volume Range: -96 dB ~ 0 dB

*The term non-microphone describes all playback devices and recording devices other than microphones. For
information about the operational characteristics of the physical volume sliders that are represented by the
software volume sliders in Windows applications, see Audio-Tapered Volume Controls.

Related topics
Customizing Default Audio Volume Settings
Software Volume Control Support
6/25/2019 • 2 minutes to read • Edit Online

In Windows Vista and later, software volume support is provided for audio hardware that does not include and
amplifier with an associated physical volume control.
The following diagram shows a simplified representation of the Windows software volume support.

The diagram shows two separate audio data paths. One when an amplifier is present and one when the Windows
APO software volume control is used. If an amplifier is present, the driver advertises,
KSPROPERTY_AUDIO_VOLUMELEVEL. If the audio driver does not indicate that it supports
KSPROPERTY_AUDIO_VOLUMELEVEL, the Windows audio engine creates a software volume control APO.
On a typical PC, only one of these data paths will be present, since there will typically be one set of audio
components in the computer. The two paths are shown here for illustrative purposes.
The IAudioEndpointVolume interface represents the volume controls on the audio stream to or from an audio
endpoint device.
If Bluetooth or USB audio is present, their volume controls will be controlled separately.

Data path with amplifier present


When a client application calls the IAudioEndpointVolume interface in a configuration where there is an
amplifier and a physical volume control present, the audio driver exposes a KSNODETYPE_VOLUME node in the
topology filter. The presence of the volume node makes IAudioEndpointVolume aware that the volume level of
the audio signal will be modified by the hardware.

Data path with no amplifier present


When there is no amplifier present, IAudioEndpointVolume works with the audio engine to initialize the
Windows software volume support APO.
Since there is no physical volume control to be modeled, a KSNODETYPE_VOLUME node is not exposed in the
topology filter. Volume attenuation and gain are performed by the APO software volume support component.
For information about the volume ranges and the default volume levels for the different versions of Windows, see
Default Audio Volume Settings.
Opting Out of Volume Level Persistence
6/25/2019 • 2 minutes to read • Edit Online

By default the volume level settings are maintained when you restart your computer. This default system behavior
is referred to as volume persistence. If you do not want the volume levels to be maintained by the system after a
computer restart, you can use an INF file at the time of installation of the audio adapter, to opt out of the default
system behavior.
You may want your driver to opt out of volume persistence if your driver had its own registry cache and sets the
levels on the hardware itself, on driver load.
To opt out of volume persistence using an INF file, use the AddProper ty registry directive to set the value of the
PKEY_AudioDevice_DontPersistControls registry key to "1". The default value is "0".
The following INF file fragment shows how to opt out of volume persistence:

;; INF file fragment to show how to use AddProperty


;; to opt out of volume persistence
;;
[Version]
Signature = "$CHICAGO$"
Class = MEDIA
ClassGUID = {...}
...
[Manufacturer]
%MfgName% = CompanyName
...
[CompanyName]
%DeviceDescription% = HdAudModel, hw-id
;; ... other device models listed here

[HdAudModel]
Include=ks.inf, wdmaudio.inf
Needs=KS.Registration, WDMAUDIO.Registration
CopyFiles = HdAudModel.CopyList, HdAudProp.CopyList, HdAudShortCut.CopyList
AddReg = HdAudModel.AddReg, HdAudProp.AddReg, HdAudShortCut.AddReg, HdAudBranding.AddReg
AddProperty = HdAudModel.AddProperty
...
[HdAudModel.AddProperty]
;; {F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},2,7,,0
{F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},2,7,,1
...
[Strings]
MfgName = "My Company Name Inc"
DeviceDescription = "My WDM device driver"

Note The preceding INF file fragment, only shows the Version section and the sections relevant to the
AddProper ty directive.
The %MfgName% = CompanyName line entry in the Manufacturer section references the CompanyName
section where the model and hardware ID (hw-id) of the audio adapter are provided. This section in an INF file,
where model and hw-id information is provided, is called the models section. The actual title of the section is user-
defined and in the preceding example it is CompanyName . For more information about the models section of an
INF file, see INF Models Section .
The models section, in turn, references the device driver install (DDInstall) section, where information is provided
about other INF files that the setup program must copy. The actual title of this section is user-defined and in the
preceding example it is HdAudModel . The Needs=KS.Registration... line entry provides information about the
specific sections within the INF files, from which the setup program must retrieve data for installation
The HdAudModel section also contains references to the AddReg and AddProperty sections. The setup program
retrieves data from AddReg and AddProperty to set registry keys and device properties respectively. The
AddProperty section referenced here is HdAudModel.AddProper ty and it uses the following format to provide
information about the device property:
{property-category-guid}, property-pid, type, [flags], value
The HdAudModel section shows two line entries with the first one commented out. The line entry that is
commented out sets the value of the device property to "1." The line entry that is not commented out is the one
that the setup program reads. This line entry causes the value of the device property to be set to "0." When this
device property is set to "0," the audio device opts out of volume persistence.
For more information about the AddProperty directive, see INF AddProper ty Directive .
The property name that corresponds to the property category GUID and property ID in the preceding INF file
fragment is PKEY_AudioDevice_DontPersistControls.
Customizing HD Audio Driver Volume Settings
6/25/2019 • 4 minutes to read • Edit Online

The ability to customize the in box HD audio default audio volume and microphone boost levels to suit a specific
PC, provides OEMs with some flexibility in their audio adapter installation parameters.
Note The process described here can only be used if the default Microsoft HD Audio driver is being used.
By default, the HD Audio class function driver sets the audio volume and the microphone boost levels at
predetermined values to ensure a pleasant “out of the box” experience for the user.
The HD Audio class function driver, which I shall now refer to as the Audio Class driver, uses various hard-coded
default values that cannot be customized for any particular PC. As such, OEMs are not able to override these values
to meet their own requirements. And one of the most important settings to adjust is the volume level, as users are
sensitive to the loudness or quietness of their audio systems, especially during first-time use.
The Audio Class driver has been redesigned to allow you to override the hard-coded default values. The
mechanism for overriding the Audio Class driver’s hard-coded values involves writing an INF file that wraps the
Audio Class driver’s inbox INF file (hdaudio.inf), and using this wrapper INF to specify the desired values.
The following diagram which shows a sample HD Audio codec topology. Note that there are IDs for the individual
nodes, as well as IDs for the pin complexes.

The pin complexes represent the physical connectors for the associated device (e.g. speaker, mic, or line).
To specify a custom audio volume level or microphone boost level, use the wrapper INF file to specify custom
levels per pin complex ID. The levels are expressed as DWORDs that represent the default kernel streaming (KS)
decibel levels that the class driver should return.
When the HD Audio class driver receives a GET request for KSPROPERTY_AUDIO_VOLUMELEVEL, the driver
determines whether or not there is a default volume (or Mic boost) value in the registry for the path that contains
the node that received the request. If there is a value in the registry, but there is no previously cached value, the
default value in the registry will be applied to the device, and also returned in the
KSPROPERTY_AUDIO_VOLUMELEVEL response. If there is no value in the registry, the HD Audio class driver
retrieves a default value from the sub-device graph implementation.
Starting with Windows Vista, the default values are as follows:
Endpoint volume defaults to max minus 6 dB for all device types.
Microphone boost defaults to 0 dB.
The following steps summarize the algorithm that is used by the Audio Class driver to determine the default values
to return in response to a GET request for KSPROPERTY_AUDIO_VOLUMELEVEL:
1. Determine the pin complex at which the path containing the queried volume node terminates.
2. Perform a registry lookup to see if a volume or microphone boost default value has been provided for the
pin complex found in step 1.
3. If a value is found in the registry, then the driver sets that value to the minimum, if it falls below the
minimum value supported by the amplifier. Otherwise the value is set to the maximum, if it falls above the
maximum value supported by the amplifier. If the value found in the registry is within the range supported
by the amplifier, then the value is returned in response to the GET request. In addition, the driver programs
the associated HD Audio amplifier widget with this value when rendering to or capturing from the pin
complex.
The following folder tree shows the layout for the driver instance key that holds the default values.
<Driver Key> DefaultVolumeLevels Pin Complex (2 digit HEX, not preceded by “0x”) Volume (DWORD in KS DB
steps) Boost (DWORD in KS DB steps)
The KS DB stepping values are defined as follows: -2147483648 is -infinity decibels (attenuation)
-2147483647 is -32767.99998474 decibels (attenuation)
+2147483647 is +32767.99998474 decibels (gain)
For more information on the unit of measurement that is used (1/65536 dB), see
KSPROPERTY_AUDIO_VOLUMELEVEL .
To override the wdmudio.inf file, use the Include and Needs directives as shown in this code segment from the
Microsoft Virtual Audio Device Driver Sample available as part of the Windows Driver Kit (WDK) 8.1 Samples.

;Copyright (c) Microsoft Corporation. All rights reserved.


;
...
[MSVAD_Simple.NT]
Include=ks.inf,wdmaudio.inf
Needs=KS.Registration, WDMAUDIO.Registration
...

For more information about the Include and Needs directives, see INF DDInstall Section and Source Media for
INF Files.
The following is a sample INF wrapper that wraps the INF file for the Audio Class driver.

;Copyright (c) Microsoft Corporation. All rights reserved.


;
;Module Name:
; HDAUDVOL.INF
;
;Abstract:
; Wrapper INF file for installing the Microsoft UAA Function Driver for High
; Definition Audio with specific INF overrides

[Version]
Signature="$Windows NT$"
Class=MEDIA
ClassGuid={4d36e96c-e325-11ce-bfc1-08002be10318}
Provider=Microsoft
DriverVer=07/28/2012,6.2.9201.0
DriverVer=07/28/2012,6.2.9201.0
CatalogFile=hdaudvol.cat

[Manufacturer]
Microsoft = Microsoft,ntamd64,ntarm

[ControlFlags]
ExcludeFromSelect = *

;;====================================================================================
;; Edit the PNP ID (HDAUDIO\FUNC_01...) below to match the codec + subsystem you are ;; configuring.
;;====================================================================================

[Microsoft]
%HdAudModel_DefaultVolume_DeviceDesc% = HdAudModel_DefaultVolume,
HDAUDIO\FUNC_01&VEN_10EC&DEV_0889&SUBSYS_00000000&REV_1000

[Microsoft.ntamd64]
%HdAudModel_DefaultVolume_DeviceDesc% = HdAudModel_DefaultVolume,
HDAUDIO\FUNC_01&VEN_10EC&DEV_0889&SUBSYS_00000000&REV_1000

[Microsoft.ntarm]
%HdAudModel_DefaultVolume_DeviceDesc% = HdAudModel_DefaultVolume,
HDAUDIO\FUNC_01&VEN_10EC&DEV_0889&SUBSYS_00000000&REV_1000

;;===================== HdAudModel_DefaultVolume ==============================

[HdAudModel_DefaultVolume]
Include=hdaudio.inf
Needs=HDAudModel
AddReg=HdAudModel_DefaultVolume.HdAudInit

[HdAudModel_DefaultVolume.HW]
Include=hdaudio.inf
Needs=HdAudModel.HW

[HdAudModel_DefaultVolume.Services]
Include=hdaudio.inf
Needs=HdAudModel.Services

[HdAudModel_DefaultVolume.Interfaces]
Include=hdaudio.inf
Needs=HdAudModel.Interfaces

[HdAudModel_DefaultVolume.HdAudInit]
;;====================================================================================
;; Units are in KS dB so 1dB == 65536 (0x00010000)
;; ======================================================================================
HKR,DefaultVolumeLevels\18,Volume,1,00,00,FE,FF ; Set to 0xFFFE0000 to set to -2dB
HKR,DefaultVolumeLevels\18,Boost,1,00,00,0A,00 ; Set to 0x000A0000 to set to 10dB

[Strings]
HdAudModel_DefaultVolume_DeviceDesc = "High Definition Audio Device"

Because an HKR relative path is specified, the exact driver registry path will be determined based on the specific
INF file section that is used. For more information about HKR relative paths, see INF AddReg Directive
(Windows Drivers) . The following two registry paths are examples, your registry path will likely be different.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96c-e325-11ce-bfc1-
08002be10318}\0002
or -
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96c-e325-11ce-bfc1-
08002be10318}\0002\DeviceInterfaces\eAuxIn
Related topics
Default Audio Volume Settings
KSPROPERTY_AUDIO_VOLUMELEVEL
Operating System Upgrades
6/25/2019 • 3 minutes to read • Edit Online

An audio device's driver and registry settings can frequently be preserved across operating system upgrades. The
discussion below presents some guidelines for accomplishing this.
Preserving Audio Settings
An audio adapter driver can keep track of its current device settings--chiefly volume levels and mute settings--in
the system registry. The driver typically stores these settings in the system-supplied driver key (represented by the
INF keyword HKR) under the subkey "Settings". When the user alters these settings through a control panel or
other audio application, the driver updates the appropriate registry entries. Each time the system boots, the driver
restores the device settings from the registry.
When upgrading from Windows Me/98 to Windows XP or Windows 2000, the Windows installation program is
unable to preserve these settings.
However, when upgrading from Windows 98 to Windows Me, or from one NT-based operating system to another
(for example, from Windows 2000 to Windows XP), the installation program leaves the driver's existing registry
settings intact. Users largely prefer this behavior because it preserves the adjustments they have made to the
system over time instead of forcing them to try to restore their settings manually each time they upgrade the
operating system.
Some proprietary drivers, however, blindly overwrite these registry settings with defaults each time they are
installed. A better approach is for a driver to determine at installation time whether certain driver-specific registry
entries already exist. If they do exist, the driver should preserve the settings that are contained in these entries
instead of overwriting them.
The directives in the add-registry section of the driver's INF file specify whether existing registry entries should be
overwritten. For more information, see the description of the FLG_ADDREG_NOCLOBBER flag in INF AddReg
Directive .
Migration DLL
During an upgrade from Windows Me/98 to an NT-based operating system (Windows 2000 and later), the
Windows installation program treats a device driver that was installed under Windows Me/98 as incompatible and
discards both the driver and its registry settings.
In addition, if the Windows 2000 setup program finds no in-box driver support for the device, the program
immediately prompts the user to provide the driver software. In Windows XP and later, if the setup program is
unable to find a suitable driver either in-box or at the Windows Update site, it waits until the upgrade has
completed to inform the user of the missing driver.
Although a driver cannot avoid the loss of its registry settings during such an upgrade, Microsoft recommends the
use of a migration DLL to reinstall a compatible driver transparently to the user. For this purpose, Microsoft
provides the Devupgrd migration DLL, which is included in the Setup Plug and Play samples in the Windows Driver
Kit (WDK). The sample includes a help file that describes the migration DLL.
The migration DLL should be used only with WDM drivers that are initially installed under Windows Me/98 but are
also capable of running on Windows 2000 or Windows XP. Note that the migration DLL cannot upgrade drivers
from Windows Me/98 to Windows Server 2003, Windows Vista, or later. It can only upgrade drivers from Windows
Me/98 to Windows XP or Windows 2000.
During the upgrade from Windows Me/98 to Windows XP or Windows 2000, the migration DLL does the
following:
Reads the device driver's migration information from its location in the Windows Me/98 registry.
Adds the necessary information to the driver's INF file to ensure that the device installs properly under
Windows XP or Windows 2000.
To make the migration information available later to the Windows XP or Windows 2000 setup program, the INF file
that installs the device under Windows Me/98 should do the following:
Copy the migration DLL to an INF-specified backup directory and add that directory's path name to the
Windows Me/98 registry.
Add to the registry the device IDs that identify the devices that can migrate.
Save backup copies of the device driver files (.sys and .inf) into INF-specified backup directories and add
those directories' path names to the registry.
During the upgrade, the Windows XP or Windows 2000 setup program adds the backup directory names to the
INF search path for the registered device IDs.
As discussed above, the setup program discards the driver's registry settings during an upgrade from Windows
Me/98 to Windows XP or Windows 2000. The driver reinstallation that is performed with the help of a migration
DLL is a "clean install" in which the driver's volume, mute, and other settings assume their initial, default values.
The Ac97 audio adapter sample in the Windows Driver Kit (WDK) contains an example of an INF file (Ac97smpl.inf)
that migrates an audio driver from Windows Me/98 to Windows XP or Windows 2000.
System-Wide Unique Device IDs
10/23/2019 • 3 minutes to read • Edit Online

A driver for a typical audio adapter should easily be able to support several instances of the same audio adapter
card in a system. Nearly all the data structures that a driver maintains are stored in the device-extension buffer (see
the description of the DEVICE_OBJECT structure's DeviceExtension field). If several instances of a driver share
any global data, however, those instances should synchronize their access to this data.
One additional requirement is that each subdevice on a particular instance of an adapter card should have a
device-ID string that uniquely identifies the subdevice across all instances of the same adapter card in the system.
The most straightforward way to accomplish this is to expose each subdevice on the adapter card as a logically
distinct device to the Plug and Play manager. This is presented as option (1) in Multifunction Audio Devices.
A second approach is to use the system-supplied multifunction bus driver to manage the subdevices on the
adapter card. The MF bus driver assigns to each subdevice a device ID that is guaranteed to be unique across the
system, even if the system contains several instances of the same adapter card. The MF bus driver accommodates
designs in which the subdevices share a common set of configuration registers but each subdevice has its own set
of PCI base-address registers. The subdevices should have no hidden dependencies on each other and should be
able to operate concurrently without interfering with each other or with other devices in the system. This is option
(2) in Multifunction Audio Devices.
A third approach is to use a proprietary bus driver to manage the subdevices on an adapter card. This is frequently
necessary if the subdevices have mutual dependencies that must be managed centrally. Such dependencies can
occur in a couple of ways:
The subdevices might share some on-card resource. For example, if the subdevices share a digital signal
processor (DSP), the bus driver might need to download the proprietary operating system that runs on the
DSP before starting up the first subdevice.
A design flaw might cause a dependency among subdevices. For example, a design flaw might require the
subdevices to be powered up or down in a particular sequence.
When either type of dependency exists, a proprietary bus driver is nearly always a better solution than presenting
the subdevices directly to the Plug and Play manager and attempting to hide the dependency.
If you provide your own bus driver for an adapter card, you should ensure that the device IDs that your bus driver
assigns are unique across the system.
A bus driver provides a device ID for one of its children in response to an IRP_MN_QUERY_ID query from the
Plug and Play manager. The ID can be specified in one of two ways, which the bus driver indicates in its response to
an IRP_MN_QUERY_CAPABILITIES query by setting the DEVICE_CAPABILITIES structure's UniqueID field to
TRUE or FALSE :
UniqueID = TRUE
This means that the name of the child is guaranteed to be unique throughout the system. The device ID
string contains a device ID plus an instance ID, which is a serial number that uniquely identifies the hardware
instance.
UniqueID = FALSE
This means that the name of the child is unique only with respect to the parent. Most devices use this means
of identification. In this case, the Plug and Play manager extends the device-ID string that it receives to make
it unique through the system. The extended string is a function of the parent device's unique ID.
All audio bus drivers should set UniqueID = FALSE for their children. This causes the Plug and Play manager to
extend the child's device ID string by adding information about the device's parent to make the ID unique on the
machine.
Media-Specific INF File Keywords
6/25/2019 • 2 minutes to read • Edit Online

The list of INF file keywords at INF File Sections and Directives contains keywords that are common to all device
classes, but the following media-specific INF file keywords do not appear in the list:
SetupPreferredAudioDevices
The SetupPreferredAudioDevices keyword is supported in Windows 2000 and later. For more information, see
Media-Class INF Extensions.
Retrieving Device Setup Information
10/23/2019 • 2 minutes to read • Edit Online

To retrieve setup information from the registry, an adapter driver can call the PcGetDeviceProper ty function, and
a miniport driver can call the port driver's IPor t::GetDeviceProper ty method.
For either of these calls, the caller selects the type of setup information to request by setting the device-property
parameter to one of the following DEVICE_REGISTRY_PROPERTY enumeration values from header file Wdm.h:
DeviceProper tyAddress
DeviceProper tyBootConfiguration
DeviceProper tyBootConfigurationTranslated
DeviceProper tyBusNumber
DeviceProper tyBusTypeGuid
DeviceProper tyClassGuid
DeviceProper tyClassName
DeviceProper tyCompatibleIDs
DeviceProper tyDetachability
DeviceProper tyDeviceDescription
DeviceProper tyDriverKeyName
DeviceProper tyEnumeratorName
DeviceProper tyFriendlyName
DeviceProper tyHardwareID
DeviceProper tyInstallState
DeviceProper tyLegacyBusType
DeviceProper tyLocationInformation
DeviceProper tyManufacturer
DeviceProper tyPhysicalDeviceObjectName
DeviceProper tyUINumber
For a description of the DevicePropertyXxx values above, see IoGetDeviceProper ty .
Port Driver Helper Objects
12/5/2018 • 2 minutes to read • Edit Online

To reduce the difficulty of developing miniport drivers, the PortCls system driver and its built-in port drivers
provide a number of helper objects for use by miniport drivers. These objects help miniport drivers to manage
DMA channels, resource lists, registry keys, interrupt service calls, and interrupt synchronization.
This section discusses the following topics:
DMA Channel Objects
Registry Key Objects
Resource List Objects
Service Sink and Service Group Objects
Interrupt Sync Objects
DMA Channel Objects
10/23/2019 • 4 minutes to read • Edit Online

The PortCls system driver implements the IDmaChannel and IDmaChannelSlave interfaces for the benefit of
WaveCyclic and WavePci miniport drivers. IDmaChannel represents a DMA channel plus its associated DMA
buffer and buffer-usage parameters. In addition, WaveCyclic miniport drivers use IDmaChannelSlave to manage
a DMA channel for a subordinate device. IDmaChannelSlave inherits from IDmaChannel . For information about
controlling DMA operations, see Adapter Objects and DMA.
An IDmaChannel object encapsulates the following:
A DMA channel for a master or subordinate device
The data buffer that is associated with the channel
Information that describes how the channel is to be used
Port and miniport drivers use DMA channel objects to communicate information regarding DMA channel usage.
Typically, a miniport driver allocates a set of DMA channels during initialization or during the creation of a stream.
During the creation of a new stream, the miniport driver tells the port driver which DMA channel object will be
used for the stream.
A DMA channel object can be created for a master or subordinate device:
A subordinate device has no built-in DMA-hardware capabilities and must rely on the system DMA
controller to perform any data transfers that the device requires.
A master device uses its own bus-mastering DMA hardware to perform data transfers on the system bus.
For an example of a WaveCyclic device that uses a subordinate DMA channel object, see the Sb16 sample audio
driver in the Microsoft Windows Driver Kit (WDK). A master DMA channel object is little more than a backboard for
sharing information about the DMA channel between the port and miniport drivers. For more information about
master and subordinate devices, see Introduction to Adapter Objects.
The DMA channel object for a master or subordinate device exposes the following:
An adapter object
A single common buffer that the driver and DMA hardware can share
A buffer-size value that can be queried and changed
The adapter object is a DMA-adapter structure for a physical device object (PDO). The adapter object is
automatically created when the miniport driver creates the DMA channel object by calling one of the following
methods:
IPor tWavePci::NewMasterDmaChannel
IPor tWaveCyclic::NewMasterDmaChannel
IPor tWaveCyclic::NewSlaveDmaChannel
The method IDmaChannel::GetAdapterObject can be used to obtain a pointer to the adapter object.
An adapter driver can also call the PcNewDmaChannel function to create a DMA channel object, but this function
is more difficult to use than the IPor tWave Xxx ::New Xxx DmaChannel calls because the caller must explicitly
specify a device object and other contextual information.
In the case of a DMA channel for a subordinate device, the IDmaChannel::TransferCount method returns the
maximum transfer size (the MapSize parameter) that was specified in the call to IDmaChannelSlave::Star t . Also,
the adapter object provides some methods for manipulating and querying the DMA device. None of these methods
are meaningful for master DMA channels.
IDmaChannel::AllocateBuffer and IDmaChannel::FreeBuffer are used to manage the single common buffer
that is associated with the DMA channel object. The buffer that is allocated by the object is guaranteed to be
accessible to both the driver (with kernel virtual-memory addresses) and DMA device (with physical-memory
addresses). In addition, the buffer will be physically contiguous. Typically, the best strategy is to allocate the DMA
buffer during miniport-driver initialization when physically contiguous memory is most plentiful.
IDmaChannel::AllocatedBufferSize returns the size of the buffer as it was specified in the call to
IDmaChannel::AllocateBuffer .
IDmaChannel::MaximumBufferSize indicates the actual maximum buffer size that can be used. This might
exceed the allocated size if the allocated size is not an even multiple of the page size. It might be less than the
allocated size if the DMA device cannot support transfers of the allocated size. IDmaChannel::BufferSize and
IDmaChannel::SetBufferSize are used to query and set the size of the buffer to be used for DMA transfers.
When the buffer is allocated, the buffer size is set to the maximum buffer size. After initialization, both the port
driver and miniport driver have the opportunity to change the buffer size or discover its current value. The
miniport driver uses the result of IDmaChannel::BufferSize to determine the transfer size for DMA operations
when the DMA channel is started. IDmaChannel::SystemAddress and IDmaChannel::PhysicalAddress are
used to obtain the virtual and physical addresses of the buffer, respectively.
IDmaChannel::CopyTo and IDmaChannel::CopyFrom copy sample data to and from the DMA buffer. The
WaveCyclic port driver calls these methods to copy audio data between the application buffer and the miniport
driver's cyclic buffer.
The DMA buffer is not necessarily used to transfer the streamed data. In the case of the WavePci port driver, the
streamed data is delivered to (or retrieved from) the miniport driver as a list of scatter/gather mappings. However,
the miniport driver might still make use of the DMA buffer as a shared memory space for communicating with the
adapter driver.
Port drivers provide miniport drivers with functions that they can use to create DMA channels. Unless otherwise
noted in the description of the port driver, it is not absolutely necessary to use DMA objects allocated from the port
driver. The port driver simply requires a pointer to an IDmaChannel interface that supports the methods it needs.
Check the documentation for each port driver for a list of the DMA channel methods that the port driver requires.
Typically, the easiest approach is to use the DMA channel allocation functions that the port driver implements. In
rare instances, miniport driver developers might need to implement their own DMA channel objects to meet the
special requirements of their particular adapters. This sometimes requires the implementation of a new object. At
other times, it is sufficient to have the miniport driver's stream object expose an IDmaChannel interface and
implement the DMA channel methods itself.
The IDmaChannel interface supports the following methods:
IDmaChannel::AllocateBuffer
IDmaChannel::AllocatedBufferSize
IDmaChannel::BufferSize
IDmaChannel::CopyFrom
IDmaChannel::CopyTo
IDmaChannel::FreeBuffer
IDmaChannel::GetAdapterObject
IDmaChannel::MaximumBufferSize
IDmaChannel::PhysicalAddress
IDmaChannel::SetBufferSize
IDmaChannel::SystemAddress
IDmaChannel::TransferCount
The IDmaChannelSlave interface extends IDmaChannel by adding the following methods:
IDmaChannelSlave::ReadCounter
IDmaChannelSlave::Star t
IDmaChannelSlave::Stop
IDmaChannelSlave::WaitForTC
Registry Key Objects
10/23/2019 • 2 minutes to read • Edit Online

The PortCls system driver implements the IRegistryKey interface for the benefit of miniport drivers. An
IRegistryKey object represents a registry key. Miniport drivers use registry key objects to do the following:
Create and delete registry keys
Enumerate registry keys
Query and set registry keys
When querying a registry key object for information about a registry entry under the specified key, the query can
output the information in one of three formats, each of which uses a different key-query structure. The following
table shows the KEY_INFORMATION_CL ASS enumeration values that indicate which of the three key-query
structures is output by the query.

K EY _IN F O RM AT IO N _C L A SS VA L UE K EY - Q UERY ST RUC T URE

KeyBasicInformation KEY_BASIC_INFORMATION

KeyFullInformation KEY_FULL_INFORMATION

KeyNodeInformation KEY_NODE_INFORMATION

To open an existing registry key or create a new registry key, an adapter driver can call the PcNewRegistr yKey
function, and a miniport driver can call the port driver's IPor t::NewRegistr yKey method. The two calls are similar,
except that the PcNewRegistr yKey function requires two additional parameters, DeviceObject and SubDevice. For
more information, see PcNewRegistr yKey .
When a miniport driver creates a new IRegistryKey object, the object either opens an existing subkey or creates a
new registry subkey if none exists. In either case, the registry key object stores the handle to the key. When that
object is later released and its reference count decrements to zero, the object automatically closes its handle to the
key.
The IRegistryKey interface supports the following methods:
IRegistr yKey::DeleteKey
IRegistr yKey::EnumerateKey
IRegistr yKey::EnumerateValueKey
IRegistr yKey::NewSubKey
IRegistr yKey::Quer yKey
IRegistr yKey::Quer yRegistr yValues
IRegistr yKey::Quer yValueKey
IRegistr yKey::SetValueKey
Resource List Objects
10/23/2019 • 2 minutes to read • Edit Online

The PortCls system driver implements the IResourceList interface for the benefit of miniport drivers. An
IResourceList object represents a configuration resource list, which is a list of the system hardware resources that
the Plug and Play manager assigns to a device at device-startup time. For more information about resource
assignment at startup time, see Starting a Device in a Function Driver.
A resource list contains the following types of resources:
Interrupt vectors
DMA channels
I/O port addresses
Blocks of bus-relative memory addresses
For information about resource types, see Hardware Resources.
An IResourceList object encapsulates both the translated and untranslated (or "raw") versions of a resource list. For
more information about translated and untranslated resources, see Mapping Bus-Relative Addresses to Virtual
Addresses.
The IResourceList interface supports the following methods:
IResourceList::AddEntr y
IResourceList::AddEntr yFromParent
IResourceList::FindTranslatedEntr y
IResourceList::FindUntranslatedEntr y
IResourceList::NumberOfEntries
IResourceList::NumberOfEntriesOfType
IResourceList::TranslatedList
IResourceList::UntranslatedList
Header file Portcls.h defines set of macros to simplify the handling of resource-list objects. These macros generate
calls to the IResourceList methods. For more information, see IResourceList.
In addition, Portcls.h defines a pair of functions for creating resource lists:
PcNewResourceList
PcNewResourceSublist
To start up the devices on an audio adapter card, the operating system calls the adapter driver's start-device routine
(see Startup Sequence) and passes in a resource list object as an input parameter. This list contains all the system
resources that the operating system has assigned to the adapter driver.
In the start-device routine, the adapter driver starts up all of the adapter driver's devices (wave device, MIDI device,
and so on). To manage each device, the adapter driver creates a miniport driver object and its associated port
driver object. The adapter driver divides up the resources in the resource list among the various devices in the
adapter card. For this purpose, the driver typically calls PcNewResourceSublist to create a resource list object for
each device. The driver then calls IResourceList::AddEntr yFromParent as many times as necessary to copy
selected resources from the parent list into the various child lists. In addition, the adapter driver might assign some
resources to itself.
Next, the start-device routine calls each port driver's IPor t::Init method and passes in the device's resource list
object (containing the child list) as an input parameter. Each port driver's IPor t::Init method calls the
corresponding miniport driver's IMiniportXxx::Init method, which is one of the following:
IMinipor tDMus::Init
IMinipor tMidi::Init
IMinipor tTopology::Init
IMinipor tWaveCyclic::Init
IMinipor tWavePci::Init
The IPor t::Init method passes its resource list object to the IMiniportXxx::Init method as an input parameter. The
miniport driver can then make use of the DMA channels, interrupts, and other system resources in the resource list.
For a code example, see the Sb16 sample audio driver in the Microsoft Windows Driver Kit (WDK).
Service Sink and Service Group Objects
10/23/2019 • 4 minutes to read • Edit Online

The PortCls system driver implements the IServiceSink and IServiceGroup interfaces for the benefit of port and
miniport drivers. The port driver uses these interfaces to distribute interrupt notifications to its own service
routines, and a miniport driver has the option of using these interfaces for similar purposes. An IServiceSink object
encapsulates a service routine, and an IServiceGroup object represents a group of IServiceSink objects. When a
service group receives a service request, it distributes the request to each of its service sinks.
IServiceGroup inherits from IServiceSink. Because a service group is also a service sink, a service group is capable
of containing other service groups, although audio drivers typically make no use of this capability. Port drivers
currently use service groups to demultiplex requests for interrupt service, although the functionality of a service
group is general enough to make it potentially useful for other purposes as well.
The miniport driver's interrupt service routine (ISR) calls one of the following notification methods in the port
driver:
IPor tDMus::Notify
IPor tMidi::Notify
IPor tWaveCyclic::Notify
IPor tWavePci::Notify
The notification method takes a pointer to the service group as a call parameter. During this call, the port driver
calls the service group's ISer viceSink ::RequestSer vice method, which queues a deferred procedure call (DPC).
When the DPC executes, it forwards the service request to all member objects in the service group.
The miniport-driver code typically does not need to call any IServiceGroup interface methods. However, the port
driver calls these methods to add its own IServiceSink objects to the service groups that it obtains from the
miniport driver. Miniport drivers create service group objects as required and associate those service groups with
miniport and stream objects that require periodic servicing. For example, a WaveCyclic miniport driver associates
a stream object with the service group that it specifies as an output parameter to the
IMinipor tWaveCyclic::NewStream method.
In the context of WaveCyclic miniport drivers, associating all streams with one service group causes the port driver
to service all streams based on a single notification. Associating each stream with its own service group allows the
interrupt service routine to select the stream that will be serviced by the port driver during the execution of the
DPC.
A miniport driver outputs a reference to its service group when the port driver calls one of the following
initialization methods:
IMinipor tDMus::Init
IMinipor tMidi::Init
IMinipor tWavePci::Init
The port driver adds its own IServiceSink object to the service group that it obtains from the Init call. When the
miniport driver's ISR later calls Notify to send notification to that service group, the service group queues a DPC
that forwards notification to the port driver's IServiceSink object, which in turn forwards notification to the
miniport driver by calling one of the following service methods:
IMinipor tDMus::Ser vice (not used)
IMinipor tMidi::Ser vice
IMinipor tWavePci::Ser vice
A miniport driver also outputs a reference to its service group when the port driver calls one of the following
stream-creation methods:
IMinipor tDMus::NewStream
IMinipor tMidi::NewStream
IMinipor tWaveCyclic::NewStream
IMinipor tWavePci::NewStream
As discussed previously, the miniport driver has the option of creating a different service group for each stream or
sharing a single service group across all streams.
The following methods help MIDI and DMus port drivers avoid dropping hardware interrupts:
IPor tMidi::RegisterSer viceGroup
IPor tDMus::RegisterSer viceGroup
During execution of its Init method, a MIDI or DMus miniport driver typically calls the port driver's
RegisterSer viceGroup method before starting up the synthesizer. The purpose for this call is to allow the port
driver to insert its service sink object (containing its interrupt handler) into the service group before the hardware
begins generating interrupts. Although the Init method outputs a service group pointer to the port driver, the port
driver can make use of this pointer only after the return from Init .
In the case of a WavePci port driver, the port object adds its own IServiceSink object to the service group that it
obtains from the IMinipor tWavePci::NewStream call. When the miniport driver's ISR later calls Notify to send
notification to that service group, the service group queues a DPC that forwards the notification to the port
driver's IServiceSink object, which in turn does the following:
Forwards notification to the miniport stream by calling the service method
IMinipor tWavePciStream::Ser vice .
Triggers any position and/or clock events on the pin that are ready to fire.
The IServiceSink interface supports a single method:
ISer viceSink ::RequestSer vice
The IServiceGroup interface supports the following methods:
ISer viceGroup::AddMember
ISer viceGroup::CancelDelayedSer vice
ISer viceGroup::RequestDelayedSer vice
ISer viceGroup::RemoveMember
ISer viceGroup::Suppor tDelayedSer vice
In addition, the PortCls system driver provides a PcNewSer viceGroup function for creating a new service group
object. However, no similar function exists for creating a service sink object. The port driver simply adds an
IServiceSink interface to the implementation of its main port object--when the object is created, so is the service
sink. The port driver can add the port object's IServiceSink interface to the service group that it receives from the
miniport driver's Init or NewStream method. For convenience, header file Portcls.h defines IMP_ISer viceSink
and IMP_ISer viceGroup constants for adding IServiceSink and IServiceGroup interfaces to driver objects.
Interrupt Sync Objects
10/23/2019 • 3 minutes to read • Edit Online

The PortCls system driver implements the IInterruptSync interface for the benefit of miniport drivers.
IInterruptSync represents an interrupt sync object that synchronizes the execution of a list of interrupt service
routines (ISRs) with non-interrupt routines.
Interrupt sync objects provide two key capabilities:
Execution of a list of ISRs in response to an interrupt. The sync object is connected to an interrupt source.
Each time the interrupt occurs, the sync object executes the ISRs in a specified order according to the
selected mode. (See the following description of the three modes.)
Execution of routines that are not ISRs. These non-interrupt routines are not connected to the sync object's
interrupt. Instead, a non-interrupt routine runs at a time of the caller's choosing. However, the sync object
executes the non-interrupt routine synchronously with the object's list of ISRs. In other words, the non-
interrupt routine runs to completion before any of the ISRs in the sync object's list begin executing, and vice
versa.
An interrupt sync object is flexible in dealing with multiple ISRs. The ISRs reside in a linked list that the sync object
traverses at interrupt time. When a miniport driver registers an ISR with a sync object, it specifies whether the ISR
should be added to the beginning or end of this list.
A miniport driver calls the PcNewInterruptSync function to create an interrupt sync object. During this call, the
driver specifies the manner in which the object is to traverse its list of ISRs at interrupt time. The call supports the
three options that are specified by the INTERRUPTSYNCMODE enumeration constants in the following table.

C O N STA N T M EA N IN G

InterruptSyncModeNormal Call each ISR in the list until one of them returns
STATUS_SUCCESS.

InterruptSyncModeAll Call each ISR in the list exactly once, regardless of the
return codes of the preceding ISRs.

InterruptSyncModeRepeat Traverse the entire list of ISRs until a trip through the list
occurs in which no ISR in the list returns STATUS_SUCCESS.

In the InterruptSyncModeNormal mode, the sync object calls each ISR in the list until one of them returns
STATUS_SUCCESS. Any ISRs in the list that follow this ISR are not called. This mode emulates the way that the
operating system normally handles ISRs. If none of the ISRs return STATUS_SUCCESS, the behavior is the same as
InterruptSyncModeAll .
In the InterruptSyncModeAll mode, each ISR in the list is called exactly once, regardless of the return codes of
the preceding ISRs. This is intended for more primitive hardware where the source of the interrupt is not
deterministic, although it might be useful in other situations as well. For example, two interrupt sources might be
tightly synchronized on every interrupt, regardless of which of the two sources a particular interrupt comes from.
In the InterruptSyncModeRepeat mode, the sync object repeatedly traverses the entire list of ISRs until a trip
through the list occurs in which no routine in the list returns STATUS_SUCCESS. This mode is appropriate for
situations in which interrupts from multiple sources might fire on the same interrupt line at the same time, or a
second interrupt might fire during ISR processing. Every interrupt source must be able to determine whether it
requires processing. The system will stop responding if an ISR that always returns STATUS_SUCCESS is registered
with a sync object in this mode.
In any of these modes, the sync object will acknowledge the interrupt to the operating system if any of the
registered ISRs return STATUS_SUCCESS. In all three modes, if all interrupt sources indicate that they did not
successfully handle the interrupt, the sync object will return an unsuccessful result code to the operating system.
The IInterruptSync interface supports the following methods:
IInterruptSync::CallSynchronizedRoutine
IInterruptSync::Connect
IInterruptSync::Disconnect
IInterruptSync::GetKInterrupt
IInterruptSync::RegisterSer viceRoutine
Power Management for Audio Devices
10/23/2019 • 2 minutes to read • Edit Online

The PortCls system driver handles all power-management IRPs (see Handling Power IRPs) on behalf of audio
adapter drivers. PortCls manages the power state of an audio device by making calls through the adapter driver's
IAdapterPowerManagement and IPowerNotify interfaces. Both interfaces are optional. The adapter driver for a
device that can change its power state in response to requests from PortCls should expose an
IAdapterPowerManagement interface. A miniport object that requires advance warning of an impending power-
down should expose an IPowerNotify interface.
In Windows Server 2003 SP1, Windows XP SP2, and later, PortCls uses timers to determine when to power down
audio devices that have remained inactive for some specified time-out interval. PortCls provides default values for
the time-out intervals and the target power state when a time-out occurs. Hardware vendors can optionally
override these defaults with their own driver-specific values.
This section discusses the following topics:
Implementing IAdapterPowerManagement
Implementing IPowerNotify
Audio Device Class Inactivity Timer Implementation
Implementing IAdapterPowerManagement
10/23/2019 • 2 minutes to read • Edit Online

When implementing the IAdapterPowerManagement interface for your driver, refer to the implementation of the
CAdapterCommon class in the sample audio drivers in the Microsoft Windows Driver Kit (WDK). This class
handles device interrupts and performs other functions that are common to all audio adapter drivers. Your
adapter's CAdapterCommon class should inherit from the IAdapterPowerManagement interface and support
this interface in its NonDelegatingQuer yInterface method. (For details on nondelegating interfaces, see the
description of the INonDelegatingUnknown interface.)
You can use the IMP_IAdapterPowerManagement definition from header file Portcls.h to add the function
declarations for the IAdapterPowerManagement::PowerChangeState ,
IAdapterPowerManagement::Quer yPowerChangeState , and
IAdapterPowerManagement::Quer yDeviceCapabilities methods to your driver's CAdapterCommon class
definition.
During the PortCls system driver's call to an adapter's device-startup routine (see Starting a Device), the adapter
should register its IAdapterPowerManagement interface with PortCls by calling
PcRegisterAdapterPowerManagement . For a code example, see the Star tDevice function in the Sb16 sample
adapter driver in the WDK. The PcRegisterAdapterPowerManagement function's first parameter is an
IUnknown pointer to the adapter driver's CAdapterCommon object. PortCls queries this object for its
IAdapterPowerManagement interface.
When PortCls calls the adapter driver's IAdapterPowerManagement::PowerChangeState method to change
the device's power state, the adapter driver should cache the device's new power state in the adapter's
CAdapterCommon object. During the CAdapterCommon::Init call (see the implementation in the WDK's
sample adapter drivers), the driver should set the initial power state to PowerDeviceD0 (described in DeviceState)
before returning from a successful initialization. The driver should write to the hardware only if it is known to be in
an appropriate power state. In the Sb16 sample driver in the WDK, for example, the driver writes to the hardware
only in the PowerDeviceD0 state.
Before powering down in response to a PowerChangeState call, the adapter driver should place the audio
outputs in a state that prevents speaker noise from occurring when the power switches off. For example, the
shutdown process might include ramping the DAC outputs to zero, turning off the DACs, and muting the MIDI
lines.
Implementing IPowerNotify
10/23/2019 • 2 minutes to read • Edit Online

If your driver's miniport objects (see Audio Miniport Object Interfaces) or stream objects (see Audio Stream Object
Interfaces) need to know about power-state changes, they can support the IPowerNotify interface in their
Quer yInterface methods and receive notification from the PortCls system driver each time a power change
occurs.
When the power state changes, PortCls calls the IPowerNotify::PowerChangeNotify method to individually
notify each of the miniport and stream objects that support the IPowerNotify interface. During the
PowerChangeNotify call, a miniport object should cache the new device power state. During the
CAdapterCommon::Init call (for example, see the implementation in the Msvad sample adapter in the Microsoft
Windows Driver Kit [WDK]), the miniport driver should set its cached power state to the initial value
PowerDeviceD0.
Before calling PowerChangeState to power down, PortCls calls IPowerNotify::PowerChangeNotify to give the
miniport driver an opportunity to save any necessary device context. This context might include the hardware-
register values that embody the current filter topology and mixer-line settings, for example. After calling
PowerChangeState to power up, PortCls calls PowerChangeNotify so that the miniport driver can restore the
saved context.
When powering down, PortCls pauses any active audio data streams before calling PowerChangeNotify . When
powering up, PortCls calls PowerChangeNotify before restarting any paused audio data streams.
Your miniport driver's miniport and stream object classes can inherit from the IPowerNotify interface and
support this interface in their NonDelegatingQuer yInterface method. You can use the IMP_IPowerNotify
definition from header file Portcls.h to add the function declaration for the PowerChangeNotify method to the
class definition for your driver's miniport and stream objects.
Audio Device Class Inactivity Timer Implementation
10/23/2019 • 3 minutes to read • Edit Online

In Windows Server 2003 SP1, Windows XP SP2, and later, the PortCls system driver utilizes the system's power-idle
detection capabilities to implement an inactivity timer for its audio clients. PortCls programs two time-out values
and a desired idle power state into the timer when it initializes it. PortCls monitors any accesses (such as I/O and
property accesses) of the device and effectively resets the timer count on each access. If the timer times out, the
system requests a power IRP to place the device in the desired idle state. After the device has been placed in the
idle state, PortCls will power the device back up in the event of new access activity.
PortCls contains hard-coded default values for the idle time-outs and the idle power state. Hardware vendors can
optionally override the default values by writing their own values to driver-specific keys in the system registry. In
this way, vendors can select the power-idle parameter values that are best-suited to their devices.
Vendors can override the default values of the following power-idle parameters:
ConservationIdleTime
This parameter specifies the idle time-out interval when the system is running in power-conservation mode.
This is the mode that is typically used when the system is running on battery power. The default value for
this parameter is 0, which disables the power-idle timer in conservation mode. The hardware vendor can
override the default by writing a DWORD value to the following driver-specific registry key:

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\xxxx\yyyy\PowerSettings\ConservationIdleTime

Note that xxxx represents the Media class GUID (see System-Supplied Device Setup Classes) and yyyy
represents the name of the driver's subkey under the Media class GUID. The value of the key specifies the
time-out interval in seconds.
PerformanceIdleTime
This parameter specifies the idle time-out interval when the system is running in performance mode. This is
the mode that is typically used when the system is running on AC power. The default value for this
parameter is 0, which disables the power-idle timer in performance mode. The hardware vendor can
override the default by writing a DWORD value to the following driver-specific registry key:

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\xxxx\yyyy\PowerSettings\PerformanceIdleTime

Again, xxxx represents the Media class GUID and yyyy represents the name of the driver's subkey. The value
of the key specifies the time-out interval in seconds.
IdlePowerState
This parameter specifies the power state that the device will be placed in if the idle time-out period expires.
The default value for this parameter is 0, corresponding to device power state D0 (full power). The hardware
vendor can override the default by writing a DWORD value to the following driver-specific registry key:

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\xxxx\yyyy\PowerSettings\IdlePowerState

Again, xxxx represents the Media class GUID and yyyy represents the name of the driver's subkey. The value
placed in the key should be 0, 1, 2, or 3, corresponding to device power state D0, D1, D2, or D3, respectively.
The three power-idle registry keys exist only if the device-installation INF file creates them. Before configuring the
power-idle timer, PortCls attempts to retrieve the driver-specific power-idle parameters from the registry. PortCls
uses the default values in place of any power-idle parameters it does not find in the registry. As explained
previously, the default power-idle parameter values disable the idle timer.
For more information about specifying the ConservationIdleTime, PerformanceIdleTime, and IdlePowerState
parameters, see the definitions of the last three call parameters in PoRegisterDeviceForIdleDetection .
Example
For example, a hardware vendor might want to specify the following power-idle parameters for an audio device:
ConservationIdleTime = 0x0000001e (30 seconds), PerformanceIdleTime = 0x0000012c (300 seconds), and
IdlePowerState = 0x00000003 (device power state D3). To enable these settings, the device-installation file can
include an INF AddReg section containing the following directives:

[MyAudioDevice.AddReg]
HKR,PowerSettings,ConservationIdleTime,1,1e,00,00,00
HKR,PowerSettings,PerformanceIdleTime,1,2c,01,00,00
HKR,PowerSettings,IdlePowerState,1,03,00,00,00

HKR represents the driver's root key in the registry:

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\xxxx\yyyy

Again, xxxx represents the Media class GUID and yyyy represents the name of the driver's subkey. The
PowerSettings subkey is specified relative to the path name for the root key.
Version Numbers for Audio Drivers
12/5/2018 • 2 minutes to read • Edit Online

Windows operating systems support three types of audio driver models: the VxD, WDM, and NT4 (Microsoft
Windows NT 4.0) driver models. The version number that you assign to your audio adapter driver depends on the
driver model that you use, the Windows release that you target, and perhaps the Microsoft DirectX release as well.
The following four tables list driver version numbers by driver model.
Driver Model: VxD Drivers for Windows 95
DIREC T X REL EA SE DRIVER VERSIO N N UM B ERS

Windows 95 without DirectX support 4.00.00.0096 to 4.02.00.0094

DX1 4.02.00.0096 to 4.02.00.9999

DX2 4.03.00.1097 to 4.03.00.9999

DX3 4.04.00.1097 to 4.04.00.9999

DX5 4.05.00.1000 to 4.05.00.9999

DX6 4.06.00.1000 to 4.06.00.9999

Driver Model: VxD Drivers for Windows 98


DIREC T X REL EA SE DRIVER VERSIO N N UM B ERS

DX5 4.05.01.2500 to 4.05.99.9999

DX6 4.06.00.1000 to 4.06.00.9999

Driver Model: WDM Drivers for Windows Me/98, and Windows 2000 and Later
W IN DO W S REL EA SE DRIVER VERSIO N N UM B ERS

Windows 98 4.10.00.2500 to 4.10.00.9999

Windows 2000 5.00.00.3500 to 5.00.00.9999

Windows Me 4.90.00.3500 to 4.90.00.9999


W IN DO W S REL EA SE DRIVER VERSIO N N UM B ERS

Windows XP 5.10.00.3500 to 5.10.00.9999

Windows Vista 6.00.00.3500 to 6.00.00.9999

Windows 7 7.00.00.3500 to 7.00.00.9999

Windows 8 8.00.00.3500 to 8.00.00.9999

Driver Model: NT4 Drivers (Windows NT 4.0 Only)


W IN DO W S REL EA SE DRIVER VERSIO N N UM B ERS

Windows NT 4.0 4.00.00.1400 to 4.00.00.9999

For device drivers that do not support DirectX, the version number should be greater than or equal to
4.00.00.0096 and less than or equal to 4.02.00.0094. Device drivers that support DirectX version 1.0 should have a
version number in the range 4.02.00.0096 to 4.02.00.9999. Device drivers that support later versions of DirectX
should have version numbers in the range appropriate for the distributed version of DirectX, as shown in the
preceding tables.
All WDM drivers should have version numbers that are greater than or equal to 4.10.00.2500, which is the low end
of the Windows 98 version-number range.
Note that WDM drivers that are written for earlier versions of Windows run correctly on later versions as well. For
example, a WDM driver that is written to run in Windows 2000 also runs in Microsoft Windows XP and later.
DirectX Version 1.0 drivers work in systems with DirectX 2.0 installed. However, DirectX 2.0 drivers do not work
correctly unless DirectX 2.0 is installed. The same is true for DirectX 3.0 and later releases.
A cross-platform driver should set its version number to the highest version number for the platforms on which
the driver runs. For example, a vendor should use a driver-version number of 5.00.00.Xxxx for a driver that
supports Windows 2000, Windows 98, Windows 98 SE, and Windows Me.
This section includes:
Internal and External Version Numbers
INF Driver-Version Entry
DirectX File Version Numbers
Internal and External Version Numbers
12/5/2018 • 2 minutes to read • Edit Online

The driver's resource file specifies the driver-file version in two ways:
As an internal or binary version number that is specified in the double-DWORD value FILEVERSION . The
operating system currently does not use this value.
As an external or display version number that is specified in the FileVersion character string. The operating
system displays this string when the user views the properties of individual driver files.
Under the Windows XP user interface, for example, there are several alternative ways to view a driver file's
FileVersion string:
In Windows Explorer:
1. Right-click the file icon.
2. Select the Proper ties of the driver file.
3. On the Version tab, view the File version number.
In Device Manager:
1. Select the Proper ties of a particular audio device.
2. On the Driver tab click Driver Details .
3. Select the driver file from the list of files in the driver package.
4. view the File version number of the selected driver file.
In Control Panel:
1. Click the Sounds and Audio Devices icon.
2. On the Hardware tab select the device, click the Proper ties button.
3. On the Driver tab select Driver Details , select the driver file from the list of files in the driver package,
and view the File version number of the selected driver file.
To make your driver version numbers compatible with both Windows and DirectX, follow these rules when you
specify the internal and external version numbers:
The internal version number has the format x.xx.00.xxxx. The two extra zeros before the last dot are required.
The external version string should use the format x.xx.xxxx (without the two extra zeros in the internal
version number).
These internal and external version numbers should match (except for the two extra zeros, as noted above).
INF Driver-Version Entry
6/25/2019 • 2 minutes to read • Edit Online

The INF file in a driver package specifies the driver-version information for the drivers that are installed by the INF.
The version information in the file identifies the driver package as a whole, in contrast to the internal and external
version numbers for the individual driver files within the package.
The file specifies each driver's date and version number in an INF DriverVer directive with the following format:
DriverVer = mm / dd / yyyy[,x.y.v.z]
The date parameter mm/dd/yyyy consists of a two-digit month code mm, two-digit day code dd, and four-digit
year code yyyy. This parameter specifies the date of the driver package and applies to all the driver files, including
the INF file. A hyphen (-) can be used as the date-field separator in place of the slash (/). The operating system uses
the DriverVer date to perform driver-version comparisons when selecting between two versions of a driver. This
date also appears in the Driver Date value displayed by the Device Manager.
The optional version number x.y.v.z , which is shown in brackets above, is used for display purposes only (for
example, in the Driver Version number displayed by the Device Manager). The operating system does not use this
value for driver selection. When compiling driver files, make sure that the internal version number that is specified
in the FILEVERSION parameter in the driver's resource file matches the DriverVer version number in the INF file.
When the operating system searches for drivers, it chooses a driver with a more recent DriverVer date over a
driver with an earlier date. If an INF file has no DriverVer entry or is unsigned, the operating system applies the
default date of 00/00/0000.
In Windows 2000, Windows XP and later, the INF file for a driver package must provide a DriverVer directive.
DirectX File Version Numbers
12/5/2018 • 2 minutes to read • Edit Online

VxDs that support DirectX should meet the DirectX setup requirements for driver version numbers and driver
capabilities. See the DirectX 8.0 Programmer's Reference. These requirements do not apply to WDM or Windows
NT 4.0 drivers.
Use the following procedure to check the driver version numbers:
Use the Setup application provided with any DX-supported game to install the device driver. Record the
version numbers for all installed files, including all .drv, .dll, .vxd, and .exe files in the driver-installation
package.
Confirm that all internal version numbers correspond to external (string) version numbers and that the
numbers follow the version-numbering rules (see Version Numbers for Audio Drivers).
Use Windows Explorer to view the directory containing the files. Right-click each file and click Proper ties to
verify that the copyright information is correct. In particular, verify that your driver does not specify
"Microsoft" as the vendor name.
Other Implementation Issues for Audio Drivers
12/5/2018 • 2 minutes to read • Edit Online

This section discusses two additional implementation issues for audio drivers:
Writing 64-Bit Audio Drivers
Accessing PCI Configuration Space
Writing 64-Bit Audio Drivers
10/23/2019 • 2 minutes to read • Edit Online

If you are writing a 64-bit driver or writing a driver that can be compiled to run on both 32- and 64-bit systems,
follow the porting guidelines in Driver Programming Techniques. Some of the pitfalls that you might encounter in
writing a 64-bit audio driver are described below.
First and foremost, a potential problem to look for in existing 32-bit driver code is conversion between pointer
types and integer types such as DWORD or ULONG. Programmers with experience writing code for 32-bit
machines might be used to assuming that a pointer value fits into a DWORD or ULONG. For 64-bit code, this
assumption is dangerous. Casting a pointer to type DWORD or ULONG can cause a 64-bit pointer to be truncated.
A better approach is to cast the pointer to type DWORD_PTR or ULONG_PTR. An unsigned integer of type
DWORD_PTR or ULONG_PTR is always large enough to store the entire pointer, regardless of whether the code is
compiled for a 32- or 64-bit machine.
For example, the IRP pointer field IoStatus .Information is of type ULONG_PTR. The following code shows what
not to do when copying a 64-bit pointer value to this field:

PDEVICE_RELATIONS pDeviceRelations;
Irp->IoStatus.Information = (ULONG)pDeviceRelations; // wrong

This code sample erroneously casts the pDeviceRelations pointer to type ULONG, which can truncate the pointer
value if sizeof(pDeviceRelations) > sizeof(ULONG) . The correct approach is to cast the pointer to ULONG_PTR, as
shown in the following:

PDEVICE_RELATIONS pDeviceRelations;
Irp->IoStatus.Information = (ULONG_PTR)pDeviceRelations; // correct

This preserves all 64 bits of the pointer value.


A resource list stores the physical address of a resource in a structure of type PHYSICAL_ADDRESS (see
IResourceList). To avoid truncating a 64-bit address, you should access the structure's QuadPar t member rather
than its LowPar t member when copying an address into the structure or reading an address from the structure.
For example, the FindTranslatedPor t macro returns a pointer to a CM_PARTIAL_RESOURCE_DESCRIPTOR
structure that contains the base address of an I/O port. The u .Por t .Star t member of this structure is a
PHYSICAL_ADDRESS pointer to the base address. The following code shows what not to do:

PUSHORT pBase = (PUSHORT)FindTranslatedPort(0)->u.Port.Start.LowPart; // wrong

Again, this can truncate the pointer. Instead, you should access the QuadPar t of this member, as shown in the
following:

PUSHORT pBase = (PUSHORT)FindTranslatedPort(0)->u.Port.Start.QuadPart; // correct

This copies the entire 64-bit pointer.


Inline Win64 functions such as PtrToUlong and UlongToPtr safely convert between pointer and integer types
without relying on assumptions about the relative sizes of these types. If one type is shorter than the other, it must
be extended when converting to the longer type. Whether the shorter type is extended by filling with the sign bit or
with zeros is well defined for each Win64 function. This means that any code snippets such as

ULONG ulSlotPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysDmaBuffer) + DMA_BUFFER_SIZE; // wrong

should be replaced by

ULONG_PTR ulSlotPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysDmaBuffer) + DMA_BUFFER_SIZE; // correct

This is preferred even though ulSlotPhysAddr might represent the value of a hardware register that is only 32
rather than 64 bits long. For a list of all the new Win64 helper functions for converting between pointer and integer
types, see The New Data Types.
Accessing PCI Configuration Space
10/23/2019 • 2 minutes to read • Edit Online

In Windows Me/98, and Windows 2000 and later, an adapter driver can access its adapter card's PCI configuration
space at IRQL PASSIVE_LEVEL by using the IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG requests.
In Windows 2000 and later, PCI driver stacks export the BUS_INTERFACE_STANDARD interface, which provides
access to the PCI configuration space at IRQL DISPATCH_LEVEL.
For more information, see Accessing Device Configuration Space.
Implement PnP Rebalance for PortCls Audio Drivers
10/23/2019 • 4 minutes to read • Edit Online

PnP rebalancing is used in certain PCI scenarios where memory resources need to be reallocated.
Rebalance can be triggered in two main scenarios:
1. PCI hotplug: A user plugs in a device and the PCI bus does not have enough resources to load the driver for the
new device. Some examples of devices that fall into this category include Thunderbolt, USB-C and NVME
Storage. In this scenario memory resources need to be rearranged and consolidated (rebalanced) to support
the additional devices being added.
2. PCI resizeable BARs: After a driver for a device is successfully loaded in memory, it requests additional
resources. Some examples of devices include high-end graphics cards and storage devices. For more
information about video driver support see, Resizable BAR support. This topic describes what needs to be done
to implement PnP rebalance for PortCls audio drivers.
PnP rebalancing is available in Windows 10, version 1511 and later versions of Windows.

Rebalance Requirements
Portcls audio drivers have the ability to support rebalance if the following conditions are met:
The Miniport must register the IAdapterPnpManagement interface with Portcls.
The Miniport must return PcRebalanceRemoveSubdevices from
IAdapterPnpManagement::GetSuppor tedRebalanceType .
Topology and WaveRT are the two Port types supported.
In order to support rebalance when there are active audio streams, portcls audio drivers need to meet one of these
two additional requirements.
The driver supports the IMinipor tWaveRTInputStream::GetReadPacket and IMiniportWaveRTOutputStream
packet interfaces for the audio stream. This is the recommended option.
OR
If the driver doesn’t support get/write IMiniportWaveRT for the streams, the driver must not support
KSPROPERTY_RTAUDIO_POSITIONREGISTER and KSPROPERTY_RTAUDIO_CLOCKREGISTER . The audio
engine will use the IMinipor tWaveRTStream::GetPosition in this scenario.

Audio Stream Behavior When Rebalancing Occurs


If the rebalance is triggered, when there are active audio streams, and the driver provides supports rebalance for
active audio streams, then all active audio streams will be stopped and they will not be restarted automatically.

IPortClsPnp COM Interface


IPortClsPnp is the PnP management interface that the port class driver (PortCls) exposes to the adapter.
IPortClsPnp inherits from IUnknown and also supports the following methods:
IPor tClsPnp::RegisterAdapterPnpManagement
IPor tClsPnp::UnregisterAdapterPnpManagement
Audio miniport drivers can register a PNP notification interface using Portcls exports or via the IPor tClsPnp COM
interface IPortClsPnp exposed on the WaveRT port object. Use IPor tClsPnp::RegisterAdapterPnpManagement
and IPor tClsPnp::UnregisterAdapterPnpManagement to register and unregister.

Required PortCls Export DDIs


IAdapterPnpManagement is an interface that adapters should implement and register if they want to receive PnP
management messages. Register this interface with PortCls using PcRegisterAdapterPnpManagement .
Unregister this interface with PortCls using PcUnregisterAdapterPnpManagement .

Required Driver DDIs


The following IAdapterPnpManagement DDIs must be implemented to support rebalance.
IAdapterPnpManagement::GetSuppor tedRebalanceType is called by Portcls while processing the
QueryStop. The miniport returns the supported rebalance type as defined in the PC_REBAL ANCE_TYPE
enum.
Note Portcls acquires the device global lock before making this call, thus the miniport must execute this
call as fast as possible.
IAdapterPnpManagement::PnpQuer yStop is invoked by portcls just before succeeding the QueryStop
IRP. This is just a notification and the call doesn’t return a value.
Note Portcls acquires the device global lock before making this call, thus the miniport must execute this
call as fast as possible. While a Stop is pending, Portcls will block (hold) any new create requests.
IAdapterPnpManagement::PnpCancelStop is invoked by portcls while processing the CanceStop IRP.
This is just a notification. It is possible for the miniport to receive PnpCancelStop even without previously
receiving a PnpQueryStop notification. The miniport should be written to accommodate this behavior. For
example, this is the case when the QueryStop logic fails the IRP before Portcls has an opportunity to
forward this notification to the miniport. In this scenario PnP manager still invokes a PnP Cancel Stop.
Note Portcls acquires the device global lock before making this call, thus the miniport must execute this
call as fast as possible. While a Stop is pending, Portcls will block (hold) any new create requests. PortCls
restarts any pended create requests when a pending Stop is cancelled.
IAdapterPnpManagement::PnpStop is invoked by Portcls after stopping all Ioctl operations and moving
active streams from [run|pause|acquire] state to the [stop] state. This call is not made while holding the
device global lock. Thus the miniport has an opportunity to wait for its async operations (work-items, dpc,
async threads) and unregister its audio subdevices. Before returning from this call the miniport must ensure
that all the h/w resources have been released.
Note The miniport must not wait for the current miniport/stream objects to be deleted since it is unclear
when existing audio clients will release the current handles. The PnpStop thread cannot block forever
without crashing the system, i.e., this is a PnP/Power thread.

IMiniportPnpNotify
IMiniportPnpNotify is an optional interface to allow miniport objects (audio subdevices) to receive PnP state
change notifications.
Miniports have an opportunity to receive a PnP Stop notification for each audio subdevice they have registered. To
receive this notification, the subdevice must support IMiniportPnpNotify. Only the
IMinipor tPnpNotify::PnpStop notification is defined on this interface.
IMiniportPnpNotify interface available is on both WaveRT and Topology.
Note Because Portcls acquires the device global lock before making this call, the miniport must execute this call as
fast as possible. The miniport must not wait on other activity while processing this call to prevent deadlock when
other threads/work-items are waiting for the device global lock. If needed, the miniport can wait in the
IAdapterPnpManagement::PnpStop call.
Legacy Audio Interfaces
12/5/2018 • 2 minutes to read • Edit Online

These interfaces were used with previous versions of Windows.


WavePci Port Driver
10/23/2019 • 2 minutes to read • Edit Online

Impor tant The use of WavePci is no longer recommended, instead use WaverRT.
The WavePci port driver manages the playback or recording of a wave stream by an audio device that can perform
scatter/gather DMA transfers to or from any location in physical memory. With scatter/gather DMA, the device can
process audio data in a buffer consisting of a series of mappings. Each mapping is a block of physically contiguous
memory, but successive mappings are not necessarily contiguous to each other. The WavePci-compatible device is
a hardware function on an audio adapter. Typically, the adapter is part of an integrated chipset on the motherboard
or is mounted on an audio card that plugs into a PCI slot on the motherboard. The adapter driver provides a
corresponding WavePci miniport driver that binds to the WavePci port driver object to form a wave filter that can
capture or render a wave stream.
The WavePci port driver exposes an IPortWavePci interface to the miniport driver. IPortWavePci inherits the
methods in base interface IPort. In addition, IPortWavePci provides the following methods:
IPor tWavePci::NewMasterDmaChannel
Creates a new master DMA channel object. IPor tWavePci::Notify
Notifies the port driver that the DMA controller has advanced to a new position in the audio stream. The WavePci
port driver also exposes an IPortWavePciStream interface to each of the miniport driver's stream objects.
IPortWavePciStream inherits the methods in base interface IUnknown . IPortWavePciStream provides the following
additional methods:
IPor tWavePciStream::GetMapping
Gets the next mapping from the port driver. IPor tWavePciStream::ReleaseMapping
Releases a mapping that was previously obtained by a GetMapping call.
IPor tWavePciStream::TerminatePacket
Terminates an I/O packet even if it is only partially filled with capture data. An I/O packet is a portion of the audio
buffer consisting of all the mappings that are associated with a particular mapping IRP.
The WavePci port and miniport objects communicate with each other through their respective IPortWavePci and
IMiniportWavePci interfaces. In addition, the WavePci port and miniport stream objects communicate with each
other through their respective IPortWavePciStream and IMiniportWavePciStream interfaces.
WavePci Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

Impor tant The use of WavePci is no longer recommended, instead use WaverRT.
A WavePci miniport driver manages the hardware-dependent functions of a wave-rendering or wave-capture
device that has scatter/gather DMA hardware that can transfer audio data to or from any location in physical
memory. A wave device that lacks the ability to perform scatter/gather transfers or is able to access only restricted
regions in physical memory should use a WaveCyclic miniport driver instead.
A WavePci miniport driver should implement two interfaces:
The minipor t interface performs miniport driver initialization, channel enumeration, and stream creation.
The stream interface manages a wave stream and exposes most of the miniport driver's functionality.
The miniport interface, IMiniportWavePci, inherits the methods in the IMiniport interface. IMiniportWavePci
provides the following additional methods:
IMinipor tWavePci::Init
Initializes the miniport object.
IMinipor tWavePci::NewStream
Creates a new stream object.
IMinipor tWavePci::Ser vice
Notifies the miniport driver of a request for service.
The stream interface, IMiniportWavePciStream, inherits the methods from the IUnknown interface.
IMiniportWavePciStream provides the following additional methods:
IMinipor tWavePciStream::GetAllocatorFraming
Gets the miniport driver's preferred allocator-framing parameters for the wave stream.
IMinipor tWavePciStream::GetPosition
Gets the device's current position in the wave stream.
IMinipor tWavePciStream::MappingAvailable
Indicates that a new mapping is available from the port driver.
IMinipor tWavePciStream::NormalizePhysicalPosition
Converts a physical buffer position value into a time-based value.
IMinipor tWavePciStream::RevokeMappings
Revokes previously issued mappings.
IMinipor tWavePciStream::Ser vice
Notifies the stream object of a request for service.
IMinipor tWavePciStream::SetFormat
Sets the data format of the wave stream.
IMinipor tWavePciStream::SetState
Sets the state of the wave stream.
Implementation Issues for WavePci Devices
12/5/2018 • 2 minutes to read • Edit Online

This section presents guidelines for hardware and software design that audio hardware vendors can use to
improve the performance and reliability of their WavePci devices. All of these guidelines apply to audio devices and
drivers that are designed to work with Microsoft Windows XP and later, but many also apply to earlier versions of
Windows going back to Windows 98 Second Edition.
As discussed in Wave Filters, the port class system driver, Portcls.sys, provides two different port drivers for wave
rendering and capture devices:
WaveCyclic is less demanding of hardware and software, but its performance is limited by the software
overhead of copying data between buffers.
WavePci is the performance-oriented alternative to WaveCyclic, but requires more sophisticated hardware
and driver software.
Although the name WavePci implies an audio device that plugs into the PCI bus, in fact, the primary requirement
for a WavePci device is that it contains a scatter/gather DMA controller capable of accessing data anywhere in
system memory:
A typical WavePci device does reside on a PCI bus, but, in theory, at least, a WavePci miniport driver could be
written for a device that resides on a system bus other than PCI (for example, AGP).
A wave device that resides on a PCI bus but lacks scatter/gather DMA can be represented by a WaveCyclic
driver, but not by a WavePci driver.
Historically, some vendors have had difficulty in implementing fully functional WavePci devices. The two main
problem areas are:
1. Hardware design flaws that degrade performance.
2. Driver implementation errors affecting performance or reliability.
This experience is distilled into the following topics, which address the key hardware and software design issues for
WavePci devices:
Hardware Requirements for WavePci Devices
Performance Issues for a WavePci Miniport Driver
Reliability Issues for a WavePci Miniport Driver
Hardware Requirements for WavePci Devices
10/23/2019 • 6 minutes to read • Edit Online

When choosing the features of a new hardware design, vendors should follow these general principles:
Instead of trying to simply move all processing to hardware, vendors should weigh the cost of each feature
against its impact on performance.
When considering the potential value of a hardware feature, a vendor should evaluate that feature in terms
of its impact on the system as a whole rather than focusing narrowly on a particular subsystem such as
audio.
By judiciously selecting which features to accelerate in hardware, vendors can relieve the CPU workload and
improve memory usage, thereby making more of the system's resources available to other tasks.
Historically, not all audio hardware designs have succeeded in following these principles.
When playing audio content or mixing multiple streams, some WDM audio drivers needlessly consume a lot of
CPU time and bus bandwidth. Such deficiencies are usually the result of flawed hardware designs and inefficient
driver implementations. Hardware design flaws can also prevent an audio driver from handling certain wave
formats or necessitate workarounds that require software intervention.
The purpose of the WaveCyclic device model is to accommodate the hardware limitations of older audio devices.
New hardware designs should be fully compliant with WavePci.
A WavePci device that can perform true scatter/gather DMA eliminates the need for the CPU to spend time copying
audio data between buffers. Unlike WaveCyclic, WavePci has no inherent need for data copying, making it the
preferred miniport driver for multistream or hardware-accelerated audio devices. A well-designed WavePci device
should consume almost no CPU resources, making it possible to send large numbers of audio streams (64 or
more) to the hardware for 3-D processing and mixing.
A WavePci device requires a bus-master DMA controller supporting scatter/gather DMA transfers. Hardware
designs should not place arbitrary limits on the kinds of data transfers that the DMA controller can handle. A
WavePci device should meet the following requirements:
The device must be a bus master.
It should be able to autonomously access system memory without intervention from the operating system
and without using system DMA resources.
The device must be able to handle data transfers of arbitrar y length.
It should handle mappings (see IPor tWavePciStream::GetMapping ) larger than a memory page. A device
with a transfer limitation of 4 kilobytes, for example, does not fit the full requirements for WavePci. On 64-
bit CPUs that support Microsoft Windows, the page size is 8 kilobytes, which makes it likely that some
mappings will be larger than 4 kilobytes in size. Data transfers that exceed 32 kilobytes in a single mapping
are theoretically possible, depending on physical memory fragmentation. At the other extreme, a mapping
size of one byte is possible.
The device should handle data transfers to or from any location in system memor y.
Data transfers that straddle 32-kilobyte or larger power-of-two boundaries are quite likely. A computer can
now contain more than 4 gigabytes of RAM, and in those systems, mappings can be located higher than 4
gigabytes in physical memory in the case of either a 64-bit CPU or the x86 physical address extension (PAE).
To achieve the best performance on these machines, vendors should create devices that support 64-bit
addressing. Otherwise, data copying in software is required. Data copying has historically been required for
devices with 24-bit addressing on systems with more than 16 megabytes of RAM. Devices should use
WaveCyclic instead of WavePci if they cannot read from or write to anywhere in physical memory. A driver
can make this decision at device startup time (see IRP_MN_START_DEVICE ) after it has had a chance to
determine whether its address reach is sufficient to access the full address range of the system memory bus.
The device should handle data transfers with arbitrar y alignment.
Mappings can begin and end on arbitrary byte boundaries in memory. A frame of audio data can be split
between mappings, with the samples for the first few channels at the end of the first mapping and the
samples for the remaining channels in the second mapping. For an example, see Wave Filters. For some
sample sizes, even a sample container can be split between mappings. If the device requires that transfers
must be on cache-line boundaries, or if the device requires that the transfers are strictly aligned to audio-
frame boundaries (for example, assuming that the transfer size divides evenly into four, in the stereo 16-bit
case), this device is not adequate for complete WavePci compliance. Note that a noncompliant piece of
hardware can be exposed as a WavePci device by limiting the data ranges or formats that the driver exposes
(for example, only certain bit depths or only certain channel configurations).
Regarding the last point in the preceding list, a WavePci device's scatter/gather DMA engine should handle buffers
that straddle memory page boundaries. For example, a buffer containing 10 milliseconds worth of 16-bit PCM
audio samples for a 48-kHz, 5.1-channel wave stream has the following size:
(6 samples/frame)*(2 bytes/sample)*(48K frames/second)*(10 milliseconds) = 5760 bytes
This exceeds the memory page size (4096 bytes), which means that the buffer contains either one or two page
boundaries, depending on how it is positioned in memory. The buffer contains an integral number (480) of frames
of audio data, but one or two of these frames might straddle page boundaries.
For this reason, the scatter/gather DMA hardware for a WavePci device should be designed to handle audio frames
(such as frame 197 in the following figure) that are split between two physically noncontiguous pages in memory.

At the top of the preceding figure is a 5760-byte buffer that straddles the boundary between two pages. In this
example, the buffer begins at a 1728-byte offset from the start of the first page, which aligns the start of the buffer
to a 64-byte boundary in memory. Assume that each audio frame occupies 12 bytes and contains six channels. The
first page contains all of frames 0 through 196 but only the first four bytes of frame 197.
At the bottom of the figure is a detailed view of audio frame 197, which shows that only the samples for channels 0
and 1 fall within the first page. The samples for channels 2 through 5 are contained in the second page.
Although the two pages appear next to each other at the top of the figure, they are, in fact, contiguous only in
kernel virtual memory. Because the pages containing the buffer are noncontiguous in physical memory, a
scatter/gather DMA controller, which uses physical addresses, must specify the two parts of the buffer as two
separate entries in its transfer queue. The WavePci port driver automatically splits the buffer into two separate
physical mappings at the page boundary.
Even if the preceding example is changed to align the buffer with the start of the first page, the split-frame problem
does not disappear. The following figure demonstrates this point. In this case, frame 341 gets split at the page
boundary with the samples for channels 0 and 1 again falling within the first page and the samples for channels 2
through 5 located in the second page.

A WavePci device whose scatter/gather DMA controller does not properly handle split audio frames is limited in the
kinds of audio data formats it can handle, although software workarounds might help alleviate some hardware
design flaws. For more information, see WavePci Latency.
Performance Issues for a WavePci Miniport Driver
10/23/2019 • 10 minutes to read • Edit Online

An audio driver's performance impact on the system can be significantly reduced by following these general
principles:
Minimize the code that is run during normal operation.
Run code only when necessary.
Consider the total system resource consumption (not just CPU loading).
Optimize code for speed and size.
In addition, WavePci miniport drivers must address several performance issues that are specific to audio devices.
The following discussion deals primarily with audio-rendering issues, although some of the suggested techniques
apply to audio capture as well.
Stream Servicing Mechanisms
Before discussing performance optimizations, some background is necessary to understand the WavePci
mechanisms for servicing streams.
When processing a wave render or capture stream, an audio device requires servicing at regular intervals by the
miniport driver. When new mappings are available for a stream, the driver adds those mappings to the stream's
DMA queue. The driver also removes from the queue any mappings that have already been processed. For
information about mappings, see WavePci Latency.
To perform the servicing, the miniport driver provides either a deferred procedure call (DPC) or interrupt service
routine (ISR), depending on whether the interval is set by a system timer or by DMA-driven interrupts. In the latter
case, the DMA hardware typically triggers an interrupt each time if finishes transferring some amount of stream
data.
Each time the DPC or ISR executes, it determines which streams require servicing. The DPC or ISR services a stream
by calling the IPor tWavePci::Notify method. This method takes as a call parameter the stream's service group,
which is an object of type IServiceGroup. The Notify method calls the service group's RequestSer vice method
(see ISer viceSink ::RequestSer vice ).
A service-group object contains a group of service sinks, which are objects of type IServiceSink. IServiceGroup is
derived from IServiceSink, and both interfaces have RequestSer vice methods. When the Notify method calls the
service group's RequestSer vice method, the service group responds by calling the RequestSer vice method on
each service sink in the group.
A stream's service group contains at least one service sink, which the port driver adds to the service group
immediately following creation of the stream. The port driver calls the miniport driver's
IMinipor tWavePci::NewStream method to obtain a pointer to the service group. The service sink's
RequestSer vice method is the port driver's stream-specific service routine. This routine does the following:
Calls the miniport driver's IMinipor tWavePciStream::Ser vice method.
Triggers any newly pending position or clock events on the stream since the last time the service routine
executed.
As discussed in KS Events, clients can register to be notified when a stream reaches a particular position or when a
clock reaches a particular time stamp. The NewStream method has the option of not supplying a service group, in
which case the port driver sets up its own timer to mark off the intervals between calls to its service routine.
Like the NewStream method, the miniport driver's IMinipor tWavePci::Init method also outputs a pointer to a
service group. Following the Init call, the port driver adds its service sink to the service group. This particular
service sink contains the service routine for the filter as a whole. (The preceding paragraph describes the service
sink for the stream associated with a pin on the filter.) This service routine calls the miniport driver's
IMinipor tWavePci::Ser vice method. The service routine executes each time the DPC or ISR calls Notify with the
service group for the filter. The Init method has the option of not supplying a service group, in which case the port
driver never calls its filter service routine.
Hardware Interrupts
Some miniport drivers generate either too many or not enough hardware interrupts. In some WavePci rendering
devices with DirectSound hardware acceleration, a hardware interrupt occurs only when the supply of mappings is
nearly exhausted and the rendering engine is at risk of starvation. In other hardware-accelerated WavePci devices, a
hardware interrupt occurs on every single mapping completion or some other relatively small interval. In this case,
the ISR frequently finds that it has little to do, but each interrupt still consumes system resources with register
swaps and cache reloads. The first step in improving driver performance is to reduce the number of interrupts as
much as possible without risking starvation. After eliminating unnecessary interrupts, additional performance
gains can be achieved by designing the ISR to execute more efficiently.
In some drivers, ISRs waste time by calling a stream's Notify method every time a hardware interrupt occurs--
regardless of whether the stream is actually running. If no streams are in the RUN state, then DMA is inactive, and
any time spent trying to acquire mappings, release mappings, or check for new events in any streams is wasted. In
an efficient driver, the ISR verifies that a stream is running before calling the stream's Notify method.
However, a driver with this type of ISR needs to make sure that any pending events on a stream are triggered when
the stream exits the RUN state. Otherwise, the events might be delayed or lost. This issue arises only during RUN-
to-PAUSE transitions in operating systems older than Microsoft Windows XP. In Windows XP and later, the port
driver automatically signals any outstanding position events immediately when a stream changes state from RUN
to PAUSE. In the older operating systems, however, the miniport driver is responsible for triggering any
outstanding events by making a final call to Notify immediately after the stream is paused. For more information,
see PAUSE/ACQUIRE Optimizations below.
A typical WavePci miniport driver manages a single playback stream from the KMixer system driver. The current
implementation of KMixer uses a minimum of three mapping IRPs to buffer a playback stream. Each IRP contains
enough buffer storage for about 10 milliseconds of audio. If the miniport driver triggers a hardware interrupt each
time the DMA controller finishes with the final mapping in an IRP, interrupts should occur at fairly regular 10-
millisecond intervals, which is frequent enough to keep the DMA queue from starving.
Timer DPCs
If a driver manages any hardware-accelerated DirectSound streams, it should use a timer DPC (see Timer Objects
and DPCs) instead of DMA-driven hardware interrupts. Equivalently, a WavePci device on a PCI card with an on-
board timer can use a timer-driven hardware interrupt instead of a DPC.
In the case of a DirectSound buffer, the entire buffer can be attached to a single IRP. If the buffer is large and the
miniport driver schedules a hardware interrupt only when it reaches the end of the buffer, successive interrupts can
occur so far apart that the DMA queue starves. Also, if the driver is managing a large number of hardware-
accelerated DirectSound streams, and each stream generates its own interrupts, then the cumulative impact of all
the interrupts can degrade system performance. In these circumstances, the miniport driver should avoid using
hardware interrupts to schedule servicing of individual streams. Instead, it should service all streams in a single
DPC that is scheduled to run at regular timer-generated intervals.
By setting the timer interval to 10 milliseconds, the interval between successive DPC executions is similar to that
described previously for the hardware interrupt in the case of a single KMixer playback stream. Thus, the DPC can
handle the KMixer playback stream in addition to hardware-accelerated DirectSound streams.
When the last stream exits the RUN state, the miniport driver should disable the timer DPC to avoid wasting
system CPU cycles. Immediately after disabling the DPC, the driver should make sure that any clock or position
events pending on previously running streams are flushed. In Windows 98/Me and Windows 2000, the driver
should call Notify to trigger any pending events on the streams that are being paused. In Windows XP and later,
the operating system triggers any pending events automatically when a stream exits the RUN state, without
requiring intervention by the miniport driver.
PAUSE/ACQUIRE Optimizations
In Windows 98/Me and Windows 2000, the WavePci port driver's stream service routine (the RequestSer vice
method) always generates a call to the miniport driver's IMinipor tWavePciStream::Ser vice method regardless
of whether the stream is in the RUN state. In these operating systems, the Ser vice method should check whether
the stream is running before spending time doing actual work. (However, if the miniport driver's DPC or ISR has
already been optimized to call Notify only for streams that are running, adding this check to the Ser vice method
might be redundant.)
In Windows XP and later, this optimization is unnecessary because the Notify method calls the Ser vice method
only on streams that are running.
Using the IPreFetchOffset Interface
DirectSound users are familiar with the dual concepts of the play cursor and the write cursor. The play cursor
indicates the position in the stream of the data being emitted from the device (the driver's best estimate of the
sample currently at the DAC). The write position is the position in the stream of the next safe place for the client to
write additional data. For WavePci, the default assumption is that the write cursor is positioned at the end of the last
mapping requested. If the miniport driver has acquired a large number of outstanding mappings, the offset
between the play cursor and write cursor can be very large—large enough to fail certain WHQL audio-position
tests. In Windows XP and later, the IPreFetchOffset interface addresses these issues.
The miniport driver uses IPreFetchOffset to specify the bus-master hardware's prefetch characteristics, which are
largely determined by the hardware FIFO size. The audio subsystem uses this data to set a constant offset between
the play cursor and the write cursor. This constant offset, which can be significantly smaller than the default offset,
takes advantage of the fact that data can be written into a mapping even after the mapping has been handed to the
hardware, as long as the play cursor is far enough away from the location into which data is written. (This
statement assumes that the driver does not copy or otherwise manipulate the data in mappings.) A typical offset
might be on the order of 64 samples, depending on the engine design. With an offset this small, a WavePci driver
can be fully responsive and functional while still requesting a large number of mappings.
Note that DirectSound currently pads the write cursor of a hardware-accelerated pin by 10 milliseconds.
For a more information, see Prefetch Offsets.
Processing Data in Mappings
Avoid having your hardware driver touch the data in the mappings if at all possible. Any software processing of
data contained in mappings should be split out into a software filter separate from the hardware driver. Having a
hardware driver perform such processing reduces its efficiency and creates latency problems.
A hardware driver should strive to be transparent about its real hardware capabilities. The driver should never
claim to provide hardware support for a data transform that is actually performed in software.
Synchronization Primitives
A driver is less likely to have deadlock or performance problems now and in the future if its code is designed to
avoid being blocked whenever possible. Specifically, a driver's thread of execution should strive to run to
completion without the risk of stalling while waiting for another thread or resource. For example, driver threads
can use the InterlockedXxx functions (for example, see InterlockedIncrement ) to coordinate their accesses to
certain shared resources without the risk of being blocked.
Although these are powerful techniques, you might not be able to safely remove all spin locks, mutexes, and other
blocking synchronization primitives from the execution path. Use the InterlockedXxx functions judiciously, with the
knowledge that an indefinite wait might cause data starvation.
Above all, do not create custom synchronization primitives. The built-in Windows primitives (mutexes, spin locks,
and so on) are likely to be modified as needed to support new scheduler features in the future, and a driver that
uses custom constructs is virtually guaranteed not to work in the future.
IPinCount Interface
In Windows XP and later, the IPinCount interface provides a way for a miniport driver to more accurately account
for the hardware resources that are consumed by allocating a pin. By calling the miniport driver's
IPinCount::PinCount method, the port driver does the following:
Exposes the filter's current pin counts (as maintained by the port driver) to the miniport driver.
Gives the miniport driver the opportunity to revise the pin counts to dynamically reflect the current
availability of hardware resources.
For some audio devices, wave streams with different attributes (3-D, stereo/mono, and so on) might also have
different "weights" in terms of how many hardware resources they consume. When opening or closing a
"lightweight" stream, the driver increments or decrements the count of available pins by one. When opening a
"heavyweight" stream, however, the miniport driver might need to decrement the available pin count by two
instead of by one in order to more accurately indicate the number of pins that can be created with the remaining
resources.
The process is reversed when a heavyweight stream is closed. The available pin count might increase by more than
one in order to reflect the fact that two or more lightweight streams can be created from the newly freed resources.
Reliability Issues for a WavePci Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

A WavePci miniport driver must keep track of the mappings that it receives from the port driver. A WavePci
miniport driver maintains its list of mappings in a data structure that is shared between driver threads. The driver
threads must also share access to the DMA channel in order to add new mappings to the hardware queue and
remove completed mappings from the queue. To prevent data corruption, miniport drivers use spin locks to
serialize accesses to shared data structures and peripherals. A spin lock protects the shared data and hardware
queue from simultaneous access by two or more driver threads.
When developing the portion of the driver that manages mappings, vendors should pay particular attention to the
following points.
Spin Locks
To avoid potential deadlocks, the miniport driver must not hold its own spin lock when calling into Portcls.sys to
acquire or release mappings. The Ac97 sample driver in the Microsoft Windows Driver Kit (WDK) illustrates this
principle. Before calling either IPor tWavePciStream::GetMapping or IPor tWavePciStream::ReleaseMapping ,
the sample driver calls KeReleaseSpinLock to release the spin lock. After the GetMapping or ReleaseMapping
call returns, the driver calls KeAcquireSpinLock to acquire the spin lock again. Between the calls to release and
acquire the spin lock, a driver thread must not assume that it has exclusive access to the list of mappings. Accessing
the shared data during this unprotected interval is dangerous. If the interval between releasing and acquiring the
spin lock is small, the likelihood of the data being corrupted by a race condition between two driver threads is also
small. This means that the resulting failures are intermittent and thus difficult to trace. After releasing and acquiring
a spin lock, a well-written driver should assume that any temporary pointers or indices that it previously used to
access the contents of the shared data structures are no longer valid.
IRP Cancellation
At any time during the processing of a playback or capture stream, cancellation of an IRP can cause the operating
system to revoke one or more mappings that the miniport driver has acquired. When this occurs, the port driver
calls the IMinipor tWavePciStream::RevokeMappings method to notify the miniport driver. In order to avoid
either playing data from or capturing data into the revoked mappings, the miniport driver has to remove the
mappings from both its software list and the DMA controller's hardware queue. Because the software list and
hardware queue are shared between driver threads, some care is required to perform these operations reliably.
For example, a set of mappings to be revoked might contain a mapping that has just been or is just about to be
released. In this case, two driver threads might simultaneously attempt to remove the same mapping from the
DMA queue. If the driver fails to prevent simultaneous access, the result can be corruption of the data in the
registers or memory structures that manage the queue.
For a working code example, see the Ac97 sample driver in the Windows Driver Kit (WDK).
WaveCyclic Port Driver
10/23/2019 • 2 minutes to read • Edit Online

Impor tant The use of WaveCyclic is no longer recommended, instead use WaverRT.
The WaveCyclic port driver manages the playback or recording of a wave stream by a DMA-based audio device
that processes audio data in a cyclic buffer. This device is a hardware function on an audio adapter. Typically, the
adapter is part of an integrated chipset on the motherboard or is mounted on an audio card that plugs into a PCI or
ISA slot on the motherboard. The adapter driver provides a corresponding WaveCyclic miniport driver driver object
that binds to the WaveCyclic port driver object to form a wave filter that can capture or render a wave stream.
The WaveCyclic port driver exposes an IPortWaveCyclic interface to the miniport driver. IPortWaveCyclic inherits
the methods in base interface IPort. IPortWaveCyclic provides the following additional methods:
IPor tWaveCyclic::NewMasterDmaChannel
Creates a new master DMA channel object for an audio device with a built-in DMA controller.
IPor tWaveCyclic::NewSlaveDmaChannel
Creates a new subordinate DMA channel object for an audio device without a built-in DMA controller.
IPor tWaveCyclic::Notify
Notifies the port driver that the DMA controller has advanced to a new position in the audio stream.
The WaveCyclic port and miniport driver objects communicate with each other through their respective
IPortWaveCyclic and IMiniportWaveCyclic interfaces. In addition, the port driver communicates with the miniport
driver's stream objects through their IMiniportWaveCyclicStream interfaces.
WaveCyclic Miniport Driver
10/23/2019 • 2 minutes to read • Edit Online

Impor tant The use of WavePci is no longer recommended, instead use WaverRT.
A WaveCyclic miniport driver manages the hardware-dependent functions of a wave-rendering or wave-capture
device that uses a cyclic buffer for audio data. The cyclic buffer is typically a single block of contiguous physical
memory and can be located in a region of memory of the driver's choosing. A device with any of the following
limitations should provide a WaveCyclic miniport driver rather than a WavePci miniport driver:
The device lacks DMA hardware.
The device's DMA hardware can access data only in a buffer that occupies a single block of contiguous
physical memory.
The device's DMA hardware is unable to access data in all regions of physical memory.
A WaveCyclic miniport driver should implement two interfaces:
The minipor t interface supports miniport driver initialization and stream creation.
The stream interface manages a wave stream and exposes most of the miniport driver's functionality.
The miniport interface, IMiniportWaveCyclic, inherits the methods in the IMiniport interface. IMiniportWaveCyclic
provides the following additional methods:
IMinipor tWaveCyclic::Init
Initializes the miniport object.
IMinipor tWaveCyclic::NewStream
Creates a new stream object.
The stream interface, IMiniportWaveCyclicStream, inherits the methods in the IUnknown interface.
IMiniportWaveCyclicStream provides the following additional methods:
IMinipor tWaveCyclicStream::GetPosition
Gets the device's current position in the wave stream.
IMinipor tWaveCyclicStream::NormalizePhysicalPosition
Converts a physical buffer position value into a time-based value.
IMinipor tWaveCyclicStream::SetFormat
Sets the data format of the wave stream.
IMinipor tWaveCyclicStream::SetNotificationFreq
Sets the frequency at which notification interrupts occur.
IMinipor tWaveCyclicStream::SetState
Sets the state of the wave stream.
IMinipor tWaveCyclicStream::Silence
Copies silence into a buffer.
Driver Support for DirectSound
12/5/2018 • 2 minutes to read • Edit Online

The WDM audio system provides driver support for application programs that access audio devices through the
Microsoft DirectSound API. For a description of the system components that provide DirectSound driver support,
see WDM Audio Components.
The following section discusses the features that audio miniport drivers can implement to better support the audio
capabilities that the DirectSound API exposes to application programs. These capabilities include hardware
acceleration of 2D and 3D sound effects, support for a variety of speaker configurations, and capture effects such as
acoustic echo cancellation for full-duplex telephone conferencing.
This section presents the following topics:
DirectSound Hardware Acceleration in WDM Audio
DirectSound Speaker-Configuration Settings
DirectSound Capture Effects
DirectSound Hardware Acceleration in WDM Audio
12/5/2018 • 2 minutes to read • Edit Online

This section describes WDM audio driver support for hardware acceleration of DirectSound. The following topics
are discussed:
Overview of DirectSound Hardware Acceleration
Supporting 2D DirectSound Acceleration in WDM Audio
Supporting 3D DirectSound Acceleration in WDM Audio
DirectSound Node-Ordering Requirements
Supporting a Mixture of 2D and 3D Pins
DirectSound Hardware-Acceleration and SRC Sliders
Exposing Custom Audio Property Sets
Prefetch Offsets
Overview of DirectSound Hardware Acceleration
6/25/2019 • 2 minutes to read • Edit Online

A number of audio adapters offer DirectSound hardware acceleration, which is the ability to perform hardware
mixing for one or more DirectSound streams. Hardware mixing improves performance by offloading audio mixing
operations from the CPU and performing them at hardware speeds. In addition to mixing, the hardware performs
related operations such as sample-rate conversion (SRC), attenuation, and, optionally, 3D processing that would
otherwise need to be performed in software.
All WaveCyclic or WavePci rendering devices present one or more hardware pins for mixing audio streams. In the
case of a single-stream device, the KMixer system driver is always instantiated on the one available hardware
rendering pin.
Devices with DirectSound hardware acceleration provide more than one hardware mixing pin. Each additional pin
can be used to mix a DirectSound stream. DirectSound streams that feed into hardware mixer pins bypass KMixer
and avoid the latency of software mixing in KMixer. DirectSound makes use of all of an audio device's available
hardware-accelerated mixer pins as long as those pins have a topology that conforms to the DirectSound node-
ordering requirements. DirectSound also requires that the pins support the DirectSound data format specified by
KSDATAFORMAT_SPECIFIER_DSOUND (see DirectSound Stream Data Format).
The SysAudio system driver always reserves one hardware pin for KMixer so that after the other (unreserved)
hardware pins have all been allocated, any additional streams can be mixed by KMixer and fed into the reserved
hardware pin.
The figure in Rendering Wave Content Using DirectSound Software and Hardware Buffers illustrates these
concepts.
If an audio device provides a sufficient number of hardware mixing pins, all of a DirectSound application's output
streams can be hardware-accelerated. If not, the DirectSound application has a couple of options:
It can statically allocate the available hardware mixing pins to the streams that require the lowest latencies.
It can dynamically allocate the available hardware mixing pins to the streams as they are needed by treating
the pins as a pool of shared resources.
For more information, see the discussion of voice management in the Microsoft Windows SDK documentation.
DirectSound can use two types of hardware mixer pins: 2D and 3D. A 2D pin performs SRC, attenuation, and
mixing, but not 3D positioning. DirectSound can use a 2D pin to do 3D positioning by performing the necessary
attenuation and frequency calculations in software and applying the results to the appropriate nodes on the 2D pin.
In contrast, a 3D pin contains a 3D node that is able to calculate its own 3D effects directly from the 3D-buffer and
3D-listener properties instead of relying on DirectSound to do this. For a list of the properties of a 3D node, see
KSNODETYPE_3D_EFFECTS . For more information about 2D and 3D pins, see Supporting 2D DirectSound
Acceleration in WDM Audio and Supporting 3D DirectSound Acceleration in WDM Audio.
Supporting 2D DirectSound Acceleration in WDM
Audio
10/23/2019 • 2 minutes to read • Edit Online

DirectSound exposes hardware-accelerated 2D mixing for WDM audio miniport drivers that meet the following
requirements:
The miniport driver includes a pin factory that is an IRP sink (KSPIN_COMMUNICATION_SINK), has a
KSPIN_DATAFLOW direction of KSPIN_DATAFLOW_IN, and exposes a data range
(KSDATARANGE_AUDIO structure) in which the specifier (DataFormat .Specifier member) is set to
KSDATAFORMAT_SPECIFIER_DSOUND.
The pin factory's KSPROPERTY_PIN_CINSTANCES handler sets the PossibleCount member of the
KSPIN_CINSTANCES structure to a value of two or greater (the first pin is always reserved for KMixer).
The PossibleCount value specifies the number of pin instances that can currently be instantiated from the
pin factory.
The pin factory must support the KSPROPERTY_AUDIO_CPU_RESOURCES property and should report
KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU for all nodes that are hardware accelerated.
The pin should meet the DirectSound node-ordering requirements.
Supporting 3D DirectSound Acceleration in WDM
Audio
6/25/2019 • 2 minutes to read • Edit Online

DirectSound exposes hardware-accelerated 3D mixing for WDM audio miniport drivers that meet the following
requirements:
The pin must meet the requirements listed in Supporting 2D DirectSound Acceleration in WDM Audio.
The pin should include a 3D node (KSNODETYPE_3D_EFFECTS ) in its node chain. (See DirectSound
Node-Ordering Requirements.)
The pin must support the KSPROPSETID_DirectSound3DBuffer property set on the 3D node.
The pin must support the KSPROPSETID_DirectSound3DListener property set on the 3D node.
DirectSound Node-Ordering Requirements
6/25/2019 • 2 minutes to read • Edit Online

A DirectSound 2D or 3D mixer pin should have a node chain that contains the following sequence of nodes:
Volume node (See KSNODETYPE_VOLUME .)
3D node (This node is optional. See KSNODETYPE_3D_EFFECTS .)
Supermixer node (See KSNODETYPE_SUPERMIX .)
Volume node (for panning effects)
SRC node (See KSNODETYPE_SRC .)
SUM node (See KSNODETYPE_SUM .)
The nodes in this list appear in the order in which they are encountered by data streaming into the pin. Other
nodes can be interleaved between these nodes without causing problems, provided that the above ordering is
preserved.
A 2D pin requires all the nodes in the previous list, except for the 3D node, which is optional. A 3D pin requires all
the nodes in the list, including the 3D node.
The SRC (sample-rate conversion) node should precede the SUM node. The SRC and SUM nodes are typically
adjacent, although this is not a requirement. The IDirectSoundBuffer ::SetFrequency method (see Microsoft
Windows SDK documentation) perturbs the SRC node's resampling rate.
A mixer that contains only SRC and SUM nodes is sufficient for mixing streams that are managed by system
drivers such as SWMidi and Redbook (see SWMidi System Driver and Redbook System Driver), but DirectSound
additionally requires that two volume nodes and a supermixer node precede the SUM node. DirectSound sends
volume changes resulting from IDirectSoundBuffer ::SetVolume calls to the first volume node and sends
panning effects from IDirectSoundBuffer ::SetPan calls to the second volume node.
DirectSound can produce 3D effects on a 2D pin by using the SetVolume , SetPan , and SetFrequency calls to
control the volume and SRC nodes:
SetVolume calls can simulate changes in the distance of a sound source from the listener.
SetPan calls can simulate changes in orientation of a sound source relative to the listener.
SetFrequency calls can simulate Doppler effects and HRTFs (head-related transfer functions).
The supermixer node is a crossbar matrix that connects M input channels to N output channels, where N should
be equal to the number of channels in your device's final output stream.
The optional 3D node is required to manage hardware-accelerated 3D effects (see Supporting 3D DirectSound
Acceleration in WDM Audio), but is not needed for software-emulated 3D processing. Most existing
implementations place the 3D node before the SRC node and between the first volume node and the supermixer
node, but other configurations are possible.
The input stream to the 3D node typically contains a single channel. In DirectSound 8.0 and later, only mono PCM
buffers can be created with 3D effects. Earlier versions of DirectSound, however, support 3D nodes with both
mono and stereo input streams, and drivers should support both to ensure compatibility with older applications.
Supporting a Mixture of 2D and 3D Pins
12/5/2018 • 2 minutes to read • Edit Online

If your WDM audio driver supports a mixture of 2D and 3D pins, a 3D pin can double for use as a 2D pin, but not
vice versa. When DirectSound requires a 2D pin, it can substitute an unused 3D pin for that purpose, if one is
available from the driver. If DirectSound requires a 3D pin, however, it continues to search the driver's list of pin
instances until it finds a 3D pin, ignoring any 2D pins encountered during the search. DirectSound checks the
driver's list of pin factories in the order in which they are listed until it finds a pin instance that satisfies its
requirements.
When reporting the 2D-pin count, your driver should specify the number of 2D-pin instances plus the number of
3D-pin instances. When reporting the 3D-pin count, your driver should ignore the 2D pins and specify only the
number of 3D-pin instances.
DirectSound versions that were distributed with Microsoft Windows 2000 and Windows 98 have a known problem
in dealing with a pin factory that exposes a mixture of 2D and 3D pins: DirectSound incorrectly reports the 3D-pin
count to be the number of 2D pin instances plus the number of 3D pin instances. A workaround solution to this
problem is to write your driver so that it segregates the 2D and 3D pins into two separate pin factories. One factory
exposes only the 2D pins, and the other factory exposes only the 3D pins.
With WDM drivers, DirectSound correctly reports the 2D-pin count as the sum of the counts of the 2D and 3D pins
from the two factories, and it correctly reports the 3D-pin count as the number of 3D pins from the one 3D-pin
factory. When exposing separate factories for 2D and 3D pins, your driver should list the 2D-pin factory before the
3D-pin factory. This is necessary because when DirectSound is looking for a 2D pin, it uses the first 2D or 3D pin
that it finds, and DirectSound checks the pin factories in the order in which the driver lists them. If the driver lists
the 3D factory first, it risks having DirectSound deplete the supply of 3D pins by unnecessarily using them in place
of 2D pins.
In summary, if your driver exposes a mixture of 2D and 3D pins, it should follow these rules to run correctly on
earlier versions of DirectSound:
Provide two separate pin factories for the 2D and 3D pins, respectively.
List the 2D-pin factory ahead of the 3D-pin factory.
These workarounds are unnecessary with later versions of DirectSound. The problem that is described above is
fixed in Windows Me and in Windows XP and later. It is also fixed in DirectSound 8, which is redistributed for use
with earlier Windows versions. With this fix, your driver can safely combine 2D and 3D pins in a single pin factory
and DirectSound will correctly report the 2D- and 3D-pin counts. Also, when DirectSound requires a 2D pin, it uses
a 3D pin in place of a 2D pin only when it has exhausted the supply of 2D pins from all pin factories.
DirectSound Hardware-Acceleration and SRC Sliders
12/5/2018 • 2 minutes to read • Edit Online

Windows provides global slider controls for altering DirectSound performance on a system-wide basis. The sliders
control the level of hardware acceleration and quality of sample-rate conversion (SRC) that are made available to
DirectSound applications. Changes made to the hardware-acceleration and SRC sliders are persistent across boot-
ups.
The hardware-acceleration and SRC settings can be changed only by direct end-user action. No API is available for
changing the hardware-acceleration or SRC setting from an application program. This behavior improves stability
and prevents software from placing the audio system in a state from which it cannot be removed without
rebooting.
These settings affect only DirectSound applications. Note that the waveOut API always uses the best SRC quality
regardless of the setting of the DirectSound SRC slider. Also, in all current versions of Windows, waveOut
applications are unable to use hardware-accelerated pins on audio devices and are unaffected by the setting of the
DirectSound hardware-acceleration slider. For more information about the Windows multimedia waveOut API, see
the Microsoft Windows SDK documentation.
To locate the DirectSound hardware-acceleration and SRC sliders in Windows, for example, follow these steps:
1. In Control Panel, double-click the Sounds and Audio Devices icon (or just run mmsys.cpl).
2. On the Audio tab, select a device from the Sound Playback list.
3. Click the Advanced button.
4. Click the Performance tab.
At this point, you should see two sliders that are labeled Hardware acceleration and Sample rate conversion
quality .
The hardware-acceleration slider has four settings that range from None (level 0) on the left to Full (level three)
on the right. The following table shows the meaning of these settings.

A C C EL ERAT IO N L EVEL SET T IN G N A M E DESC RIP T IO N

0 Emulation Forces emulation.

1 Basic Disables hardware acceleration of


DirectSound secondary buffers.

2 Standard Enables hardware acceleration of


DirectSound secondary buffers but
disables vendor-specific property-
set extensions.

3 Full Enables hardware acceleration of


DirectSound secondary buffers and
enables vendor-specific property-
set extensions.
Emulation Setting
The Emulation setting above forces DirectSound into emulation mode. In this mode, DirectSound applications run
as though no DirectSound driver is present. All mixing is done by DirectSound in user mode, and the resulting
audio data is played back through the waveOut API. The result is typically a large increase in latency.
Basic Setting
The Basic setting disables hardware acceleration of DirectSound secondary buffers. Under this setting, all
DirectSound applications run as though no hardware acceleration is available, regardless of the capabilities of the
sound card that is being used. You can use this setting during testing to emulate a sound card that has no
DirectSound acceleration. With an adapter such as the OPL, which has no acceleration of DirectSound secondary
buffers, this setting has the same effect as the Standard setting. In Windows Server 2003, Basic is the default
setting.
Standard Setting
The Standard setting enables hardware acceleration of DirectSound secondary buffers but disables vendor-
specific extensions such as EAX (Creative Technologies' environmental audio extensions) that are exposed as
property sets through the IKsProper tySet interface (see Exposing Custom Audio Property Sets). In Windows
2000, the Standard setting is selected by default.
Full Setting
The Full setting enables full acceleration of DirectSound secondary buffers. This setting also enables property sets
for vendor-specific extensions that are exposed through the IKsProper tySet interface (see Exposing Custom
Audio Property Sets). IKsProper tySet extensions include vendor-specific hardware enhancements such as EAX.
If the user adjusts either the hardware-acceleration or SRC setting to a value other than the default, DirectSound
uses the new setting instead of the default.
Exposing Custom Audio Property Sets
10/23/2019 • 2 minutes to read • Edit Online

DirectSound supports the use of custom properties on sound cards and provides an IKsProper tySet interface for
this purpose.
Note Header files Dsound.h and Ksproxy.h define similar but incompatible versions of the IKsProper tySet
interface. DirectSound applications should use the version defined in Dsound.h. The DirectSound version of
IKsProper tySet is defined in the DirectSound reference pages in the Microsoft Windows SDK documentation. For
the KSProxy version, see IKsPropertySet.
Custom audio property sets are enabled by default in Windows 98 Second Edition and Windows Me, and in
Windows XP and later. By default, DirectSound ignores custom property sets in Windows 2000, and in Windows
Server 2003 and later server versions of Windows. For DirectSound to recognize a custom property set in one of
these operating systems, users must first enable custom property sets on their systems.
For example, to enable custom audio property sets in Windows 2000:
1. In Control Panel, double-click the Sounds and Multimedia icon (or just run mmsys.cpl).
2. On the Audio tab, select the appropriate preferred device in the Sound Playback list.
3. Click the Advanced button.
4. On the Performance tab, slide the Hardware Acceleration slider to Full .
5. Click Apply .
DirectSound is now enabled to pass custom property sets to the driver.
Four settings are available on the Hardware Acceleration slider:
None
Basic
Standard
Full
Custom property sets are enabled only when the slider is set to Full . For more information, see DirectSound
Hardware-Acceleration and SRC Sliders.
Prefetch Offsets
10/23/2019 • 3 minutes to read • Edit Online

A WavePci miniport driver calls the IPreFetchOffset::SetPreFetchOffset method to specify the prefetch offset of
a hardware-accelerated DirectSound output stream. This offset is the number of bytes of data separating the write
cursor from the play cursor in the audio device's hardware buffer. The write cursor specifies the buffer position into
which a DirectSound application can safely write the next sound sample. The play cursor specifies the buffer
position of the sound sample that is currently being played by the audio device.
DirectSound queries the WavePci port driver for the current positions of the play and write cursors by sending a
KSPROPERTY_AUDIO_POSITION property request. In response to this request, the port driver obtains the
current play position from the miniport driver by calling IMinipor tWavePciStream::GetPosition . How the port
driver determines the write position depends on whether SetPreFetchOffset has been called.
By default, the port driver positions the write cursor in the last mapping requested by the miniport driver. With
each call to IPor tWavePciStream::GetMapping , the default prefetch offset grows larger. If the WavePci miniport
driver acquires a large number of mappings, the default offset can grow very large.
Calling SetPreFetchOffset overrides the default. Following this call, the port driver calculates the write position
by adding the specified prefetch offset to the play position (taking into account the wraparound at the end of the
DirectSound buffer).
A miniport driver might allocate a large number of mappings for a couple of reasons. One is to reduce the
overhead of audio operations on the system processor. With more mappings, the driver requires fewer interrupts
to keep the audio device continuously supplied with data. Another reason is that allocating more mappings
decreases the likelihood that audio playback will suffer glitches when badly behaved device drivers tie up the
system for short periods.
One problem with a large prefetch offset is that some DirectSound applications can become confused about the
relative positions of the play and write cursors. In Windows 95/98, audio VxDs maintain a relatively small prefetch
offset, and DirectSound applications written for these operating systems might not run correctly if the offset is
larger than they expect.
For example, an application might divide the DirectSound buffer into an upper half and a lower half and then "ping
pong" the two halves between the application and the device. When the write cursor first enters the upper or lower
half of the buffer, it writes a half buffer's worth of data to that half of the buffer. This scheme assumes that the play
cursor is always positioned in the other half of the buffer--the half that is not being written to. Note that this
assumption is incorrect if the prefetch offset exceeds half the buffer size. In that case, when the write cursor
reaches the end of the DirectSound buffer and wraps around to the beginning of the buffer, it will be in the same
half of the buffer as the play cursor. When the application writes a half buffer's worth of data to the new write
cursor position, it ends up overwriting the play cursor position and destroying data that has not been played yet.
Although the application itself can certainly be blamed for this type of failure, a WavePci miniport driver can
eliminate the failure mode simply by calling SetPreFetchOffset to set the prefetch offset to a smaller value.
Setting the prefetch offset to a smaller value moves the resulting write cursor closer to the play cursor. You should
set the prefetch offset to the FIFO size of your hardware. A typical prefetch offset is about 64 samples, depending
on the DMA engine's hardware design.
To remain compatible with certain older DirectSound applications, DirectSound currently pads the write cursors of
hardware-accelerated pins by 10 milliseconds. Note that the amount of padding might change in the future.
For additional information about managing write cursors and play cursors at the driver level, see Audio Position
Property.
DirectSound Speaker-Configuration Settings
12/5/2018 • 2 minutes to read • Edit Online

This section describes the DirectSound speaker-configuration settings and how to implement WDM audio drivers
that support these configurations. The following topics are discussed:
Translating Speaker-Configuration Requests
Applying Speaker-Configuration Settings
Proprietary Speaker-Configuration Utilities
DSSPEAKER_SURROUND Speaker Configuration
DSSPEAKER_DIRECTOUT Speaker Configuration
Translating Speaker-Configuration Requests
6/25/2019 • 2 minutes to read • Edit Online

Note This information applies to Windows XP and earlier operating systems. Starting with Windows Vista,
IDirectSound::GetSpeakerConfig and IDirectSound::SetSpeakerConfig have been deprecated.
When an application calls IDirectSound::SetSpeakerConfig (see Microsoft Windows SDK documentation) to
change the speaker configuration, DirectSound translates the specified DSSPEAKER_Xxx speaker-configuration
parameter to the equivalent KSAUDIO_Xxx channel-configuration mask. It sends a
KSPROPERTY_AUDIO_CHANNEL_CONFIG set-property request containing this mask to the filter that
represents the DirectSound device.
In the following table, each DSSPEAKER_Xxx parameter on the left is paired with the equivalent KSAUDIO_Xxx
channel-configuration mask on the right.

DSSP EA K ER PA RA M ET ER K SA UDIO C H A N N EL - C O N F IGURAT IO N M A SK

DSSPEAKER_DIRECTOUT KSAUDIO_SPEAKER_DIRECTOUT

DSSPEAKER_HEADPHONE KSAUDIO_SPEAKER_STEREO

DSSPEAKER_MONO KSAUDIO_SPEAKER_MONO

DSSPEAKER_STEREO KSAUDIO_SPEAKER_STEREO

DSSPEAKER_QUAD KSAUDIO_SPEAKER_QUAD

DSSPEAKER_SURROUND KSAUDIO_SPEAKER_SURROUND

DSSPEAKER_5POINT1 KSAUDIO_SPEAKER_5POINT1

DSSPEAKER_7POINT1 KSAUDIO_SPEAKER_7POINT1

In the preceding table, DirectSound specifies both its headphone and stereo speaker configurations with the same
channel mask, KSAUDIO_SPEAKER_STEREO. To distinguish between these two configurations, DirectSound sends
the filter a second set-property request, which specifies a speaker geometry (see
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY ). To indicate headphones, DirectSound passes the value
KSAUDIO_STEREO_SPEAKER_GEOMETRY_HEADPHONE with the speaker-geometry request.
In the case of stereo speakers, however, the caller to SetSpeakerConfig can specify one of several possible
DSSPEAKER_Xxx stereo-speaker geometries. These appear in the left column of the following table, and the
equivalent KSAUDIO_Xxx parameters appear on the right.
DSSP EA K ER ST EREO - SP EA K ER GEO M ET RY K SA UDIO ST EREO - SP EA K ER GEO M ET RY

DSSPEAKER_GEOMETRY_WIDE KSAUDIO_STEREO_SPEAKER_GEOMETRY_WIDE

DSSPEAKER_GEOMETRY_NARROW KSAUDIO_STEREO_SPEAKER_GEOMETRY_NARROW

DSSPEAKER_GEOMETRY_MIN KSAUDIO_STEREO_SPEAKER_GEOMETRY_MIN

DSSPEAKER_GEOMETRY_MAX KSAUDIO_STEREO_SPEAKER_GEOMETRY_MAX

If the caller does not explicitly specify one of the geometries in the left column above, DirectSound assumes
DSSPEAKER_GEOMETRY_WIDE by default.
Applying Speaker-Configuration Settings
6/25/2019 • 4 minutes to read • Edit Online

Note This information applies to Windows XP and earlier operating systems. Starting with Windows Vista,
IDirectSound::GetSpeakerConfig and IDirectSound::SetSpeakerConfig have been deprecated.
DirectSound keeps track of its current speaker-configuration setting in the registry and applies that setting to the
audio hardware each time a new DirectSound device is created.
An application program can change the system-wide speaker configuration by calling the
IDirectSound::SetSpeakerConfig method, which updates the speaker-configuration setting in the registry. The
method also attempts to apply the new setting immediately to the hardware, although audio devices are typically
unable to change speaker settings while the DirectSound object exists. For a list of the speaker configurations that
DirectSound defines for this method, see Translating Speaker-Configuration Requests.
A user can change the configuration through the speaker-configuration dialog in the Multimedia Proper ties
page (mmsys.cpl) in Control Panel. To locate the DirectSound speaker-configuration dialog under Windows XP, for
example, follow these steps:
1. In Control Panel, double-click the Sounds and Audio Devices icon.
2. On the Audio tab, select a device from the Sound Playback list.
3. Click the Advanced button.
4. Click the Speakers tab.
At this point, you should see the label Speaker Setup next to a list of the speaker configurations that you can
select from.
DirectSound uses a KSPROPERTY_AUDIO_CHANNEL_CONFIG set-property request to send the speaker-
configuration information to a 3D node or DAC node (KSNODETYPE_3D_EFFECTS or KSNODETYPE_DAC ) in
an audio filter graph. For a 3D node, the target for the property request is actually the pin (3D-stream object) that
feeds the node. For a DAC node, the target is the filter object that contains the DAC node. In either case, the
speaker-configuration setting is global and affects the audio device as a whole. All audio applications that
subsequently run are subject to the new setting until DirectSound changes the setting again.
Note that only versions of DirectSound that ship with Windows Me, and with Windows XP and later, send speaker-
configuration property requests to DAC nodes--earlier versions of DirectSound do not support this feature.
However, all versions of DirectSound send these requests to 3D nodes.
If an application program has created more than one 3D node, DirectSound sends speaker-configuration requests
only to the first 3D node to be created.
DirectSound sends speaker-configuration requests to the 3D and DAC nodes each time an application creates a
DirectSound object or calls the IDirectSound::SetSpeakerConfig method. Audio devices are typically unable to
change their speaker configuration while they are managing active streams, and DirectSound tries to avoid this
limitation where possible. For example, when creating a DirectSound object, DirectSound sends the speaker-
configuration requests after instantiating the filter but before instantiating any pins on the filter--that is, before
creating any streams.
This limitation is more difficult to avoid in the case of a call to SetSpeakerConfig . When an application calls
SetSpeakerConfig , the adapter driver typically fails DirectSound's speaker-configuration request. This is because
the DirectSound object already exists, which means that the device already has active streams to manage.
In this situation, the adapter driver has two options for dealing with a speaker-configuration request that it has
failed:
The driver can remember the requested configuration and apply it just as soon as all its streams are
destroyed.
The driver can ignore the request and rely on DirectSound to send another speaker-configuration request
the next time that a DirectSound object is created.
The first option gives a better user experience because if the user selects a new setting through the speaker-
configuration dialog, the change takes effect immediately in all applications--not just DirectSound applications. (Of
course, if any audio applications are running at the time that the new setting is selected, the change is deferred
until all audio applications terminate.) With the second option, however, the change does not take effect until a
DirectSound application runs. For example, if an application that uses the Windows multimedia waveOut API is the
first application to run after changing a Control Panel setting, the user may wonder why the new setting has no
apparent effect.
In response to a speaker-configuration request sent to a 3D or DAC node, a typical adapter driver updates the
speaker configuration in the audio hardware only if no pins are currently instantiated by any audio application.
That means that if a waveOut application, for example, has one or more pins open at the time that a second
application calls DirectSoundCreate , the driver might need to defer any pending changes to the audio device's
speaker configuration until a later time.
If your driver is unable to fulfill a request to change the device's speaker-configuration, it should simply fail the
request. Failing a speaker-configuration request during DirectSound object creation or a SetSpeakerConfig call
does not cause the DirectSound object creation or SetSpeakerConfig call to fail.
At boot time, an audio adapter driver initializes the hardware's speaker configuration to its default setting, which is
typically stereo. As soon as any application creates a DirectSound object, DirectSound applies the setting stored in
the registry to the hardware. An application program must create a DirectSound device before it can call
SetSpeakerConfig to change the speaker-configuration setting in the registry, but this registry setting typically
takes effect in the hardware only after the DirectSound device is released and a second DirectSound device is
created.
Immediately after installing an audio device or when a speaker-configuration error occurs, the DirectSound
speaker configuration defaults to stereo.
Proprietary Speaker-Configuration Utilities
6/25/2019 • 2 minutes to read • Edit Online

Note This information applies to Windows XP and earlier operating systems. Starting with Windows Vista,
IDirectSound::GetSpeakerConfig and IDirectSound::SetSpeakerConfig have been deprecated.
Hardware vendors occasionally provide proprietary speaker-configuration utilities to be used with their audio
drivers in place of the speaker dialog in Control Panel. Such utilities have a potential problem: they sometimes
change the speaker configuration in a proprietary way that fails to notify Windows of the change. This can result in
a bad user experience if the settings in the proprietary utility do not match those in Control Panel. If you believe
that your device requires a proprietary utility, you should take the following steps to integrate your utility with
Windows:
1. Implement a DAC node in your driver that supports the KSPROPERTY_AUDIO_CHANNEL_CONFIG
property. Through this node, Windows informs the driver immediately of changes made by the user in
Control Panel.
2. Design your configuration utility to manage the speaker configuration by calling the DirectSound methods
GetSpeakerConfig and SetSpeakerConfig .
The SetSpeakerConfig call informs DirectSound (and Windows) of changes that your utility makes to the speaker
configuration. Also, your utility's initialization code should call GetSpeakerConfig to determine if the user has
changed any settings through Control Panel. If so, the utility should reflect these changes in its user interface.
If your device supports multichannel formats that have no precise Windows equivalents, your configuration utility
should do the following:
When changing to a speaker configuration that has no precise Windows equivalent, call SetSpeakerConfig
with the closest Windows equivalent. This is in addition to making any proprietary calls that are needed to
configure the driver.
When changing to a speaker configuration that does have a precise Windows equivalent, call
SetSpeakerConfig to update the speaker mode.
If you make Windows more aware of your device's capabilities, DirectSound can enable some features that it could
not otherwise enable (for example, multichannel 3D panning).
DSSPEAKER_SURROUND Speaker Configuration
10/23/2019 • 2 minutes to read • Edit Online

Note This information applies to Windows XP and earlier operating systems. Starting with Windows Vista,
IDirectSound::GetSpeakerConfig and IDirectSound::SetSpeakerConfig have been deprecated.
An application program can change the DirectSound speaker configuration to surround mode by calling the
IDirectSound::SetSpeakerConfig method with the speaker-configuration parameter set to
DSSPEAKER_SURROUND. This specifies a four-channel PCM format in which the channels are mapped to left, right,
center, and back speakers.
Once it takes effect, the DSSPEAKER_SURROUND speaker-configuration setting is global and affects the audio
device as a whole. All audio applications that subsequently run are subject to the new setting until DirectSound
changes the setting again.
DirectSound uses the following algorithm to configure the audio system for surround mode:
1. DirectSound first asks the driver to go into the surround speaker mode by sending a
KSPROPERTY_AUDIO_CHANNEL_CONFIG set-property request to the driver's DAC node (or 3D node if
it has no DAC node). (See KSNODETYPE_DAC and KSNODETYPE_3D_EFFECTS .) The
KSAUDIO_CHANNEL_CONFIG structure that accompanies this property request specifies the
KSAUDIO_SPEAKER_SURROUND speaker configuration. If the request succeeds, the audio device routes the
four channels to four analog outputs that are connected directly to left, right, center, and back speakers.
2. If that fails, DirectSound asks the driver to configure the device in stereo speaker mode and to enable its
KSNODETYPE_PROLOGIC_ENCODER node, if it has one. If this succeeds, the device converts the four-
channel stream from the application to a surround-encoded stereo signal that it outputs in either digital or
analog form. (The hardware should do the encoding after mixing the streams that flow into the device's
various mixer pins.) The user can connect the device's stereo outputs to an external decoder that converts
the encoded signal into four channels that are output to left, right, center, and back speakers.
3. If that fails, DirectSound enables the KSNODETYPE_PROLOGIC_ENCODER node in KMixer. (The device is
already in stereo mode from the previous step.) Again, the stereo signal that is output by the device can be
fed to an external decoder.
If this algorithm succeeds, the application can create and play four-channel PCM buffers. In cases 1 and 2 above,
the hardware buffers that the device reads from use four channels, but in case 3 the hardware buffers use a stereo
format. The application can write directly to the hardware buffers in cases 1 and 2, but in case 3 it should write to a
software buffer and allow KMixer to convert the application's four-channel stream to the surround-encoded stereo
format needed for the hardware buffer.
In case (3) above, the application should avoid using hardware buffers for any of its output streams. Note that
KMixer mixes all its input streams before encoding the mix to produce the surround stereo stream. However, any
stream that enters a hardware mixer pin is mixed in hardware with the encoded stereo from KMixer, which
degrades the quality of the surround audio when it is decoded. The application can prevent this by using only
software buffers.
A stereo stream that has been surround-encoded by a KSNODETYPE_PROLOGIC_ENCODER node can be decoded
into four channels (left, right, center, and back) by a KSNODETYPE_PROLOGIC_DECODER node.
DSSPEAKER_DIRECTOUT Speaker Configuration
10/23/2019 • 5 minutes to read • Edit Online

Note This information applies to Windows XP and earlier operating systems. Starting with Windows Vista,
IDirectSound::GetSpeakerConfig and IDirectSound::SetSpeakerConfig have been deprecated.
An application program can change the DirectSound speaker configuration to direct-out mode by calling the
IDirectSound::SetSpeakerConfig method with the speaker-configuration parameter set to
DSSPEAKER_DIRECTOUT (see Microsoft Windows SDK documentation). This specifies a speakerless configuration
in which the channels in the playback stream from the application are output directly to the audio adapter without
being interpreted as speaker positions. However, the input stream can still be modified by sample-rate conversion,
attenuation, filtering, and other types of processing that require no assumptions about the assignment of speakers
to channels.
Once it takes effect, the DSSPEAKER_DIRECTOUT speaker-configuration setting is global and affects the audio
device as a whole. All audio applications that subsequently run are subject to the new setting until DirectSound
changes the setting again.
In direct-out mode, the audio device renders the first channel to the first output connector on the device, the
second channel to the second output on the device, and so on. This allows an audio authoring application to output
multichannel data directly to a device such as an external mixer or an audio storage device (hard disk, ADAT, and so
on). For example, the channels in a 48-channel stream might be assigned as shown in the following table.
Channel Number Content 0
Vocal
1
Drums
2
Guitar
3
Bass
...
47
Piano
For this kind of raw audio data, speaker positions are meaningless, and assigning speaker positions to the input or
output streams might cause unwanted side effects. For example, a component such as KMixer might intervene
inappropriately by applying speaker-specific effects such as 3D virtualization or Dolby Surround Pro Logic
encoding to the stream. Note that the number of raw-data channels is not limited by the number of bits in the
channel mask.
Even a device that is not designed specifically for audio editing should typically accept a
KSPROPERTY_AUDIO_CHANNEL_CONFIG set-property request to change its speaker configuration to
KSAUDIO_SPEAKER_DIRECTOUT. In general, a device should avoid failing the request unless it can somehow verify
that its outputs are connected to speakers and cannot be used externally for any other purpose (for example, as
inputs to an external mixer).
An application that uses direct-out mode is typically written for a specific hardware device. This allows the
application to know in advance which direct-out data formats the device supports, including the number of
channels and how the data in those channels should be interpreted. This knowledge is necessary because when an
application calls IDirectSound::GetSpeakerConfig on a device that is configured in direct-out mode, the device
merely confirms that it is in this mode; it provides no additional information regarding the number of channels in
the stream formats that it supports in direct-out mode. (This information might be obtained, however, by sending a
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS get-property request to the supermixer node on the device's mixer
pin; see DirectSound Node-Ordering Requirements.)
When specifying the wave format for a direct-out stream, an application should set the dwChannelMask member
of the WAVEFORMATEXTENSIBLE structure to the value KSAUDIO_SPEAKER_DIRECTOUT, which is zero. A
channel mask of zero indicates that no speaker positions are defined. As always, the number of channels in the
stream is specified in the Format.nChannels member.
Hardware vendors have the option of supporting DirectSound hardware acceleration when their devices are
configured in direct-out mode. A DirectSound application can play back a direct-out stream through one of the
device's mixing pins, if one is available. Once all the available hardware pin instances have been exhausted, any new
streams pass through KMixer instead.
When mixing streams for a device that is configured in direct-out mode, KMixer applies a one-to-one mapping
between the channels of the input streams from the applications and the channels of the mix stream that it outputs
to the device. This means that if the application generates several direct-out streams that have the same number of
channels, for example, each channel N of the output mix is simply the sum of channels N of all the streams that
enter KMixer.
When mixing several direct-out streams that differ in the number of channels they contain, KMixer's mixing
algorithm is slightly more complex. In this case, each channel N of the mix is the sum of channels N of all input
streams that have a channel N. For example, if KMixer mixes quad and stereo input streams to form a quad output
mix, channels zero and one of the output mix are the sums of channels zero and one, respectively, of the input
stereo and quad streams. The stereo input stream contributes nothing, however, to channels two and three of the
mix, which are taken solely from the last two channels of the quad input stream.
An application that attempts to do either of the following is risking unpredictable behavior:
Play a stream that is not in direct-out format through a device that is configured in direct-out mode.
Play a direct-out stream through a device that is not configured in direct-out mode.
When faced with one of these cases, KMixer avoids simply failing the attempt to open the stream. Instead, it tries to
handle the apparent incompatibility by using the one-to-one mapping algorithm that is described above. The user
may or may not be satisfied with the result. Other audio components cannot be expected to handle these cases in
the same way as KMixer. For example, the driver for a device that is configured in direct-out mode should fail an
attempt to open a hardware buffer for an output stream that is not in direct-out format, and vice versa.
An audio authoring application might need to let the user listen to the data that it has mixed into the first several
channels of its output stream but ignore the raw data that is still contained in the remaining channels of the stream.
KMixer's behavior makes this straightforward. For example, if a 24-channel playback stream contains a stereo mix
in channels 0 and 1 and raw data in channels 2 through 23, the application does the following:
Configures the target audio device (this is not necessarily the device that the application uses to edit the
stream) in stereo mode by calling SetSpeakerConfig with DSSPEAKER_STEREO.
Changes dwChannelMask in the playback stream's WAVEFORMATEXTENSIBLE structure to
KSAUDIO_SPEAKER_STEREO but leaves Format.nChannels set to 24, which is the total number of channels
in the stream.
KMixer mixes only the stereo channels of the playback stream, which are described in the channel mask, and
discards the remaining 22 channels, which contain raw data. Remember that any change made to the DirectSound
speaker-configuration setting is unlikely to take effect until the current DirectSound object is destroyed and
another is created (see Applying Speaker-Configuration Settings).
DirectSound Capture Effects
6/25/2019 • 2 minutes to read • Edit Online

DirectSound 8 adds some new features for enabling and controlling third-party effects during audio capture. This
and later versions of DirectSound support the following two capture effects:
Acoustic echo cancellation (AEC)
Noise suppression (NS)
In a full-duplex audio application such as telephone conferencing, echoes of the render stream being output
through the speakers are picked up in the microphone that generates the capture stream. After characterizing the
sound reflections in the room or other physical environment, the full-duplex system uses AEC to monitor the
render stream to cancel out the echoes that it adds to the capture stream. The system can further improve the
quality of the capture stream by using NS to detect noise spikes and remove them from the stream.
A full-duplex DirectSound application can use the IDirectSoundCaptureFXAec and
IDirectSoundCaptureFXNoiseSuppress interfaces to control the AEC and NS effects. The
IDirectSoundCaptureBuffer ::GetObjectInPath method retrieves pointers to objects with these interfaces. The
DirectSoundFullDuplexCreate function creates the IDirectSoundCaptureBuffer object, and the parameters
that the caller passes to this function include an array of DSCEFFECTDESC structures. The array specifies the effects
that are to be enabled in the capture buffer. The guidDSCFXClass member of each structure in the array contains
a GUID that specifies an effect: AEC or NS. The DirectSound name for each GUID is shown in the following table,
along with the KS name for the same GUID value. For details, see the DirectX 8.0 SDK documentation.

DIREC T SO UN D GUID N A M E K S GUID N A M E

GUID_DSCFX_CLASS_AEC KSNODETYPE_ACOUSTIC_ECHO_CANCEL

GUID_DSCFX_CLASS_NS KSNODETYPE_NOISE_SUPPRESS

In Microsoft Windows XP and later, you can expose your audio device's hardware-accelerated capture effects to
DirectSound applications. In addition, the AEC system filter (Aec.sys) provides software emulation of AEC and NS
effects.
These topics are discussed in the remainder of this section:
Exposing Hardware-Accelerated Capture Effects
AEC System Filter
Exposing Hardware-Accelerated Capture Effects
6/25/2019 • 4 minutes to read • Edit Online

In Windows XP and later, the WDM audio framework supports hardware acceleration of audio-capture effects that
are exposed through DirectSound. These effects include acoustic echo cancellation (AEC) and noise suppression
(NS). For information about how a DirectSoundCapture application enables use of hardware-accelerated AEC and
NS, see the Microsoft Windows SDK documentation.
A miniport driver can expose hardware acceleration for any subset of these effects, depending on the capabilities
of the underlying device. To expose the hardware's capabilities for AEC and NS effects, each pin on the AEC filter
that the driver implements should meet these requirements:
The pin should include an individual node in its node chain to represent each hardware effect that is to be
incorporated into the graph. The KS node types for AEC and NS effects are specified by the following GUIDs:
KSNODETYPE_ACOUSTIC_ECHO_CANCEL KSNODETYPE_NOISE_SUPPRESS
The AEC and NS nodes on the pin should support the KSPROPSETID_General property set and should
provide information about the manufacturer when queried for the
KSPROPERTY_GENERAL_COMPONENTID property.
The AEC and NS nodes on the pin should support the KSPROPSETID_TopologyNode property set and its two
properties:
KSPROPERTY_TOPOLOGYNODE_ENABLE enables an effect.
KSPROPERTY_TOPOLOGYNODE_RESET resets the effect to its default state.
The AEC and NS nodes on the pin should support the following properties of the KSPROPSETID_Audio
property set: KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
The pin should support the following properties of the KSPROPSETID_Audio property set:
KSPROPERTY_AUDIO_POSITION KSPROPERTY_AUDIO_L ATENCY
The pin should expose its data-range capabilities (see Pin Data-Range and Intersection Properties).
The specific requirements for exposing hardware-accelerated AEC and NS nodes are presented below.
Acoustic Echo Cancellation
A PCM miniport driver exposes hardware support for AEC in the form of a topology for both the capture and
render streams that meets this additional requirement:
The pin must include an AEC node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL ), which must be specified in
its proper position in the ordered node chain (see below).
Noise Suppression
A PCM miniport driver exposes hardware support for NS in the form of a topology for the capture stream that
meets this additional requirement:
The pin must include an NS node (KSNODETYPE_NOISE_SUPPRESS ), which must be specified in its proper
position in the ordered node chain (see below).
Node -Chain Ordering
Currently, the DirectSound capture-effects architecture requires that the nodes be specified in the order in which
they are requested by the application. As a result, the order in which the miniport driver specifies its nodes must
match the order that is used by the AEC system filter (Aec.sys), which implements the AEC and NS algorithms in
software.
To enable hardware acceleration, the driver must specify the effects that are implemented by the hardware in the
following order:
KSNODETYPE_ADC
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_NOISE_SUPPRESS
Note that this list can omit any unimplemented effects as long as the relative ordering is preserved.
AEC Node Pin Assignments
An adapter driver uses an array of PCCONNECTION_DESCRIPTOR structures to specify the connections within a
filter. Each array element describes one connection, which can be node-to-node, node-to-pin, or pin-to-pin. For
details, see Nodes and Connections.
To use the PCCONNECTION_DESCRIPTOR structure, the driver writer assigns "logical" pins to nodes. These are
"pins" on the nodes themselves and are used solely to specify the connections inside the filter. This is in contrast to
the external pins on the filter, which are used to connect to other filters.
The following table shows the pin IDs that the adapter driver should assign to the four logical pins on the AEC
node.

P IN ID PA RA M ET ER N A M E VA L UE M EA N IN G

KSNODEPIN_AEC_RENDER_IN 1 Sink pin (node input) for render


stream

KSNODEPIN_AEC_RENDER_OUT 0 Source pin (node output) for render


stream

KSNODEPIN_AEC_CAPTURE_IN 2 Sink pin (node input) for capture


stream

KSNODEPIN_AEC_CAPTURE_OUT 3 Source pin (node output) for


capture stream

The pin IDs in the preceding table are defined in the header file Ksmedia.h.
The following code example shows how an adapter driver can specify the internal topology of an AEC filter that
contains both an AEC node and an NS node:
// AEC Filter Topology

// Pin IDs for external pins on AEC filter


#define ID_CaptureOutPin 0 // microphone stream
#define ID_CaptureInPin 1
#define ID_RenderOutPin 2 // speaker stream
#define ID_RenderInPin 3

// Generic pin IDs for simple node with one input and one output
#define NODE_INPUT_PIN 1
#define NODE_OUTPUT_PIN 0

// Node IDs
#define NODE_ID_AEC 0 // acoustic echo cancellation
#define NODE_ID_NS 1 // noise suppression

// The array below defines the internal topology of an


// AEC filter that contains an AEC node and an NS node.

const PCCONNECTION_DESCRIPTOR AecConnections[] = {


{ PCFILTER_NODE, ID_RenderInPin, NODE_ID_AEC, KSNODEPIN_AEC_RENDER_IN },
{ NODE_ID_AEC, KSNODEPIN_AEC_RENDER_OUT, PCFILTER_NODE, ID_RenderOutPin },
{ PCFILTER_NODE, ID_CaptureInPin, NODE_ID_AEC, KSNODEPIN_AEC_CAPTURE_IN },
{ NODE_ID_AEC, KSNODEPIN_AEC_CAPTURE_OUT, NODE_ID_NS, NODE_INPUT_PIN },
{ NODE_ID_NS, NODE_OUTPUT_PIN, PCFILTER_NODE, ID_CaptureOutPin }
};

The AecConnections array in the preceding code example defines the filter topology that is shown in the following
figure.

The preceding figure represents each connection inside the filter with a dashed arrow that points in the direction of
data flow. A total of five connections appear in the figure. Each connection corresponds to one of the five elements
in the AecConnections array in the code example.
AEC System Filter
10/23/2019 • 6 minutes to read • Edit Online

The AEC system filter (Aec.sys) implements the acoustic echo cancellation (AEC) and noise suppression (NS)
algorithms in software. This filter is a standard operating-system component in Windows XP and later. For
information about how DirectSoundCapture applications enable use of the AEC system filter, see the Microsoft
Windows SDK documentation.
Constraints Imposed by AEC System Filter
An audio filter graph that incorporates a capture effect that is implemented in the AEC system filter is subject to the
following restrictions:
The AEC system filter can connect only to pins that handle PCM data formats.
The bit depth must be 16 bits for the capture stream and 8 or 16 bits for the render stream.
The AEC system filter performs all internal processing at 16 kHz. The input and output streams are source-
rate converted as necessary.
In Windows XP SP1, Windows Server 2003, and later, the AEC system filter's capture-out and render-in pins
(see the following figure) must have the same sample rate, but the sample rates at the capture-in and
render-out pins can each be selected independently of the other pins. The sample rate at the capture-in pin
can be (in order of preference) 16 kHz, 48 kHz, 44.1 kHz, or 8 kHz. (The order of preference is based on
processing time and audio quality.) The sample rate at the render-out pin can be (in order of preference) 16
kHz, 48 kHz, or 44.1 kHz. Note that the render-out pin does not support a sample rate of 8 kHz.

The AEC and NS nodes (see figure in Exposing Hardware-Accelerated Capture Effects) can handle only
monophonic streams. If the capture stream is multichannel (for example, two-channel stereo), all channels
other than the first are ignored (and discarded). Only monophonic streams can be processed by the render
side.
In Windows XP SP1, Windows Server 2003, and later, this limitation does not exist. The AEC system filter
correctly handles mismatches between the clocks for the capture and render streams, and separate devices
can be used for capture and rendering.
When the AEC system filter is used, the SysAudio system driver turns off hardware acceleration for mixing,
sample-rate conversion, 3D spatialization, and so on. All mixing of streams is done in software emulation by
the KMixer system driver. This restriction is necessary to ensure that all audio that is played by the
rendering device can be canceled out of the capture stream by the AEC system filter.
Any signal processing that is done before the AEC or NS node on the capture side of the graph or after the
AEC or NS node on the render side must be linear time-invariant. Performing any nonlinear or time-varying
signal processing in either of these locations prevents AEC from canceling the echo in the capture signal.
AEC filtering cancels only echoes coming from the AEC-filtered channels in your computer. Audio that is
output through channels that do not pass through AEC is not echo-canceled. Echoes in a non-AEC audio
channel are functionally equivalent to echoes in the audio that is playing on a radio in the office next to your
computer. AEC has no way of canceling (and no effect on) echoes from either a radio or a non-AEC channel.
The preceding requirements apply to all kernel-streaming audio filter graphs that incorporate capture effects that
are implemented in Aec.sys. These restrictions reflect fundamental assumptions in the design and implementation
of the AEC system filter. The constraints on stream formats might change in future versions of Windows.
Any product design that uses the AEC system filter should take the preceding constraints into account. The
following questions and answers show how these constraints can affect AEC filtering behavior:
Q: I've created a DirectSound buffer for stereo rendering, but both channels sound the same when I'm using AEC.
Why is this?
A: AEC works only on mono streams, so KMixer is mixing the stereo stream back to mono to meet this constraint.
Q: Why does my 44-kHz, 16-bit audio sound like 16 kHz when I use AEC?
A: Because the AEC system filter performs all internal processing at 16 kHz.
Q: Why can't I get a hardware-accelerated DirectSound buffer with AEC?
A: Because SysAudio turns off hardware-accelerated mixing when AEC is enabled.
Q: Will the AEC system filter work with my old Sound Blaster 16 card?
A: Yes. Although the Sound Blaster16 card is unable to simultaneously manage 16-bit rendering and capture
streams, it can simultaneously manage an 8-bit rendering stream and a 16-bit capture stream, which is a
combination that the AEC system filter's render-out and capture-in pins support. New audio cards should be
designed to support bit depths of at least 16 bits for both rendering and capture.
Summary of Data Formats for AEC Pins
A DirectSound application that enables the AEC system filter can choose for its DirectSound buffers any sample
rate or sample size that KMixer supports. KMixer converts the data from the application's rendering buffer to a 16-
kHz mono 16-bit format before it enters the AEC system filter. Similarly, KMixer can convert the data that is
destined for a DirectSoundCapture application's capture buffer to a 16-kHz mono 16-bit format after it leaves the
AEC system filter. However, to both minimize the amount of processing done in the graph and achieve the highest
audio quality, the applications should use a 16-kHz mono 16-bit format for both the rendering and capture buffers.
If you want your audio hardware to work with the AEC system filter, then the hardware rendering pin must support
at least one of the sample rates supported by the AEC render-out pin, and the hardware capture pin must support
one of the sample rates supported by the AEC capture-in pin. To achieve the best AEC performance, your hardware
should support a 16-kHz sample rate in addition to any higher rates it supports. By supporting the 16-kHz rate, the
hardware reduces the amount of processing that the AEC system filter must do by eliminating the need to do
sample-rate conversion.
The AEC system filter's render-in pin connects to KMixer's output pin. KMixer performs the necessary conversion of
its input streams to the format that the render-in pin requires. The render-in pin supports only two data formats:
A 16-kHz mono PCM format with a sample size of 16 bits
A 16-kHz mono PCM format with a sample size of 8 bits
The capture-out pin supports only one format:
A 16-kHz mono PCM format with a sample size of 16 bits
If the DirectSoundCapture application's buffer format is 16-kHz mono 16-bit PCM, the AEC capture-out pin can
bypass KMixer and connect directly to DSound.DLL (see preceding figure). Otherwise, the AEC capture-out pin
connects to KMixer, which converts the 16-kHz mono 16-bit PCM stream from the pin into whatever format the
application's capture buffer uses.
The AEC render-out pin can handle any of the following formats:
16-kHz 16-bit PCM with two channels (stereo)
16-kHz 8-bit PCM with two channels
48-kHz 16-bit PCM with two channels
48-kHz 8-bit PCM with two channels
44.1-kHz 16-bit PCM with two channels
44.1-kHz 8-bit PCM with two channels
The render-out pin produces a stereo stream by copying the single channel from the AEC node into both channels
of the output stream.
The capture-in pin can handle any of the following formats:
16-kHz 16-bit PCM with any number of channels
48-kHz 16-bit PCM with any number of channels
44.1-kHz 16-bit PCM with any number of channels
8-kHz 16-bit PCM with any number of channels
The capture-in pin uses only the first channel and ignores (and discards) the others.
All of the AEC system filter's pins use the data-format parameter values shown in the following table.

K SDATA RA N GE M EM B ER PA RA M ET ER VA L UE

MajorFormat KSDATAFORMAT_TYPE_AUDIO

SubFormat KSDATAFORMAT_SUBTYPE_PCM

Specifier KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
For more information about the MajorFormat , SubFormat , and Specifier members, see KSDATARANGE . For
an example of a KSDATARANGE_AUDIO data-range descriptor that uses these three parameter values, see PCM
Stream Data Range.
Driver Support for DirectMusic
12/5/2018 • 2 minutes to read • Edit Online

This document is a design guide for implementing drivers for Microsoft DirectMusic synthesizers (synths) and wave
sinks:
A synthesizer is a device that inputs a stream of time-stamped MIDI messages and outputs an analog audio
signal or a periodically sampled wave digital audio stream.
A wave sink is a streaming wave device that pulls wave audio samples from the synthesizer and feeds them
to a target audio device.
Software synths and wave sinks can be implemented in user mode. Software or hardware components that provide
the same functionality can be implemented in kernel mode. For more information about the relationship between
synths and wave sinks, see Synthesizers and Wave Sinks. For information about the DirectMusic API, see the
Microsoft Windows SDK documentation.
This design guide contains the following sections:
DirectMusic DDI Overview
Custom Rendering in User Mode
Kernel Mode Hardware Acceleration DDI
DirectMusic DDI Overview
10/23/2019 • 2 minutes to read • Edit Online

The design principles that are needed to implement user-mode synths generally apply to kernel-mode synths as
well. For this reason, this guide begins with a discussion of user-mode implementations and progresses to specific
kernel-mode topics.
Typically, the best design strategy is to first write a software implementation of the DirectMusic device driver
interface (DDI) that runs in user mode. This approach is beneficial even if the final product is a kernel-mode
implementation that uses hardware components. After the user-mode version is completed, the software can be
converted to kernel mode and connections established with the hardware, one feature at a time. For more
information, see User Mode Versus Kernel Mode.
DirectMusic uses the following user-mode interfaces to control user-mode synthesizers and communicate with
kernel-streaming drivers:
IDirectMusicSynth
This is the user-mode interface for implementing custom software synths.
IDirectMusicSynthSink
This is the user-mode interface for implementing custom wave sinks in Microsoft DirectX 6.1 and DirectX 7. In
DirectX 8 and later, DirectMusic always uses its private wave sink with a user-mode synth, and no public interface is
supported for user-mode wave sinks.
IKsControl
DirectMusic uses this interface to access the properties of kernel-streaming drivers from user mode in DirectX 6.1
and later.
Kernel-mode terminology differs slightly from user-mode because of the port-miniport driver model (see
Introduction to Port Class), which delegates generic kernel-streaming tasks to the DMus port driver and assigns
hardware-specific functions to the DMus miniport driver. The port and miniport drivers share responsibilities for
the synth. The kernel-mode wave sink is part of the kernel-resident port driver. Unlike the user-mode wave sink in
DirectX 6.1 and DirectX 7, the kernel-mode wave sink is not replaceable. Most of the work that is required to build a
custom kernel-mode driver is in the writing of the miniport driver. In most cases, the miniport driver is the only
component that the driver writer needs to implement to support a piece of hardware, or to implement a custom
software synth for DirectMusic.
Custom DMus miniport drivers use the following kernel-mode interfaces:
IAllocatorMXF
IMiniportDMus
ISynthSinkDMus
IMXF
IMasterClock
IPortDMus
DMus miniport drivers implement the IMinipor tDMus , ISynthSinkDMus , and IMXF interfaces. The DMus port
driver implements the IAllocatorMXF , IMasterClock , and IPor tDMus interfaces and exposes them to miniport
drivers.
User Mode Versus Kernel Mode
6/25/2019 • 3 minutes to read • Edit Online

A custom synth can be written to run in either user mode or kernel mode. In general, software synths are easier to
implement in user mode, but they frequently can achieve lower latency in kernel mode. Hardware components can
be supported only in kernel mode. Good reasons exist, however, for beginning development in user mode even if
the final implementation is to run in kernel mode.
Building software synthesizers (and wave sinks) is much simpler in user mode. The user-mode interfaces are easy
to use, and debugging is simplified. Another benefit is that the resulting component is a Microsoft Windows
executable file. Because this executable file is a COM object, installing it is simply a matter of self-registering from
the command line with regsvr32.exe. (The RegSvr32 system application calls your DLL's DllRegisterSer ver
function. For more information, see the Microsoft Windows SDK documentation.)
If a user-mode implementation is all you need, you can deliver your product with an application program instead
of a driver. The user avoids a complicated driver-installation process, and no reboot is needed after installing. Your
user-mode component can then be enumerated as one of the available ports, depending on whether you want
other applications to be able to use it. For more information, see Registering Your Synthesizer.
The advantage of a kernel-mode software implementation is lower latency. With the advent of time-stamped
messages, however, this advantage is not as great as it used to be. Legacy MIDI APIs had no time stamping, so
when you played a note, that was exactly when it was queued to play. Time stamping makes it possible to queue
notes to play at specified times in the future. Using time stamping means that the note plays at the correct time
unless the advance warning is less than the latency inherent in the system.
Latency is only an issue when sounds are queued to play with little or no advance warning. Thus, kernel-mode
implementations are recommended only when there is an undesirable limitation to a user-mode software
implementation or when supporting hardware acceleration.
If you decide to do a kernel-mode implementation, the best approach is still to begin development in user mode.
The source code for Microsoft's user-mode synth is provided in the Microsoft Windows Driver Kit (WDK), so you do
not have to write a new synth from scratch. You can use the existing code to understand how the downloadable
sounds (DLS) downloads are parsed. Then, you can add any new functionality (such as parsing additional chunks)
and debug this logic in user mode first, stubbing out the routines that access the hardware. (A stubbed-out routine
can either do nothing or emulate the hardware function in software.) For more information about DLS, see the
Windows SDK documentation.
When you have your implementation working in user mode, you can move it down to kernel mode and make it
work there. After you have the software version working in kernel mode, your next step is to begin moving the
functionality to your hardware. The user-mode and kernel-mode software synths serve as useful intermediate
steps in the process of getting your hardware synth up and running.
To summarize the recommendations above:
For software-only components, implement the components first in user mode (in order to work out the
design issues with easy interfaces, debugging, installation, and removal) and then convert to kernel mode if
necessary because of latency or other considerations.
For hardware components, first implement a software version in user mode (in order to work out the design
issues with easy interfaces, debugging, installation, and removal), then convert it to a kernel-mode software
version. Finally, connect the kernel-mode component to hardware, one feature at a time, until everything
works as desired.
Custom Rendering in User Mode
12/5/2018 • 2 minutes to read • Edit Online

The Microsoft Software Synthesizer is a user-mode component of the DirectMusic installation and should be
adequate for most synthesizer purposes. DirectMusic uses this component as its default synthesizer.
In addition, DirectMusic allows you to implement your own user-mode software synthesizer. The synthesizer
accepts an input stream consisting of MIDI events, and it generates an output stream containing wave data.
Typically, a custom synthesizer feeds its generated wave stream to DirectMusic's built-in wave sink, which plays the
stream through Microsoft DirectSound. However, in Microsoft DirectX 6.1 and 7, DirectMusic allows you to use a
custom, user-mode wave sink to redirect rendered wave output to a device other than DirectSound. However,
custom wave sinks are seldom necessary. In DirectX 8 and later, DirectMusic provides no support for custom wave
sinks.
The most important header files for DirectMusic synths are dmusics.h (user mode only), dmusicks.h (kernel mode
only), dmusbuff.h, and dmusprop.h.
The remainder of this section discusses various aspects of customizing the rendering process. The examples in this
section assume a user-mode implementation, although the concepts that they present apply to both user and
kernel mode, except where noted otherwise. The following topics are discussed:
Synthesizers and Wave Sinks
IDirectMusicSynth and IDirectMusicSynthSink
MIDI to Wave
Synthesizer Timing
DLS Download Support
Registering Your Synthesizer
Synthesizers and Wave Sinks
6/25/2019 • 2 minutes to read • Edit Online

The rendering engine has two parts:


The synthesizer, which takes MIDI messages and converts them to wave audio samples.
The wave sink, which provides a destination for the wave samples and helps synchronize the output.
By default, a DirectMusic application uses the Microsoft Software Synthesizer (dmsynth.dll) as the synthesizer and
DirectSound as the wave-output device.
In DirectX 6.1 and DirectX 7, a DirectMusic application can override these defaults. For example, the application
might use the Microsoft Software Synthesizer but direct the output to a .wav file, or it might implement a custom
synthesizer that works with the default wave sink. The latter scenario is more likely because the default wave sink
should work well for most synthesizers.
In DirectX 8 and later, DirectMusic always uses its built-in wave sink to output data from a user-mode synth, but an
application can override the default software synth. This means that a DirectMusic application can implement a
custom user-mode synthesizer, but the synthesizer must use DirectMusic's built-in wave sink.
The figure below shows how the DirectMusic architecture incorporates user-mode synthesizers and wave sinks.
Note that the block labeled "DirectMusic Port" in the following figure should not be confused with the kernel-
mode DMus port driver in the PortCls system driver module, portcls.sys. A DirectMusic port is a user-mode object
with an IDirectMusicPor t interface (part of the DirectMusic API) and is implemented in dmusic.dll. For more
information about DirectMusic ports, see the Microsoft Windows SDK documentation.

In the preceding figure, the application sends data to the user-mode DirectMusic port, which passes the data (MIDI
or DLS) down to the software synth (dmsynth.dll by default) so that it can render the notes into wave data. The
wave sink manages the timing and hands the synth a buffer to fill when it is ready to receive a burst of data. The
synth fills up the buffer (an IDirectSoundBuffer object by default) with data so that it can be passed to
DirectSound. DirectSound either plays the data through the KMixer system driver or plays it through a
DirectSound hardware-accelerated rendering pin on the audio device, if one is available (see Overview of
DirectSound Hardware Acceleration).
This same basic architecture also applies to kernel-mode implementations, with the exception that the wave sink
hands the data buffer directly to the hardware or to the KMixer system driver. The DMus port driver implements
the wave sink for a kernel-mode software synthesizer. For more information, see A Wave Sink for Kernel-Mode
Software Synthesizers.
When these steps are completed, the user-mode DirectMusic port should be open and activated for use. As soon
as this much of the driver code is working, you can start implementing features. Use the source code for the user-
mode Microsoft Software Synthesizer as a template and begin adding the new functionality.
A user-mode software synthesizer can be implemented as an object with an IDirectMusicSynth interface. A user-
mode wave sink can be implemented as an object with an IDirectMusicSynthSink interface. For more information,
see IDirectMusicSynth and IDirectMusicSynthSink.
IDirectMusicSynth and IDirectMusicSynthSink
6/25/2019 • 3 minutes to read • Edit Online

As described in Synthesizers and Wave Sinks, you can implement a custom software synthesizer or wave sink that
runs in user mode and communicates with DirectMusic. The synthesizer object must have an IDirectMusicSynth
interface. The wave sink object must have an IDirectMusicSynthSink interface.
DirectMusic communicates with a software synthesizer through its IDirectMusicSynth interface. DirectMusic
supports this interface in DirectX 6.1 and later. IDirectMusicSynth supports the methods shown in the following
table, which organizes the methods into functional groups.

GRO UP M ET H O D N A M ES

Activation IDirectMusicSynth::Activate

Channels IDirectMusicSynth::GetChannelPriority
IDirectMusicSynth::SetChannelPriority

Instruments IDirectMusicSynth::Download
IDirectMusicSynth::Unload

Information IDirectMusicSynth::GetAppend
IDirectMusicSynth::GetFormat
IDirectMusicSynth::GetLatencyClock
IDirectMusicSynth::GetPor tCaps
IDirectMusicSynth::GetRunningStats

Playback IDirectMusicSynth::PlayBuffer
IDirectMusicSynth::Render

Ports IDirectMusicSynth::Open
IDirectMusicSynth::Close
IDirectMusicSynth::SetNumChannelGroups

Miscellaneous parameters IDirectMusicSynth::SetMasterClock


IDirectMusicSynth::SetSynthSink

Most applications do not need to call the methods in the IDirectMusicSynth interface directly; the DirectMusic
port typically manages the synthesizer. However, your application can interface directly to the synthesizer during
development and testing.
The synthesizer is not complete without a connection to a wave sink, which is represented as an object with an
IDirectMusicSynthSink interface. The wave sink connects the synthesizer's audio output stream to an audio
rendering module such as DirectSound, DirectShow, or the Windows Multimedia waveOut API.
By default, DirectMusic uses its internal IDirectMusicSynthSink implementation to handle the wave data that the
software synthesizer generates. This wave sink feeds the data to DirectSound.
Before the synthesizer can be activated, a wave sink must first be created and connected to the synthesizer via a
call to IDirectMusicSynth::SetSynthSink . This should be the very first call after creating the synthesizer because
many of the timing-related calls, including IDirectMusicSynth::GetLatencyClock and
IDirectMusicSynth::SetMasterClock , are actually passed through to equivalent calls on
IDirectMusicSynthSink .
Only DirectX 6.1 and DirectX 7 support the implementation of a custom user-mode wave sink with an
IDirectMusicSynthSink interface. IDirectMusicSynthSink supports the methods shown in the following table,
which organizes the methods into functional groups.

GRO UP M ET H O D N A M ES

Initialization IDirectMusicSynthSink ::Activate


IDirectMusicSynthSink ::GetDesiredBufferSize
IDirectMusicSynthSink ::Init
IDirectMusicSynthSink ::SetDirectSound

Timing IDirectMusicSynthSink ::GetLatencyClock


IDirectMusicSynthSink ::RefTimeToSample
IDirectMusicSynthSink ::SampleToRefTime
IDirectMusicSynthSink ::SetMasterClock

In DirectX 8 and later, DirectMusic always uses its internal wave sink with a user-mode synthesizer. These later
versions of DirectMusic do not support custom implementations of IDirectMusicSynthSink .
In DirectX 6.1 and DirectX 7, however, you are free to implement your own IDirectMusicSynthSink object and
use it to manage the synthesizer's audio output stream in any way you like. For example, you might feed the wave
data into DirectShow or the waveOut API. If you create a wave stream object, it must have an
IDirectMusicSynthSink interface to plug into the IDirectMusicSynth object.
In addition to managing the wave stream, the wave sink is responsible for controlling the timing for the
synthesizer. The wave sink receives the master clock by a call to IDirectMusicSynth::SetMasterClock , which
passes the master time source on with an identical call to IDirectMusicSynthSink ::SetMasterClock . Because
the master clock is not generated from the same crystal as the wave stream, the wave sink must keep them
synchronized by compensating for clock drift.
Additionally, so that the synthesizer can keep track of time appropriately, it provides two calls to convert from
master clock time to sample time and back:
IDirectMusicSynthSink ::RefTimeToSample
IDirectMusicSynthSink ::SampleToRefTime
The wave sink generates the latency clock because it actually manages the times at which samples get written by
calls to IDirectMusicSynth::Render . When DirectMusic calls IDirectMusicSynth::GetLatencyClock on the
DirectMusic port, it simply turns around and calls IDirectMusicSynthSink ::GetLatencyClock .
When a software synthesizer is first opened, DirectMusic gives the synthesizer a DMUS_PORTPARAMS structure
(described in the Microsoft Windows SDK documentation) that specifies the sample rate and number of channels
for the audio output stream. The synthesizer then converts these into a standard WAVEFORMATEX structure that
it passes to the wave sink when the wave sink calls the IDirectMusicSynth::GetFormat method.
For additional information, see the descriptions of the IDirectMusic and IDirectMusicPor t interfaces in the
Windows SDK documentation.
MIDI to Wave
6/25/2019 • 2 minutes to read • Edit Online

The main work of the synthesizer is done in two steps:


Getting MIDI messages
Mixing the rendered notes into the wave audio stream
This section details generally how this is done in user mode, although the concepts are essentially the same in
kernel mode. See Kernel Mode Hardware Acceleration DDI for specifics on how to do the same with a kernel-mode
miniport driver.
In user mode, the application calls IDirectMusicSynth::PlayBuffer when it has MIDI messages ready to play. The
application is responsible for calling PlayBuffer in a timely fashion and for time-stamping the buffer correctly,
taking the synthesizer latency into account. Your implementation of this method retrieves the waiting messages
and stores them in an internal format, which is stamped with a time that is based on the reference time that is
passed in with the buffer.
The wave sink calls IDirectMusicSynth::Render whenever it is ready to receive data. For example, if the
destination for the rendered data is a DirectSound secondary buffer, your implementation of
IDirectMusicSynthSink ::Activate might set up a thread that waits for a DirectSound PlayBuffer notification.
When the DirectSound buffer requires data, DirectSound notifies the thread, which in turn calls Render , passing in
a pointer to the IDirectSoundBuffer object (described in the Microsoft Windows SDK documentation) and the
number and position of the samples that are to be rendered.
The DirectSound buffer is circular. Because wraparound occurs at the end of the buffer, the possibility of a virtually
contiguous region being split into two pieces must be taken into account. The wave sink typically handles the split
by calling Render twice, once for each part of the locked portion of the DirectSound buffer, so that the Render
method only has to deal with contiguous blocks of memory. The wave sink calls IDirectSoundBuffer ::Lock on a
DirectSound buffer to ask for write permission to a region within the buffer. For example, if the wave sink calls
Lock on 2 kilobytes of data starting 1 kilobyte from the end of the buffer, then the call locks the last 1 kilobyte up
to the end of the buffer and another 1 kilobyte starting at the beginning of the buffer. In this case, Lock actually
returns two pointers and corresponding lengths, which together describe the region of the buffer that is locked.
Each pointer is guaranteed to point to a contiguous block of memory.
Your implementation of the Render method is responsible for determining what must be done in response to the
MIDI messages that are retrieved in PlayBuffer . From the dwLength parameter values of successive calls to
Render , the method can keep track of the sample time and act on messages that are valid for the current
rendering period. When a note-on message is processed, the note can be stored internally and rendered again on
each pass through the method until a corresponding note-off message is received.
Synthesizer Timing
6/25/2019 • 2 minutes to read • Edit Online

The synthesizer works with two different systems of time:


Reference time
Sample time
Reference time is the absolute time (in master-clock units) at which a sequence of messages is to be played. In user-
mode implementations, it is passed to the IDirectMusicSynth::PlayBuffer method when MIDI messages are fed
to the synthesizer. The synthesizer, wave sink, and the rest of DirectMusic should all work under the same master
clock, which is attached to the synthesizer by your implementation of the IDirectMusicSynth::SetMasterClock
method and to the wave sink by IDirectMusicSynthSink ::SetMasterClock .
Sample time is used to measure offsets into the synthesizer's output buffer. This buffer is filled with wave samples,
so sample time is relative to the sampling rate. For example, at a sampling rate of 22.1 kHz, each second of time is
equivalent to 22,100 samples or 44,200 bytes (in the case of a 16-bit mono format).
Because the playback of the wave sample buffer is likely to be controlled by a different timing crystal than the
master clock, reference time and sample time tend to drift apart. The wave sink keeps them in step by
implementing a phase-locked loop. This clock synchronization is described in Clock Synchronization.
This section also includes:
Synthesizer Latency
Time-Stamped Events
Synthesizer Latency
7/13/2019 • 2 minutes to read • Edit Online

Another consideration in synthesizer timing is latency, which is the difference between the current time and the
first time that a note can play. A MIDI message cannot be submitted to the synthesizer and rendered into the
output buffer at the current sample time. Allowance should be made for data that has already been placed in the
buffer but has not yet been streamed to the wave output device.
The wave sink therefore should implement a latency clock, which is an IReferenceClock object (described in the
Microsoft Windows SDK documentation). The latency clock's IReferenceClock ::GetTime method retrieves the
sample time up to which data has already been written to the buffer, and converts this to reference time relative to
the master clock. The wave sink does conversions between reference and sample time with
IDirectMusicSynthSink ::SampleToRefTime and IDirectMusicSynthSink ::RefTimeToSample , so in this case,
the synth calls IDirectMusicSynthSink ::RefTimeToSample to accomplish the conversion.
Latency time is all managed by the wave sink. Your implementation of the
IDirectMusicSynthSink ::GetLatencyClock method should output a pointer to the latency clock, and this
pointer must in turn be retrieved by IDirectMusicSynth::GetLatencyClock . The application uses the latency
clock to determine the earliest point in time at which a MIDI message can be queued to play when it is passed to
the synthesizer by calling the IDirectMusicSynth::PlayBuffer method.
An example of the latency of a MIDI message is shown in the following figure.

In the preceding figure, the latency clock points to the first place in the PCM buffer loop where a note can be
played. Note that the master clock is at 22 time units, which is the point where sound is currently playing from, but
the space between 22 and 30 time units has already been filled with wave data and can no longer be written to.
Therefore, the first place where a new time-stamped MIDI event can be scheduled to play is at time 30. Thus, the
latency clock reads 30 time units.
Messages can be scheduled to play at, or any time after, this latency time. Therefore, messages that are to be
rendered immediately are stamped with the latency time (not the current time) before being placed in the
synthesizer's input buffer.
Time-Stamped Events
6/25/2019 • 3 minutes to read • Edit Online

The big picture of the synthesizer timing is that instead of sending a note exactly when it needs to play, each note is
time stamped and placed in a buffer. This buffer is then processed and played within two milliseconds of the time
that is specified by the time stamp. (Although the timing resolution is in hundreds of nanoseconds, we will talk in
terms of milliseconds, which are more convenient time units for this discussion.)
Because the latency is known to the system through the latency clock, time-stamped events can be waiting in a
buffer to play at their proper time, rather than just dropping events into a queue and hoping the latency is low.
A master clock implements a COM IReferenceClock interface (described in the Microsoft Windows SDK
documentation). All of the devices on the system use this reference time.
Microsoft's wave sink implementation builds a thread that wakes up every 20 milliseconds. The thread's job is to
create another buffer and hand it to DirectSound. To create that buffer, it calls into the synthesizer and asks it to
render a specified amount of music data. The amount it asks for is determined by the actual time the thread wakes
up, which is unlikely to be exactly 20 milliseconds.
What is actually passed into the synthesizer is simply a pointer to the location in memory at which to start writing
data into the PCM buffer, and a length parameter that specifies how much data to write. The synth can then write
PCM data into this buffer and fill it in up to the specified amount. That is, it renders from the start address until it
reaches the specified length. That block of memory can be a DirectSoundBuffer (which is the default case), but it
could also be a DirectShow graph or some other target defined by the wave sink.
The PCM buffer is conceptually cyclical (that is, it is constantly looping). The synthesizer renders the 16-bit numbers
that describe the sound into successive slices of the buffer. The slice size is slightly different every time the thread
awakens, because the sink cannot wake up exactly every 20 milliseconds. So every time the thread does wake up, it
plays catch up to determine how far it should progress through the buffer before going back to sleep.
From the application's perspective, the synth port driver itself has a IDirectMusicSynth::GetLatencyClock
function that gets the clock from the wave sink. So there are two clocks:
The master clock that everyone, including the wave sink, listens to.
The latency clock that is implemented by the wave sink, which is seen by the application as a DirectMusic
port providing the latency clock.
In other words, the application asks for the latency clock, but sees the clock as coming from the DirectMusic port
abstraction rather than from the wave sink.
The time returned by this latency clock is the earliest time that the buffer can be rendered to, because the synth has
already rendered up to that point in the buffer. If the synth had rendered a smaller buffer on its last write, the
latency would also be smaller.
Therefore, the wave sink calls IDirectMusicSynth::Render on the synth, presenting the buffer and requesting that
it be filled with rendered data. As shown in the following figure, the synth takes all the time-stamped events that
come in as a result of IDirectMusicSynth::PlayBuffer function calls.
Each input buffer contains time-stamped messages. Each of these messages is put in a queue to be rendered into a
buffer at the time specified by its time stamp.
One of the important things about this model is that there is no particular order other than the time stamp. These
events are streamed in, so they can be added into the queue at any time before rendering. Everything is event-
based with regard to time. For example, if the reference time is currently at 400 time units, then everything time-
stamped to happen at time 400 is happening now. Events time-stamped to happen 10 units from now will happen
at time 410.
Clock Synchronization
6/25/2019 • 3 minutes to read • Edit Online

A critical task for the wave sink to do is to resolve time drift between the reference-clock and sample-clock crystals.
It does this with the software equivalent of a phase-locked loop.
The wave sink keeps track of what sample number in the buffer it can write to next. So even though it knows that it
is on, for example, sample 20, the wave sink still needs to check the master clock to get a reference time. It has a
thread that wakes up approximately every 20 milliseconds and asks the master clock for the current time. The
master clock might report back that the current time (in milliseconds) is 420, for example.
The wave sink also maintains a latency clock, which shows the offset between the current time according to the
master clock and the sample time. It uses this information to calculate the expected master clock time and
compares this with the actual master clock reading to see if the two clocks have drifted apart.
The wave sink uses a phase-locked loop to adjust the sample time. When checking for drift, the wave sink does not
adjust by the whole amount, because the readings contain some jitter. Instead, it moves the sample clock by some
fraction of the distance toward the master clock. In this way, the wave sink smoothes out jitter errors while staying
roughly in sync. It also takes this time and converts it to a latency clock time that is relative to the master clock. This
is important because the application might need to know where the synthesizer is rendering at any point.
The latency clock tells the application the earliest time at which a new note can be scheduled to play. The latency
clock time is the master clock time plus an offset that represents the synthesizer's latency. This latency represents
the minimum delay from the time that the application submits a new note to be played to the time that the
synthesizer actually plays the note. At any instant, the application can schedule a note to be played at or later than--
but no earlier than--the current latency clock time.
For example, if the master clock is currently at time 420 and the application has a note that it wants to play as soon
as possible, the latency clock tells it the earliest time that the note can be played. If the software synthesizer has a
latency of 100 milliseconds, the next time it can play a note is at time 520.
Suppose an event is marked to play at time 520 in reference time. The synthesizer does its work by rendering notes
down into samples and performing all its calculations in sample time. Therefore, it needs to know what a reference
time of 520 converts to in sample time. In user mode, the wave sink provides two functions that the synth uses:
IDirectMusicSynthSink ::SampleToRefTime
IDirectMusicSynthSink ::RefTimeToSample
To do the conversion in this case, the synth calls IDirectMusicSynthSink ::RefTimeToSample on the wave sink.
The wave sink then gives back a sample time (for example, 600). The note in question gets rendered at sample time
600. Then, when the synth IDirectMusicSynth::Render method gets called by the wave sink to render the next
portion of the stream (for example, from sample time 600 to 800), the note is rendered into the buffer at sample
time 600.
Note The sample time is kept as a 64-bit number to avoid rollover. (A DWORD value rolls over in 27 hours.)
To summarize, the synth does all its internal math in sample time and the wave sink does the conversion to sample
time from reference time and vice versa. The wave sink also manages synchronization with the master clock and
provides latency information. Hiding this functionality in the wave sink makes writing the synth easier.
DLS Download Support
6/25/2019 • 2 minutes to read • Edit Online

If you are writing your own synthesizer, you also have to provide support for downloadable sounds (DLS) so that
the application can convert MIDI note messages to particular instrument sounds. Specifically, you should
implement your IDirectMusicSynth::Download method so that it can download instrument wave and
articulation data to the synthesizer. This method should accept raw data (typically from a collection file) and store it
in a form that can be used by your rendering engine.
When DirectMusic downloads DLS data to the driver, the format of the data buffer is defined in terms of several
DirectMusic structures. The downloaded data begins with two structures:
DMUS_DOWNLOADINFO
A fixed-size header describing the information that is being downloaded.
DMUS_OFFSETTABLE
An offset table that follows the header and describes the offsets of the various chunks of information within the
downloaded data.
Following the offset table is the actual data, which can begin with either of the following:
DMUS_INSTRUMENT
A structure describing a DLS instrument.
DMUS_WAVEDATA
A structure containing a chunk of wave data in PCM format.
For more information about these data structures and the data formats that are used to download instrument and
wave data, see the discussion of DirectMusic low-level DLS in the Microsoft Windows SDK documentation.
The DLS data format is identical in kernel and user modes.
The KSPROPSETID_Synth_Dls property set contains properties that are used to download DLS samples and
instruments to a DirectMusic synthesizer. This property set can be used to download both DLS Level 1 and DLS
Level 2 data. Only the format of the downloaded data changes between DLS Levels 1 and 2.
Registering Your Synthesizer
6/25/2019 • 2 minutes to read • Edit Online

After your software synthesizer is created, it must be added to the system registry so that it is available to
applications as a DirectMusic port that can be enumerated. When the installation program calls your DLL's
DllRegisterSer ver COM function to tell the DLL to register itself as a COM object, the function can register the
synthesizer as well. To do so, the function adds an entry to the list of available software synthesizers by creating a
key in the following path:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectMusic\SoftwareSynths

Header file dmusicc.hdefines constant REGSTR_PATH_SOFTWARESYNTHS to represent this path.


The key is named with the class identifier of the synthesizer COM object. Within the key is a string field called
"Description" with the name of the synthesizer.
The following example code shows a function, RegisterSynth , that can be called from DllRegisterSer ver to
register the synthesizer:
const char cszSynthRegRoot[] = REGSTR_PATH_SOFTWARESYNTHS "\\";
const char cszDescriptionKey[] = "Description";
const int CLSID_STRING_SIZE = 39;
HRESULT CLSIDToStr(const CLSID &clsid, char *szStr, int cbStr);

HRESULT RegisterSynth(REFGUID guid,


const char szDescription[])
{
HKEY hk;
char szCLSID[CLSID_STRING_SIZE];
char szRegKey[256];

HRESULT hr = CLSIDToStr(guid, szCLSID, sizeof(szCLSID));


if (!SUCCEEDED(hr))
{
return hr;
}

strcpy(szRegKey, cszSynthRegRoot);
strcat(szRegKey, szCLSID);

if (RegCreateKey(HKEY_LOCAL_MACHINE,
szRegKey,
&hk))
{
return E_FAIL;
}

hr = S_OK;
if (RegSetValueEx(hk,
cszDescriptionKey,
0L,
REG_SZ,
(const unsigned char *)szDescription,
strlen(szDescription) + 1))
{
hr = E_FAIL;
}

RegCloseKey(hk);
return hr;
}

CLSIDToStr is a locally defined function (not shown in the preceding code example) that converts a CLSID value to
a character string. It is similar to the StringFromCLSID function that is described in the Microsoft Windows SDK
documentation.
Kernel Mode Hardware Acceleration DDI
12/5/2018 • 2 minutes to read • Edit Online

This portion of the design guide contains information necessary to write a kernel-mode DMus miniport driver for
DirectMusic-enabled hardware or a software synthesizer. The features described here are optional and can be
implemented in addition to the base-level MIDI miniport driver, which supports the midiOut and midiIn APIs
under Microsoft Windows 95/98/Me, Windows NT 4.0, Windows 2000, and later.
Implementing kernel-mode components entails making additions to the miniport device driver interface (DDI) that
allow WDM MIDI drivers to support DirectMusic hardware acceleration. A good design strategy is to begin by
implementing a user-mode version of your driver and then converting it to kernel mode (see User Mode Versus
Kernel Mode).
If you have not written a user-mode version before doing your kernel-mode implementation, read the user-mode
sections of this document to become familiar with the concepts, which apply to kernel mode as well. Kernel-mode
discussions build on common concepts that are introduced in the user-mode examples.
The next two sections give a brief background of WDM kernel streaming and an overview of how to implement a
miniport-driver for a synthesizer:
DirectMusic WDM Kernel Streaming Background
Synthesizer Miniport Driver Overview
This section also includes:
DirectMusic Miniport Driver Interface
Voice Allocation
Default Sound Sample Sets
Support for DirectMusic Properties
DirectMusic WDM Kernel Streaming Background
10/23/2019 • 5 minutes to read • Edit Online

This section may be useful for driver writers who are new to DirectMusic and WDM kernel streaming, or to anyone
who wants a brief overview of kernel-mode architecture. Experienced WDM audio driver writers might want to skip
to Synthesizer Miniport Driver Overview. For a more general introduction to kernel streaming, see Kernel
Streaming.
Historically, there were two types of drivers for Windows:
Windows 95-style VxDs
Drivers for the NT-based operating systems
Windows 98/Me contains ntkern.vxd, which has all the NT kernel services and allows most NT drivers to run on
Windows 98/Me. WDM drivers use the NT driver environment for cross-platform compatibility. They also
implement power management and Plug and Play.
WDM kernel streaming architecture had its roots in ActiveMovie (which became DirectShow), where the concept of
filter chains was used for streaming media. Each filter in the chain could be a user-mode filter, a piece of user-mode
code that served as a proxy for a kernel-mode filter, or even a piece of user-mode code that was marshaling a piece
of hardware (see Using AVStream with the Kernel Streaming Proxy Module). This architecture was brought into the
Windows 2000 kernel to create kernel streaming.
The "pin" terminology comes originally from Microsoft DirectAnimation and DirectShow. A pin is now a kernel-
streaming term for a target that can be used to connect one filter with another. For example, when there are two
filters--the first with an "out" pin and the second with an "in" pin--the pins can be connected so that the first filter
can pass a stream of data to the second filter. For more information, see Audio Filter Graphs.
Kernel streaming is now part of WDM and is used by WDM Audio. DirectMusic uses the WDMAud system driver as
a kernel-mode component, passing its information down into kernel-mode in the form of I/O request packets
(IRPs). All the DirectMusic interfaces are strictly WDM.
WDM kernel streaming audio filter chains are usually system-provided, but can also be provided by ISVs and IHVs.
The SysAudio system driver is a component that manages the filter chains. It locates the filters and hooks them
together to construct a filter graph. (SysAudio is not itself a member of the graph.)
You do not need to be a kernel-streaming expert to implement your DMus miniport driver. Microsoft provides a
large set of common code that vendors can leverage to make writing filters for DirectMusic easier. Vendors can
write their miniport drivers to make use of the generic capabilities of the system-supplied DMus port driver. This
approach is similar to the class driver/minidriver model that other Windows driver architectures use (for a
comparison, see WDM Audio Terminology).
WDM Audio has a component called PortCls (see Port Class Adapter Driver and PortCls System Driver), which is
the class driver for several types of audio filters. These audio filters handle PCI wave devices, cyclical DMA wave
devices, and MIDI devices. Instead of referring to the driver components as filters and mini-filters or as drivers and
minidrivers, we refer to them as port and miniport drivers. PortCls contains a MIDI port driver, for example.
For each port driver, there can be different kinds of miniport drivers that do device-specific operations. For
example, in Windows 98, there is one MIDI port driver and different miniport drivers can be connected to it, such
as the MPU-401 device and FM synthesizer device. The port driver sequences MIDI data in the same way
regardless of whether it is going to an FM or MPU device. The miniport driver handles the specifics of actually
playing the MIDI data.
Because the sequencer is in the MIDI port driver itself, it holds the time-stamped data until it is due, then plays it
through the appropriate miniport driver. For example, the MPU-401 miniport driver sends wave data to the device
via the external synthesizer module. The miniport driver's output is managed by the port driver's wave sink.
The miniport driver stores up MIDI notes and when the wave sink, which is part of the MIDI port driver, asks for the
next block of audio data, the miniport driver renders the requested amount of wave data into the specified
memory location. For more information about this process, see DirectMusic Miniport Driver Interface.
Microsoft provides standard miniport driver functionality for all MPUs. Because the MPU specification defines
exactly what the hardware should do and how it responds, Microsoft provides a miniport driver to handle MPUs as
part of PortCls. All sound cards that have MPUs can use this same miniport driver.
The built-in miniport drivers in PortCls only attached to the MIDI port driver, so DirectMusic introduced the DMus
port driver to attach to a DMus miniport driver. The DMus port driver handles MIDI sequencing and other functions
for DirectMusic and manages MIDI, wave, and downloadable sounds (DLS) data. The sample MPU-401 adapter
driver in the Windows Driver Kit (WDK) uses the DMus port driver and one of the DMus miniport drivers that are
built into PortCls.
If all you need is MPU-401 functionality, use the built-in mpu401.sys miniport driver, which ships with the WDK.
Just bind it to the DMus port driver and set an IRQ. Previously, this driver referenced the built-in interfaces that
were identified by the IID_IPor tMidi (the MIDI port driver in PortCls) and IID_IMinipor tDriverUar t (the MPU-
401 miniport driver that is built into PortCls) class GUIDs (see PcNewPor t and PcNewMinipor t ). Now, the
mpu401.sys driver references the CLSID_Por tDMus and CLSID_Minipor tDriverDMusUART GUIDs so that it
can support DirectMusic.
When the DMus port driver receives MIDI data, it routes the data to the sequencer, which sorts each note on the
basis of its time stamp. When the note is due, the sequencer passes it down to the miniport driver. The miniport
driver implementation can specify how far in advance it wants to prefetch these notes.
When the DMus port driver receives a property-request containing DLS data (see
KSPROPERTY_SYNTH_DLS_DOWNLOAD ), it routes the request directly to the miniport driver. Because these
are just sounds that can be played, there is no need to involve the sequencer or wave sink when they are
downloaded.
Synthesizer Miniport Driver Overview
10/23/2019 • 2 minutes to read • Edit Online

Both a synth and a sink are necessary for DirectMusic support. Default implementations of each are provided with
DirectMusic. The user-mode Microsoft Software Synthesizer is provided as the default synth and DirectSound is
the default wave sink. These provide full hardware emulation, but further performance enhancements can typically
be achieved with kernel-mode software or hardware implementations.
If you are implementing support for hardware, the only choice is to write a kernel-mode driver. In kernel mode, the
wave sink is provided by the DMus port driver in PortCls and should not need to be replaced for custom
implementations (as is sometimes done in user mode).
For kernel-mode DirectMusic drivers, the most important header file is dmusicks.h. It contains the main kernel-
mode interfaces you need to implement your miniport driver. These interfaces are:
IMiniportDMus
ISynthSinkDMus
IMXF
IAllocatorMXF
IMasterClock
IPortDMus
The last three of these interfaces are implemented in PortCls.sys.
Two other header files that are of interest are dmusprop.h, which contains DirectMusic property items, and
dmusbuff.h, which contains the main IRP structure, DMUS_EVENTHEADER.
The following diagram shows the relationship between the IHV adapter driver and the rest of the DirectMusic
system.

At the topmost level, the driver is exposed via a DirectMusic port driver (an IDirectMusicPor t interface instance).
This is how an application talks to DirectMusic. This port driver communicates downward to a pin instance via
standard kernel streaming calls through the DeviceIoControl function (described in the Microsoft Windows SDK
documentation).
Note that the term "port" has two conflicting meanings in the figure above. Avoid confusing the usage of the term
port by the DirectMusic API, in user mode above, with the kernel-mode DMus port driver. The terms have similar
but slightly different meanings in the two contexts. In particular, note that the IDirectMusicPor t interface at the
top of the figure presents an abstraction of a single pin instance that the DMus port driver implements in the
lower half of the figure.
Each miniport driver object is connected to a matching port driver object. The port driver object provides basic
services to the miniport driver. Each pin instance that maps to one open instance of the device has services such as
format conversion, sequencing, and "thruing" (for a discussion of thruing, see the description of the
IDirectMusicThru interface in the Windows SDK documentation). Pins can be targets or sources, and can support
multiple data formats and ranges. Each pin instance specifies target or source, and specifies which data format and
range is supported.
The miniport driver object is created by the IHV's adapter driver. While there is one pin instance and sequencer per
open instance of the driver, there is only one port-miniport driver pair per piece of hardware (or loaded kernel
software synthesizer). Communication with the miniport driver is through a stream of events that is passed down
to the miniport driver and by property items that are supported by the miniport driver.
The section DirectMusic Miniport Driver Interface presents the details of a DirectMusic miniport driver
implementation.
DirectMusic Miniport Driver Interface
10/23/2019 • 2 minutes to read • Edit Online

The DMus miniport driver interface is based on the MIDI miniport driver interface, but it adds the following
extensions to support advanced synthesizers:
DLS downloads greater than 16 channels per instance
Sequencing of note events in hardware
The DMus miniport driver interface differs from the MIDI miniport driver interface in several ways. A DMus
miniport driver implements the interface IMiniportDMus as opposed to IMiniportMidi. This interface is similar to
IMinipor tMidi , but the IMinipor tDMus::NewStream method creates an IMXF (MIDI transform filter) interface
and connects to an IAllocatorMXF interface in the DMus port driver, as opposed to implementing an
IMiniportMidiStream interface. IAllocatorMXF and IMXF wrap the standard GetMessage and PutMessage calls
(see IAllocatorMXF::GetMessage and IMXF::PutMessage ). These calls deal with packaged events rather than
with raw MIDI bytes.
The DMus miniport driver for a synthesizer can implement some or all of the DirectMusic properties. These
properties allow the system to manage DLS downloads and channel allocations for the device. The dmusprop.h
header file defines DirectMusic-specific property items. For a list of these properties, see KSPROPSETID_Synth and
KSPROPSETID_Synth_Dls.
DMus miniport drivers are expected to allow the creation of multiple pin instances. Each pin instance acts as one
virtual synthesizer and contains a set of channels and DLS downloads independent of the other pin instances.
Some of the synth properties described in Audio Drivers Property Sets act on a pin instance, and others are global.
To process the global properties, the synthesizer must have a synthesizer node in its topology. The description of
each property item indicates whether that item is sent to the synthesizer node or to a pin instance. For each piece
of hardware supporting synthesis, there exists a port driver object and a miniport driver object, as shown in the
following figure.

The port driver object exposes one instance of an IPortDMus interface, which is held by the miniport driver object.
The miniport driver exports one instance of an IMinipor tDMus interface, which is held by the port driver. For
every instantiated pin, the port driver requests a matching IMXF interface. Communication between the system
and this instance is the combination of property requests addressed to the pin and events flowing to or from the
IMXF stream interface.
Two objects must be passed to the miniport driver when it is created:
Clock
Allocator object
The clock is very important for render and capture operations. The miniport driver needs to render notes at their
specified times; when the miniport driver reads in MIDI data, it needs to know the time so it can time-stamp the
kernel event. For more information, see Latency Clocks.
The allocator object, which has an IAllocatorMXF interface, is used as a memory pool to recycle memory. All MIDI
messages in the system are allocated from this common pool. The allocator object should be used to create or
destroy the individual messages.
This section includes:
MIDI Transport
Latency Clocks
Miniport Driver Property Item Requests
Making PortDMus the Default DirectMusic Port Driver
Exposing Your Synthesizer as a Legacy Device
MIDI Transport
10/23/2019 • 2 minutes to read • Edit Online

The DMus port driver is involved on the front and back sides of the DMus miniport driver's synthesizer work. The
port driver inputs a MIDI stream that consists of time-stamped MIDI data and routes the stream to the sequencer.
The sequencer removes the time stamps and passes the raw MIDI messages to the miniport driver when their time
stamps are due. (DLS data passes right through the port driver to the miniport driver with no preprocessing.)
When DMus miniport driver's MIDI input stream gets converted to wave data, its output is managed by the wave
sink (also called a "synth sink" or "render sink").
The DMus port driver implements a kernel-streaming filter with an input pin that accepts DirectMusic data from
the DirectMusic user-mode component, dmusic.dll. The port driver also has a wave-output pin that emits the
synthesized audio stream. The wave sink manages this pin and tells the synth where in memory to write its data.
This arrangement insulates the synth from the details of kernel streaming. Your DMus miniport driver needs only
to deal with the details of synthesizing wave data from the input MIDI stream. The port driver sends the wave data
out to the system, and SysAudio's filter graph connects the filters to make everything flow correctly. As shown in
the following diagram, MIDI data comes into the DMus port driver and, after sequencing, is passed to the DMus
miniport driver.

The miniport driver converts the MIDI data to wave format, which is rendered into a buffer that is designated by
another part of the port driver: the wave sink. Then, instead of going out to DirectSound as it does in user mode,
the wave output goes to the audio hardware through the KMixer system driver. DirectSound is really just an API
that exposes KMixer, and DirectSound acceleration consists of the mixer functions being accelerated in hardware
instead of emulated in software by KMixer.
The SysAudio system driver, which builds the audio filter graph, connects the DMus port driver to a piece of
hardware. The wave sink portion of the port driver hands the data out through its wave-out pin, which SysAudio
can connect to the hardware device. It pulls wave data from the DMus miniport driver (without regard to whether it
is a hardware or software synth), and handles all timing issues. Compared to user mode, the miniport driver is
analogous to the synth, whereas the wave sink is just part of the port driver.
If a DMus miniport driver can provide its output back to the host, it exposes a wave pin with a data direction of
KSPIN_DATAFLOW_OUT (see KSPIN ), which SysAudio recognizes and connects to KMixer.
For more information about the wave sink, see A Wave Sink for Kernel-Mode Software Synthesizers.
This section also includes:
IMXF Interfaces
Allocator
IMXF Interfaces
10/23/2019 • 2 minutes to read • Edit Online

All MIDI transport in the DirectMusic port and miniport driver is carried out using the same interface: IMXF.
IMXF is the COM interface for a DirectMusic MIDI transform filter. The miniport driver, the sequencer, and other
entities in the port driver that handle MIDI data use IMXF as their common COM interface. When the miniport
driver implements this interface, it can participate in MIDI transport. IPortDMus, which resides in PortCls, manages
IMXF . The interface from the capture device to capture sink is also an IMXF interface.
MIDI data is transported between user mode and kernel mode in buffers of packed time-stamped data. The kernel
port driver breaks these buffers into individual events (see DMUS_KERNEL_EVENT ). The high-resolution MIDI
sequencer passes these events to the miniport driver when the trigger time occurs.
On the input side, the kernel port driver extracts individual input messages from the miniport driver and builds
packed buffers to pass up to user mode. Accordingly, the data transport model for DirectMusic miniport drivers
consists of IMXF::PutMessage and IAllocatorMXF::GetMessage .
The IMXF interface supports the following methods:
IMXF::ConnectOutput
IMXF::DisconnectOutput
IMXF::PutMessage
IMXF::SetState
The IAllocatorMXF interface extends IMXF by adding the following methods:
IAllocatorMXF::GetMessage
IAllocatorMXF::GetBufferSize
IAllocatorMXF::GetBuffer
IAllocatorMXF::PutBuffer
For more information about the use of these interfaces, see Allocator.
Allocator
10/23/2019 • 2 minutes to read • Edit Online

The interfaces to and from the allocator are IMXF and IAllocatorMXF. These interfaces allow you to reuse
DMUS_KERNEL_EVENT structures without allocating and deallocating memory. IMXF::PutMessage gives a
structure to the allocator and IAllocatorMXF::GetMessage retrieves a freshly zeroed DMUS_KERNEL_EVENT
structure from the allocator for reuse. (The allocator gets created with empty DMUS_KERNEL_EVENT structures in
the pool so that it never starts out empty.) As shown in the following diagram figure, IRPs (in the form of
DMUS_EVENTHEADER structures) come in from dmusic.dll to the unpacker.

The unpacker calls IAllocatorMXF::GetMessage to retrieve an empty DMUS_KERNEL_EVENT structure. The


unpacker retrieves the DMUS_KERNEL_EVENT structures from the IRP, fills in these structures (one per MIDI event),
and passes them down to the sequencer (using its MXF interface). The sequencer reorders them based on their
time stamps and, when they are due, passes them to the miniport driver by calling IMXF::PutMessage . The
miniport driver pulls the MIDI data out of the DMUS_KERNEL_EVENT structures so that it can render it into wave
data. It passes the used DMUS_KERNEL_EVENT structures back to the allocator with another IMXF::PutMessage
call.
The reverse situation happens for capture. MIDI data comes in from the hardware to the miniport driver and the
miniport driver calls IAllocatorMXF::GetMessage to get an empty DMUS_KERNEL_EVENT structure.
DMUS_KERNEL_EVENT structures are filled with time stamps and data and passed to the capture sink via
IMXF::PutMessage . The miniport driver can pass more than one message per structure if it sets the
DMUS_KEF_EVENT_INCOMPLETE flag in the DMUS_KERNEL_EVENT structure. The capture sink in the DMus port
driver parses this raw data stream and emits DMUS_KERNEL_EVENT structures that contain time-stamped MIDI
messages (one per structure).
It is also possible for the miniport driver itself to emit time-stamped messages to the capture sink. In this case, the
driver does not set the DMUS_KEF_EVENT_INCOMPLETE bit in DMUS_KERNEL_EVENT. The capture sink passes the
time-stamped structures directly to the packer, which packages the messages into IRPs and sends them on to
dmusic.dll. DirectMusic capture is only for recording MIDI. For wave recording, use DirectSound capture.
When the packer pulls the data out of a DMUS_KERNEL_EVENT structure, it discards the used
DMUS_KERNEL_EVENT structure into the allocator with IMXF::PutMessage . When the IRP buffer is full, it is
passed up to dmusic.dll. The packer receives empty IRPs from dmusic.dll, fills them, and completes them. More
IRPs keep trickling down so that it always has one to fill.
A Wave Sink for Kernel-Mode Software Synthesizers
10/23/2019 • 3 minutes to read • Edit Online

As explained in Synthesizers and Wave Sinks, the DMus port driver implements the wave sink for a software
synthesizer that operates in kernel mode. The miniport driver for the synthesizer exposes an ISynthSinkDMus
interface to the port driver. The port driver's wave sink uses this interface to read the wave data that is produced
by the synthesizer.
To make use of the DMus port driver's wave sink, a DMus miniport driver should define a DirectMusic filter with
two types of pin:
A DirectMusic input pin or MIDI input pin. This pin is a sink for a render stream containing MIDI messages.
A wave output pin. This pin is a source for a render stream containing PCM samples.
The following figure shows a DirectMusic filter containing a synthesizer node (KSNODETYPE_SYNTHESIZER ).
This filter meets the preceding requirements for a kernel-mode software synthesizer by providing a DirectMusic
input pin and a wave output pin. (In addition, a DMus miniport driver that supports legacy MIDI synthesis can
provide a MIDI input pin.)

On the left side of the figure, a MIDI stream enters the filter through the DirectMusic input pin. This pin has an
IMXF interface that it exposes to the port driver. The port driver obtains this interface by calling the
IMinipor tDMus::NewStream method. The port driver feeds MIDI messages to the pin by calling the
IMXF::PutMessage method.
On the right side of the figure, a wave stream exits the filter through the wave output pin and flows to the port
driver's wave sink. The port driver communicates with the pin through its ISynthSinkDMus interface. The port
driver obtains this interface by first calling IMinipor tDMus::NewStream to obtain a stream object with an IMXF
interface, and then querying the object for its ISynthSinkDMus interface. The wave sink pulls wave data from the
pin by calling the ISynthSinkDMus::Render method.
Although a hardware synthesizer could, in principle, rely on the port driver's wave sink for rendering, the call to
ISynthSinkDMus::Render adds enough latency to the MIDI stream to make it unattractive for many interactive
applications. To reduce stream latency, hardware synthesizers are likely to have internal connections to mixing and
wave-rendering hardware instead of using the port driver's wave sink. This type of synthesizer replaces the wave
output pin on the right side of the preceding figure with a hardwired connection (represented as a bridge pin) to a
hardware mixer.
The ISynthSinkDMus interface provides methods to render wave data through a wave sink, convert from
reference time to sample time and back, and synchronize to the master clock:
ISynthSinkDMus::RefTimeToSample
ISynthSinkDMus::Render
ISynthSinkDMus::SampleToRefTime
ISynthSinkDMus::SyncToMaster
ISynthSinkDMus inherits from the IMXF interface. For more information, see ISynthSinkDMus.
The DMus miniport driver in the preceding figure identifies its DirectMusic input pin and wave output pin as
follows:
To identify its DirectMusic input pin, the miniport driver defines the pin's data range to have a major format
of type KSDATAFORMAT_TYPE_MUSIC and a subformat of type KSDATAFORMAT_SUBTYPE_DIRECTMUSIC.
This combination indicates that the pin accepts a time-stamped MIDI stream. The data range descriptor is a
structure of type KSDATARANGE_MUSIC . (For an example, see DirectMusic Stream Data Range.) The
miniport driver defines the pin's data flow direction to be KSPIN_DATAFLOW_IN. (The
PCPIN_DESCRIPTOR structure's KsPinDescriptor .DataFlow member indicates the data flow direction.)
When calling IMinipor tDMus::NewStream to create the stream object for this pin, the port driver sets the
StreamType parameter to DMUS_STREAM_MIDI_RENDER.
To identify its wave output pin, the miniport driver defines the pin's data range to have a major format of
type KSDATAFORMAT_TYPE_AUDIO and a subformat of type KSDATAFORMAT_SUBTYPE_PCM. This
combination indicates that the pin emits a wave audio stream containing PCM samples. The data range
descriptor is a structure of type KSDATARANGE_AUDIO . (See the example in PCM Stream Data Range.)
The miniport driver defines the pin's data flow direction to be KSPIN_DATAFLOW_OUT. When calling
IMinipor tDMus::NewStream to create the stream object for this pin, the port driver sets the StreamType
parameter to DMUS_STREAM_WAVE_SINK.
In addition, if the driver were to support a MIDI input pin for the synthesizer, its definition would be similar to that
of the DirectMusic input pin, but the pin definition would specify a subformat of type
KSDATAFORMAT_SUBTYPE_MIDI, and the pin would accept a raw MIDI stream rather than a time-stamped MIDI
stream.
Latency Clocks
10/23/2019 • 2 minutes to read • Edit Online

The synthesizer miniport driver model is designed to allow synchronization of audio output between multiple
devices. As such, it contains a more complex timing model than that provided by a pure UART device.
Events are delivered to (and captured from) the miniport driver with an associated time stamp. This time stamp is
relative to a master clock. The master clock is the same clock used by all sequencing in the entire system. Master-
clock time is measured in units of 100-nanosecond ticks.
The miniport driver obtains the current time from the master clock by calling IMasterClock ::GetTime . At pin
creation time, the port driver passes the kernel-mode IMasterClock interface to the miniport driver as one of the
input parameters to the IMinipor tDMus::NewStream method. Currently, the master clock wraps the system
real-time clock. The master clock never changes when there are pins that require it to be in the run state. It is a
constant-rate clock that never pauses.
All rendering devices have some amount of latency between the time they accept an event and the time the event
can be heard. This latency can be constant or variable (as in the case of a software synthesizer, where the latency
depends on the current playback position of the audio buffer). This latency is compensated for by:
Allowing the DMus miniport driver to receive events far enough in advance so that they can be played on
time, despite the latency of the device. Events are sequenced for the miniport driver by a sequencer engine
in the DMus port driver.
At pin-creation time, the port driver queries the miniport driver for a delta time in 100-nanosecond units.
This delta time is how far ahead of each event's presentation time the miniport driver wants to receive the
event. The port driver makes its best effort to deliver events this far ahead. Specifying a very large value for
this delta (specified by SchedulePreFetch parameter of IMinipor tDMus::NewStream ) makes the port
driver pass the events to the miniport driver as soon as they are delivered to the port driver from user
mode.
Informing applications how far ahead to schedule events. Using the maximum latency is not desirable in this
case. Because events cannot be canceled once they are submitted, the closer that events can be submitted to
their presentation time, the more responsively the application and synth can interact. To handle this
requirement, DirectMusic has introduced the concept of a latency clock.
The latency clock provides the nearest time in the future that an event can be scheduled to play and still play
on time. In other words, if the application schedules an event to be played before the current time according
to the latency clock, then the event is played late. Synthesizer miniport drivers provide a latency clock by
responding to the KSPROPERTY_SYNTH_L ATENCYCLOCK property item.
The miniport driver is queried for KSPROPSETID_Synth and KSPROPERTY_SYNTH_LATENCYCLOCK. The
miniport driver's property handler should return a latency clock that specifies, in terms of the master clock,
the next time that data can be rendered on time. For example, if the master clock currently reads 50, and
there are currently 25 units of latency, then the latency clock reads 75. The reason the clock is implemented
in this way is that the latency does not need to be constant, and the returned value is of more use to
applications than just the delta.
Miniport Driver Property Item Requests
6/25/2019 • 2 minutes to read • Edit Online

This section is a brief introduction to DirectMusic property item requests. A complete overview of this and other
kernel-streaming concepts can be found in Kernel Streaming.
DirectMusic miniport drivers must handle audio drivers property sets. A property request comes in two parts. The
first part is the property set that is defined by the KSPROPERTY structure. The second is a data buffer that
contains instance data that is specific to the property item.
The KSPROPERTY structure contains the following:
A predefined GUID specifying the set (such as KSPROPSETID_Synth_Dls).
An item ID specifying the property item within the set (such as
KSPROPERTY_SYNTH_DLS_DOWNLOAD ).
Flags specifying the requested operation.
The Flags member of KSPROPERTY may contain exactly one of the following flags to specify the operation
requested of the miniport driver:
KSPROPERTY_TYPE_GET
To retrieve the given property item's value.
KSPROPERTY_TYPE_SET
To set the given property item's value.
KSPROPERTY_TYPE_BASICSUPPORT
To determine the type of support available for the property set. The data returned in *pvPropertyData is a DWORD
containing one or both of KSPROPERTY_TYPE_GET and KSPROPERTY_TYPE_SET, indicating which operations are
possible.
The second part of the property item request is the instance data, which is a buffer that can be used to pass data to
or from the miniport driver. How this buffer is used is dependent on whether the request is a SET or a GET:
If the request is a KSPROPERTY_TYPE_SET, the instance data is sent to the miniport driver but is not returned
to the requester.
If the request is a KSPROPERTY_TYPE_GET, the instance data is filled out in the miniport driver and returned
to the requester.
A property item request can be directed to a particular node in the miniport driver topology. The miniport driver
topology describes the layout of the driver and the underlying hardware. Within the topology can be nodes where
property items can be sent, whether there are pin instances available at the time of the request.
A pin instance must be created for DirectMusic playback. DirectMusic data is sent to the node of type
KSNODETYPE_DMSYNTH . The following is an example of a miniport driver connection:
Connect stream in to synth:
PCFILTER_NODE Pin 0 (out) -> Node 0 Pin 1 (in)
Connect synth to audio out:
Node 0 Pin 0 (out) -> PCFILTER_NODE Pin 1 (in)
The supported data formats are a data range that specifies what format a pin can receive data in.
The DirectMusic format (STATIC_KSDATAFORMAT_SUBTYPE_DIRECTMUSIC) must be defined in the miniport
driver's topology so that DirectMusic can send its data to the miniport driver. This format is defined by the
DMUS_EVENTHEADER structure (see the Microsoft Windows SDK documentation) in dmusbuff.h. When the
miniport driver specifies that it supports this particular data range, DirectMusic can expose that data range to the
user (through a pin on the port itself).
Making PortDMus the Default DirectMusic Port
Driver
10/23/2019 • 2 minutes to read • Edit Online

To make the DMus port driver the default for all DirectMusic applications, generate a GUID (using uuidgen.exe or
guidgen.exe, which are included in the Microsoft Windows SDK) to uniquely identify your synth. Your
KSPROPERTY_SYNTH_CAPS property handler should copy this GUID into the Guid member of the
SYNTHCAPS structure. Also, modify your driver's INF file to set up the following registry entry:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectMusic\Defaults
String Value: DefaultOutputPort
Exposing Your Synthesizer as a Legacy Device
12/5/2018 • 2 minutes to read • Edit Online

You may want to write a single device driver that exposes your synth hardware as both a DirectMusic device and a
legacy MIDI device (that is, through the Windows Multimedia midiOutXxx API). This technique can be useful in the
following three cases:
1. If the device does not support DLS. Examples include the MPU-401 driver (see the mpu401 sample in the
Windows Driver Kit [WDK]), a device that has only a ROM set, and a fixed-function software synth (for
example, FM).
In this case, the device can expose a legacy MIDI interface as well as a DirectMusic interface. It should expose
only one legacy MIDI pin. It is important to list the pin with the legacy interface first so that WDM Audio
enumerates it as a legacy MIDI device.
2. If the device does support DLS, but powers up in a loaded state. This device has both RAM for DLS and ROM
containing GM/GS/XG wave tables.
In this case, the device can also expose both interfaces. If the two interfaces are mutually exclusive (that is, if
once you download something, the ROM is not visible), then it should be a single pin with two interfaces to
choose from (as opposed to two pins).
3. When the device does support DLS, but powers up "empty" (for example, the DirectMusic software synth)
and thus needs DLS downloads to initialize its wave table.
This initialization is unnecessary if the device does not require DLS downloads (if it has a default sample set
in ROM, for example) or if a DirectMusic pin is opened (the DirectMusic APIs ensure that DLS downloads
occur).
Exposing your DLS device through the legacy APIs requires some extra work. When a legacy pin is opened
on a device that requires DLS instruments, the driver should locate and open a file containing the DLS
collection to be used. The driver should then intercept update and bank changes, retrieve the appropriate
data from the DLS file, and perform the necessary DLS downloads to the device.
This case is problematic because the WDMAud system driver and other clients are not aware that they need
to download a collection. They just start sending MIDI update changes and notes.
Voice Allocation
6/25/2019 • 2 minutes to read • Edit Online

Most adapter drivers that contain a synthesizer miniport driver also contain DirectSound hardware acceleration.
This brings up the question of voice allocation between synthesizer voices and hardware-accelerated DirectSound
buffers.
DirectMusic synths--both hardware and software--should support multiple instances in order to maximize the
number of concurrent clients. A synth writer might be tempted to statically allocate voices to synths, but should
probably consider all available instances of synths as drawing from a common, dynamic voice pool. Each instance
then reports the available number of voices as the total number available in the pool.
When implemented this way, even a hardware synth with a limited number of physical voices can support
numerous synth instances. In real time, the STATS call informs the client of how many voices each instance is
currently using. If the dynamic pool is depleted and a synth instance requires a new voice, then that synth instance
must implement a voice-stealing scheme to free a voice from within that instance.
The following allocation scheme is based on the idea that voices used by a synthesizer are more easily shared than
DirectSound buffers because the driver has control over what data goes in what voice and can make decisions
about voice stealing (outlined in the DLS Level 1 specification).
All of the voices available to the miniport driver (hardware, software, or some combination of hardware and
software) are divided into two pools. The first pool, the free pool, consists of voices that are not committed
anywhere. The second pool, the dynamic pool, consists of voices that are committed to use by synthesizer
instances. These voices may or may not currently be in use by a synthesizer instance. The dynamic pool is sized as
the maximum number of voices requested by any synthesizer instance, subject to the current contents of the free
pool. DirectSound buffers are removed from the free pool upon allocation and returned on deallocation.
The following table contains an example sequence of voice allocations that illustrate the scheme in practice.

M IN IP O RT DRIVER
T IM E REQ UEST F REE P O O L DY N A M IC P O O L A C T IO N

T0 Power Up 64 0 Initialize.

T1 DSound (4) 60 0 Statically allocate


four voices to
DirectSound
buffers.

T2 Synth (32) 28 32 Increase dynamic


pool to 32 voices.

T3 Synth (24) 28 32 No action. There


are already more
than 24 voices in
the dynamic pool.
M IN IP O RT DRIVER
T IM E REQ UEST F REE P O O L DY N A M IC P O O L A C T IO N

T4 DSound (24) 4 32 Statically allocate


24 voices to
DirectSound
buffers.

T5 Synth (48) 0 36 Increase dynamic


pool to 36 voices.
(The method that
creates the port
returns S_FALSE
and sets
DMUS_PORTPAR
AMS.dwVoices =
36.)

T6 DSound (10) 0 36 Fail. No voices in


free pool.

T7 DSound (-5) 5 36 Free five voices.


Note that these
do not go back
into the dynamic
pool, even
though the last
request (at time
T5) was for more
than were
granted.

Note that DirectSound buffers are actually allocated one by one, and are grouped together in the table for the
purpose of readability.
Immediately after a synthesizer pin instance is created, no voices should be allocated based on it. Shortly after
creation, a KSPROPERTY_SYNTH_PORTPARAMETERS property item is received. This property item indicates,
among other things, the number of voices that are to be associated with this instance. This item also gives the
miniport driver the chance to report back the actual new size of the dynamic pool in case all requested voices could
not be allocated.
Default Sound Sample Sets
12/5/2018 • 2 minutes to read • Edit Online

Some synthesizers ship with a default sound set that conforms to General MIDI or some extension thereof. This
sound set is provided for applications that do not support sample downloading or desire a default sound set to use
in conjunction with downloaded samples. There are two possible delivery mechanisms for such a sound set: as a
prepackaged DLS set, or as a ROM set.
In the case of the prepackaged DLS set, management of the set is delegated to DirectMusic. Microsoft provides a
default DLS set based on the Roland GS samples. Manufacturers wishing to use a different default set with their
hardware should contact the DirectMusic group at Microsoft. Sample sets provided in this manner should not set
the capabilities bits indicating hardware support for a sample set; only ROM sets should set these bits.
ROM sets are also managed by the system. In order to preserve maximum sample memory for use by
downloadable samples, the miniport driver should not load the entire ROM set into sample RAM. (This is not an
issue for hardware that can play samples directly out of ROM.) The system provides instrument download requests
for needed updates before the update change itself is delivered. If an instrument download refers to an update in
the ROM sample set, then the dwDLId member of the DMUS_DOWNLOADINFO structure (described in the
Microsoft Windows SDK documentation) contains the tag DOWNLOAD_ID_ROMSET (defined as 0xFFFFFFFF).
Support for DirectMusic Properties
10/23/2019 • 2 minutes to read • Edit Online

A DirectMusic-synthesis miniport driver specifies its hardware capabilities in the form of an array of property
items. Each property item is a PCPROPERTY_ITEM structure that contains the following:
A property set GUID that defines a particular hardware feature that is defined by DirectMusic.
A pointer to a property-handler method that is implemented within the driver.
A set of flags that specify whether the handler can get the property, set the property, and indicate basic
support for the property.
Property Set GUIDs
The following property-set GUIDs are defined by DirectMusic:
GUID_DMUS_PROP_DLS1
GUID_DMUS_PROP_DLS2
GUID_DMUS_PROP_Effects
GUID_DMUS_PROP_GM_Hardware
GUID_DMUS_PROP_GS_Capable
GUID_DMUS_PROP_GS_Hardware
GUID_DMUS_PROP_INSTRUMENT2
GUID_DMUS_PROP_LegacyCaps
GUID_DMUS_PROP_MemorySize
GUID_DMUS_PROP_SampleMemorySize
GUID_DMUS_PROP_SamplePlaybackRate
GUID_DMUS_PROP_SetSynthSink
GUID_DMUS_PROP_SynthSink_DSOUND
GUID_DMUS_PROP_SynthSink_WAVE
GUID_DMUS_PROP_Volume
GUID_DMUS_PROP_WavesReverb
GUID_DMUS_PROP_WriteLatency
GUID_DMUS_PROP_WritePeriod
GUID_DMUS_PROP_XG_Capable
GUID_DMUS_PROP_XG_Hardware
For definitions of the preceding property set GUIDs, see the description of the KSPROPERTY structure in the
DirectX 8.0 Programmer's Reference in the Microsoft Windows SDK. The property set for each of the preceding
GUIDs consists of a single element that is identified by an index of zero.
IKsControl Interface
The IKsControl interface is used to get, set, or query for basic support of properties, events, and methods. This
interface is part of the WDM kernel streaming (KS) architecture, but is also used by DirectMusic to expose
properties of DirectMusic ports. To retrieve this interface, call the IDirectMusicPor t::Quer yInterface method
(described in the Windows SDK documentation) with the riid parameter set to IID_IKsControl .
The IKsControl interface has three methods: KsProper ty , KsEvent , and KsMethod . At present, only KsProper ty
is supported by DirectMusic.
The IKsControl::KsProper ty method gets or sets the value of a property. The manner in which a property item
request is routed to a particular DirectMusic port depends on how the port is implemented:
No properties are supported by ports that represent DirectMusic emulation on top of the Microsoft Win32
handle-based multimedia calls (the midiOut and midiIn APIs). Use the GUID_DMUS_PROP_LegacyCaps
property set GUID to query a port for whether it is implemented with Win32 multimedia calls.
Property item requests to a port that represents a pluggable software synthesizer are handled entirely in
user mode. The topology of this type of port is a synthesizer (represented by an IDirectMusicSynth interface)
that is connected to a sink node (an IDirectMusicSynthSink interface). The property request is given first to
the synthesizer node, and then to the sink node if it is not recognized by the synthesizer.
Driver Support for Legacy Audio Interfaces
12/5/2018 • 2 minutes to read • Edit Online

The WDM audio system provides driver support for application programs that access audio devices through the
legacy Windows multimedia functions. These functions include the following audio-specific APIs:
aux
mixer
midiIn
midiOut
waveIn
waveOut
For information about these APIs, see the Microsoft Windows SDK documentation. For a description of the system
components that provide driver support for legacy audio functions, see WDM Audio Components.
This section discusses features that audio miniport drivers can implement to better support the audio capabilities
that the Windows multimedia functions expose to application programs. These capabilities include wave-stream
capture and rendering, MIDI recording and synthesis, and mixer control. In addition, this section describes several
extensions to the legacy audio-specific APIs that applications can use to retrieve driver-specific information about
audio devices.
This section discusses the following topics:
Kernel Streaming Topology to Audio Mixer API Translation
WDM Audio Extensions to Legacy Windows Multimedia APIs
Kernel Streaming Topology to Audio Mixer API
Translation
10/23/2019 • 3 minutes to read • Edit Online

The mixer API is a set of Windows multimedia functions that are used to retrieve information about audio-mixer
devices. The mixer API classifies audio-mixer lines as source and destination lines. Source lines are inputs into the
audio card (for example, CD, microphone, line-in, and wave). Destination lines are outputs from the card (for
example, speakers, headphones, phone line, and wave in). For a source line to be valid, it should have a unique
path from the source to a destination. A single source line might map to more than one destination, but no more
than a single path can connect a source line to a destination line. For more information about the mixer API, see
the Microsoft Windows SDK documentation.
The WDM driver for an audio adapter exposes a KS-filter topology that represents the data paths through the
hardware and the functions that are available on those paths. The WDMAud system driver (in the Wdmaud.sys
and Wdmaud.drv files) should interpret the KS-filter topology and generate the corresponding source and
destination mixer lines that are exposed through the mixer API. WDMAud also handles the mixer API calls and
translates them into the equivalent property calls on the filter pins and nodes that are managed by the adapter
driver.
The KMixer system driver (Kmixer.sys) and SWMidi system driver (Swmidi.sys) are integral components of the
kernel audio stack. KMixer provides system-wide audio mixing, bit-depth conversion, sample-rate conversion, and
channel-to-speaker configuration (supermix) translation for PCM audio streams. SWMidi provides high-quality
software synthesis of MIDI streams. The system audio driver, SysAudio (Sysaudio.sys; see SysAudio System
Driver), combines the capabilities of KMixer and SWMidi with the installed audio adapter drivers to form
functionally enhanced virtual audio devices.
WDMAud manages the interface between the KS portion and the legacy (see WinMM System Component)
portion of the audio stack. WDMAud translates the pins on the SysAudio-virtualized filters into the legacy mixer
lines that are presented in applications such as SndVol32. The translation from KS topology to mixer lines is
performed as follows:
Source pins (KSPIN_DATAFLOW_OUT) in the KS topology are exposed as destination mixer lines
(MIXERLINE_COMPONENTTYPE_DST_XXX).
Sink pins (KSPIN_DATAFLOW_IN) in the KS topology are exposed as source mixer lines
(MIXERLINE_COMPONENTTYPE_SRC_XXX).
WDMAud walks the KS filter graph beginning at the source pin that lies at the endpoint of the filter graph
and traverses the graph in the direction opposite to data flow until a sink pin is reached.
The properties that are supported on each KS node that is encountered during the traversal are exposed as
controls on the source mixer line.
In the first two items above, the mapping of KS source and sink pins to destination and source mixer lines is
potentially confusing because of the differences in terminology. In KS, a device is wrapped in a filter that has sink
(input) pins and source (output) pins. The terms "sink" and "source" refer not to the filter but rather to the
(typically buffered) connection between two filters:
The upstream filter's source pin is the source of the data stream that enters the connection.
The data stream exits the connection through the downstream filter's sink pin.
In contrast, the mixer-line terminology is device-centric:
A source mixer line is the source of a stream that enters the device.
A destination mixer line is the destination of a stream that exits the device.
Also, the KS terminology is somewhat inconsistent in the stream-flow direction that it assigns to a pin on a KS
filter. The pin descriptor uses a KSPIN_DATAFLOW enumeration value to specify the direction:
A stream that enters the filter through a sink pin has a direction of KSPIN_DATAFLOW_IN.
A stream that exits the filter through a source pin has a direction of KSPIN_DATAFLOW_OUT.
The directions "in" and "out" are clearly filter-centric, whereas the terms "sink" and "source" are connection-centric.
For more information about the topology parsing algorithm used by WDMAud, see WDMAud Topology Parsing.
This section also includes:
Topology Pins
Topology Nodes
SysTray and SndVol32
Exposing Filter Topology
Topology Pins
10/23/2019 • 5 minutes to read • Edit Online

The WDMAud system driver translates topology pins on KS filters into the source and destination mixer lines that
the mixer API exposes to applications. Input (sink) pins become source mixer lines, and output (source) pins
become destination mixer lines.
As described in Pin Factories, a miniport driver provides an array of pin descriptors, each of which is a structure of
type PCPIN_DESCRIPTOR that describes a pin factory belonging to a filter. Each pin descriptor includes the
following information:
Dataflow direction specifier
Indicates whether the data stream enters (KSPIN_DATAFLOW_IN) or exits (KSPIN_DATAFLOW_OUT) the filter
through the pin.
KS pin categor y GUID
Indicates the pin category to which the pin belongs. For example, on an audio playback device, one pin
might accept a wave-formatted digital audio stream, and another pin might generate an analog audio signal
to drive a speaker. The miniport driver identifies these two types of pins as belonging to distinct pin
categories.
Communications type specifier
Indicates the type of IRP communications that the pin supports. A pin that supports IRP communications
can be an IRP sink (KSPIN_COMMUNICATION_SINK), IRP source (KSPIN_COMMUNICATION_SOURCE), or
both (KSPIN_COMMUNICATION_BOTH). A pin that does not support IRP communications can either lie
inside a KS filter graph (KSPIN_COMMUNICATION_NONE) or be a bridge pin at the endpoint of a graph
(KSPIN_COMMUNICATION_BRIDGE).
For more information about bridge pins, see Audio Filter Graphs.
WDMAud converts the information from the miniport driver's pin descriptor into a mixer-line descriptor, which is a
structure of type MIXERLINE that includes the following information:
Mixer-line component type
Indicates whether the mixer line is a source or a destination line, and also indicates the general function of
the mixer line. For example, the component type for a mixer line that transports an analog signal that is
generated from a wave output (rendering) stream to drive a set of headphones is
MIXERLINE_COMPONENTTYPE_DST_HEADPHONES.
Mixer-line target type
Indicates the type of data stream that the mixer line transports. For example, the target type for a wave
output (rendering) stream is MIXERLINE_TARGETTYPE_WAVEOUT, and the target type for a wave input
(capture) stream is MIXERLINE_TARGETTYPE_WAVEIN.
For more information about the MIXERLINE structure, see the Microsoft Windows SDK documentation.
The following two tables show how WDMAud translates input (KSPIN_DATAFLOW_IN) pins to source mixer lines.
The first table shows how the input pin KS pin categor y GUID s map to the associated MIXERLINE target types.
PCPIN_DESCRIPTOR values MIXERLINE values KS pin category GUID Bridge pin? Target type
KSNODETYPE_MICROPHONE
KSNODETYPE_DESKTOP_MICROPHONE
--
MIXERLINE_TARGETTYPE_WAVEIN
KSNODETYPE_LEGACY_AUDIO_CONNECTOR
KSCATEGORY_AUDIO
KSNODETYPE_SPEAKER
--
MIXERLINE_TARGETTYPE_WAVEOUT
KSNODETYPE_CD_PLAYER
--
MIXERLINE_TARGETTYPE_UNDEFINED
KSNODETYPE_SYNTHESIZER
--
MIXERLINE_TARGETTYPE_MIDIOUT
KSNODETYPE_LINE_CONNECTOR
--
MIXERLINE_TARGETTYPE_UNDEFINED
KSNODETYPE_TELEPHONE
KSNODETYPE_PHONE_LINE
KSNODETYPE_DOWN_LINE_PHONE
--
MIXERLINE_TARGETTYPE_UNDEFINED
KSNODETYPE_ANALOG_CONNECTOR
Yes
MIXERLINE_TARGETTYPE_WAVEIN
KSNODETYPE_ANALOG_CONNECTOR
No
MIXERLINE_TARGETTYPE_WAVEOUT
KSNODETYPE_SPDIF_INTERFACE
Yes
MIXERLINE_TARGETTYPE_WAVEIN
KSNODETYPE_SPDIF_INTERFACE
No
MIXERLINE_TARGETTYPE_WAVEOUT
The following table shows how the input pin KS pin categor y GUID s map to the associated MIXERLINE
component types.

P C P IN _DESC RIP TO R VA L UES M IXERL IN E VA L UES

KS pin category GUID Component type

KSNODETYPE_MICROPHONE MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
KSNODETYPE_DESKTOP_MICROPHONE

KSNODETYPE_LEGACY_AUDIO_CONNECTOR MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
KSCATEGORY_AUDIO
KSNODETYPE_SPEAKER

KSNODETYPE_CD_PLAYER MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC

KSNODETYPE_SYNTHESIZER MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER

KSNODETYPE_LINE_CONNECTOR MIXERLINE_COMPONENTTYPE_SRC_LINE

KSNODETYPE_TELEPHONE MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
KSNODETYPE_PHONE_LINE
KSNODETYPE_DOWN_LINE_PHONE

KSNODETYPE_ANALOG_CONNECTOR MIXERLINE_COMPONENTTYPE_SRC_ANALOG

KSNODETYPE_ANALOG_CONNECTOR MIXERLINE_COMPONENTTYPE_SRC_ANALOG

KSNODETYPE_SPDIF_INTERFACE MIXERLINE_COMPONENTTYPE_SRC_DIGITAL

KSNODETYPE_SPDIF_INTERFACE MIXERLINE_COMPONENTTYPE_SRC_DIGITAL

In the preceding tables, the left column specifies the pin category GUID from the pin's PCPIN_DESCRIPTOR
structure, and the right columns specify the corresponding target type and component type for the MIXERLINE
structure.
The entries in the column labeled "Bridge Pin?" indicate whether the pin is a bridge pin. A "Yes" means that the pin
communications type is KSPIN_COMMUNICATION_BRIDGE. A "No" means that the pin communications type is a
KSPIN_COMMUNICATION_Xxx value other than KSPIN_COMMUNICATION_BRIDGE. If WDMAud ignores the pin
communications type when translating the pin parameters to mixer-line parameters, the "Bridge Pin?" entry is a
dash (-).
For all pin categories that do not appear in the preceding tables, WDMAud translates the input pins to source mixer
lines with target types of MIXERLINE_TARGETTYPE_UNDEFINED and component types of
MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED.
The following tables show how WDMAud translates output (KSPIN_DATAFLOW_OUT) pins to destination mixer
lines. The column headings have the same meanings as in the preceding table. The first table shows how the
output pin KS pin categor y GUID s map to the associated MIXERLINE target types.
PCPIN_DESCRIPTOR values MIXERLINE values KS pin category GUID Bridge pin? Target type
KSNODETYPE_SPEAKER
KSNODETYPE_DESKTOP_SPEAKER
KSNODETYPE_ROOM_SPEAKER
KSNODETYPE_COMMUNICATION_SPEAKER
--
MIXERLINE_TARGETTYPE_WAVEOUT
KSCATEGORY_AUDIO
PINNAME_CAPTURE
--
MIXERLINE_TARGETTYPE_WAVEIN
KSNODETYPE_HEADPHONES
KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO
--
MIXERLINE_TARGETTYPE_WAVEOUT
KSNODETYPE_TELEPHONE
KSNODETYPE_PHONE_LINE
KSNODETYPE_DOWN_LINE_PHONE
--
MIXERLINE_TARGETTYPE_UNDEFINED
KSNODETYPE_ANALOG_CONNECTOR
Yes
MIXERLINE_TARGETTYPE_WAVEOUT
KSNODETYPE_ANALOG_CONNECTOR
No
MIXERLINE_TARGETTYPE_WAVEIN
KSNODETYPE_SPDIF_INTERFACE
Yes
MIXERLINE_TARGETTYPE_WAVEOUT
KSNODETYPE_SPDIF_INTERFACE
No
MIXERLINE_TARGETTYPE_WAVEIN
The following table shows how the output pin KS pin categor y GUID s map to the associated MIXERLINE
component types.

P C P IN _DESC RIP TO R VA L UES M IXERL IN E VA L UES

KS pin category GUID Component type

KSNODETYPE_SPEAKER MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
KSNODETYPE_DESKTOP_SPEAKER
KSNODETYPE_ROOM_SPEAKER
KSNODETYPE_COMMUNICATION_SPEAKER

KSCATEGORY_AUDIO MIXERLINE_COMPONENTTYPE_DST_WAVEIN
PINNAME_CAPTURE

KSNODETYPE_HEADPHONES MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO

KSNODETYPE_TELEPHONE MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
KSNODETYPE_PHONE_LINE
KSNODETYPE_DOWN_LINE_PHONE

KSNODETYPE_ANALOG_CONNECTOR MIXERLINE_COMPONENTTYPE_DST_SPEAKERS

KSNODETYPE_ANALOG_CONNECTOR MIXERLINE_COMPONENTTYPE_DST_WAVEIN

KSNODETYPE_SPDIF_INTERFACE MIXERLINE_COMPONENTTYPE_DST_SPEAKERS

KSNODETYPE_SPDIF_INTERFACE MIXERLINE_COMPONENTTYPE_DST_WAVEIN

For all pin categories that do not appear in the preceding tables, WDMAud translates the output pins to destination
mixer lines with target types of MIXERLINE_TARGETTYPE_UNDEFINED and component types of
MIXERLINE_COMPONENTTYPE_DST_UNDEFINED.
In the preceding tables, most of the KS pin category GUIDs have KSNODETYPE_Xxx names. These names are
defined in header files Ksmedia.h and Dmusprop.h. (Two departures from this naming convention are GUIDs
KSCATEGORY_AUDIO and PINNAME_CAPTURE, which are also defined in Ksmedia.h.) As described in Topology
Nodes, KSNODETYPE_Xxx GUIDs can also be used to designate KS node types. Most KSNODETYPE_Xxx GUIDs
specify either pin categories or node types, but not both. The exception is KSNODETYPE_SYNTHESIZER , which
can specify either a pin category or a node type, depending on the context in which is used. For a list of
KSNODETYPE_Xxx GUIDs representing pin categories, see Pin Category Property. For a list of KSNODETYPE_Xxx
GUIDs representing node types, see Audio Topology Nodes.
KSCATEGORY_AUDIO is another dual-usage GUID. It can be used as either a KS pin categor y GUID or a KS filter
categor y GUID , depending on the context. During device installation, an audio driver registers its device interface
under the filter category KSCATEGORY_AUDIO. For more information, see Installing Device Interfaces for an Audio
Adapter.
For a pin category of KSNODETYPE_ANALOG_CONNECTOR or KSNODETYPE_SPDIF_INTERFACE, WDMAud needs
to know whether the pin is a bridge pin to correctly translate the pin to its mixer-line equivalent. For example, an
S/PDIF pin (with pin category KSNODETYPE_SPDIF_INTERFACE) translates to one of the four mixer-line types
shown in the following figure. The translation depends on both the pin's data direction (in or out) and whether it is
a bridge pin (yes or no), which together yield four possible types of mixer line (in+yes, in+no, out+yes, and
out+no). The four mixer-line types shown in the figure represent the bottom pairs of entries from the preceding
tables.

Note that two streams on the right side of the audio device in the figure are in S/PDIF format, and the two streams
on the left are in wave format. The audio device performs the conversion between the two digital formats.
The SndVol32 application is a client of the mixer API. The mixer API converts each pin found in the topology to
either a source or destination mixer line, but the line might not be shown in SndVol32, which recognizes only a
subset of the mixer-line component types that header file Mmsystem.h defines for the mixer API. For more
information about SndVol32, see SysTray and SndVol32.
Topology Nodes
10/23/2019 • 2 minutes to read • Edit Online

Audio applications can access mixer controls through the Microsoft Windows multimedia function
mixerGetLineControls . This function retrieves an array of one or more MIXERCONTROL structures, each of
which describes the state and metrics of a single control node on an audio line. The dwControlType member of
the MIXERCONTROL structure is set to an enumeration value that specifies the type of the control. A number of
mixer-control types have been specified for audio VxDs, but only a subset of these controls is available for WDM
audio drivers.
WDMAud translates some but not all topology nodes into corresponding mixer-line controls. The topology-node
types that are listed in the following table have counterparts that are mixer-line controls.

N O DE T Y P E TO P O LO GY - N O DE T Y P E N A M E M IXER- C O N T RO L T Y P E N A M E

AGC KSNODETYPE_AGC MIXERCONTROL_CONTROLTYPE_O


NOFF

Loudness KSNODETYPE_LOUDNESS MIXERCONTROL_CONTROLTYPE_L


OUDNESS

Mute KSNODETYPE_MUTE MIXERCONTROL_CONTROLTYPE_


MUTE

Tone (multiple) KSNODETYPE_TONE MIXERCONTROL_CONTROLTYPE_O


NOFF (if
KSPROPERTY_AUDIO_BASS_BOOST
is supported)
MIXERCONTROL_CONTROLTYPE_B
ASS (if KSPROPERTY_AUDIO_BASS
is supported)
MIXERCONTROL_CONTROLTYPE_T
REBLE (if
KSPROPERTY_AUDIO_TREBLE is
supported)

Volume KSNODETYPE_VOLUME MIXERCONTROL_CONTROLTYPE_V


OLUME

Peakmeter KSNODETYPE_PEAKMETER MIXERCONTROL_CONTROLTYPE_P


EAKMETER

MUX KSNODETYPE_MUX MIXERCONTROL_CONTROLTYPE_


MUX
N O DE T Y P E TO P O LO GY - N O DE T Y P E N A M E M IXER- C O N T RO L T Y P E N A M E

Stereo wide KSNODETYPE_STEREO_WIDE MIXERCONTROL_CONTROLTYPE_F


ADER

Chorus KSNODETYPE_CHORUS MIXERCONTROL_CONTROLTYPE_F


ADER

Reverb KSNODETYPE_REVERB MIXERCONTROL_CONTROLTYPE_F


ADER

Supermix (multiple) KSNODETYPE_SUPERMIX MIXERCONTROL_CONTROLTYPE_


MUTE (if
KSPROPERTY_AUDIO_MUTE is
supported in the supermix node)
MIXERCONTROL_CONTROLTYPE_V
OLUME (see comments in text)

Topology-node types that are missing from the preceding table are not translated into mixer-line controls, and
mixer-line controls that are missing from the table are not supported by WDM audio drivers.
Note that MIXERCONTROL_CONTROLTYPE_CUSTOM is missing from the table. This means that WDM audio
drivers do not support custom mixer controls.
A tone node supports four properties: bass , treble , mid-frequency , and bass boost . The mid-frequency
property has no mixer-line counterpart, but the other three properties do. For each tone node discovered in the
topology, a query is made for each of the supported properties:
KSPROPERTY_AUDIO_BASS
KSPROPERTY_AUDIO_TREBLE
KSPROPERTY_AUDIO_BASS_BOOST
Each property query that succeeds generates a mixer-line control. Due to naming issues, a single tone node should
support only a single property. If a device supports both bass and treble, for example, it should have two tone
nodes so that the nodes can have different names.
A supermix node supports up to two controls: mute and volume. A supermix node can be used as a mute control
when it satisfies at least one of these two conditions for every entry in the supermix node's capabilities table :
The entry supports the mute property, as specified by the Capabilities .Mute flag.
The entry is fully attenuated (-infinity decibels attenuation) and cannot be turned up, which is specified by
both Capabilities .Minimum and Capabilities .Maximum having the value LONG_MIN (0x80000000).
A supermix node can be used as a volume control when every entry in the supermix capabilities table has a
nonzero range. All other controls are translated one-to-one. When a recognized node is encountered, the mixer-
line driver queries the respective property for that node.
To check for stereo or mono support, the left channel is queried, followed by the right channel, and finally, if both
of these fail, the master channel (-1) is tried. If none of these queries succeeds, no control is generated for that
node. Note that the MUX node is not queried for each channel. Instead, a single query to retrieve the current MUX
selection is performed.
The name of the control is returned as a string when the node is queried for its
KSPROPERTY_TOPOLOGY_NAME property. If a node generates more than one control, all controls share the
same name.
WDMAud Topology Parsing
6/25/2019 • 2 minutes to read • Edit Online

The WDMAud system driver parses destination mixer lines first before parsing the source mixer lines. The order in
which WDMAud parses the destination lines is the reverse of that in which SysAudio discovers the lines. For
example, the higher numbered pins are parsed first. Parsing starts at the immediate parent of the pin and moves in
the upstream direction. Each node is translated according to these rules until the parser detects one of the
following terminating conditions:
The current node being parsed is a SUM node.
The current node is a MUX node.
The current node has multiple parents.
SUM and MUX nodes are the classic terminators of the destination line. A SUM node does not generate any
controls. A MUX node generates a MUX control in the destination line that contains references to each of the source
lines controlled by the MUX.
If multiple parents are discovered, parsing is immediately terminated. The mixer-line driver interprets this condition
as a "virtual sum" that is formed by tying multiple inputs together.
The name of the destination line comes from the name returned from the KSPROPERTY_PIN_NAME property on
that pin.
After all destination line controls have been translated, WDMAud begins translating the source lines. Again, the
order in which WDMAud parses these lines is the reverse of the order in which SysAudio queries them. Also, the
direction in which source lines are parsed is opposite to that in which destination lines are parsed. WDMAud parses
each line starting from the pin and proceeding in the downstream direction until it detects one of the following
terminating conditions:
The parser finds a destination line.
The current node being translated belongs to a destination line.
The current node is a SUM node.
The current node is a MUX node.
When a MUX is encountered during parsing of a source line that belongs to a destination line, it is translated into a
control. However, it is used only as a placeholder to update the line numbers in the MUX stored in the destination
line later. The final line numbers are not yet available at this point, so a placeholder is required.
Both a MUX and a SUM node terminate a source line; therefore, any nodes between a SUM or MUX and another
SUM or MUX are not translated.

Notes
1. The line names in the MUX are derived from the pin name for the line, except when the line feeding into a
MUX is from a SUM or MUX node. In that case, the name of the line is the name of the MUX or SUM node.
When the mixer driver discovers this, it builds a virtual mixer line with the name of the SUM or MUX node
and then translates all the controls between the SUM or MUX and the MUX.
2. A split in the topology is a case where a node has more than a single child. This is useful when a single pin
routes to two separate destinations but shares some common controls, such as volume or a mute. Any time
a split is encountered, the WDMAud driver creates a new line and duplicates all the controls parsed up to the
split. This happens unconditionally whenever a split is encountered, even after encountering a SUM node
that terminates a source line.
SysTray and SndVol32
12/5/2018 • 2 minutes to read • Edit Online

The SndVol32 program (Sndvol32.exe) controls both the volume settings for various sound sources (such as
wave, CD, and synthesizer) and the master volume setting. The SndVol32 program is represented as a speaker
icon that appears in the system-tray notification area the taskbar, which appears in the lower-right corner of the
Windows screen by default.
The SysTray program (Systray.exe) is responsible for displaying the speaker icon when it is turned on and for
hiding the speaker icon when it is turned off. In Windows XP, the speaker icon is hidden by default. In all other
Windows versions, including Windows XP SP1, the speaker icon is visible by default.
In Windows XP, follow these steps to display the speaker icon on the taskbar:
1. In Control Panel, click the Sounds and Audio Devices icon (or simply run mmsys.cpl).
2. On the Volume tab, select the Place volume icon in the taskbar check box.
If your sound card's volume level can be changed under software control, a speaker icon appears on the taskbar.
You can change the master-volume setting by single-clicking on that icon and adjusting the volume slider.
At logon time, SysTray queries the audio driver for a mixer line with a
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS (speaker destination) or
MIXERLINE_COMPONENTTYPE_DST_HEADPHONES (headphone destination) component type to determine
whether the speaker icon should be displayed. If neither of these component types is found, SysTray does not
display the speaker icon. If it does find the line, it queries the line to determine whether it contains a mute control.
SysTray completes its logon-time mixer-line processing by internally storing the line ID and mute control ID for
future reference.
The SndVol32 program also provides a user interface for controlling all volume controls in the system. When a
user double-clicks the speaker icon in the system tray (or simply runs Sndvol32.exe), SndVol32 displays a "Master
Volume" window, which contains sliders for controlling both the master volume level and the volume levels on
the various sound sources. In this case, SndVol32 uses a different algorithm to determine what it displays. For the
master volume slider , it looks for the first volume control on the "master" destination (for example, the
destination that is numbered zero). This is typically the speaker destination.
When SndVol32 runs, it queries the mixer-line driver looking for a set of controls that it knows about. To display a
slider panel, the SOURCE line should have at least one of the following controls:
Volume control
Mute control
Advanced control (AGC, bass, or treble)
If none of these controls is found, SndVol32 does not display the panel. A source line simply being part of a MUX
with no controls is not sufficient for display. This restriction is easily circumvented by inserting a fake MUTE
control into the topology to get the panels to display. When the line simply feeds into a MUX, the Select box
displayed for MUXes hides the MUTE control.
WDM Audio topology nodes that do not map well into a mixer line control are not displayed by SndVol32. Refer
to Topology Nodes for details on which nodes are translated into mixer-line controls. The WDM mixer-line driver
translates some nodes into controls, but SndVol32 displays only the set of controls that it knows about.
For information about the volume ranges and the default volume levels in the various versions of Windows, see
Default Audio Volume Settings.
Exposing Filter Topology
10/23/2019 • 4 minutes to read • Edit Online

A miniport driver describes the internal topology of a KS filter in terms of pins, nodes, and connections. This
topology specifies the data-flow paths through the filter and also defines the logical targets--pins and nodes--for
property requests. The intra-filter topology is a logical representation of the internal structure of the hardware
device that underlies the filter. The miniport driver describes this topology with static arrays of pin, node, and
connection descriptors.
Pins are specified in a static array of PCPIN_DESCRIPTOR structures. Each pin has an ID that is its ordinal
in the array.
Nodes are specified in a static array of PCNODE_DESCRIPTOR structures. Each node has an ID that is its
ordinal in the array.
Connections (pin-to-pin, pin-to-node, or node-to-node) are specified in a static array of
PCCONNECTION_DESCRIPTOR structures.
The miniport driver exposes these three arrays in the PCFILTER_DESCRIPTOR structure that it outputs from its
IMinipor t::GetDescription method.
Example
The following code example specifies the internal topology of a simple KS filter that has one input pin and one
output pin. The filter contains a single node, which is a volume-level control.
#define KSPIN_WAVEOUT_SRC 0
#define KSPIN_SPEAKERS_DST 1

PCPIN_DESCRIPTOR
MiniportPins[] =
{
{ // Pin 0 -- KSPIN_WAVEOUT_SRC
0,0,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersBridge), // DataRangesCount
PinDataRangePointersBridge, // DataRanges
KSPIN_DATAFLOW_IN, // DataFlow
KSPIN_COMMUNICATION_NONE, // Communication
&KSNODETYPE_LEGACY_AUDIO_CONNECTOR, // Category
NULL, // Name
0 // Reserved
}
},
{ // Pin 1 -- KSPIN_SPEAKERS_DST
0,0,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersBridge), // DataRangesCount
PinDataRangePointersBridge, // DataRanges
KSPIN_DATAFLOW_OUT, // DataFlow
KSPIN_COMMUNICATION_NONE, // Communication
&KSNODETYPE_SPEAKER, // Category
&KSAUDFNAME_VOLUME_CONTROL, // Name (This name shows up as the
// playback panel name in SndVol32)
0 // Reserved
}
}
};

#define KSNODE_WAVEOUT_VOLUME 0

PCNODE_DESCRIPTOR TopologyNodes[] =
{
{ // KSNODE_WAVEOUT_VOLUME
0, // Flags
&AutomationVolume, // AutomationTable
&KSNODETYPE_VOLUME, // Type
&KSAUDFNAME_WAVE_VOLUME // Name
}
};

PCCONNECTION_DESCRIPTOR MiniportConnections[] =
{ //FromNode---------------FromPin------------ToNode-----------------ToPin
{ PCFILTER_NODE, KSPIN_WAVEOUT_SRC, KSNODE_WAVEOUT_VOLUME, 1 },
{ KSNODE_WAVEOUT_VOLUME, 0, PCFILTER_NODE, KSPIN_SPEAKERS_DST }
};

The following figure shows the topology of the filter that is described by the preceding sample code.
This filter is a simple example of a topology filter, which an adapter driver forms by binding its IMiniportTopology
object to an IPortTopology object that the PortCls system driver creates. The filter's input (sink) and output (source)
pins are named KSPIN_WAVEOUT_SRC and KSPIN_SPEAKERS_DST. Both pins carry analog signals. The mixer API
exposes the connections to these pins as source and destination mixer lines
(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT and MIXERLINE_COMPONENTTYPE_DST_SPEAKERS),
respectively.
The following table illustrates a potential source of confusion when discussing the mapping of KS pins to mixer
lines.

P IN N A M E M IXER A P I T ERM IN O LO GY K S F ILT ER T ERM IN O LO GY

KSPIN_WAVEOUT_SRC Source mixer line Sink pin

KSPIN_SPEAKERS_DST Destination mixer line Source pin

Note that KSPIN_WAVEOUT_SRC is a source mixer line, and KSPIN_SPEAKERS_DST is a source pin. For more
information, see the discussion of KS and mixer-line terminology in Kernel Streaming Topology to Audio Mixer API
Translation.
Also note that the name "KSPIN_WAVEOUT_SRC" contains "WAVEOUT" not because the pin carries wave-
formatted digital data, but because it carries the analog signal that is generated by a wave filter, which is a filter of
type WaveCyclic or WavePci. The wave filter represents the portion of the audio adapter's hardware that converts a
wave stream into an analog signal. Pin KSPIN_SPEAKERS_DST outputs an analog signal that drives a set of
speakers.
The filter contains a single node, KSNODE_WAVEOUT_VOLUME, which the mixer API represents as a volume
control (MIXERCONTROL_CONTROLTYPE_VOLUME). The KS node type for the volume control is
KSNODETYPE_VOLUME . All nodes of this type support the KSPROPERTY_AUDIO_VOLUMELEVEL property,
which a client of the filter uses to control the volume level.
The volume node has two "logical" pins, which are numbered 0 and 1. The two connections that are specified by
the MiniportConnections array are represented in the figure by dashed arrows that point in the direction of data
flow. Each connection is described by one of the two elements in the array.
The KSPIN_WAVEOUT_SRC and KSPIN_SPEAKERS_DST pins are both bridge pins, which means that they represent
hardwired connections in the adapter. In the preceding sample code, the two pin descriptors in the MiniportPins
array both specify their IRP-flow direction as KSPIN_COMMUNICATION_NONE, which is appropriate because
bridge pins neither send nor receive IRPs. The two pin descriptors also refer to a PinDataRangePointersBridge
array, which is defined as follows:
static KSDATARANGE PinDataRangesBridge[] =
{
{
sizeof(KSDATARANGE),
0, 0, 0,
STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
}
};

static PKSDATARANGE PinDataRangePointersBridge[] =


{
&PinDataRangesBridge[0]
};

The PinDataRangePointersBridge array defines the data range for a bridge pin that carries an analog audio signal.
For more information, see the discussion of bridge pins in Audio Filter Graphs.
For an example of a more complex topology, see Topology Filters.
WDM Audio Extensions to Legacy Windows
Multimedia APIs
6/25/2019 • 2 minutes to read • Edit Online

Recent versions of Windows have extended the audio functions in the Windows multimedia APIs aux, midiIn,
midiOut, mixer, waveIn, and waveOut to output information about the status and capabilities of WDM audio
drivers.
The auxGetDevCaps , midiInGetDevCaps , midiOutGetDevCaps , mixerGetDevCaps , waveInGetDevCaps ,
and waveOutGetDevCaps functions can retrieve driver-specific information that uniquely identifies an audio
device.
The Windows multimedia functions waveInMessage , waveOutMessage , midiInMessage , midiOutMessage ,
and mixerMessage can retrieve the device interface name of a wave, MIDI, or mixer device. In addition, the
waveOutMessage , midiOutMessage , and waveInMessage functions can retrieve the device IDs of the
preferred audio devices for wave I/O, MIDI, and voice communications, respectively.
The following topics are discussed in this section:
Extended Capabilities from a WDM Audio Driver
System-Intercepted Device Messages
Accessing the Preferred Device ID
Preferred Voice-Communications Device ID
Obtaining a Device Interface Name
Music Technology GUIDs
Extended Capabilities from a WDM Audio Driver
10/23/2019 • 4 minutes to read • Edit Online

By handling the KSPROPERTY_GENERAL_COMPONENTID property, an audio filter can provide hardware-


specific information that applications can use to uniquely identify the underlying device. Microsoft Windows XP is
the first version of Windows to support this feature; this feature is not available in earlier versions.
The filter provides the hardware-specific information in the form of a KSCOMPONENTID structure that contains
the following:
Manufacturer GUID
Product GUID
Component GUID
Name GUID
Hardware version number
Hardware revision number
To provide access to this information, a WDM audio driver specifies a property handler for
KSPROPERTY_GENERAL_COMPONENTID in the filter automation table.
An application can access the data from the driver's KSCOMPONENTID structure through the following legacy
Windows multimedia APIs: aux , midiIn , midiOut , mixer , waveIn , and waveOut . A client queries the driver for
this information by calling one of the multimedia functions in the following table and passing in an extended-
capabilities structure as the second argument.

M ULT IM EDIA F UN C T IO N EXT EN DED- C A PA B IL IT IES ST RUC T URE

auxGetDevCaps AUXCAPS2

midiInGetDevCaps MIDIINCAPS2

midiOutGetDevCaps MINIOUTCAPS2

mixerGetDevCaps MIXERCAPS2

waveInGetDevCaps WAVEINCAPS2

waveOutGetDevCaps WAVEOUTCAPS2

After receiving the KSCOMPONENTID structure from the filter's property handler, the WDMAud system driver
(Wdmaud.sys) converts the data from this structure to the XXXCAPS2 format that the xxxGetDevCaps functions use.
After verifying that the capabilities structure passed to the function is large enough to contain the manufacturer,
product, and name GUIDs, the xxxGetDevCaps function copies this information into the extended structure before
returning. (The component GUID from KSCOMPONENTID currently is not used.)
WDMAud concatenates the Version and Revision members from KSCOMPONENTID to form the 16-bit revision
number that the xxxGetDevCaps function copies into the vDriverVersion member of the capabilities structure:
vDriverVersion = (Version << 8) | (Revision & 0xFF)
Microsoft previously required vendors to register manufacturer IDs and product IDs for their audio devices. These
IDs were then released in the header file Mmreg.h.
In Windows XP and later, registered IDs are no longer necessary; they are replaced by the manufacturer and
product GUIDs that are provided through the KSPROPERTY_GENERAL_COMPONENTID property. The GUIDs are
more convenient for vendors to use than registered IDs because GUIDs are inherently unique, are easily generated,
and require no registration.
However, if you have already registered product and manufacturer IDs with Microsoft (and they are in Mmreg.h),
you can use the macros INIT_MMREG_PID and INIT_MMREG_MID in Ksmedia.h to convert your product and
manufacturer IDs into GUIDs. If you use these macros to generate the GUIDs, WDMAud is able to recover the
original product and manufacturer IDs from the GUIDs and copy these IDs into the wPid and wMid members of
the capabilities structure that is filled in by the xxxGetDevCaps call.
Otherwise, if you do not have registered manufacturer and product IDs, simply use the GuidGen utility to generate
the manufacturer and product GUIDs. (GuidGen is included in the Microsoft Windows SDK.) When a driver's GUIDs
are of this type, WDMAud loads default constants MM_UNMAPPED and MM_PID_UNMAPPED into the wMid and
wPid members, respectively, of the capabilities structure that is filled in by the xxxGetDevCaps call.
WDMAud uses the Name GUID in the KSCOMPONENTID structure to look up a "Name" key in the registry. This
key is located under the registry path name HKLM\System\CurrentControlSet\Control\MediaCategories. The
"Name" key for a device has an associated string value that contains the device name. The xxxGetDevCaps function
copies the first 31 characters of this name string into the szPname member of the capabilities structure. For device
names longer than 31 characters, a client application can open the registry key and directly read the entire string. A
driver can populate this registry entry in one of two ways:
The driver can specify the entry in the device's INF file at install time.
The driver can load the entry during execution of its filter-initialization routine.
The name GUID is optional. If the driver sets the Name member in the KSCOMPONENTID to the GUID_NULL value,
WDMAud provides the device's friendly name to the xxxGetDevCaps function, which copies this name into the
szPname member of the capabilities structure.
If the filter exposes no handler for the KSPROPERTY_GENERAL_COMPONENTID property, WDMAud uses default
values in place of the data from the KSCOMPONENTID structure. The default values for the legacy portion of the
capabilities structure are as follows:
wMid = MM_MICROSOFT
wPid = a device class from the following list: MM_MSFT_WDMAUDIO_WAVEOUT
MM_MSFT_WDMAUDIO_WAVEIN MM_MSFT_WDMAUDIO_MIDIOUT MM_MSFT_WDMAUDIO_MIDIIN
MM_MSFT_WDMAUDIO_MIXER MM_MSFT_WDMAUDIO_AUX
vDriverVersion = 0x050a (for Windows XP) or 0x0500 (pre-Windows XP)
On Windows releases earlier than Windows XP, the legacy members of the capabilities structure are always set to
the defaults above. On Windows XP and later, the default values for the extended capabilities are as follows:
NameGuid = GUID_NULL
INIT_MMREG_MID(&ManufacturerGuid , wMid )
INIT_MMREG_PID(&ProductGuid , wPid )
The INIT_MMREG_MID and INIT_MMREG_PID macros above are defined in Ksmedia.h. These macros are used to
convert the manufacturer and product IDs in the wMid and wPid members to GUIDs that are loaded into the
ManufacturerGuid and ProductGuid members.
System-Intercepted Device Messages
6/25/2019 • 2 minutes to read • Edit Online

The following Windows multimedia functions provide a way for callers to pass messages to legacy audio devices:
waveInMessage
waveOutMessage
midiInMessage
midiOutMessage
mixerMessage
auxOutMessage
Some of these device messages are handled directly by the device driver, and some are handled by the system on
behalf of the device.
This section discusses only messages that are intercepted by the system and handled without ever being passed to
the device driver. System-intercepted messages can obtain the preferred device for voice communications or
general audio usage. In addition, system-intercepted messages can provide the following information about a
particular device:
The device interface name
For information about device interface names, see Introduction to Device Interfaces.
The device's Plug and Play devnode number
For information about devnodes, see Device Tree.
Whether the device can be used by a mapper
A mapper selects an appropriate device by mapping an application's requirements to one of the available
devices in the system. For more information about mappers, see the Microsoft Windows SDK
documentation.
For information about other types of device messages, see the Windows SDK documentation.
An XxxMessage function has the following syntax:

DWORD XxxMessage(
<device ID>,
UINT uMsg,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);

The first parameter is a device ID. The auxOutMessage function definition specifies this parameter to be of type
UINT, as expected. However, in the case of waveInMessage , waveOutMessage , midiInMessage ,
midiOutMessage , or mixerMessage , the caller must cast the device ID to handle type HWAVEIN, HWAVEOUT,
HMIDIIN, HMIDIOUT, or HMIXER, respectively. Note that if the caller supplies a valid handle instead of a device ID
for this parameter, the function fails and returns error code MMSYSERR_NOSUPPORT.
The uMsg parameter specifies a message value (for example, DRV_QUERYDEVICEINTERFACE ). For a list of
driver-specific messages, see header file Mmddk.h.
The meaning of parameters dwParam1 and dwParam2 depends on the message. For example, a particular
message might require that dwParam1 be a ULONG value; the caller must cast this value to type DWORD_PTR to
satisfy the function definition.
The function returns MMERR_NOERROR if the call succeeds, or an error status code if it does not.
For more information about the XxxMessage functions, see the Windows SDK documentation.
Header file Mmddk.h defines the following system-intercepted device messages:
DRV_QUERYDEVICEINTERFACE
For more information, see Obtaining a Device Interface Name.
DRV_QUERYDEVICEINTERFACESIZE
For more information, see Obtaining a Device Interface Name .
DRV_QUERYDEVNODE
Queries for a device's devnode number.
DRV_QUERYMAPPABLE
Queries whether a device can be used by a mapper.
DRVM_MAPPER_CONSOLEVOICECOM_GET
For more information, see Preferred Voice-Communications Device ID.
DRVM_MAPPER_PREFERRED_GET
For more information, see Accessing the Preferred Device ID.
Accessing the Preferred Device ID
6/25/2019 • 2 minutes to read • Edit Online

In Windows Me, and Windows 2000 and later, the Windows multimedia functions waveInMessage ,
waveOutMessage , and midiOutMessage can retrieve the device ID of the preferred device. These three
functions get the preferred device IDs for wave input, wave output, and MIDI output, respectively. This information
is useful to application programs that, for example, allow users to select a device to open from a list of two or more
devices. Such an application typically needs to indicate which among the devices in the list is the preferred device.
The preferred device is the device that the user selects through the multimedia control panel, mmsys.cpl. If a
Windows multimedia or DirectSound application does not explicitly specify a device, the preferred device is
selected by default.
To retrieve the device ID of the current preferred audio device, an application calls the xxxMessage function with
the message parameter set to the constant DRVM_MAPPER_PREFERRED_GET .
When calling the waveInMessage , waveOutMessage , or midiOutMessage function with the
DRVM_MAPPER_PREFERRED_GET message, specify the value of the device handle as WAVE_MAPPER (for
waveInMessage or waveOutMessage ) or MIDI_MAPPER (for midiOutMessage ) and cast this value to the
appropriate handle type: HWAVEIN, HWAVEOUT, or HMIDIOUT. The xxxMessage functions accept this value in
place of a valid device handle so that an application can query for the default device ID without first having to open
a device. For more information about the xxxMessage functions, see System-Intercepted Device Messages.
The DRVM_MAPPER_PREFERRED_GET message is intercepted by the mapper for the target device (waveIn,
waveOut, or midiOut). For information about mappers for wave and MIDI devices, see the Microsoft Windows SDK
documentation.
Preferred Voice-Communications Device ID
6/25/2019 • 2 minutes to read • Edit Online

In Windows Me, and Windows 2000 and later, the Windows multimedia functions waveInMessage and
waveOutMessage can retrieve the device ID of the preferred device for voice communications. These two
functions get the preferred voice-communication device IDs for wave input and wave output, respectively. Each
device ID identifies the wave device that is preferred specifically for voice communications, in contrast to the wave
device that is preferred for general wave audio usage. For information about obtaining the device ID of the
preferred device for general wave audio, see Accessing the Preferred Device ID.
Knowing the preferred voice-communications device can be helpful to application programs that, for example,
allow users to select a device to open from a list of two or more devices. Such an application typically needs to
indicate which among the devices in the list is the preferred device.
To retrieve the device ID of the current preferred voice-communications device, an application calls the wave
XxxMessage function with the message parameter set to the constant
DRVM_MAPPER_CONSOLEVOICECOM_GET .
When calling the waveInMessage or waveOutMessage function with the
DRVM_MAPPER_CONSOLEVOICECOM_GET message, specify the value of the device handle as WAVE_MAPPER
and cast this value to the appropriate handle type, HWAVEIN or HWAVEOUT. The wave XxxMessage functions
accept this value in place of a valid device handle so that an application can query for the default device ID without
first having to open a device. For more information about the wave XxxMessage functions, see System-Intercepted
Device Messages.
The DRVM_MAPPER_PREFERRED_GET message is intercepted by the mapper for the target device (waveIn or
waveOut). For information about mappers for wave devices, see the Microsoft Windows SDK documentation.
Obtaining a Device Interface Name
6/25/2019 • 2 minutes to read • Edit Online

In Windows Me, and Windows 2000 and later, the Windows multimedia functions waveInMessage ,
waveOutMessage , midiInMessage , midiOutMessage , and mixerMessage can retrieve the device interface
name of a device. This information is useful to application programs that need to identify the device outside of the
waveIn, waveOut, midiIn, midiOut, or mixer API. Within one of these APIs, a device ID is sufficient.
The Plug and Play manager generates a device interface name to uniquely identify each device that it enumerates.
An application should treat the string containing a device interface name as opaque. For more information about
device interfaces, see Introduction to Device Interfaces.
The header file Mmddk.h defines two message constants for the purpose of obtaining device interface names:
DRV_QUERYDEVICEINTERFACESIZE
DRV_QUERYDEVICEINTERFACE
The first message obtains the size in bytes of the buffer needed to hold the string containing the device interface
name. The second message retrieves the name string in a buffer of the required size.
The system intercepts and handles the DRV_QUERYDEVICEINTERFACESIZE and DRV_QUERYDEVICEINTERFACE
messages without sending the messages to the device driver.
The first parameter to the xxxMessage function is the device ID, which the caller must cast to the appropriate
handle type: HWAVEIN, HWAVEOUT, HMIDIIN, HMIDIOUT, or HMIXER. For more information about the xxxMessage
functions, see System-Intercepted Device Messages.
Music Technology GUIDs
10/23/2019 • 3 minutes to read • Edit Online

A MIDI or DMus miniport driver must specify the range of stream formats that each of its pins is capable of
handling. As described in Pin Factories, the driver specifies this information as an array of one or more data range
descriptors, each of which is a structure of type KSDATARANGE_MUSIC . This structure's Technology member
indicates what type of synthesizer technology the MIDI or DirectMusic device uses. A miniport driver can set the
Technology member to one of the GUID values shown in the following table (left column).

K SDATA RA N GE_M USIC T EC H N O LO GY


GUID M IDIO UTC A P S W T EC H N O LO GY VA L UE M EA N IN G

KSMUSIC_TECHNOLOGY_PORT MOD_MIDIPORT The device is an MPU-401 device.

KSMUSIC_TECHNOLOGY_SYNTH MOD_SYNTH The device is a synthesizer.

KSMUSIC_TECHNOLOGY_SQSYNTH MOD_SQSYNTH The device is a square-wave


synthesizer.

KSMUSIC_TECHNOLOGY_FMSYNTH MOD_FMSYNTH The device is an FM synthesizer.

KSMUSIC_TECHNOLOGY_MAPPER MOD_MAPPER The device is the Microsoft MIDI


mapper.

KSMUSIC_TECHNOLOGY_WAVETAB MOD_WAVETABLE The device is a hardware wavetable


LE synthesizer.

KSMUSIC_TECHNOLOGY_SWSYNTH MOD_SWSYNTH The device is a software synthesizer.

The midiOutGetDevCaps function translates the technology GUID that it receives from the driver to an index that
it writes to the wTechnology member of the MIDIOUTCAPS structure that it outputs to the caller. The preceding
table shows the wTechnology value (center column) corresponding to each technology GUID. For more
information about midiOutGetDevCaps and MIDIOUTCAPS, see the Microsoft Windows SDK documentation.
When enumerating devices, a MIDI application that uses the Windows multimedia midiOut or midiIn API can see
MIDI pins, but not DirectMusic pins. A DirectMusic application can see both MIDI and DirectMusic pins. A MIDI or
DMus miniport driver identifies a MIDI pin by setting the subtype GUID in the pin's data ranges to
KSDATAFORMAT_SUBTYPE_MIDI. A DMus miniport driver identifies a DirectMusic pin by setting the subtype GUID
to KSDATAFORMAT_SUBTYPE_DIRECTMUSIC. For examples of data ranges for MIDI and DirectMusic pins, see MIDI
Stream Data Range and DirectMusic Stream Data Range.
As explained in MIDI and DirectMusic Filters, an adapter driver calls the PcNewMinipor t function to create an
instance of one of the system-supplied miniport drivers in Portcls.sys. The caller specifies one of the driver GUIDs
in the following table to specify which miniport driver to instantiate.
DRIVER GUID T EC H N O LO GY GUID

CLSID_Minipor tDriverDMusUART KSMUSIC_TECHNOLOGY_PORT

CLSID_Minipor tDriverDMusUARTCapture KSMUSIC_TECHNOLOGY_PORT

CLSID_Minipor tDriverFmSynth KSMUSIC_TECHNOLOGY_FMSYNTH

CLSID_Minipor tDriverFmSynthWithVol KSMUSIC_TECHNOLOGY_FMSYNTH

CLSID_Minipor tDriverUar t KSMUSIC_TECHNOLOGY_PORT

The right column of the preceding table indicates the technology GUID that the corresponding miniport driver
specifies in its pins' data ranges. For example, the FmSynth miniport driver assigns the technology GUID
KSMUSIC_TECHNOLOGY_FMSYNTH to its pins.
Some wavetable synthesizer devices expose themselves to applications as MPU-401 devices (with technology
GUID KSMUSIC_TECHNOLOGY_PORT). In the absence of an external synthesizer, they are able to play a raw MIDI
byte stream through the wavetable synthesizer.
However, the midiOut API prefers wavetable synthesizer devices (with technology GUID
KSMUSIC_TECHNOLOGY_WAVETABLE) when selecting the default (preferred) MIDI playback device. It explicitly
avoids selecting an MPU-401 device to be the default device.
To make itself eligible to be the default device, a wavetable device that can play raw MIDI should expose itself as a
wavetable device, not an MPU-401 device. However, if an adapter driver is using the system-supplied MPU-401
miniport driver, DMusUART, to manage its wavetable synthesizer device, that miniport driver statically assigns the
technology GUID KSMUSIC_TECHNOLOGY_PORT to its pins.
By calling the IMusicTechnology::SetTechnology method, an adapter driver can overwrite the technology GUIDs
in a miniport driver's data ranges. In the following code example, an adapter driver changes the technology GUID
in the DMusUART miniport driver's data ranges from its default value, KSMUSIC_TECHNOLOGY_PORT, to the value
KSMUSIC_TECHNOLOGY_WAVETABLE. With this new setting, the MPU-like wavetable device is eligible to be
selected by the midiOut API as the default MIDI device.
// Create the miniport object.
PUNKNOWN miniport;

ntStatus = PcNewMiniport((PMINIPORT*)&miniport, CLSID_MiniportDriverDMusUART);

// Query the miniport driver for the IMusicTechnology interface.


IMusicTechnology* pMusicTechnology;

if (NT_SUCCESS(ntStatus))
{
ntStatus = miniport->QueryInterface(IID_IMusicTechnology, (PVOID*)&pMusicTechnology);
}

// Set the Technology members in the DirectMusic data-range entries


// for all the pins that are exposed by this miniport.
// SetTechnology should be called before initializing the miniport.
if (NT_SUCCESS(ntStatus))
{
ntStatus = pMusicTechnology->SetTechnology(&KSMUSIC_TECHNOLOGY_WAVETABLE);
}

As indicated in the comment in the preceding code example, the adapter driver should call SetTechnology before
calling the port driver's Init method (which, in turn, calls the miniport driver's Init method). The system-
supplied DMusUART and UART miniport drivers both support the IMusicTechnology interface. For other miniport
drivers, support for IMusicTechnology is optional. For more information, see the implementation of the
SetTechnology method in the DMusUART sample audio driver in the Microsoft Windows Driver Kit (WDK).
Audio Devices Troubleshooting
12/20/2019 • 2 minutes to read • Edit Online

This section provides information on troubleshooting device drivers for device driver developers.

Collecting Audio Driver Logs


To collect audio logs follow the steps outlined in this blog entry.
For general information on working with TMF files, see Displaying a Trace Log with a TMF File.

Troubleshooting Topics
USB Audio Not Playing
USB Audio Not Playing (KB 4045958) "Audio services
not responding" error and USB audio device does
not work in Windows 10 version 1703
12/20/2019 • 2 minutes to read • Edit Online

Symptoms
Consider the following scenario:
1. You connect a Universal Serial Bus (USB) audio device, such as an audio adapter or USB digital-to-analog
converter (DAC), to a Windows 10 Version 1703-based computer for the first time.
2. The operating system detects the device and loads the standard USB audio 2.0 driver (usbaudio2.sys).
3. Windows then downloads the device-specific driver from Windows Update.
4. The downloaded device driver replaces the usbaudio2.sys driver.
In this scenario, the device cannot be used, and the computer does not have sound. The speaker icon on the task
bar is marked with an X mark. When you select the icon, you receive the following message:

Audio services not responding. Both the Windows Audio and the Windows Audio End Point Builder services
must be running for audio to work correctly.

Cause
This "audio not playing" problem occurs because the default USB audio 2.0 driver (usbaudio2.sys) uses the WaveRT
port for operation but the device-specific driver does not. However, both drivers use the "wave" reference string
when the device interface is registered. When the device-specific driver replaces the default driver, the device
interface that is created by usbaudio2.sys is still used because the reference strings overlap. Therefore, the
operating system assumes that the new driver also supports the WaveRT port. Because the new driver does not
support the WaveRT port, the system cannot access the driver.

Resolution
To fix this problem, use one of the following methods.
Method 1
Uninstall the device. To do this, follow these steps:
1. Open Device Manager.
2. Right-click (or tap and hold) the name of the device, and then select Uninstall .

Note: In step 2, don't select the Delete the driver software for this device check box.

Method 2
Connect the device to a different USB port. The problem may not occur if the device is connected to a different USB
port.
Method 3
If the device is not yet connected, install the device-specific driver first. You can do this by using the appropriate
installer for the device. Then, connect the device. Windows now selects the device-specific driver instead of the
default USB audio 2.0 driver. This method works in this situation because the problem occurs only if the device-
specific driver replaces the default driver after the device is connected.

See Also
Audio Devices Troubleshooting
Audio Devices DDI Reference
12/5/2018 • 2 minutes to read • Edit Online

This section contains the reference pages for audio drivers that conform to the Windows Driver Model (WDM) and
reference pages for interfaces for audio processing objects.

In this section
Audio Drivers Enumerations
Audio Drivers Property Sets
Audio Drivers Event Sets
Audio Topology Nodes
Audio Drivers Structures
Audio Drivers Interfaces
Bluetooth HFP DDI Reference
High Definition Audio DDI Reference
DRM Functions
Audio Device Messages for MIDI
Legacy Audio Device Messages
Media-Class INF Extensions
Port Class Audio Driver Reference

Additional resources
For general information about developing drivers for audio devices, see Audio Devices Design Guide.
Audio Drivers Enumerations
10/23/2019 • 2 minutes to read • Edit Online

This section describes the enumerations that are used by various audio properties and structures.

Windows 10 and later operating systems


The following enumerations are used in Windows 10 and later operating systems:
TELEPHONY_CALLCONTROLOP . Used by audio driver structures to specify an operation to perform on a phone
call.
TELEPHONY_CALLSTATE . Used by audio driver structures to specify the state of a phone call.
TELEPHONY_CALLTYPE . Used by audio driver structures to specify the type a phone call.
TELEPHONY_PROVIDERCHANGEOP . Used by audio driver structures to specify the type of change operation
requested by the provider.

Windows 8 and later operating systems


The following enumerations are used in Windows 8 and later operating systems:
AUDIO_CURVE_TYPE . Used by audio driver structures to indicate the type of curve algorithm that should be
applied to an audio data stream for volume level control.
EPcMinipor tEngineEvent . Used by the audio engine to provide information related to a glitching error.
PC_EXIT_L ATENCY . Used by the audio port class driver (PortCls) to indicate the maximum delay times for exiting
sleep state and entering the fully functional state.
eEngineFormatType . Used by miniport drivers to indicate the data format type supported by the audio engine.
eChannelTargetType . Used by miniport drivers to indicate the type of node (target) that is in the path of the
audio data stream.

Windows 7 and earlier operating systems


The following enumerations were introduced in Windows 7 and earlier operating systems:
KSPROPERTY_AUDIOENGINE . Used by miniport drivers to specify attributes and setup parameters for the audio
engine.
KSPROPERTY_JACK . Used by miniport drivers to specify the attributes of an audio endpoint jack.
Audio Drivers Property Sets
10/23/2019 • 2 minutes to read • Edit Online

This section describes the audio-specific property sets that are available for audio drivers that use WDM kernel-
streaming services in Microsoft Windows 2000 and later, and in Windows Millennium Edition (Me) and Windows
98.
The reference page for each property contains a table with the following column headings.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

These headings have the following meanings:


Get
Does the target KS object support the KSPROPERTY_TYPE_GET property request? (Specify yes or no.)
Set
Does the target KS object support the KSPROPERTY_TYPE_SET property request? (Specify yes or no.)
Target
The target for the request is the KS object that the property request is sent to. The target for an audio
property is either a filter or a pin. (The property request specifies the target object by its kernel handle.)
Proper ty Descriptor Type
The property descriptor specifies the property and the operation to perform on that property. The descriptor
always begins with a KSPROPERTY structure, but some types of descriptor contain additional information.
For example, the KSNODEPROPERTY structure is a property descriptor that begins with a KSPROPERTY
structure but also includes a node ID.
Proper ty Value Type
A property typically has a value, and the type of this value depends on the property. For example, a property
that can be in one of only two states--on or off--typically has a BOOL value. A property that can assume
integer values from 0 to 0xFFFFFFFF might have a ULONG value. More complex properties might have
values that are arrays or structures.
The preceding property descriptor and property value are the property-specific versions of the instance-
specification and operation-data buffers that are discussed in KS Properties, Events, and Methods.
A property request uses one of the following flags to specify the operation that is to be performed on the property:
KSPROPERTY_TYPE_BASICSUPPORT
KSPROPERTY_TYPE_GET
KSPROPERTY_TYPE_SET
All filter and pin objects support the basic-support operation on their properties. Whether they support the get and
set operations depends on the property. A property that represents an inherent capability of the filter or pin object
is likely to require only a get operation. A property that represents a configurable setting might require only a set
operation, although a get operation might also be useful for reading the current setting. For more information
about using the get, set, and basic-support operations with audio properties, see Audio Endpoints, Properties and
Events.
The following property sets are defined for audio drivers:
KSPROPSETID_AC3
KSPROPSETID_Acoustic_Echo_Cancel
KSPROPSETID_Audio
KSPROPSETID_AudioEngine
KSPROPSETID_AudioGfx
KSPROPSETID_DirectSound3DBuffer
KSPROPSETID_DirectSound3DListener
KSPROPSETID_DrmAudioStream
KSPROPSETID_FMRXTopology
KSPROPSETID_Hrtf3d
KSPROPSETID_Itd3d
KSPROPSETID_Jack
KSPROPSETID_RTAudio
KSPROPSETID_SoundDetector
KSPROPSETID_Synth
KSPROPSETID_SynthClock
KSPROPSETID_Synth_Dls
KSPROPSETID_Sysaudio
KSPROPSETID_Sysaudio_Pin
KSPROPSETID_TelephonyControl
KSPROPSETID_TelephonyTopology
KSPROPSETID_TopologyNode
KSPROPSETID_AC3
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_AC3 property set exposes the AC-3 decoding and encoding capabilities of an audio device driver.
An audio driver that supports the AC-3 format can expose a wide range of properties for controlling the features of
an AC-3 decoder/encoder. In addition, the properties of a stream can be queried to determine characteristics of the
AC-3-encoded audio.
When the audio hardware does not support a particular capability, the driver for that hardware should fail the get-
and set-property calls in order to inform the upper-layer driver that it must find another way to perform the
specified function. For example, the driver for a decoder that does not support dynamic range compression should
fail calls for that capability so that the upper layer will know that it needs to insert a compressor into the stream
following the AC-3 decoder.
For information about AC-3 compression, see the AC-3 specification at the Dolby Laboratories website. The
specification is titled Digital Audio Compression Standard (AC-3).
The property items in this set are specified by KSPROPERTY_AC3 enumeration values.
The KSPROPSETID_AC3 property set contains the following properties:
KSPROPERTY_AC3_ALTERNATE_AUDIO
KSPROPERTY_AC3_BIT_STREAM_MODE
KSPROPERTY_AC3_DIALOGUE_LEVEL
KSPROPERTY_AC3_DOWNMIX
KSPROPERTY_AC3_ERROR_CONCEALMENT
KSPROPERTY_AC3_L ANGUAGE_CODE
KSPROPERTY_AC3_ROOM_TYPE
KSPROPSETID_Acoustic_Echo_Cancel
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_Acoustic_Echo_Cancel property set is used to control and monitor an AEC node
(KSNODETYPE_ACOUSTIC_ECHO_CANCEL ). This property set is supported in Microsoft Windows XP and later.
The properties in this set are optional properties of an AEC node.
The properties in this set are specified as KSPROPERTY_AEC enumeration values.
The KSPROPSETID_Acoustic_Echo_Cancel property set includes the following properties:
KSPROPERTY_AEC_MODE
KSPROPERTY_AEC_NOISE_FILL_ENABLE
KSPROPERTY_AEC_STATUS
KSPROPSETID_Audio
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_Audio property set indicates the range of data and control supported by an audio stream. The
miniport driver should support the KSPROPERTY_AUDIO_LATENCY property. All other properties in this property
set are optional.
In cases where the hardware does not support a capability, the miniport driver should return an error for the get-
and set-property calls so that the upper-layer driver can handle the call. For example, a miniport driver for
hardware that does not support volume control should return an error for the
KSPROPERTY_AUDIO_VOLUMELEVEL calls, thus enabling a driver higher in the stack (such as a kernel mixer)
to set the volume of a stream.
The property items in this set are specified by KSPROPERTY_AUDIO enumeration values.
The following properties are part of the KSPROPSETID_Audio property set:
KSPROPERTY_AUDIO_3D_INTERFACE
KSPROPERTY_AUDIO_AGC
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
KSPROPERTY_AUDIO_BASS
KSPROPERTY_AUDIO_BASS_BOOST
KSPROPERTY_AUDIO_BUFFER_DURATION
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_AUDIO_CHORUS_LEVEL
KSPROPERTY_AUDIO_CHORUS_MODUL ATION_DEPTH
KSPROPERTY_AUDIO_CHORUS_MODUL ATION_RATE
KSPROPERTY_AUDIO_COPY_PROTECTION
KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_DEL AY
KSPROPERTY_AUDIO_DEMUX_DEST
KSPROPERTY_AUDIO_DEV_SPECIFIC
KSPROPERTY_AUDIO_DYNAMIC_RANGE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSPROPERTY_AUDIO_EQ_BANDS
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_FILTER_STATE
KSPROPERTY_AUDIO_L ATENCY
KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION
KSPROPERTY_AUDIO_LOUDNESS
KSPROPERTY_AUDIO_MANUFACTURE_GUID
KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY
KSPROPERTY_AUDIO_MIC_SENSITIVITY
KSPROPERTY_AUDIO_MIC_SNR
KSPROPERTY_AUDIO_MID
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
KSPROPERTY_AUDIO_MIX_LEVEL_TABLE
KSPROPERTY_AUDIO_MUTE
KSPROPERTY_AUDIO_MUX_SOURCE
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_PEAKMETER2
KSPROPERTY_AUDIO_POSITION
KSPROPERTY_AUDIO_POSITIONEX
KSPROPERTY_AUDIO_PREFERRED_STATUS
KSPROPERTY_AUDIO_PRESENTATION_POSITION
KSPROPERTY_AUDIO_PRODUCT_GUID
KSPROPERTY_AUDIO_QUALITY
KSPROPERTY_AUDIO_REVERB_LEVEL
KSPROPERTY_AUDIO_REVERB_TIME
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_STEREO_ENHANCE
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
KSPROPERTY_AUDIO_SURROUND_ENCODE
KSPROPERTY_AUDIO_TREBLE
KSPROPERTY_AUDIO_VOLUMELEVEL
KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_L ASTBUFFER_POSITION
KSPROPERTY_AUDIO_WIDE_MODE
KSPROPERTY_AUDIO_WIDENESS
KSPROPSETID_AudioEffectsDiscovery
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_AudioEffectsDiscover y property set is implemented by audio device drivers that use
Microsoft’s generic proxy audio processing object (APO).
KSPROPSETID_AudioEffectsDiscover y is available with Windows 8.1 and later versions of the Windows
operating system.
The MsApoFxProxy.h header file defines the KSPROPSETID_AudioEffectsDiscover y property set as follows:

#define STATIC_KSPROPSETID_AudioEffectsDiscovery\
0xb217a72, 0x16b8, 0x4a4d, 0xbd, 0xed, 0xf9, 0xd6, 0xbb, 0xed, 0xcd, 0x8f
DEFINE_GUIDSTRUCT("0B217A72-16B8-4A4D-BDED-F9D6BBEDCD8F", KSPROPSETID_AudioEffectsDiscovery);
#define KSPROPSETID_AudioEffectsDiscovery DEFINE_GUIDNAMED(KSPROPSETID_AudioEffectsDiscovery)

The KSPROPSETID_AudioEffectsDiscover y property set contains the following KS property.


KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST
This property name is defined in the KSPROPERTY_AUDIOEFFECTSDISCOVERY enum.
KSPROPSETID_AudioEngine
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_AudioEngine property set contains KS properties that the audio driver can use to provide
more information about the hardware audio engine node.
KSPROPSETID_AudioEngine is available with Windows 8 and later versions of the Windows operating system.
When a hardware solution supports audio offloading, the audio driver for the hardware must expose its
capabilities in a specific manner so that the Windows 8 user-mode audio stack can discover these capabilities and
take advantage of them.
To support the audio offloading architecture provided with Windows 8, the hardware solution must implement a
hardware audio engine. The audio driver for this hardware must then expose the hardware audio engine as an
audio engine kernel streaming (KS) node that is contained within a KS filter. The node type that has been newly
defined for this purpose is KSNODETYPE_AUDIO_ENGINE . The KSPROPERTY_AUDIOENGINE enumeration is
used to represent the new KS properties.
The Ksmedia.h header file defines the KSPROPSETID_AudioEngine property set as follows:

#define STATIC_KSPROPSETID_AudioEngine\
0x3A2F82DCL, 0x886F, 0x4BAA, 0x9E, 0xB4, 0x8, 0x2B, 0x90, 0x25, 0xC5, 0x36
DEFINE_GUIDSTRUCT("3A2F82DC-886F-4BAA-9EB4-082B9025C536", KSPROPSETID_AudioEngine);
#define KSPROPSETID_AudioEngine DEFINE_GUIDNAMED(KSPROPSETID_AudioEngine)

The KSPROPSETID_AudioEngine property set contains the following KS properties.

KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
KSPROPERTY_AUDIOENGINE_DESCRIPTOR
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT
KSPROPERTY_AUDIOENGINE_GFXENABLE
KSPROPERTY_AUDIOENGINE_LFXENABLE
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION
KSPROPERTY_AUDIOENGINE_MIXFORMAT
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL
These property names are defined in the KSPROPERTY_AUDIOENGINE enum.
KSPROPSETID_AudioGfx
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_AudioGfx property set is used to inform GFX filters of the device IDs of the audio devices that are
used for rendering and capture. A device ID is specified in the form of a null-terminated Unicode string (see Device
Identification Strings).
The property items in this set are specified by KSPROPERTY_AUDIOGFX enumeration values.
The following properties are part of the KSPROPSETID_AudioGfx property set:
KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID
KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID
KSPROPSETID_AudioModule
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_AudioModule property set is used by the audio driver to retrieve the list of audio modules.
The Ksmedia.h header file defines the KSPROPSETID_AudioModule property set as follows:

#define STATIC_KSPROPSETID_AudioModule \
0xc034fdb0, 0xff75, 0x47c8, 0xaa, 0x3c, 0xee, 0x46, 0x71, 0x6b, 0x50, 0xc6
DEFINE_GUIDSTRUCT("C034FDB0-FF75-47C8-AA3C-EE46716B50C6", KSPROPSETID_AudioModule);
#define KSPROPSETID_AudioModule DEFINE_GUIDNAMED(KSPROPSETID_AudioModule)

The KSPROPSETID_AudioModule property set contains the following KS properties.


KSPROPERTY_AUDIOMODULE_DESCRIPTORS
KSPROPERTY_AUDIOMODULE_COMMAND
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID
This property name is defined in the KSPROPERTY_AUDIOMODULE enum.
For more information about audio modules, see Implementing Audio Module Discovery.
KSPROPERTY_AUDIOMODULE_COMMAND
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOMODULE_COMMAND property is a command property used to get and set buffers
and instructions on the hardware (pin handle) or software cache (filter handle).
The Set value is provided as part of the command. When the Get is used, it returns the results of this command.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter or Pin KSAUDIOMOD UNDEFINED


ULE_PROPERTY
+ [optional
custom module
arguments]

The property value type is a undefined. The implementer can create a module specific custom command structure.
Return Value
KSPROPERTY_AUDIOMODULE_COMMAND returns audio module command specific information.

Remarks
Support for the KSPROPERTY_AUDIOMODULE_COMMAND property allows Audio Module clients to send
custom commands to query and set parameters on Audio Modules. The property can be sent through the filter or
pin handle and a KSAUDIOMODULE_PROPERTY is passed as the input buffer for the DeviceIoControl call. A
client can optionally send additional information immediately adjacent to the KSAUDIOMODULE_PROPERTY in
the input buffer to send custom commands.
For more information about audio modules, see Implementing Audio Module Discovery.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Version Windows 10, version 1703

See also
KSPROPSETID_AudioModule
KSPROPERTY_AUDIOMODULE_DESCRIPTORS
10/23/2019 • 2 minutes to read • Edit Online

KSPROPERTY_AUDIOMODULE_DESCRIPTORS is used to retrieves the static data descriptor for each audio
module on the endpoint wave filter.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter or Pin KSPROPERTY For filter target, a


KSMULTIPLE_ITE
M followed by an
array of
KSAUDIOMODUL
E_DESCRIPTOR
that describe the
template
modules.
For pin target, a
KSMULTIPLE_ITE
M followed by an
array of
KSAUDIOMODUL
E_DESCRIPTOR
for the
instantiated
modules in that
stream path.

The property value is a structure, followed by zero (0) or more KSAUDIOMODULE_DESCRIPTOR structures.
Return Value
KSPROPERTY_AUDIOMODULE_DESCRIPTORS returns an array of these descriptors is returned in response to
this request.
If the driver support this property but it doesn’t have any audio modules, it returns an ksmultiple_item with zero
element count.
For more information about audio modules, see Implementing Audio Module Discovery.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Version Windows 10, version 1703


See also
KSAUDIOMODULE_DESCRIPTOR
KSPROPSETID_AudioModule
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID retrieves the audio module notification device


identifier GUID.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes No Filter Handle or Pin KSPROPERTY GUID


Handle

The returned property value is a single GUID.


Return Value
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID returns the GUID associated with the audio module
notification device identifier.
The same device GUID value is returned if the filter handle or pin handle is provided as the target.

Remarks
Support for the KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID is required to enable the miniport to signal
notifications and pass information to Audio Module clients. The lifetime of this ID is tied to the lifetime of the audio device
being exposed and active to the Windows Audio stack. The property can be sent through the filter or pin handle and a
KSPROPERTY is passed as the input buffer for the DeviceIoControl call.
For an example of using this KSPROPERTY see the SYSVAD audio driver sample.
For more information about audio modules, see Implementing Audio Module Discovery.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Version Windows 10, version 1703

See also
KSPROPSETID_AudioModule
KSAUDIOMODULE_NOTIFICATION
KSPROPSETID_AudioSignalProcessing
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_AudioSignalProcessing property set is used by the audio driver to retrieve the list of audio
signal processing modes supported by a pin factory.
The Ksmedia.h header file defines the KSPROPSETID_AudioSignalProcessing property set as follows:

#define STATIC_KSPROPSETID_AudioEffectsDiscovery\
0xb217a72, 0x16b8, 0x4a4d, 0xbd, 0xed, 0xf9, 0xd6, 0xbb, 0xed, 0xcd, 0x8f
DEFINE_GUIDSTRUCT("0B217A72-16B8-4A4D-BDED-F9D6BBEDCD8F", KSPROPSETID_AudioEffectsDiscovery);
#define KSPROPSETID_AudioEffectsDiscovery DEFINE_GUIDNAMED(KSPROPSETID_AudioEffectsDiscovery)

The KSPROPSETID_AudioSignalProcessing property set contains the following KS property.


KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
This property name is defined in the KSPROPERTY_AUDIOSIGNALPROCESSING enum.
KSPROPSETID_BtAudio
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_BtAudio property set is used to send Bluetooth audio-specific properties to a Bluetooth audio
kernel streaming (KS) filter or pin.
The KSPROPSETID_BtAudio property set contains the following properties:
KSPROPERTY_ONESHOT_DISCONNECT
KSPROPERTY_ONESHOT_RECONNECT
KSPROPSETID_DirectSound3DBuffer
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_DirectSound3DBuffer property set contains all the device-specific properties that are needed to
implement the IDirectSound3DBuffer interface (see the Microsoft Windows SDK documentation). Using this
property set, the 3D-buffer properties that are specified by the API are passed directly between DirectSound and
the WDM audio driver. This property set is handled by the KSNODETYPE_3D_EFFECTS node, which handles both
the 3D-buffer and 3D-listener properties.
The property items in this set are specified by KSPROPERTY_DIRECTSOUND3DBUFFER enumeration values.
The KSPROPSETID_DirectSound3DBuffer property set contains the following properties:
KSPROPERTY_DIRECTSOUND3DBUFFER_ALL
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME
KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MODE
KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION
KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY
KSPROPSETID_DirectSound3DListener
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_DirectSound3DListener property set contains all the device-specific properties that are needed to
implement the IDirectSound3DListener interface (see the Microsoft Windows SDK documentation). Using this
property set, the 3D-buffer properties that are specified by the API are passed directly between DirectSound and
the WDM audio driver. This property set is handled by the KSNODETYPE_3D_EFFECTS node. This node handles
both the 3D-buffer and 3D-listener properties, so the WDM audio driver should apply any updated listener
properties to other buffers that share the same listener.
The property items in this set are specified by KSPROPERTY_DIRECTSOUND3DLISTENER enumeration values.
The KSPROPSETID_DirectSound3DListener property set contains the following properties:
KSPROPERTY_DIRECTSOUND3DLISTENER_ALL
KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION
KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION
KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION
KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
KSPROPSETID_DrmAudioStream
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_DrmAudioStream property set specifies the DRM content ID and DRM content rights on a KS audio
stream. For background information about DRM content IDs, see Digital Rights Management.
The KSPROPSETID_DrmAudioStream property set contains only a single property item:
KSPROPERTY_DRMAUDIOSTREAM_CONTENTID
KSPROPSETID_FMRXControl
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_FMRXControl property set is used to control whether FM radio reception is enabled.
The KSPROPSETID_FMRXControl property set includes the following properties:
KSPROPERTY_FMRX_STATE
KSPROPERTY_FMRX_STATE
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_FMRX_STATE property specifies whether FM radio is enabled.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY BOOL

The property value is of type BOOL and specifies whether FM radio is enabled.
Return Value
A KSPROPERTY_FMRX_STATE property request returns TRUE if FM radio is enabled and FALSE if FM radio is
disabled.

Remarks
FM radio can be enabled or disabled by setting the KSPROPERTY_FMRX_STATE property on the wave filter. The
FM volume and routing (endpoint selection) is controlled by the KSPROPERTY_FMRX_VOLUME and
KSPROPERTY_FMRX_ENDPOINTID properties on the topology filter. Basic support for the
KSPROPERTY_FMRX_VOLUME property should return the minimum volume, maximum volume, and the
volume ranges.
A new KSNODETYPE_FM_RX topology node endpoint is implemented as any other audio endpoint is in the
system, and it supports all audio endpoint properties. This endpoint also supports jack properties that are defined
under the KSPROPSETID_Jack property set. This endpoint is in the unplugged state at boot. If capturing FM radio is
supported by driver, this endpoint becomes active when FM radio is enabled. Creating a capture pin on the
KSNODETYPE_FM_RX topology node allows audio capture that comes over from FM receiver.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPSETID_FMRXTopology
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_FMRXTopology property set is used to set FM radio properties.


The KSPROPSETID_FMRXTopology property set includes the following properties:
KSPROPERTY_FMRX_ANTENNAENDPOINTID
KSPROPERTY_FMRX_ENDPOINTID
KSPROPERTY_FMRX_VOLUME

Remarks
FM radio can be enabled or disabled by setting the KSPROPERTY_FMRX_STATE property on the wave filter. The
FM volume and routing (endpoint selection) is controlled by the KSPROPERTY_FMRX_VOLUME and
KSPROPERTY_FMRX_ENDPOINTID properties on the topology filter. Basic support for the
KSPROPERTY_FMRX_VOLUME property should return the minimum volume, maximum volume, and the
volume ranges.
A new KSNODETYPE_FM_RX topology node endpoint is implemented as any other audio endpoint is in the
system, and it supports all audio endpoint properties. This endpoint also supports jack properties that are defined
under the KSPROPSETID_Jack property set. This endpoint is in the unplugged state at boot. If capturing FM radio is
supported by driver, this endpoint becomes active when FM radio is enabled. Creating a capture pin on the
KSNODETYPE_FM_RX topology node allows audio capture that comes over from FM receiver.
KSPROPSETID_Hrtf3d
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_Hrtf3d property set is used to configure the 3D head-relative transfer function (HRTF) for a
DirectSound buffer. This set contains optional properties of a 3D node (KSNODETYPE_3D_EFFECTS ) on a
DirectSound pin instance.
Not all 3D nodes support HRTF processing. A client can send a basic-support query for an HRTF property to a 3D
node to determine whether that node is capable of performing HRTF processing. A 3D node that supports the
KSPROPSETID_Hrtf3d property set must support all three of the properties in the set.

The definition of this property set assumes that the HRTF algorithm is implemented with infinite impulse response
(IIR) filters that represent the effects of an audio source at a single position.
Digital filters typically have an initial transient response. When moving a source from one position to the next, the
filter coefficients change and the HRTF algorithm cross-fades the outputs from the filter at the old position to the
filter at the new position. The FilterTransientMuteLength member of the KSDS3D_HRTF_INIT_MSG structure
specifies the number of samples by which to delay the cross fade in order to avoid rendering the new filter's initial
transient. During this time, the output comes from the old filters only. The FilterOverlapBufferLength member
(same structure) specifies the total number of samples over which to mute and cross-fade the filter outputs.
When the source moves from the right half-plane to the left, the filters switch. This switch might cause an audible
pop. The SwapChannels member of the KSDS3D_HRTF_PARAMS_MSG structure tells the HRTF algorithm to
swap the outputs to reverse the location of the source to the other half-plane. The CrossFadeOutput member
(same structure) tells the algorithm to cross-fade the output channels after a transition across azimuth angle zero.
The OutputOverlapBufferLength member of KSDS3D_HRTF_INIT_MSG specifies the number of samples over
which to cross-fade when this transition occurs.
Because of symmetry, only half of the filter coefficients need to be downloaded to the HRTF algorithm when the
azimuth angle is zero. The ZeroAzimuth member of KSDS3D_HRTF_PARAMS_MSG indicates when this condition
occurs.
For information about configuring HTRF processing through the DirectSound API, see the Microsoft Windows SDK
documentation.
The KSPROPSETID_Hrtf3d property set contains the following three members:
KSPROPERTY_HRTF3D_FILTER_FORMAT
KSPROPERTY_HRTF3D_INITIALIZE
KSPROPERTY_HRTF3D_PARAMS
KSPROPSETID_InterleavedAudio
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_InterleavedAudio property set is implemented by audio device drivers that would like to
contain extra information about the interleaving of loopback audio and capture audio in the audio stream.
KSPROPSETID_InterleavedAudio is available with Windows 10 version 19H1 and later versions of Windows.
The ksmedia.h header file defines the KSPROPSETID_InterleavedAudio property set as follows:

#define STATIC_KSPROPSETID_InterleavedAudio\
0xe9ebe550, 0xd619, 0x4c0a, 0x97, 0x6b, 0x70, 0x62, 0x32, 0x2b, 0x30, 0x6
DEFINE_GUIDSTRUCT("E9EBE550-D619-4C0A-976B-7062322B3006", KSPROPSETID_InterleavedAudio);
#define KSPROPSETID_InterleavedAudio DEFINE_GUIDNAMED(KSPROPSETID_InterleavedAudio)

The KSPROPSETID_InterleavedAudio property set contains the following KS property.


KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION
This property name is defined in the KSPROPERTY_INTERLEAVEDAUDIO enum.
KSPROPSETID_Itd3d
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_Itd3d property set is used to configure the interaural time delay (ITD) algorithm used by a 3D
node (KSNODETYPE_3D_EFFECTS ).
The sound reaching a listener's left and right ears from a particular sound source is delayed by different amounts
depending on the source's position. The listener can infer the direction of the sound source from the amount of
differential delay. The ITD algorithm controls the differential delay to simulate a sound source at a particular
location in 3D space.
The ITD algorithm provides an additional sound-positioning cue by controlling the amount by which the sound
reaching each ear is muffled. High-frequency sounds can be muffled to simulate sound sources located behind the
listener's head. For a sound source located near the right ear, for example, the sound reaching the left ear is more
muffled than that reaching the right ear. A muffled sound is produced by combining the original signal from the
sound source in some proportion with a low-pass filtered version of the same signal. Attenuating the original
signal while increasing the contribution from the low-pass filtered version simulates the effect of moving the
simulated sound source further behind the listener's head.
When the position of a sound source changes, the following parameters must be updated:
The amount of delay in the sound reaching each ear.
The amount by which the sound reaching each ear is muffled.
Making instantaneous changes to these parameters can cause clicks and other spurious noises. The ITD algorithm
smoothes transitions in these parameters over a number of samples in order to filter out such noises.
For more information about the parameters used by the ITD algorithm, see KSDS3D_ITD_PARAMS .
This property set contains only a single property:
KSPROPERTY_ITD3D_PARAMS
KSPROPSETID_Jack
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_Jack property set is used to implement a representation of a physical audio jack. The property
set exposes the physical characteristics and usage of the audio jack.
The KSPROPSETID_Jack property set includes the KSPROPERTY_JACK enumeration and the following properties:
KSPROPERTY_JACK_DESCRIPTION
KSPROPERTY_JACK_DESCRIPTION2
KSPROPERTY_JACK_SINK_INFO
KSPROPERTY_JACK_CONTAINERID
KSPROPSETID_RTAudio
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_RTAudio property set specifies the properties of a WaveRT audio device. These properties are
supported in Windows Vista and later Windows operating systems.
In the following property definitions, the property is get-only and the target is a pin:
All properties in this property set support Get property requests from the client, but not Set property
requests.
For all the properties in this set, the target to which a client sends a property request is a pin instance.
(Other KS property sets, on the other hand, support properties on filter instances.)
The KSPROPSETID_RTAudio property set contains the following properties:
KSPROPERTY_RTAUDIO_BUFFER
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_CLOCKREGISTER
KSPROPERTY_RTAUDIO_GETREADPACKET
KSPROPERTY_RTAUDIO_HWL ATENCY
KSPROPERTY_RTAUDIO_PACKETCOUNT
KSPROPERTY_RTAUDIO_POSITIONREGISTER
KSPROPERTY_RTAUDIO_PRESENTATION_POSITION
KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT
KSPROPERTY_RTAUDIO_SETWRITEPACKET
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT
KSPROPSETID_SoundDetector
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_SoundDetector property set contains properties that are used to register a filter for an audio
capture device that also supports a detector. The filter has a KS pin factory that has pin category
KSNODETYPE_AUDIO_KEYWORDDETECTOR . There cannot be more than one pin factory having this KS pin
category in a given KS filter instance.
Property items in this set are specified by KSPROPERTY_SOUNDDETECTOR enumeration values, as defined in
header file ksmedia.h.
The header file defines the KSPROPSETID_SoundDetector property set as follows:

#define STATIC_KSPROPSETID_SoundDetector\
0x113c425e, 0xfd17, 0x4057, 0xb4, 0x22, 0xed, 0x40, 0x74, 0xf1, 0xaf, 0xdf
DEFINE_GUIDSTRUCT("113C425E-FD17-4057-B422-ED4074F1AFDF", KSPROPSETID_SoundDetector);
#define KSPROPSETID_SoundDetector DEFINE_GUIDNAMED(KSPROPSETID_SoundDetector)

The KSPROPSETID_SoundDetector property set contains the following properties:


KSPROPERTY_SOUNDDETECTOR_ARMED
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
KSPROPSETID_SoundDetector2
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_SoundDetector2 property set contains properties that are used to register a filter for an audio
capture device that also supports a detector. The filter has a KS pin factory that has pin category
KSNODETYPE_AUDIO_KEYWORDDETECTOR. There cannot be more than one pin factory having this KS pin
category in a given KS filter instance.
KSPROPSETID_SoundDetector2 is supported in Windows 10 Version 1903 and later. The
KSPROPSETID_SoundDetector2 property set is used to support multiple voice agents. For more information, see
Multiple Voice Assistant. KSPROPSETID_SoundDetector property set is used on systems that support just Cortana.
KSPROPSETID_SoundDetector2 uses the KSSOUNDDETECTORPROPERTY structure, instead of a KSPROPERTY:

typedef struct {
KSPROPERTY Property;
GUID EventId;
} KSSOUNDDETECTORPROPERTY, *PKSSOUNDDETECTORPROPERTY;

All KSPROPSETID_SoundDetector2 properties are called with a KSSOUNDDETECTORPROPERTY data structure.


This data structure contains a KSPROPERTY and the event id for the keyword to be armed, reset, detected, etc.
The header file defines the KSPROPSETID_SoundDetector2 property set as follows:

#define STATIC_KSPROPSETID_SoundDetector2\
0xfe07e322, 0x450c, 0x4bd5, 0x84, 0xca, 0xa9, 0x48, 0x50, 0xe, 0xa6, 0xaa
DEFINE_GUIDSTRUCT("FE07E322-450C-4BD5-84CA-A948500EA6AA", KSPROPSETID_SoundDetector2);

The KSPROPSETID_SoundDetector2 property set contains the following properties:


KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS - This property is set by the operating system to
configure the keywords to be detected.
KSPROPERTY_SOUNDDETECTOR_PATTERNS - The driver’s KS filter supports this read/write property. The
OS sets this property to configure the keywords to be detected.
KSPROPERTY_SOUNDDETECTOR_ARMED - This read/write property is a simply Boolean status indicating
whether the detector is armed. The OS sets this to engage the keyword detector. The OS can clear this to
disengage. The driver automatically clears this when keyword patterns are set and also after a keyword is
detected. (The OS must rearm.)
KSPROPERTY_SOUNDDETECTOR_RESET - Reset the detector to an unarmed state with no pattern set.
KSPROPERTY_SOUNDDETECTOR_STREAMINGSUPPORT - Future use for voice onset detectors only. Fail this
request indicating property not supported or succeed and return true for all other drivers.
At keyword detection time, a PNP notification containing KSNOTIFICATIONID_SoundDetector is sent. NOTE: This is
not a KSEvent, but rather a PNP event which is sent, with a payload, via
IoReportTargetDeviceChangeAsynchronous.
KSPROPSETID_Synth
10/23/2019 • 10 minutes to read • Edit Online

The KSPROPSETID_Synth property set contains properties that are global to the configuration of a synth node
(KSNODETYPE_SYNTHESIZER ).
Property items in this set are specified by KSPROPERTY_SYNTH enumeration values, as defined in header file
Dmusprop.h.

Usage Summary Table


The KSPROPERTY_SYNTH_CAPS property is used by the system to determine the capabilities of a synthesizer.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE SYNTHCAPS


RTY

The property value (operation data) is a structure of type SYNTHCAPS and specifies the synthesizer's capabilities.
These capabilities include:
Amount of sample memory available
Maximum number of channel groups
Maximum number of voices
Maximum number of audio channels
Rendering effects
For more information, see SYNTHCAPS .
Return Value
A KSPROPERTY_SYNTH_CAPS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.
For more information about synthesizer capabilities, see the IDirectMusicPor t::GetCaps method and the
DMUS_PORTCAPS structure in the Microsoft Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_CHANNELGROUPS property is used by the system to set or get the number of active
channel groups on the pin instance. Channel groups are numbered, beginning with zero, on each pin instance.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and specifies how many channel groups the pin supports. If
a pin supports n channel groups, the channel groups on the pin are numbered from 0 to n-1.
Return Value
A KSPROPERTY_SYNTH_CAPS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code. The following table shows some of
the possible failure codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

For more information about channel groups, see the descriptions of the
IDirectMusicPor t::GetNumChannelGroups and IDirectMusicPor t::SetNumChannelGroups methods in the
Microsoft Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_LATENCYCLOCK property is used to query the miniport driver for the stream's current
latency-clock time, which is always greater than the master-clock time.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE ULONGLONG


RTY

The property value (operation data) is of type ULONGLONG and represents the synthesizer's current latency time.
This time is specified relative to the master clock and expressed in 100-nanosecond units.
Return Value
A KSPROPERTY_SYNTH_LATENCYCLOCK property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible failure codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

STATUS_INVALID_DEVICE_REQUEST The operation is invalid for this device.

Latency clocks are typically used to synchronize audio output streams among multiple devices.
A KSPROPERTY_SYNTH_LATENCYCLOCK get-property request should return a latency-clock time that equals the
current master-clock time, plus the minimum guaranteed latency of the audio filter that the stream passes through.
An application program that schedules audio data to be played earlier than the current latency-clock time risks
having the data played late.
For more information about latency clocks, see the following:
The discussion of the KSPROPERTY_SYNTH_LATENCYCLOCK property in Latency Clocks.
The descriptions of the IDirectMusicPor t::GetLatencyClock and IReferenceClock ::GetTime methods in
the Microsoft Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_PORTPARAMETERS property is used to get the configuration parameters for a
DirectMusic port, which is a DirectMusic term for a device that sends or receives music data. (In KS terminology,
DirectMusic port does not correspond to a DMus port driver. It corresponds to a render or capture pin on a
DirectMusic filter.)

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE SYNTH_PORTPA


RTY + RAMS
SYNTH_PORTPA
RAMS

The property descriptor (instance data) consists of a KSNODEPROPERTY structure that is immediately followed by
a SYNTH_PORTPARAMS structure. Before sending the property request, the client specifies its requested parameter
values by writing them into the SYNTH_PORTPARAMS structure.
The property value (operation data) is also of type SYNTH_PORTPARAMS. The miniport driver loads this structure
with the parameter values that it actually uses to configure the port.
Return Value
If the miniport driver succeeds in configuring the DirectMusic port exactly as specified by the caller, it returns the
STATUS_SUCCESS code. Otherwise, it returns an appropriate error code. The following table indicates some of the
possible error status codes.

STAT US C O DE M EA N IN G

STATUS_NOT_ALL_ASSIGNED The operation succeeded, but the miniport driver had to


modify one or more of the parameter values that the
caller marked as valid in the property value.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

This is the most complicated of the DirectMusic property items to handle. Although this property supports only the
get request, the get request also sets the port parameters. The port passes a SYNTH_PORTPARAMS structure as the
property descriptor for the property request. A property-value buffer accompanies the property request, but
because this is a get request, the buffer is only used to retrieve information from the miniport driver.
The miniport driver should first copy the SYNTH_PORTPARAMS structure from the property descriptor to the
property-value buffer. Next, it should check to see if it is capable of supporting all the parameter values that the
caller has requested (marked as valid). If the miniport driver is unable to support one or more of the requested
parameter values, it should overwrite (in the SYNTH_PORTPARAMS structure in the property-value buffer) the
requested values for these particular parameters with the values that it can support.
If the miniport driver makes no changes to the caller's SYNTH_PORTPARAMS, the caller should get back a property
value that exactly matches the parameters in the property descriptor that the caller originally sent down to the
miniport driver.
By convention, the driver also fills in values for parameters that do not have corresponding bits set in the
dwValidParams member of SYNTH_PORTPARAMS. This allows the caller to see what default values the miniport
driver used for these parameters. The miniport driver outputs the actual parameter values that it used to build the
wave-interface device.
The miniport driver's KSPROPERTY_SYNTH_PORTPARAMETERS handler should be prepared to correctly handle
requests for sample-rate changes.

Usage Summary Table


The KSPROPERTY_SYNTH_RUNNINGSTATS property is used to query the miniport driver for the synthesizer's
performance statistics.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE SYNTH_STATS


RTY

The property value (operation data) is a structure of type SYNTH_STATS. The miniport driver's property handler
writes the following statistics into this structure:
The average number of voices playing
CPU usage
Number of notes lost
Amount of free memory
Peak volume level
Return Value
A KSPROPERTY_SYNTH_RUNNINGSTATS property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

STATUS_INVALID_DEVICE_REQUEST The operation is invalid for this device.

The synthesizer's performance statistics are continuously updated while the device remains in the KSSTATE_RUN
state. Each time the device enters this state, it resets the statistics, which zeros cumulative values such as the peak
volume and number of notes lost.
For additional information, see the description of the IDirectMusicPor t::GetRunningStats method and the
DMUS_SYNTHSTATS structure in the Microsoft Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_VOICEPRIORITY property specifies what priority a particular voice in a MIDI synthesizer
should have when the miniport driver needs to bump voices from its voice cache.
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE DWORD


RTY +
SYNTHVOICEPR
IORITY_INSTAN
CE

The property descriptor (instance data) consists of a KSNODEPROPERTY structure that is immediately followed by
a SYNTHVOICEPRIORITY_INSTANCE structure, which specifies the voice's channel group (set of 16 MIDI channels)
and channel number (within the group).
The property value (operation data) is a DWORD that specifies the priority. The client uses a
KSPROPERTY_SYNTH_VOICEPRIORITY set-property request to send the voice's new priority to the miniport driver,
and it uses a KSPROPERTY_SYNTH_VOICEPRIORITY get-property request to retrieve the voice's current priority
from the miniport driver.
Voice Priorities
The following channel-group priorities are defined in header file Dmusprop.h:

DAUD_CRITICAL_VOICE_PRIORITY
DAUD_HIGH_VOICE_PRIORITY
DAUD_STANDARD_VOICE_PRIORITY
DAUD_LOW_VOICE_PRIORITY
DAUD_PERSIST_VOICE_PRIORITY

The preceding list is ordered with the highest priority at the top of the list and the lowest at the bottom. These
priorities are ORed with the channel priority offsets to arrive at the voice priority for each channel within a channel
group. The resulting priorities are passed in the get- and set-property requests.
The preceding channel-group priority values are large compared to the channel priority offsets. The result is that
changing the channel-group priority raises or lowers the priority of the entire channel group relative to other
channel groups without altering the relative priorities of the channels within the channel group.
Default Priorities
When a synthesizer miniport driver is created, it assigns a default priority to each of its voices. The defaults are
defined as follows:
By default, priorities are equal across channel groups. This means, for example, that channel 5 on channel
group 1 has the same priority as channel 5 on channel group 2.
In accordance with DLS Level-1 specifications, channel 10 (the MIDI percussion channel) has the highest
priority, followed by 1 through 9 and 11 through 16.
Header file Dmusprop.h defines the following priority offsets:
DAUD_CHAN10_VOICE_PRIORITY_OFFSET
DAUD_CHAN1_VOICE_PRIORITY_OFFSET
DAUD_CHAN2_VOICE_PRIORITY_OFFSET
DAUD_CHAN3_VOICE_PRIORITY_OFFSET
DAUD_CHAN4_VOICE_PRIORITY_OFFSET
DAUD_CHAN5_VOICE_PRIORITY_OFFSET
DAUD_CHAN6_VOICE_PRIORITY_OFFSET
DAUD_CHAN7_VOICE_PRIORITY_OFFSET
DAUD_CHAN8_VOICE_PRIORITY_OFFSET
DAUD_CHAN9_VOICE_PRIORITY_OFFSET
DAUD_CHAN11_VOICE_PRIORITY_OFFSET
DAUD_CHAN12_VOICE_PRIORITY_OFFSET
DAUD_CHAN13_VOICE_PRIORITY_OFFSET
DAUD_CHAN14_VOICE_PRIORITY_OFFSET
DAUD_CHAN15_VOICE_PRIORITY_OFFSET
DAUD_CHAN16_VOICE_PRIORITY_OFFSET

The preceding list of offsets is ordered with the highest priority at the top of the list. Header file Dmusprop.h also
defines the default priorities of the channels in each channel group by bitwise ORing each of these offsets with
DAUD_STANDARD_VOICE_PRIORITY. For example, the following definition gives the default priority for channel 1
in each channel group:

#define DAUD_CHAN1_DEF_VOICE_PRIORITY \
(DAUD_STANDARD_VOICE_PRIORITY | DAUD_CHAN1_VOICE_PRIORITY_OFFSET)

Return Value
A KSPROPERTY_SYNTH_VOICEPRIORITY property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

For more information about voice priorities, see the descriptions of the IDirectMusicPor t::GetChannelPriority
and IDirectMusicPor t::SetChannelPriority methods in the Microsoft Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_VOLUME property gets or sets the volume level of a synthesizer device.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSPROPERTY LONG

The property value (operation data) is of type LONG and specifies the volume level of the synthesizer device. The
volume setting is specified in units of 1/100ths of a decibel. The miniport driver should either change its volume or
report its volume, depending on whether the request is to get or set the property.
Return Value
A KSPROPERTY_SYNTH_VOLUME property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code. The following table shows some of
the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

Usage Summary Table


The KSPROPERTY_SYNTH_VOLUMEBOOST property specifies the amount by which a synthesizer device's volume
is boosted.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE LONG


RTY

The property value (operation data) is of type LONG and specifies by how much to boost the audio signal after the
mix stage. This is the amount of volume to add to the final output of the synthesizer after all voice articulation and
mixing have been completed. The volume boost amount is specified in 1/100ths of a decibel. This value can be
positive or negative.
Return Value
A KSPROPERTY_SYNTH_VOLUMEBOOST property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

No other boost should be added to the output. The synthesizer should follow strict DLS Level-1 conventions for
articulation.
This property is used to equalize the volume of the synthesizer with other audio output in the system, and boost
amounts should therefore be interpreted in a consistent manner across all devices.
KSPROPSETID_SynthClock
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_SynthClock property set is used to get the master clock time for a DirectMusic synthesizer. This set
contains a single property of a DirectMusic filter object. The DMus port driver implements the handler for this
property.
For more information, see Master Clocks and Synthesizer Timing.
Property items in this set are specified by KSPROPERTY_SYNTHCLOCK enumeration values, as defined in header
file Dmusprop.h.

Usage Summary Table


The KSPROPERTY_SYNTH_MASTERCLOCK property is used to get the master clock time.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY ULONGLONG

The property value (operation data) is of type ULONGLONG and represents the master clock time. This time is
specified in 100-nanosecond units.
Return Value
A KSPROPERTY_SYNTH_MASTERCLOCK property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.
For more information, see Master Clocks.
KSPROPSETID_Synth_Dls
10/23/2019 • 6 minutes to read • Edit Online

The KSPROPSETID_Synth_Dls property set contains properties that are used to download DLS samples and
instruments to a MIDI synthesizer. These are the properties of a synth node (KSNODETYPE_SYNTHESIZER ) on a
DirectMusic pin of a DirectMusic filter (see MIDI and DirectMusic Filters).
This section describes the behavior of these properties with regard to how they download and unload "chunks" of
memory containing DLS data. The actual format of the downloaded instrument and wave data chunks is specified
in the low-level DLS discussion in the Microsoft Windows SDK documentation.
DLS downloads and unloads can occur at any time during the pin's existence. Unlike DirectMusic events, they are
not time-stamped and should be processed as soon as possible.
In this section, the term DLS resource, or just resource, refers to either a DLS instrument chunk or a DLS wave
chunk. The system properly maintains reference counts on all DLS resources:
When a client unloads the last instrument referencing a wave, the system automatically generates a call to
unload the wave.
Conversely, the system defers the call to unload a wave until the client unloads the last instrument
referencing the wave.
Property items in this set are specified by KSPROPERTY_SYNTH_DLS enumeration values, as defined in header file
Dmusprop.h.

Usage Summary Table


The KSPROPERTY_SYNTH_DLS_APPEND property specifies the amount of reserved storage space that the client
appends to the DLS data in each buffer that it downloads to the synthesizer.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and specifies the number of bytes that the miniport driver
needs to reserve for its own use at the end of each downloaded DLS data buffer. The client then allocates each
download buffer to be large enough to contain the requested number of bytes after the end of the downloaded
data.
Return Value
A KSPROPERTY_SYNTH_DLS_APPEND property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code. The following table shows some of
the possible error codes.

STAT US C O DE M EA N IN G

STATUS_UNSUCCESSFUL The operation did not complete successfully.

These additional bytes are intended for drivers that need extra padding for alignment requirements or to replicate
the start of a sample in order to simplify sample interpolation.

Usage Summary Table


The KSPROPERTY_SYNTH_DLS_COMPACT property is a request for the synthesizer to make available the largest
possible chunk of free sample memory.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSNODEPROPE None


RTY

No property value (operation data) is associated with this property.


Return Value
A KSPROPERTY_SYNTH_DLS_COMPACT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_UNSUCCESSFUL The operation did not complete successfully.

The implementation of the handler for this property should not interrupt playback.
For more information, see the description of the IDirectMusicPor t::Compact method in the Microsoft Windows
SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_DLS_DOWNLOAD property is used to download DLS data to the synthesizer.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE SYNTHDOWNL


RTY + OAD
SYNTH_BUFFER

The property descriptor (instance data) consists of a KSNODEPROPERTY structure that is immediately followed by
a SYNTH_BUFFER structure, which specifies the location and size of the DLS data buffer that is being downloaded.
The property value (operation data) is a SYNTHDOWNLOAD structure. The miniport driver passes back the
following information in this structure:
A handle that the miniport driver generates to uniquely identify the downloaded DLS data. This client should
save this handle and use it later to unload the data (see KSPROPERTY_SYNTH_DLS_UNLOAD ).
A Boolean value that indicates whether the client can free the buffer containing the DLS data after the
property request completes. If the miniport driver has made its own copy of the DLS data, the client can free
the buffer. Otherwise, if the miniport driver continues to use the client's original DLS data buffer, the client
should not free the buffer until the miniport driver unloads the DLS data.
Return Value
A KSPROPERTY_SYNTH_DLS_DOWNLOAD property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

STATUS_NO_MEMORY No memory is available to complete this request.

For more information, see the discussion of the IDirectMusicPor t::DownloadInstrument method in the
Microsoft Windows SDK documentation.
Example
The KSPROPERTY_SYNTH_DLS_DOWNLOAD property request specifies the location of the DLS download data
with a user memory address. The miniport driver should probe and lock the user memory containing the DLS data
before attempting to access it. The following example code shows how to do this:

NTSTATUS Status = STATUS_UNSUCCESSFUL;


PSYNTH_BUFFER pDlsBuffer = (PSYNTH_BUFFER)pRequest->Instance;
PMDL pMdl = IoAllocateMdl(pDlsBuffer->BufferAddress, pDlsBuffer->BufferSize,
FALSE, FALSE, NULL);
if (pMdl)
{
__try
{
MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
PVOID pvUserData = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);

// do something with the data here


}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = GetExceptionCode();
}

MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
}
else
{
Status = STATUS_NO_MEMORY;
}

Usage Summary Table


The KSPROPERTY_SYNTH_DLS_UNLOAD property unloads a DLS data resource that was previously downloaded.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSNODEPROPE HANDLE


RTY

The property value (operation data) is of type HANDLE and contains the handle of the downloaded DLS data
resource that is to be freed. This is the handle that the miniport driver generated to identify the DLS data in a
previous KSPROPERTY_SYNTH_DLS_DOWNLOAD get-property request.
Return Value
A KSPROPERTY_SYNTH_DLS_UNLOAD property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

STATUS_UNSUCCESSFUL The operation did not complete successfully.

STATUS_PENDING The operation will complete at a later time.

The miniport driver should unload the DLS data as soon as there are no notes playing that use the DLS data. If the
synthesizer is not able to free the memory associated with the DLS data resource at the time of the
KSPROPERTY_SYNTH_DLS_UNLOAD set-property request, it can use asynchronous property completion to finish
the request at a later time.
If, after unloading the DLS data resource, the synthesizer receives a note-on event that uses the resource, the
miniport driver should ignore the event unless a new DLS data resource has been downloaded in the interim.
For more information, see the discussion of the IDirectMusicPor t::UnloadInstrument method in the Microsoft
Windows SDK documentation.

Usage Summary Table


The KSPROPERTY_SYNTH_DLS_WAVEFORMAT property is used to query the synthesizer for its output wave
format.

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE WAVEFORMATE


RTY X

The property value (operation data) is of type WAVEFORMATEX and specifies the wave format of the synthesizer's
output stream.
Return Value
A KSPROPERTY_SYNTH_DLS_WAVEFORMAT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code. The following table shows
some of the possible error codes.

STAT US C O DE M EA N IN G

STATUS_BUFFER_TOO_SMALL The buffer was too small to complete the operation.

A property-value buffer of sizeof (WAVEFORMATEX) bytes might not be large enough for all wave formats. For
example, a multichannel format requires a buffer of sizeof (WAVEFORMATEXTENSIBLE ) bytes. If the property
request returns a status code of STATUS_BUFFER_TOO_SMALL, the client can check the property-value size that the
miniport driver outputs, allocate a larger buffer, and then submit a second request.
For more information, see the description of the IDirectMusicPor t::GetFormat method in the Microsoft
Windows SDK documentation.
KSPROPSETID_Sysaudio
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_Sysaudio property set is used to access the properties of the SysAudio system driver. Sysaudio is
the driver that creates and manages virtual audio devices on behalf of DirectSound and other clients.
SysAudio's clients use this property set to do the following:
Enumerate the virtual audio devices that are available to SysAudio's clients.
Enumerate the pins that SysAudio is capable of instantiating on a virtual audio device.
Determine the capabilities of those pins.
Enumerate the nodes that lie along the path of the data stream that flows through each pin.
Configure the data path through a pin to either include or bypass an AEC node.
After exploring the properties of the available virtual audio devices, the client should be ready to select one of the
virtual audio devices and create a pin on that device. Some clients might choose to create more than one pin on a
virtual audio device or to create pins on more than one device. For information about creating pins, see Pin
Factories.
After the pin is created, the client can use the KSPROPSETID_Sysaudio_Pin property set to manage the pin.
The following properties are members of the KSPROPSETID_Sysaudio property set:
KSPROPERTY_SYSAUDIO_COMPONENT_ID
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE
KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
KSPROPERTY_SYSAUDIO_INSTANCE_INFO
KSPROPERTY_SYSAUDIO_SELECT_GRAPH
KSPROPSETID_Sysaudio_Pin
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_Sysaudio_Pin property set provides access to the properties of a pin instance on a virtual audio
device. The SysAudio system driver manages virtual audio devices on behalf of DirectSound and other clients.
The following property is the only member of the KSPROPSETID_Sysaudio_Pin property set:
KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE
KSPROPSETID_TelephonyControl
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_TelephonyControl property set is used to work with telephony control properties. These properties
can be used to determine the state of a call and perform certain operations such as putting a call on hold or muting
the local microphone.
The KSPROPSETID_TelephonyControl property set contains the following properties:
KSPROPERTY_TELEPHONY_CALLCONTROL
KSPROPERTY_TELEPHONY_CALLHOLD
KSPROPERTY_TELEPHONY_CALLINFO
KSPROPERTY_TELEPHONY_MUTE_TX
KSPROPERTY_TELEPHONY_PROVIDERCHANGE
KSPROPERTY_TELEPHONY_PROVIDERID
KSPROPSETID_TelephonyTopology
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPSETID_TelephonyTopology property set is used access endpoints associated with cellular audio routing as
well as the cellular call volume.
The KSPROPSETID_TelephonyTopology property set contains the following properties:
KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR
KSPROPERTY_TELEPHONY_VOLUME
KSPROPSETID_TopologyNode
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPSETID_TopologyNode property set provides generic control over the various topology nodes. For a list of
topology node types, see Audio Topology Nodes. The properties in this set can be used to enable, disable, and reset
topology nodes.
To expose AEC (acoustic echo cancellation) hardware acceleration to the system, an audio driver must implement
AEC and noise-suppression nodes (KSNODETYPE_ACOUSTIC_ECHO_CANCEL and
KSNODETYPE_NOISE_SUPPRESS ), and must support enabling and disabling of these nodes through the
KSPROPSETID_TopologyNode properties. For more information, see Exposing Hardware-Accelerated Capture Effects.

A KSNODETYPE_PROLOGIC_ENCODER node must also support the KSPROPSETID_TopologyNode properties.


The KSPROPSETID_TopologyNode property set contains the following properties:
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
Audio Drivers Event Sets
12/5/2018 • 2 minutes to read • Edit Online

The following event sets define events that occur in audio hardware controls and audio streams:
KSEVENTSETID_AudioControlChange
KSEVENTSETID_LoopedStreaming
KSEVENTSETID_PinCapsChange
KSEVENTSETID_SoundDetector
KSEVENTSETID_VolumeLimit
KSEVENTSETID_AudioControlChange
6/25/2019 • 2 minutes to read • Edit Online

The KSEVENTSETID_AudioControlChange event set is used to notify clients when a miniport driver detects a hardware
event, which is a change in a hardware volume-control knob, mute switch, or other type of manual control.
The event items in this set are specified as KSEVENT_AUDIO_CONTROL_CHANGE enumeration values.
The only event in this set is KSEVENT_CONTROL_CHANGE .
KSEVENTSETID_LoopedStreaming
6/25/2019 • 2 minutes to read • Edit Online

This event set is intended only for internal use by the system.
The KSEVENTSETID_LoopedStreaming event set defines position events in audio streams that use looped buffers. A
looped buffer is a data buffer for an audio stream of type KSINTERFACE_STANDARD_LOOPED_STREAMING .
Through a position event, a client can receive notification from a driver when an audio stream reaches a specified
position in a looped buffer.
In Microsoft Windows Server 2003, Windows XP, Windows 2000, Windows Me, and Windows 98, the only system
components that implement driver support for this event set are KMixer and PortCls (Kmixer.sys and Portcls.sys).
DirectSound (Dsound.dll) is the only system component that uses this event set as a client. Custom audio drivers
typically do not implement support for this event set.
In Windows Vista and later, no system components use or support the KSEVENTSETID_LoopedStreaming event set.
The event items in this set are specified as KSEVENT_LOOPEDSTREAMING enumeration values.
The only event in this set is KSEVENT_LOOPEDSTREAMING_POSITION .
KSEVENTSETID_PinCapsChange
12/5/2018 • 2 minutes to read • Edit Online

In Windows 7 and later versions of the Windows operating systems, the KSEVENTSETID_PinCapsChange event set is
used by audio drivers to notify the operating system that the audio format, jack information or some other
property of an audio device has changed.
The event items in this set are specified as the following KSEVENT_PINCAPS_CHANGENOTIFICATIONS enumeration
values:
KSEVENT_PINCAPS_FORMATCHANGE
KSEVENT_PINCAPS_JACKINFOCHANGE
KSEVENTSETID_SoundDetector
12/5/2018 • 2 minutes to read • Edit Online

The KSEVENTSETID_SoundDetector event set is used by audio drivers to notify the operating system that the sound
detector has detected a match.
The event item in this set is specified as the following KSEVENT_SOUNDDETECTOR enumeration value:
KSEVENT_SOUNDDETECTOR_MATCHDETECTED
KSEVENTSETID_VolumeLimit
12/5/2018 • 2 minutes to read • Edit Online

The KSEVENTSETID_VolumeLimit event set has been introduced with Windows 8.1, to provide OEMs and IHVs with
a mechanism for displaying a warning message when the user selects an unsafe volume level.
The events in this set are specified as KSEVENT_VOLUMELIMIT enumeration values. The following is the currently
defined event ID:
KSEVENT_VOLUMELIMIT_CHANGED
KSEVENT_VOLUMELIMIT_CHANGED
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_VOLUMELIMIT_CHANGED event indicates to the audio stack that the audio volume level limit for the
audio device has changed.
Usage Summary Table
TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Pin KSEVENT KSEVENTDATA

The event value type (operation data) is a KSEVENTDATA structure that specifies the notification method to use for
this event.

Remarks
For information about how to implement support for the KSEVENT_PINCAPS_VOLUMELIMITCHANGE event, see
the Remarks section of KSEVENT_PINCAPS_FORMATCHANGE .
Note that while KSEVENT_PINCAPS_FORMATCHANGE is implemented on the Wave filter (for miniport drivers that
are linked to Portcls), the KSEVENT_VOLUMELIMIT_CHANGED event is implemented on the Topology filter.

See also
KSEVENT
KSEVENT_PINCAPS_FORMATCHANGE
KSEVENTDATA
Audio Topology Nodes
6/25/2019 • 2 minutes to read • Edit Online

The WDM audio driver framework defines a standard set of topology nodes for audio devices. A miniport driver
describes the device's audio topology by specifying a set of nodes and the connections between the nodes. The
SysAudio system driver uses this information to construct the audio filter graphs that it presents to client
applications.
Each data path in the topology begins or ends at a pin and passes through some number of nodes, which can be
thought of as beads strung along the data path. Each node in the data path is identified by a node ID (essentially an
index) that uniquely identifies that node within the data path. Two pin instances could have nodes with the same ID,
but the combination of pin instance and node ID uniquely identifies each node within the audio topology.
A topology node supports a set of node properties. Node properties differ from pin properties by the inclusion of
a node ID identifying the internal node that the property belongs to. To send a get- or set-property request to a
particular node, the client specifies the target node ID in addition to the target pin instance. When the pin's
property handler receives the request, it looks at the node ID and directs the request to the handler for that node.
The following list contains the more commonly used audio topology node types:
KSNODETYPE_3D_EFFECTS
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_ADC
KSNODETYPE_AGC
KSNODETYPE_AUDIO_ENGINE
KSNODETYPE_AUDIO_KEYWORDDETECTOR
KSNODETYPE_CHORUS
KSNODETYPE_DAC
KSNODETYPE_DEL AY
KSNODETYPE_DEMUX
KSNODETYPE_DEV_SPECIFIC
KSNODETYPE_DMSYNTH
KSNODETYPE_DMSYNTH_CAPS
KSNODETYPE_DRM_DESCRAMBLE
KSNODETYPE_EQUALIZER
KSNODETYPE_FM_RX
KSNODETYPE_LOUDNESS
KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR
KSNODETYPE_MUTE
KSNODETYPE_MUX
KSNODETYPE_NOISE_SUPPRESS
KSNODETYPE_PEAKMETER
KSNODETYPE_PROLOGIC_DECODER
KSNODETYPE_PROLOGIC_ENCODER
KSNODETYPE_REVERB
KSNODETYPE_SRC
KSNODETYPE_STEREO_ENHANCE
KSNODETYPE_STEREO_WIDE
KSNODETYPE_SUM
KSNODETYPE_SUPERMIX
KSNODETYPE_SWMIDI
KSNODETYPE_SWSYNTH
KSNODETYPE_SYNTHESIZER
KSNODETYPE_TELEPHONY_BIDI
KSNODETYPE_TONE
KSNODETYPE_VOLUME
KSNODETYPE_3D_EFFECTS
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_3D_EFFECTS node represents a 3D-effects processor for the device-specific 3D HAL (hardware
acceleration layer) that underlies the IDirectSound3DBuffer and IDirectSound3DListener APIs (described in
the Microsoft Windows SDK documentation). The 3D node has one input stream with either one or two channels
and one output stream with n channels. It positions the individual channels of the input stream within the 3D-
sound field of the output stream.
The input stream to the 3D node typically contains a single channel. In DirectSound 8.0 and later, only mono PCM
buffers can be created with 3D effects. Earlier versions of DirectSound, however, support 3D nodes with both
mono and stereo input streams, and drivers should support both in order to ensure compatibility with older
applications.
The KSNODETYPE_3D_EFFECTS node is used to control the DirectSound speaker configuration through the
following optional properties:
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
For more information, see DirectSound Speaker-Configuration Settings.
In addition, DirectSound requires that a KSNODETYPE_3D_EFFECTS node support the following 3D-listener and
3D-buffer properties:
KSPROPERTY_DIRECTSOUND3DBUFFER_ALL
KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION
KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME
KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE
KSPROPERTY_DIRECTSOUND3DBUFFER_MODE
KSPROPERTY_DIRECTSOUND3DLISTENER_ALL
KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION
KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH
A KSNODETYPE_3D_EFFECTS node might implement a head-relative transfer function (HRTF), in which case it
should support the following optional properties:
KSPROPERTY_HRTF3D_FILTER_FORMAT
KSPROPERTY_HRTF3D_INITIALIZE
KSPROPERTY_HRTF3D_PARAMS
A KSNODETYPE_3D_EFFECTS node might implement an interaural time delay (ITD) algorithm, in which case it
should support the following optional property:
KSPROPERTY_ITD3D_PARAMS
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_ACOUSTIC_ECHO_CANCEL node represents an AEC (acoustic echo cancellation) control. An


AEC node has connections for two input streams and two output streams. One input/output pair is used for the
capture stream, and the other input/output pair is used for the render stream. The capture-output and render-
input streams have the same format. The capture-input and render-output streams can have a different number
of channels and different sample rates. However, in a typical implementation, the two streams either have the
same sample rate or a combination, such as 16 kHz and 48 kHz or 11.025 kHz and 44.1 kHz, in which one
sample rate is an integer multiple of the other.
An AEC node should number its logical pins with the pin IDs from header file Ksmedia.h, which are shown in the
following table.

P IN ID PA RA M ET ER M EA N IN G

KSNODEPIN_AEC_RENDER_IN Sink pin (node input) for render stream.

KSNODEPIN_AEC_RENDER_OUT Source pin (node output) for render stream.

KSNODEPIN_AEC_CAPTURE_IN Sink pin (node input) for capture stream.

KSNODEPIN_AEC_CAPTURE_OUT Source pin (node output) for capture stream.

Note that the pins in the preceding table are logical pins on the node, which are used solely to specify
connections internal to the filter, rather than external pins on the filter, which are used to connect to other filters.
For more information, see PCCONNECTION_DESCRIPTOR .
For information about how a filter containing an AEC node can provide support for full-duplex DirectSound
applications, see DirectSound Capture Effects.
When a filter containing an AEC node is created or the node is reset, the node is initially configured to operate in
pass-through mode.
A KSNODETYPE_ACOUSTIC_ECHO_CANCEL node should support the following properties in order to enable
hardware acceleration:
KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
The KSPROPERTY_TOPOLOGYNODE_ENABLE property is used to enable and disable an AEC node. When
disabled, the node operates in pass-through mode; that is, it allows the render and capture streams to pass
through the node without modification.
A KSNODETYPE_ACOUSTIC_ECHO_CANCEL node can also support the following optional properties in order to
provide additional control and monitoring capabilities:
KSPROPERTY_AEC_MODE
KSPROPERTY_AEC_NOISE_FILL_ENABLE
KSPROPERTY_AEC_STATUS
KSNODETYPE_ADC
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_ADC node represents an analog-to-digital converter (ADC). The ADC has one input stream and
one output stream.
A KSNODETYPE_ADC node can support the following optional properties:
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSNODETYPE_AGC
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_AGC node represents an automatic gain control (AGC). An AGC node has one input stream and
one output stream, and each of the two streams has the same data format. The node automatically adjusts the
amount of attenuation or gain applied to the input stream to achieve maximum dynamic range without clipping
the signal.
A KSNODETYPE_AGC node should support the following property:
KSPROPERTY_AUDIO_AGC
A KSNODETYPE_AGC node can also support the following optional properties:
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
The KSPROPERTY_TOPOLOGYNODE_ENABLE property is used to both enable and disable the node. When
disabled, the node operates in pass-through mode (that is, it allows the input stream to pass through to the output
without modification).
KSNODETYPE_AUDIO_ENGINE
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_AUDIO_ENGINE audio endpoint is a new endpoint that is available with Windows 8 and later
versions of Windows. The KSNODETYPE_AUDIO_ENGINE audio endpoint is contained within a Wave kernel
streaming (KS) audio filter, and it allows an audio driver to expose the capabilities of the hardware audio engine.
The KSNODETYPE_AUDIO_ENGINE audio endpoint is a required endpoint and its introduction made it necessary
to develop a new Wave data sink pin factory to which the new endpoint directly connects.
The KSNODETYPE_AUDIO_ENGINE audio endpoint must support the KSPROPERTY_AUDIOENGINE enumerated
values in addition to the following KS properties:
KSPROPERTY_AUDIO_MUTE
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_VOLUMELEVEL
KSPROPSETID_AudioEngine
KSNODETYPE_AUDIO_KEYWORDDETECTOR
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_AUDIO_KEYWORDDETECTOR audio endpoint is a new endpoint that is available with


Windows 10 and later versions of Windows. The KSNODETYPE_AUDIO_KEYWORDDETECTOR allows an audio
capture driver to support a detector.
This filter cannot be shared with other capture devices. The filter has a KS pin factory that has pin category
KSNODETYPE_AUDIO_KEYWORDDETECTOR. There cannot be more than one pin factory having this KS pin
category in a given KS filter instance.
The KSNODETYPE_AUDIO_KEYWORDDETECTOR audio endpoint must support the following KS properties:
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSPROPERTY_SOUNDDETECTOR_ARMED
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT

See also
KSPROPSETID_SoundDetector
KSNODETYPE_CHORUS
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_CHORUS node represents a chorus effects processor, which adds a chorus effect to the output
stream. The chorus node has one input stream and one output stream, and these two streams share the same
data format.
A KSNODETYPE_CHORUS node should support the following required properties:
KSPROPERTY_AUDIO_CHORUS_LEVEL
KSPROPERTY_AUDIO_CHORUS_MODUL ATION_DEPTH
KSPROPERTY_AUDIO_CHORUS_MODUL ATION_RATE
KSNODETYPE_DAC
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_DAC node represents a digital-to-analog converter (DAC). The DAC node has one input stream
and one output stream.
A good, general rule is that an audio driver should expose only one DAC node in its topology. Because
DirectSound assumes that a driver's topology contains only a single DAC node, it sends speaker-configuration
property requests to the first DAC node that it discovers, but not to any others. In fact, a topology can safely
contain more than one DAC node, but only if all the DAC nodes represent the same physical control. In this case,
setting a property on any one of the DAC nodes has the effect of setting the same property on all the DAC nodes.
Some audio drivers might need to use multiple DAC nodes to work around a problem in Windows Me/98,
Windows 2000, and Windows XP: If a miniport driver provides more than one wave-rendering pin factory and
has a topology that mixes the streams from these pins together through a SUM node that feeds a DAC node,
wdmaud.drv (the mixer-line driver) incorrectly reports a separate wave volume control for each of the pin
factories. It should generate only a single wave volume control. To fix this problem, a work-around solution is to
insert a DAC node into the data path from each of the pin factories.
A KSNODETYPE_DAC node can support the following optional properties:
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
KSNODETYPE_DELAY
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_DELAY node represents a delay control. The delay control has one input stream and one output
stream, and these two streams share the same data format. The delay control causes the output stream to lag
behind the input stream by some specified amount of time.
A KSNODETYPE_DELAY node should support the following required property:
KSPROPERTY_AUDIO_DEL AY
KSNODETYPE_DEMUX
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_DEMUX node represents a demultiplexer. This control has a single input stream and multiple
output streams.
A KSNODETYPE_DEMUX node should support the following property:
KSPROPERTY_AUDIO_DEMUX_DEST
KSNODETYPE_DEV_SPECIFIC
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_DEV_SPECIFIC node represents a device-specific control. The device-specific control can have
multiple input streams and multiple output streams. It performs a set of functions that are specific to the particular
audio device.
A KSNODETYPE_DEV_SPECIFIC node should support the following required property:
KSPROPERTY_AUDIO_DEV_SPECIFIC
KSNODETYPE_DMSYNTH
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_DMSYNTH_CAPS
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_DRM_DESCRAMBLE
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_EQUALIZER
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_EQUALIZER node represents an equalizer with multiple frequency bands. By adjusting the level
that the equalization table assigns to each of the frequency bands, an EQ node can control the amount of each
frequency band that appears in the node's output stream.
An EQ node has one input stream and one output stream, and the two streams share a common data format.
A KSNODETYPE_EQUALIZER node should support the following required properties:
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_EQ_BANDS
KSNODETYPE_FM_RX
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_FM_RX node represents an FM capture audio endpoint in the system and supports all audio
endpoint properties (see KSPROPSETID_Audio). Creating a capture pin on KSNODETYPE_FM_RX will allow audio
capture from the FM receiver.
The filter associated with the KSNODETYPE_FM_RX node should support the following additional properties:
KSPROPERTY_FMRX_ANTENNAENDPOINTID
KSPROPERTY_FMRX_ENDPOINTID
KSPROPERTY_FMRX_STATE
KSPROPERTY_FMRX_VOLUME
KSNODETYPE_LOUDNESS
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_LOUDNESS node represents a loudness control that adjusts the dynamic range of the output
stream. The loudness control has one input stream and one output stream, and each of the two streams has the
same data format.
A KSNODETYPE_LOUDNESS node should support at least one of the following properties:
KSPROPERTY_AUDIO_LOUDNESS
KSPROPERTY_AUDIO_DYNAMIC_RANGE
KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_MUTE
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_MUTE node represents a mute control. This node has one input stream and one output stream,
and each of the two streams has the same data format. It switches the input on or off.
A KSNODETYPE_MUTE node should support the following required property:
KSPROPERTY_AUDIO_MUTE
KSNODETYPE_MUX
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_MUX node represents a multiplexer (MUX). The MUX has multiple input streams and one output
stream, all with the same data format. Only one input stream at a time is routed to the output stream.
A KSNODETYPE_MUX node should support the following required property:
KSPROPERTY_AUDIO_MUX_SOURCE
KSNODETYPE_NOISE_SUPPRESS
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_NOISE_SUPPRESS node represents a noise-suppression (NS) control. An NS node has


connections for one input stream and one output stream. Both streams have the same format.
When a filter containing an NS node is created or the node is reset, the node is initially configured to operate in
pass-through mode.
An NS node can be incorporated into an AEC (acoustic echo cancellation) filter to support full-duplex DirectSound
applications. For more information, see DirectSound Capture Effects.
A KSNODETYPE_NOISE_SUPPRESS node in an AEC filter should support the following properties in order to
enable hardware acceleration:
KSPROPERTY_AUDIO_CPU_RESOURCES
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
The KSPROPERTY_TOPOLOGYNODE_ENABLE property is used to both enable and disable the node. When
disabled, the node operates in pass-through mode (that is, it allows the input stream to pass through to the output
without modification).
KSNODETYPE_PEAKMETER
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_PEAKMETER node represents a hardware peakmeter. A KS peakmeter node has one input pin
and one output pin, and the two pins share the same data format.
A KS peakmeter internally logs the maximum value of the audio signal since the last time the peakmeter was reset
to zero. The peakmeter automatically resets itself to zero after an IOCTL_KS_PROPERTY request to get a
KSPROPERTY_AUDIO_PEAKMETER property.
A peakmeter requires hardware support. A software peakmeter is not feasible, and this is because the adapter
driver does not have access to signals that are present on line-in, microphone, or other inputs that are mixed with
the playback channel.
Microsoft recommends making a peakmeter node the final node through which a stream passes within a filter. On
a render stream, an audio adapter usually connects a peakmeter node after a master output
KSNODETYPE_MUTE node or a KSNODETYPE_VOLUME node. The same approach applies to a capture stream
or any other streams for which the filter incorporates a peakmeter node.
An audio adapter should name a peakmeter node KSAUDFNAME_PEAKMETER.
A peakmeter node should provide a property handler for the property flags (see KSPROPERTY ) that appear in the
following table.

FLAG NAME M EA N IN G

KSPROPERTY_TYPE_GET Returns the current value of the hardware peakmeter.

KSPROPERTY_TYPE_BASICSUPPORT Returns a data range of -32768 to 32767, which is the


data range of 16-bit digital audio.

The property handler should verify input parameters and left and right channel information.
A peakmeter node should also support the properties in the following table.

P RO P ERT Y N A M E DESC RIP T IO N

KSPROPERTY_AUDIO_PEAKMETER Represents the peakmeter control.

KSPROPERTY_AUDIO_CPU_RESOURCES Indicates whether the specified node's functionality makes


use of the host CPU.
KSNODETYPE_PROLOGIC_DECODER
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_PROLOGIC_DECODER node represents a Dolby Surround Pro Logic decoder. The decoder
control has one stereo input stream and one output stream with one to four channels. In the four-channel output
format, the channels are mapped to left, right, center, and back speaker. In the three-channel output format, the
channels are mapped to left, right, and back speakers.
The functionality of the KSNODETYPE_PROLOGIC_DECODER node is complementary to the
KSNODETYPE_PROLOGIC_ENCODER node, which converts a four-channel input stream to a surround-
encoded stereo output stream.
A KSNODETYPE_PROLOGIC_DECODER node should support the following required properties:
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSPROPERTY_TOPOLOGYNODE_ENABLE
KSPROPERTY_TOPOLOGYNODE_RESET
The KSPROPERTY_AUDIO_CHANNEL_CONFIG property sets and gets the channel configuration of the node's
output stream.
KSNODETYPE_PROLOGIC_ENCODER
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_PROLOGIC_ENCODER node represents a Dolby Surround Pro Logic encoder. The node accepts
a four-channel input stream with channels for left, right, center, and back speakers. The node encodes the input
stream as a surround-encoded stereo output stream.
The functionality of the KSNODETYPE_PROLOGIC_ENCODER node is complementary to the
KSNODETYPE_PROLOGIC_DECODER node, which takes a surround-encoded stereo input stream and decodes
it into a four-channel stream with channels for left, right, center, and back speakers.
In Microsoft Windows XP and later, the KMixer system driver has a KSNODETYPE_PROLOGIC_ENCODER node.
A KSNODETYPE_PROLOGIC_ENCODER node should support the KSPROPERTY_AUDIO_SURROUND_ENCODE
property, which is used to enable and disable the node.
KSNODETYPE_REVERB
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_REVERB node represents a reverberation (or "reverb") control. The reverb node has one input
stream and one output stream, and the input and output streams have the same data format. The node adds
reverberation to the output stream.
A KSNODETYPE_REVERB node should support the following required properties:
KSPROPERTY_AUDIO_REVERB_LEVEL
KSPROPERTY_AUDIO_REVERB_TIME
KSNODETYPE_SRC
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_SRC node represents a sample-rate converter, which produces an output stream that is a
digitally resampled version of the input stream. The SRC node has one input stream and one output stream, each
with the same number of channels.
A KSNODETYPE_SRC node can support the following optional properties:
KSPROPERTY_AUDIO_SAMPLING_RATE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
KSPROPERTY_AUDIO_QUALITY
KSNODETYPE_STEREO_ENHANCE
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_STEREO_WIDE
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_STEREO_WIDE node represents a stereo wideness control. This type of control can add
spaciousness to an existing stereo (two-channel) stream by increasing the apparent width of the stereo image. In
the resulting stereo image, some sounds appear to originate from positions outside the region that is framed by
the left and right speakers.
A wideness node should support the following required property:
KSPROPERTY_AUDIO_WIDENESS
KSNODETYPE_SUM
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_SUM node represents a simple summation (SUM) function. The SUM node has multiple input
streams and one output stream, all with the same data format. The input streams are mixed equally to produce the
output stream.
A KSNODETYPE_SUM node is not required to support any properties.
KSNODETYPE_SUPERMIX
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_SUPERMIX node represents a supermixer. A supermixer has one input stream with m channels
and one output stream with n channels. For each output channel, the supermixer specifies a mix level for each of
the input channels that adds to the mix in the output channel. The m-channel input stream is upmixed or down-
mixed to n channels.
A KSNODETYPE_SUPERMIX node should support the following required properties:
KSPROPERTY_AUDIO_MIX_LEVEL_TABLE
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
KSNODETYPE_SWMIDI
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_SWSYNTH
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSNODETYPE_SYNTHESIZER
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_SYNTHESIZER node represents a MIDI synthesizer. A synth node takes as input a MIDI stream
and outputs one of the following:
A wave stream
An analog audio signal
Raw MIDI
The DMusUART audio sample driver in the Microsoft Windows Driver Kit (WDK) is an example of a miniport driver
that outputs raw MIDI to an external synthesizer and contains a synth node (on its DirectMusic pin).
A synth node should support the following required properties:
KSPROPERTY_SYNTH_CAPS
KSPROPERTY_SYNTH_PORTPARAMETERS
A synth node that supports multiple channel groups should also support the following property:
KSPROPERTY_SYNTH_CHANNELGROUPS
If the node does not support this property, the number of channel groups defaults to 1.
A synth node can also support the following optional KSPROPSETID_Synth and KSPROPSETID_Synth_Dls
properties:
KSPROPERTY_SYNTH_L ATENCYCLOCK
KSPROPERTY_SYNTH_MASTERCLOCK
KSPROPERTY_SYNTH_RUNNINGSTATS
KSPROPERTY_SYNTH_VOICEPRIORITY
KSPROPERTY_SYNTH_VOLUME
KSPROPERTY_SYNTH_VOLUMEBOOST
KSPROPERTY_SYNTH_DLS_APPEND
KSPROPERTY_SYNTH_DLS_COMPACT
KSPROPERTY_SYNTH_DLS_DOWNLOAD
KSPROPERTY_SYNTH_DLS_UNLOAD
KSPROPERTY_SYNTH_DLS_WAVEFORMAT
KSNODETYPE_TELEPHONY_BIDI
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_TELEPHONY_BIDI node represents both sides (bi-directional) of a phone call.


If the device supports cellular telephony then a KSNODETYPE_TELEPHONY_BIDI endpoint for each Provider
(executor) is required.

CELLULAR TELEPHONY
The radio stack has a concept of Provider Id (Executor Id) and call type (packet/circuit) to connect the phone call
instance to a specific hardware path.
The driver associates a provider Id to the wave filter. This provider Id will also be set on the associated cellular
streaming endpoints. The provider Id for the wave filter must not change at runtime. The audio stack will query the
provider Id from the driver by using KSPROPERTY_TELEPHONY_PROVIDERID . After this, all the calls for that
provider Id will be sent to the particular wave filter.
STARTING AND ENDING CELLUL AR CALLS
Starting and stopping calls is done by sending KSPROPERTY_TELEPHONY_CALLCONTROL to the wave filter
for the provider. This property will communicate call type (packet switched/circuit switched) and call control
operation (Enable or Disable) to driver. Call type is ignored when the call control operation is Disable.
Once the call is Enabled, associated KSNODETYPE_TELEPHONY_BIDI’s jack state will be made Active by the driver
and the call state will be updated to TELEPHONY_CALLSTATE_ENABLED. When the call is terminated, the endpoint's
jack state will change to unplugged and the call state will be updated to TELEPHONY_CALLSTATE_DISABLED.
KSNODETYPE_TONE
12/5/2018 • 2 minutes to read • Edit Online

The KSNODETYPE_TONE node represents a tone control. The tone control has one input stream and one output
stream; the two streams have the same data format. It can attenuate the amount of bass, treble, or mid-
frequencies of the output stream. In addition, it can optionally support a bass boost or gain.
A KSNODETYPE_TONE node should support at least one of the following properties:
KSPROPERTY_AUDIO_BASS
KSPROPERTY_AUDIO_MID
KSPROPERTY_AUDIO_TREBLE
KSPROPERTY_AUDIO_BASS_BOOST
KSNODETYPE_VOLUME
6/25/2019 • 2 minutes to read • Edit Online

The KSNODETYPE_VOLUME node represents a volume (gain or attenuation) control. The volume control has one
input stream and one output stream; each of the two streams has the same data format. It can apply attenuation
(reduction in volume) or gain (increase in volume) to the stream. In addition, it can optionally support inverting
the signal.
For information about multichannel volume nodes, see Exposing Multichannel Nodes.
A KSNODETYPE_VOLUME node should support the following required property:
KSPROPERTY_AUDIO_VOLUMELEVEL
Audio Drivers Structures
10/23/2019 • 2 minutes to read • Edit Online

This section describes the structures that are used by WDM audio miniport drivers. The list of structures is as
follows:
APO_REG_PROPERTIES
APOInitBaseStruct
APOInitSystemEffects
APOInitSystemEffects2
AudioFXExtensionParams
DMUS_KERNEL_EVENT
DRMFORWARD
DRMRIGHTS
DS3DVECTOR
KSAC3_ALTERNATE_AUDIO
KSAC3_BIT_STREAM_MODE
KSAC3_DIALOGUE_LEVEL
KSAC3_DOWNMIX
KSAC3_ERROR_CONCEALMENT
KSAC3_L ANGUAGE_CODE
KSAC3_ROOM_TYPE
KSAUDIO_CHANNEL_CONFIG
KSAUDIO_COPY_PROTECTION
KSAUDIO_DYNAMIC_RANGE
KSAUDIO_MIC_ARRAY_GEOMETRY
KSAUDIO_MICROPHONE_COORDINATES
KSAUDIO_MIX_CAPS
KSAUDIO_MIXCAP_TABLE
KSAUDIO_MIXLEVEL
KSAUDIO_PACKETSIZE_CONSTRAINTS
KSAUDIO_PACKETSIZE_CONSTRAINTS2
KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT
KSAUDIO_POSITION
KSAUDIO_POSITIONEX
KSAUDIO_PREFERRED_STATUS
KSAUDIO_PRESENTATION_POSITION
KSAUDIOENGINE_BUFFER_SIZE_RANGE
KSAUDIOENGINE_DESCRIPTOR
KSAUDIOENGINE_VOLUMELEVEL
KSDATAFORMAT_DSOUND
KSDATAFORMAT_WAVEFORMATEX
KSDATARANGE_AUDIO
KSDATARANGE_MUSIC
KSDRMAUDIOSTREAM_CONTENTID
KSDSOUND_BUFFERDESC
KSDS3D_BUFFER_ALL
KSDS3D_BUFFER_CONE_ANGLES
KSDS3D_HRTF_FILTER_FORMAT_MSG
KSDS3D_HRTF_INIT_MSG
KSDS3D_HRTF_PARAMS_MSG
KSDS3D_ITD_PARAMS
KSDS3D_ITD_PARAMS_MSG
KSDS3D_LISTENER_ALL
KSDS3D_LISTENER_ORIENTATION
KSJACK_DESCRIPTION
KSJACK_DESCRIPTION2
KSJACK_SINK_INFORMATION
KSMUSICFORMAT
KSNODEPROPERTY
KSNODEPROPERTY_AUDIO_CHANNEL
KSP_DRMAUDIOSTREAM_CONTENTID
KSP_PINMODE
KSRTAUDIO Structures
KSTELEPHONY_CALLCONTROL
KSTELEPHONY_CALLINFO
KSTELEPHONY_PROVIDERCHANGE
KSTOPOLOGY_ENDPOINTID
KSTOPOLOGY_ENDPOINTIDPAIR
LOOPEDSTREAMING_POSITION_EVENT_DATA
MDEVICECAPSEX
MIDIOPENDESC
RTAUDIO_GETREADPACKET_INFO
RTAUDIO_SETWRITEPACKET_INFO
SOUNDDETECTOR_PATTERNHEADER
SYNTH_BUFFER
SYNTH_PORTPARAMS
SYNTH_STATS
SYNTHCAPS
SYNTHDOWNLOAD
SYNTHVOICEPRIORITY_INSTANCE
SYSAUDIO_ATTACH_VIRTUAL_SOURCE
SYSAUDIO_CREATE_VIRTUAL_SOURCE
SYSAUDIO_INSTANCE_INFO
SYSAUDIO_SELECT_GRAPH
UNCOMPRESSEDAUDIOFORMAT
WAVEFORMATEX
WAVEFORMATEXTENSIBLE
Audio Drivers Interfaces
6/25/2019 • 2 minutes to read • Edit Online

In Windows Vista and later Windows operating systems, digital signal processing is referred to as System Effects
Audio Processing. This processing is performed by user-mode in-process COM components known as System
Effects Audio Processing Objects (sAPOs).
The following topics provide information about the interfaces and the methods that are exposed by the sAPOs.
IAudioMediaType
IAudioProcessingObject
IAudioProcessingObjectConfiguration
IAudioProcessingObjectRT
IAudioSystemEffects2
IAudioSystemEffects
IAudioSystemEffectsCustomFormats
IKeywordDetectorOemAdapter
IPropertyStore
Audio Processing Objects Utility Functions
IAudioSystemEffects
6/25/2019 • 2 minutes to read • Edit Online

The IAudioSystemEffects interface uses the basic methods that are inherited from IUnknown , and must
implement an Initialize method. The parameters that are passed to this Initialize method must be passed directly
to the IAudioProcessingObject::Initialize method.
Refer to the IAudioProcessingObject::Initialize method for information about the structure and the parameters
that are required to implement the IAudioSystemEffects::Initialize method.
IAudioSystemEffects2 interface
12/5/2018 • 2 minutes to read • Edit Online

The IAudioSystemEffects2 interface was introduced with Windows 8.1 for retrieving information about the
processing objects in a given mode.

Members
The IAudioSystemEffects2 interface inherits from IAudioSystemEffects but does not have additional members.

See also
IAudioSystemEffects
IKeywordDetectorOemAdapter interface
6/25/2019 • 2 minutes to read • Edit Online

IKeywordDetectorOemAdapter is a Component Object Model (COM) interface for interacting with the Voice
Activation Driver Interface. The IKeywordDetectorOemAdapter interface is supported in Windows 10 and later
versions of Windows.
The OEM supplies a COM object implementation that acts as an intermediary between the operating system and
the driver, helping to compute or parse the opaque data that is written and read to the audio driver through
KSPROPERTY_SOUNDDETECTOR_PATTERNS and KSPROPERTY_SOUNDDETECTOR_MATCHRESULT .
The class identifier (CLSID) of the COM object is a detector pattern type GUID returned by the
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS . The operating system calls CoCreateInstance
passing the pattern type GUID to instantiate the appropriate COM object that is compatible with keyword pattern
type and calls methods on the object’s IKeywordDetectorOemAdapter interface. The operating supplies a proxy-
stub for IKeywordDetectorOemAdapter . The OEM’s implementation may choose any of the COM threading
models.
The interface design attempts to keep the object implementation stateless. In other words, the implementation
should require no state to be stored between method calls. In fact, internal C++ classes likely do not need any
member variables beyond those required to implement a COM object in general.

Members
The IKeywordDetectorOemAdapter interface inherits from the IUnknown interface but does not have
additional members.
Bluetooth HFP DDI Reference
12/5/2018 • 2 minutes to read • Edit Online

Windows 8 has introduced the GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS class, with interfaces that


implement I/O control codes (IOCTLs) and structures for the Hands-free profile (HFP) bypass audio driver.
For each HFP on a paired Bluetooth device the HFP driver registers an interface in this class. The interface is
registered and enabled after the device is paired and the HFP driver is running. When the driver stops, the interface
is disabled and unregistered.
When you develop a driver for bypass audio connections on a Bluetooth controller, your driver can use these
interfaces to fully implement Bluetooth audio support. The HFP device allows only a single file object on the
GUID_DEVINTERFACE_BLUETOOTH_HFP_SCO_HCIBYPASS device interface.
The following topics describe the structures and IOCTLs that are defined for this class.
Bluetooth HFP DDI Structures
Bluetooth HFP DDI IOCTLs
Bluetooth HFP DDI Structures
10/23/2019 • 2 minutes to read • Edit Online

This section describes the structures that work with the Windows Bluetooth Handsfree profile (HFP) driver.
BTHHFP_DESCRIPTOR
BTHHFP_DESCRIPTOR2
HFP_BYPASS_CODEC_ID_VERSION
HFP_BYPASS_CODEC_ID_V1

Related topics
Bluetooth HFP DDI Reference
Bluetooth HFP DDI IOCTLs
10/23/2019 • 2 minutes to read • Edit Online

Windows 8 introduces a set of I/O control codes (IOCTLs) as part of a DDI that allows the audio driver to work with
the Hands-free profile (HFP) class driver, to operate a Bluetooth audio bypass connection.
Unless otherwise stated, the following is true for all the IOCTLs in this section:
If the request is successful, the Information member of the STATUS_BLOCK structure is set to the size, in
bytes, of the output buffer. Otherwise, the Information member is set to zero. The Status member is set to an
NTSTATUS value.
All IOCTLS require IRQL <= PASSIVE_LEVEL.
The audio driver should use the IOCTLs with the IRP_MJ_DEVICE_CONTROL request.
For most of the IOCTL function codes, the audio driver must initialize the FileObject pointer in the
IO_STACK_LOCATION for the HFP driver when the audio driver initializes a device control IRP to send to the HFP
driver. The audio driver typically retrieves the file object pointer by calling IoGetDeviceObjectPointer.
The audio driver will likely send many of these requests on an arbitrary thread (in other words, an “asynchronous”
request). In these cases the audio driver will need to build the IRP itself using the IoAllocateIrp method, and set
fields in the IRP directly rather than calling IoBuildDeviceIoControlRequest.
The following topics provide more details about these Windows 8 IOCTLs:
IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR
IOCTL_BTHHFP_DEVICE_GET_VOLUMEPROPERTYVALUES
IOCTL_BTHHFP_DEVICE_GET_KSNODETYPES
IOCTL_BTHHFP_DEVICE_GET_CONTAINERID
IOCTL_BTHHFP_DEVICE_REQUEST_CONNECT
IOCTL_BTHHFP_DEVICE_REQUEST_DISCONNECT
IOCTL_BTHHFP_DEVICE_GET_CONNECTION_STATUS_UPDATE
IOCTL_BTHHFP_SPEAKER_SET_VOLUME
IOCTL_BTHHFP_SPEAKER_GET_VOLUME_STATUS_UPDATE
IOCTL_BTHHFP_MIC_SET_VOLUME
IOCTL_BTHHFP_MIC_GET_VOLUME_STATUS_UPDATE
IOCTL_BTHHFP_STREAM_OPEN
IOCTL_BTHHFP_STREAM_CLOSE
IOCTL_BTHHFP_STREAM_GET_STATUS_UPDATE
Windows 8.1 has updated the set of IOCTLs by adding the following new ones:
IOCTL_BTHHFP_DEVICE_GET_DESCRIPTOR2
IOCTL_BTHHFP_DEVICE_GET_NRECDISABLE_STATUS_UPDATE
Windows 10 has updated the set of IOCTLs by adding the following new one:
IOCTL_BTHHFP_DEVICE_GET_CODEC_ID
For information about the structures that work with these IOCTLs, see Bluetooth HFP DDI Structures.

Related topics
Bluetooth HFP DDI Structures
High Definition Audio DDI Reference
10/23/2019 • 2 minutes to read • Edit Online

This section is a technical reference that describes the routines in the three versions of the High Definition (HD)
Audio device driver interface (DDI) that the HDAUDIO_BUS_INTERFACE , HDAUDIO_BUS_INTERFACE_V2 and
HDAUDIO_BUS_INTERFACE_BDL structures define. It also describes the types of structures that these routines
use as parameters.
For more information about the DDI, see High Definition Audio DDI.
Two sets of reference pages are presented:
HD Audio DDI Routines
HD Audio DDI Structures
HD Audio DDI Enumerations
HD Audio DDI Routines
10/23/2019 • 2 minutes to read • Edit Online

As explained in Differences Between the HD Audio DDI Versions, three versions of the HD Audio DDI exist. These
three DDI versions are defined by the HDAUDIO_BUS_INTERFACE , HDAUDIO_BUS_INTERFACE_V2 , and
HDAUDIO_BUS_INTERFACE_BDL structures.
The three DDI versions are accessible only in kernel mode.
Each DDI version provides access to the hardware resources that the HD Audio bus controller manages. These
resources include codecs, DMA engines, link bandwidth, link position registers, and a wall clock register. The HD
Audio bus driver implements the DDI and exposes the DDI to its children. The children are instances of kernel-
mode function drivers that use the DDI to manage the hardware codecs that are connected to the HD Audio
controller.
To obtain access to a DDI version, a function driver must query the HD Audio bus driver for a DDI context object.
For more information, see Obtaining an HDAUDIO_BUS_INTERFACE DDI Object, Obtaining an
HDAUDIO_BUS_INTERFACE_V2 DDI Object, and Obtaining an HDAUDIO_BUS_INTERFACE_BDL DDI Object.
Each routine in the three DDI versions takes a pointer to the context object as its first call parameter.
The HDAUDIO_BUS_INTERFACE structure defines a DDI that contains the following routines:
AllocateCaptureDmaEngine
AllocateDmaBuffer
AllocateRenderDmaEngine
ChangeBandwidthAllocation
FreeDmaBuffer
FreeDmaEngine
GetDeviceInformation
GetLinkPositionRegister
GetResourceInformation
GetWallClockRegister
RegisterEventCallback
SetDmaEngineState
TransferCodecVerbs
UnregisterEventCallback
The HDAUDIO_BUS_INTERFACE_V2 structure is available in Windows Vista and later versions of Windows, and it
defines a DDI that contains the following routines:
AllocateCaptureDmaEngine
AllocateDmaBuffer
AllocateDmaBufferWithNotification
AllocateRenderDmaEngine
ChangeBandwidthAllocation
FreeDmaBuffer
FreeDmaBufferWithNotification
FreeDmaEngine
GetDeviceInformation
GetLinkPositionRegister
GetResourceInformation
GetWallClockRegister
RegisterEventCallback
RegisterNotificationEvent
SetDmaEngineState
TransferCodecVerbs
UnregisterEventCallback
UnregisterNotificationEvent
The HDAUDIO_BUS_INTERFACE version of the HD Audio DDI is supported in Windows Vista and later versions of
Windows. In addition, a version of the HD Audio bus driver that supports this DDI can be installed in Windows
2000, Windows XP, and Windows Server 2003.
The HDAUDIO_BUS_INTERFACE_BDL structure defines a DDI that contains the following routines:
AllocateCaptureDmaEngine
AllocateContiguousDmaBuffer
AllocateRenderDmaEngine
ChangeBandwidthAllocation
FreeContiguousDmaBuffer
FreeDmaEngine
GetDeviceInformation
GetLinkPositionRegister
GetResourceInformation
GetWallClockRegister
RegisterEventCallback
SetDmaEngineState
SetupDmaEngineWithBdl
TransferCodecVerbs
UnregisterEventCallback
A version of the HD Audio bus driver that supports the HDAUDIO_BUS_INTERFACE_BDL version of the HD Audio
DDI can be installed in Windows 2000, Windows XP, and Windows Server 2003. However, Windows Vista provides
no support for this DDI version.
Most of the routines in the two DDIs are identical in both name and operation. However, the following two routines,
which are part of the HDAUDIO_BUS_INTERFACE version of the DDI, are not included in the
HDAUDIO_BUS_INTERFACE_BDL version:
AllocateDmaBuffer
FreeDmaBuffer
Similarly, the following three routines in the HDAUDIO_BUS_INTERFACE_BDL version of the DDI are not part of the
HDAUDIO_BUS_INTERFACE version:
AllocateContiguousDmaBuffer
FreeContiguousDmaBuffer
SetupDmaEngineWithBdl
This section describes the following DDI routines:
AllocateCaptureDmaEngine
AllocateContiguousDmaBuffer
AllocateDmaBuffer
AllocateRenderDmaEngine
ChangeBandwidthAllocation
FreeContiguousDmaBuffer
FreeDmaBuffer
FreeDmaEngine
GetDeviceInformation
GetLinkPositionRegister
GetResourceInformation
GetWallClockRegister
RegisterEventCallback
SetDmaEngineState
SetupDmaEngineWithBdl which works with PHDAUDIO_BDL_ISR
TransferCodecVerbs
UnregisterEventCallback
The preceding list contains all the routines that appear in either or both versions of the DDI.
HD Audio DDI Structures
10/23/2019 • 2 minutes to read • Edit Online

The routines in the two versions of the HD Audio DDI use the following structure types:
HDAUDIO_BUFFER_DESCRIPTOR
HDAUDIO_BUS_INTERFACE
HDAUDIO_BUS_INTERFACE_V2
HDAUDIO_BUS_INTERFACE_BDL
HDAUDIO_CODEC_COMMAND
HDAUDIO_CODEC_RESPONSE
HDAUDIO_CODEC_TRANSFER
HDAUDIO_CONVERTER_FORMAT
HDAUDIO_DEVICE_INFORMATION
HDAUDIO_STREAM_FORMAT
HD Audio DDI Enumerations
10/23/2019 • 2 minutes to read • Edit Online

[Some information relates to pre-released product which may be substantially modified before it's commercially
released. Microsoft makes no warranties, express or implied, with respect to the information provided here.]
This section describes the enumerations that are used by various HD audio properties and structures.
HDAUDIO_CODEC_POWER_STATE
HDAUDIO_STREAM_STATE
DRM Functions
10/23/2019 • 2 minutes to read • Edit Online

This section describes the DRM functions, which drivers use to manage the digital rights of kernel-streaming audio
content in Windows. System driver component Drmk.sys contains the entry points for these functions. The
definitions for these functions appear in header file drmk.h. For more information, see Digital Rights Management.
This section describes the following DRM functions:
DrmAddContentHandlers
DrmCreateContentMixed
DrmDestroyContent
DrmFor wardContentToDeviceObject
DrmFor wardContentToFileObject
DrmFor wardContentToInterface
DrmGetContentRights
In addition, this section describes the following macro:
DEFINE_DRMRIGHTS_DEFAULT
Audio Device Messages for MIDI
6/25/2019 • 2 minutes to read • Edit Online

In Windows XP and later versions of Windows (including Windows Vista), the operating system communicates with
musical instrument digital interface (MIDI) input and output drivers by using audio device messages.
Every MIDI input and output driver must have one DriverProc entry-point function to enable or disable the driver.
Additionally, it must have an additional entry-point function to process messages from the Windows operating
system. In the case of MIDI output drivers, the additional entry-point function is modMessage , which must be
provided by the manufacturer of the MIDI device. This function processes messages that WINMM sends to the MIDI
output driver. WINMM is a Windows dynamic link library (DLL) module that contains functions that help the
operating system and the MIDI output driver communicate with each other. Specifically, WINMM helps to manage
16-bit multimedia applications that run on Windows.
Each message received by the modMessage function comes with two pointers to DWORD variables
(DWORD_PTR). For some messages, one of these parameters points to a structure that contains additional
information from the client, or it points to an empty structure for the driver to fill with information for the client.
One example of such a structure is MIDIOPENDESC . There are two other structures used by MIDI output device
drivers and they are discussed in the Windows SDK. For more information about these structures, see MIDIHDR
and MIDIOUTCAPS.
The following is a list of the audio device messages and the modMessage entry-point function that processes
them for a MIDI output driver:
modMessage
MODM_CACHEDRUMPATCHES
MODM_CACHEPATCHES
MODM_DATA
MODM_GETDEVCAPS
MODM_GETNUMDEVS
MODM_GETPOS
MODM_GETVOLUME
MODM_LONGDATA
MODM_OPEN
MODM_PAUSE
MODM_PREPARE
MODM_PROPERTIES
MODM_RESET
MODM_RESTART
MODM_SETVOLUME
MODM_STOP
MODM_STRMDATA
MODM_UNPREPARE
MOM_CLOSE
MOM_DONE
MOM_OPEN
Legacy Audio Device Messages
6/25/2019 • 2 minutes to read • Edit Online

The following Windows Multimedia functions provide a way for callers to pass messages to legacy audio devices:
waveInMessage
waveOutMessage
midiInMessage
midiOutMessage
mixerMessage
auxOutMessage
Some of these device messages are handled directly by the device driver, and some are handled by the system on
behalf of the device.
This section describes only messages that are intercepted by the system and handled without ever being passed to
the device driver. For more information, see System-Intercepted Device Messages.
Each message described in this section is valid for use with one or more of the six xxxMessage functions in the
preceding list.
This section describes the following messages:
DRV_QUERYDEVICEINTERFACE
DRV_QUERYDEVICEINTERFACESIZE
DRV_QUERYDEVNODE
DRV_QUERYMAPPABLE
DRVM_MAPPER_CONSOLEVOICECOM_GET
DRVM_MAPPER_PREFERRED_GET
Audio INF File Settings
12/5/2018 • 2 minutes to read • Edit Online

The following INF file keywords are defined for installing media-class device drivers and configuring audio
processing modes:
PKEY_APO_SWFallback_ProcessingModes
PKEY_AudioDevice_EnableEndpointByDefault
PKEY_AudioDevice_NeverSetAsDefaultEndpoint
PKEY_AudioEndpoint_Default_VolumeInDb
PKEY_AudioEngine_OEMFormat
PKEY_AudioEngine_OEMPeriod
PKEY_CompositeFX_EndpointEffectClsid
PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid
PKEY_CompositeFX_KeywordDetector_ModeEffectClsid
PKEY_CompositeFX_KeywordDetector_StreamEffectClsid
PKEY_CompositeFX_ModeEffectClsid
PKEY_CompositeFX_Offload_ModeEffectClsid
PKEY_CompositeFX_Offload_StreamEffectClsid
PKEY_CompositeFX_StreamEffectClsid
PKEY_FX_EndpointEffectClsid
PKEY_FX_ModeEffectClsid
PKEY_FX_StreamEffectClsid
PKEY_EFX_ProcessingModes_Suppor ted_For_Streaming
PKEY_MFX_ProcessingModes_Suppor ted_For_Streaming
PKEY_SFX_ProcessingModes_Suppor ted_For_Streaming
PKEY_FX_KeywordDetector_StreamEffectClsid
PKEY_FX_KeywordDetector_ModeEffectClsid
PKEY_FX_KeywordDetector_EndpointEffectClsid
PKEY_SFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming
PKEY_MFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming
PKEY_EFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming
SetupPreferredAudioDevices
UsePositionLock
SetupPreferredAudioDevices
6/25/2019 • 3 minutes to read • Edit Online

The SetupPreferredAudioDevices keyword denotes the preferred audio device, which is the device that the audio
system enables by default when the system contains one or more audio devices. This keyword is media-class
specific and is supported by Microsoft Windows Millennium Edition/Windows 98, Microsoft Windows 2000,
Windows XP, and Windows Vista. SetupPreferredAudioDevicesis not supported in Windows 7.
When creating an audio device, an application program can elect to use the default (or preferred) device instead of
explicitly specifying a device. (For example, see the descriptions of the waveOutOpen and DirectSoundCreate
functions in the Microsoft Windows SDK documentation.)
The audio system keeps track of the current preferred audio device in the system registry. When a user upgrades a
system by installing a new audio device, the proprietary INF file that installs the device typically updates the
registry to designate the new device as the preferred audio device.
The SetupPreferredAudioDevices keyword can appear within a registry-update directive in the add-registr y-
section (see INF AddReg Directive ) of an INF file for an audio device. This directive has the following format:
reg-rootkey, [reg-subkey]SetupPreferredAudioDevices [flags], [dword-value]
The directive instructs the audio system to use the device's audio functions as the defaults for sound playback,
sound recording, and MIDI music playback. Following installation, these three defaults appear in the Sounds and
Multimedia control panel under the Audio tab. The user can use Control Panel to change the default devices.
The directive's dword-value parameter specifies a DWORD value that should be nonzero in order to enable the
directive. If this value is zero, the directive has no effect. Because Windows Me/98 do not support the REG_DWORD
registry data type, however, dword-value is typically expressed as a 4-byte REG_BINARY type instead of as a
DWORD (for example, as "01,00,00,00" instead of "0x00000001"). The dword-value parameter can be specified in
raw binary format by setting the directive's flags parameter to "1" (FLG_ADDREG_BINVALUETYPE).
The directive takes effect at the time that the driver for the device is installed. If another device occupies the role of
preferred device at the time that the new device is installed, the directive causes the new device to assume the role
of preferred device, thus displacing the other device from this role.
When upgrading or reinstalling the driver for a device that has already been installed, you may want to avoid
altering the user's current preferred-device selections for sound playback, sound recording, and MIDI music
playback. If so, set the FLG_ADDREG_NOCLOBBER bit in the flags parameter, which causes the directive to take
effect only if this is the device's initial installation.
Example
The following example is a part of an INF file that shows how to use the SetupPreferredAudioDevices keyword:

AddReg = XYZ-Audio-Device.AddReg
...
[XYZ-Audio-Device.AddReg]
HKR,,SetupPreferredAudioDevices,3,01,00,00,00

The directive at the end of the example specifies that the device named "XYZ-Audio-Device" is now the preferred
audio device. HKR is the audio device's root key in the registry. The flags parameter is set to 3, which is the bitwise
OR of FLG_ADDREG_BINVALUETYPE and FLG_ADDREG_NOCLOBBER. The latter prevents the device's existing
preferred-device registry entries from getting overwritten in the event that the device is already installed and its
driver is merely being upgraded. The four bytes at the end of the directive specify a nonzero value, which is
necessary to enable the directive.
With the current implementation of the SetupPreferredAudioDevices keyword in Windows Vista, any audio
endpoint with its dword-value set to an odd number can be set as the default device. To make sure that the correct
endpoint is set as the default device, make sure that the KS filter that contains the relevant endpoint is exposed last.
You have to do this because of the algorithm that the AudioEndpointBuilder service uses to populate property
stores and setting default devices.
PKEY_APO_SWFallback_ProcessingModes
12/5/2018 • 2 minutes to read • Edit Online

Starting in Windows 10 version 1809, the PKEY_APO_SWFallback_ProcessingModes property key identifies the
modes that can fallback to software processing. The driver developer should list all of the mode effect processing
modes that support software fallback that their driver supports. This list needs to encompass all the modes that the
driver supports in hardware.
If a stream is requested for one of these modes and there are insufficient HW resources available to open a pin in
that processing mode, a pin will be opened in the RAW mode and the SW APO initialized with the requested
processing mode will be used instead. Because of this, drivers that would like to support software fallback of HW
processing modes, must support RAW mode. For more information about audio modes, see Audio Signal
Processing Modes. SW fallback applies only to the HOST pin.
SW fallback is triggered when a stream is created and there aren’t available resources in the hardware. The OS
does a direct query to the driver for available resources to determine if SW fallback is required. The OS uses
knowledge of the driver, such as how many pin instances are supported by the driver, to determine if there are not
sufficient HW resources. If the HW resources are not available SW fallback is used to create streams on the RAW
pin. The SW fallback process is managed by the OS and requires no input from the driver when SW fallback occurs.
The driver does not need to return any additional specific error codes to use SWFallback.
If audio constraints have been specified, the OS will do an additional check against those. For more information,
see Audio Hardware Resource Management.
The driver needs to have the supported fallback modes in their FxPropertyStore. Any
AUDIO_SIGNALPROCESSINGMODEs for SWFallback need to be added to the FxPropertyStore for the driver under
PKEY_APO_SWFallback_ProcessingModes which is {D3993A3F-99C2-4402-B5EC-A92A0367664B},13. This will
allow for them to be recognized for SWFallback.
PKEY_APO_SWFallback_ProcessingModes Definition
PKEY_APO_SWFallback_ProcessingModes is defined as shown here.

PKEY_APO_SWFallback_ProcessingModes (REG_MULTI_SZ) = {D3993A3F-99C2-4402-B5EC-A92A0367664B},13

INF File Sample


The INF file property key lists the signal processing modes supported by the host connector that are available for
fallback to SW APO if sufficient HW resources aren't available.
An INF file specifies settings for in the add-registry section for that device. The following INF example shows the
strings and add-registry sections that loads the APO SW fallback processing modes into the registry. In this
example four modes are implemented, raw, default, movie and communications.
[Strings]
PKEY_APO_SWFallback_ProcessingModes = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},13"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS = "{98951333-B9CD-48B1-A0A3-FF40682D73F7}"
...
[PKEY.APO.SWFallback.AddReg]
;Include all supported modes:
HKR,"FX\\0",%PKEY_APO_SWFallback_ProcessingModes%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_S
IGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Related topics
Media-Class INF Extensions
Send comments about this topic to Microsoft
PKEY_AudioDevice_EnableEndpointByDefault
1/15/2020 • 2 minutes to read • Edit Online

In Windows 7 and later versions of Windows, the endpoint builder categorizes endpoints into form factors. These
form factors are based on the KSNODETYPE GUID of a pin on the kernel streaming (KS) filter to which the endpoint
is connected. When the audio endpoint builder enumerates certain endpoints, for example those with form factor
types such as UnknownFormFactor, the endpoint builder creates these endpoints as disabled and hidden. So you
must use the Sound program in Control Panel to enable such endpoints before you can use them.
If you want to override this behavior so that your endpoint is created as enabled or disabled by default, Windows 7
provides the PKEY_AudioDevice_EnableEndpointByDefault registry key that allows you to do that.
The endpoint builder creates endpoints with any of the following KSNODETYPE values as disabled and hidden.

K S N O DE T Y P E F O RM FA C TO R

KSNODETYPE_ANALOG_CONNECTOR UnknownFormFactor

KSCATEGORY_AUDIO UnknownFormFactor

KSNODETYPE_BIDIRECTIONAL_UNDEFINED UnknownFormFactor

KSNODETYPE_EMBEDDED_UNDEFINED UnknownFormFactor

KSNODETYPE_EQUALIZATION_NOISE UnknownFormFactor

KSNODETYPE_EXTERNAL_UNDEFINED UnknownFormFactor

KSNODETYPE_INPUT_UNDEFINED UnknownFormFactor

KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE UnknownFormFactor

KSNODETYPE_OUTPUT_UNDEFINED UnknownFormFactor

KSNODETYPE_TELEPHONY_UNDEFINED UnknownFormFactor

In Windows 7 and later versions of Windows, endpoints with a form factor of LineLevel but with a KSNODETYPE
not equal to KSNODETYPE_LINE_CONNECTOR are also created as disabled and hidden. The following endpoints
fall into this category.

K S N O DE T Y P E F O RM FA C TO R
K S N O DE T Y P E F O RM FA C TO R

KSNODETYPE_1394_DA_STREAM LineLevel

KSNODETYPE_1394_DV_STREAM_SOUNDTRACK LineLevel

KSNODETYPE_ANALOG_TAPE LineLevel

KSNODETYPE_CABLE_TUNER_AUDIO LineLevel

KSNODETYPE_CD_PLAYER LineLevel

KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE LineLevel

KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE LineLevel

KSNODETYPE_DSS_AUDIO LineLevel

KSNODETYPE_DVD_AUDIO LineLevel

KSNODETYPE_LEGACY_AUDIO_CONNECTOR LineLevel

KSNODETYPE_MINIDISK LineLevel

KSNODETYPE_MULTITRACK_RECORDER LineLevel

KSNODETYPE_PHONOGRAPH LineLevel

KSNODETYPE_RADIO_RECEIVER LineLevel

KSNODETYPE_RADIO_TRANSMITTER LineLevel

KSNODETYPE_SATELLITE_RECEIVER_AUDIO LineLevel

KSNODETYPE_SYNTHESIZER LineLevel

KSNODETYPE_TV_TUNER_AUDIO LineLevel

KSNODETYPE_VCR_AUDIO LineLevel
K S N O DE T Y P E F O RM FA C TO R

KSNODETYPE_VIDEO_DISC_AUDIO LineLevel

The following INF file snippet shows how to use PKEY_AudioDevice_EnableEndpointByDefault to enable or
disable an endpoint by default.

[Version]
Signature="$Windows NT$"
Class=MEDIA
ClassGuid= {4d36e96c-e325-11ce-bfc1-08002be10318}
...

[USBAudio]
...

[USBAudio.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface
...

[USBAudio.Interface]
AddReg=Xyz.AddReg
...

;; AddReg section to set default behavior of endpoint


[Xyz.AddReg]
HKR,"EP\\n",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_GUID%
HKR,"EP\\n",%PKEY_AudioDevice_EnableEndpointByDefault%,0x00010001,EnableEndpointByDefaultMaskValue
...

[Strings]
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
PKEY_AudioEndpoint_Association="{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioDevice_EnableEndpointByDefault="{F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},4"
...

In the preceding example, EnableEndpointByDefaultMaskValue represents a DWORD mask value that is a


combination of an enable or a disable flag (FLAG_ENABLE or FLAG_DISABLE) and a data flow flag
(FLOW_MASK_RENDER or FLOW_MASK_CAPTURE).
The following INF file snippet shows how a CD player is set up so that it is enabled by default and is configured as
an input device (FLOW_MASK_CAPTURE).
[Version]
Signature="$Windows NT$"
Class=MEDIA
ClassGuid= {4d36e96c-e325-11ce-bfc1-08002be10318}
...

[USBAudio]
...

[USBAudio.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface
...

[USBAudio.Interface]
AddReg=MDVAD.EPProperties.AddReg
...

;; AddReg section is used to set default behavior of endpoint for CD player.


;; Enable by default for KSNODETYPE_CD_PLAYER
[MDVAD.EPProperties.AddReg]
HKR,"EP\\0",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_CD_PLAYER%
HKR,"EP\\0",%PKEY_AudioDevice_EnableEndpointByDefault%,0x00010001,0x00000201
...

[Strings]
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
KSNODETYPE_CD_PLAYER="{DFF220E3-F70F-11D0-B917-00A0C9223196}"
PKEY_AudioEndpoint_Association="{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioDevice_EnableEndpointByDefault="{F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},4"

In the preceding example, the bitwise OR combination of FLOW_MASK_CAPTURE and FLAG_ENABLE is equivalent
to the bitwise OR combination of 0x00000200 and 0x00000001 with a result of 0x00000201. The following table
shows the values of the flags and masks that you can use with PKEY_AudioDevice_EnableEndpointByDefault .

F L A G O R EN DP O IN T M A SK VA L UE

FLAG_DISABLE 0x00000000

FLAG_ENABLE 0x00000001

FLOW_MASK_CAPTURE 0x00000200

FLOW_MASK_RENDER 0x00000100
PKEY_AudioDevice_NeverSetAsDefaultEndpoint
1/15/2020 • 2 minutes to read • Edit Online

You might decide to set up certain devices so that they can never be selected as default devices. These include, for
example, modem lines and medical audio devices.Windows 7 and later versions of Windows provide the
PKEY_AudioDevice_NeverSetAsDefaultEndpoint registry key to allow you to prevent the selection of the
endpoint of a device as the default endpoint.
The following INF file excerpt shows how to use PKEY_AudioDevice_NeverSetAsDefaultEndpoint to set up an
endpoint so that it can never be selected as default.

[Version]
Signature="$Windows NT$"
Class=MEDIA
ClassGuid= {4d36e96c-e325-11ce-bfc1-08002be10318}
...

[USBAudio]
...

[USBAudio.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface
...

[USBAudio.Interface]
AddReg=Xyz.AddReg
...

;; AddReg section to setup endpoint so that


;; it cannot be selected as the default endpoint.
[Xyz.AddReg]
HKR,"EP\\n",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_GUID%
HKR,"EP\\n",%PKEY_AudioDevice_NeverSetAsDefaultEndpoint%,0x00010001,NeverSetAsDefaultEndpointMaskValue
...

[Strings]
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
PKEY_AudioEndpoint_Association="{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioDevice_NeverSetAsDefaultEndpoint = "{F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},3"
...

In the preceding example, NeverSetAsDefaultEndpointMaskValue represents a DWORD mask value that is a


combination of device role flags and data flow flags.
The following INF file snippet shows how an undefined output device (KSNODETYPE_OUTPUT_UNDEFINED) is set
up so that its endpoint is never selected as default, regardless of the device role and the data flow direction.
[Version]
Signature="$Windows NT$"
Class=MEDIA
ClassGuid= {4d36e96c-e325-11ce-bfc1-08002be10318}
...

[USBAudio]
...

[USBAudio.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface
...

[USBAudio.Interface]
AddReg=MDVAD.EPProperties.AddReg
...

;; AddReg section to setup endpoint so that


;; it cannot be selected as the default endpoint.
[MDVAD.EPProperties.AddReg]
HKR,"EP\\0",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_OUTPUT_UNDEFINED%
HKR,"EP\\0",%PKEY_AudioDevice_NeverSetAsDefaultEndpoint%,0x00010001,0x00000305
...

[Strings]
KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}"
KSNODETYPE_OUTPUT_UNDEFINED="{DFF21CE0-F70F-11D0-B917-00A0C9223196}"
PKEY_AudioEndpoint_Association="{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioDevice_NeverSetAsDefaultEndpoint = "{F3E80BEF-1723-4FF2-BCC4-7F83DC5E46D4},3"

In the preceding example, 0x00000305 is the bitwise OR combination of all the flags and masks available for
PKEY_AudioDevice_NeverSetAsDefaultEndpoint . The following table shows the flags and masks and their
values.

F L A G O R EN DP O IN T M A SK VA L UE

FLOW_MASK_CAPTURE 0x00000200

FLOW_MASK_RENDER 0x00000100

ROLE_MASK_COMMUNICATION 0x00000004

ROLE_MASK_CONSOLE 0x00000001
PKEY_AudioEndpoint_Default_VolumeInDb
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 Version 1605 and later, the PKEY_AudioEndpoint_Default_VolumeInDb property key


configures the default volume (in dB) for the software volume node. The driver developer should provide the
default dB value that they would like to set.
If an audio driver is not implementing hardware volume node for an endpoint, the OS inserts a software volume
node to control volume on that endpoint. There are situations, where the default volume value is too low. This INF
key provides the user a better experience when appropriate gain or attenuation is applied to audio signal.

Remarks
IHVs and OEMs can override the default software volume value for an endpoint by setting
PKEY_AudioEndpoint_Default_VolumeInDb on a topology filter using the driver INF file. The value specified by the
key is in dB units.
This key will be used for both render and capture endpoints.
This key is ignored if the endpoint has implemented a hardware volume node.
Any value can be set, but the OS will make sure that the value it is within the min and max value settings. For
example, if the specified value is greater than max volume value, OS will set the default value to the max volume
value.
The data is stored as a 16.16 fixed point value. The upper 16 bits are used for the whole number of the value and
the lower 16 bits are used for the fractional portion of the value.

INF File Sample


; The following line overrides the default volume (in dB) for an endpoint.
; It is only applicable when hardware volume is not implemented.
; Decimal value expressed in fixed point 16.16 format and stored as a DWORD.

PKEY_AudioEndpoint_Default_VolumeInDb = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},9"

; 10 dB
HKR,EP\0,%PKEY_AudioEndpoint_Default_VolumeInDb%,0x00010001,0xA0000

;-10 dB
;HKR,EP\0,%PKEY_AudioEndpoint_Default_VolumeInDb%,0x00010001,0xFFF60000

Related topics
Media-Class INF Extensions
PKEY_AudioEngine_OEMFormat
10/23/2019 • 4 minutes to read • Edit Online

In Windows Vista and later, the PKEY_AudioEngine_OEMFormat property key identifies the default stream
format for an audio endpoint device. Both rendering and capture devices have default formats. The global audio
engine uses a device's default format to connect to the device for shared-mode operation. The INF file that installs
the device loads the device's default format into the registry. The user can change the default format through the
Windows multimedia control panel (Mmsys.cpl). Windows XP and previous versions of Windows do not support
the PKEY_AudioEngine_OEMFormat property key.
An INF file specifies the default format for an audio endpoint device in the add-registry section for that device. The
following INF example shows an add-registry section that loads the default format for an endpoint device into the
registry.

;;
;; Identify endpoint device as a set of speakers.
;; Set default format to 48-kHz, 16-bit stereo.
;; Add endpoint extension property page.
;;
[OEMSettingsOverride.AddReg]
HKR,"EP\\0", %PKEY_AudioEndpoint_Association%,,%KSNODETYPE_SPEAKER%
HKR,"EP\\0", %PKEY_AudioEngine_OEMFormat%, %REG_BINARY%, 41,00,00,00,28,00,00,00,
FE,FF,02,00,80,BB,00,00,00,EE,02,00,04,00,10,00,16,00,10,00,03,00,00,00,01,00,
00,00,00,00,10,00,80,00,00,AA,00,38,9B,71
HKR,"EP\\0", %PKEY_AudioEndpoint_ControlPanelProvider%,,%AUDIOENDPOINT_EXT_UI_CLSID

The preceding example is taken from the file Sysfx.inf in the Sysfx audio sample in the Windows Driver Kit. The
Strings section of this INF file contains the following definitions.

PKEY_AudioEndpoint_ControlPanelProvider = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},1"
PKEY_AudioEndpoint_Association = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioEngine_OEMFormat = "{E4870E26-3CC5-4CD2-BA46-CA0A9A70ED04},3"

In the preceding example, the name of the add-registry section, OEMSettingsOverride.AddReg, is defined by an
AddReg directive in an interface installation section in Sysfx.inf. The preceding example adds several properties of
endpoint number 0 (identified by the string "EP\\0") to the registry entry for the device interface. (If a device
interface represents a wave filter with more than one endpoint, the additional endpoints are numbered 1, 2, and so
on.) For more information about interface installation sections, see INF AddInterface Directive .
After the INF file has created the three property keys and loaded their associated values into the registry,
applications can access the properties by obtaining the IPropertyStore interface for the endpoint device. Header file
Mmdeviceapi.h in the Windows SDK contains C/C++ definitions of the three property keys. For more information
about obtaining the IPropertyStore interface, see the description of the IMMDevice::OpenProper tyStore method
in the Windows SDK documentation.
In the preceding INF example, the PKEY_AudioEndpoint_Association property key identifies the KS pin category
GUID for the endpoint device. The PKEY_AudioEndpoint_ControlPanelProvider property key identifies the
class GUID for the COM interface object that supplies the property values to the property page in Mmsys.cpl for
the endpoint device. For more information about these property keys, see the Windows SDK documentation. For
more information about KS pin category GUIDs, see Pin Category Property.
In the preceding INF example, the property value that is associated with the PKEY_AudioEngine_OEMFormat
property key is a 48-byte REG_BINARY value that contains a serialized representation of the WAVEFORMATEX or
WAVEFORMATEXTENSIBLE structure that describes the format. To calculate the REG_BINARY data value to
associate with the PKEY_AudioEngine_OEMFormat property key, embed the WAVEFORMATEX or
WAVEFORMATEXTENSIBLE structure in a PropVariant structure, and serialize the PropVariant structure by
calling the StgSerializePropVariant function. For more information about the PropVariant structure and the
StgSerializePropVariant function, see the Windows SDK documentation.
The following code example is a console application that prints the REG_BINARY data that appears in the preceding
INF example.
//
// Embed a WAVEFORMATEXTENSIBLE structure in a PropVariant
// container, and print the PropVariant structure as a
// serialized stream of bytes in REG_BINARY format.
//

#include <stdio.h>
#include <wtypes.h>
#include <propidl.h>
#include <propvarutil.h>
#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>

void PrintSerializedFormat(WAVEFORMATEX *pWfx)


{
HRESULT hr;
PROPVARIANT var;
SERIALIZEDPROPERTYVALUE* pVal;
ULONG cb;

// Create a VT_BLOB from the WAVEFORMATEX structure.


var.vt = VT_BLOB;
var.blob.cbSize = sizeof(*pWfx) + pWfx->cbSize;
var.blob.pBlobData = (BYTE*)pWfx;

// Serialize the PROPVARIANT structure. The serialized byte stream


// will eventually be written to the registry as REG_BINARY data.
hr = StgSerializePropVariant(&var, &pVal, &cb);
if (SUCCEEDED(hr))
{
// Write the binary data to stdout. Format the output so you can
// copy and paste it directly into the INF file as REG_BINARY data.
for (UINT i = 0; i < cb; i++)
{
BYTE b = ((BYTE*)pVal)[i];
wprintf(L"%2.2X,", b);
}

wprintf(L"\n");
CoTaskMemFree(pVal);
}
}

//
// Use a WAVEFORMATEXTENSIBLE structure to specify the format
// for a 48-kHz, 16-bit, (2-channel) stereo audio stream.
//
void main()
{
WAVEFORMATEXTENSIBLE wfx;

wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nChannels = 2;
wfx.Format.nSamplesPerSec = 48000;
wfx.Format.nAvgBytesPerSec = 4*48000;
wfx.Format.nBlockAlign = 4;
wfx.Format.wBitsPerSample = 16;
wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = 3;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

PrintSerializedFormat(&wfx.Format);
}
The main function in the preceding code example creates a WAVEFORMATEXTENSIBLE structure to describe the
default format. You can modify the main function to create a WAVEFORMATEX or WAVEFORMATEXTENSIBLE
structure to describe the default format for your endpoint device.
The PrintSerializedFormat function in the preceding code example serializes the format description and prints the
serialized format description as REG_BINARY data. You can copy the printed output produced by the function and
paste it into your INF file.
PKEY_AudioEngine_OEMPeriod
6/25/2019 • 2 minutes to read • Edit Online

The Windows audio engine runs at predetermined intervals that are referred to as the periodicity of the audio
engine. In Windows 7 and later versions of Windows, the audio engine runs with a periodicity of 10ms by default.
In Windows 7, you can use an INF file and a new registry key, PKEY_AudioEngine_OEMPeriod , to customize the
periodicity for your audio device driver. This is a per endpoint setting.
The following excerpt from an INF file shows how to use the INF AddReg directive to customize the periodicity
for an audio device driver.

[Version]
Signature="$CHICAGO$"
Class=MEDIA
Provider=%MSFT%
...
[USBAudio]
Include=ks.inf, wdmaudio.inf, wdma_usb.inf
Needs=KS.Registration, WDMAUDIO.Registration, USBAudio.CopyList, USBAudioOEM.AddReg

[USBAudio.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface
AddInterface=%KSCATEGORY_RENDER%,"GLOBAL",USBAudio.Interface

[USBAudio.Interface]
AddReg=USBAudio.Interface.AddReg, OEMSettingsOverride.AddReg
...
;;
;; All EP\\0 entries in the same grouping
;;
;; Set default periodicity to 8ms
;;
;; 0x013880 == 80000 (HNSTIME) == 8ms
;;
[OEMSettingsOverride.AddReg]
HKR,"EP\\0", %PKEY_AudioEndpoint_Association%,,%KSNODETYPE_ANY%
HKR,"EP\\0", %PKEY_AudioEngine_OEMPeriod%, %REG_BINARY%, 41,00,63,00,08,00,00,00,80,38,01,00,00,00,00,00

[Strings]
PKEY_AudioEndpoint_Association = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2"
PKEY_AudioEngine_OEMPeriod = "{E4870E26-3CC5-4CD2-BA46-CA0A9A70ED04},6"
REG_BINARY = "0x00000001"

Periodicity is specified as VT_BLOB. And the valid periodicity range is 50000-90000 (5-9ms) on even 10000
HNSTIME unit boundaries (for example, 50000, 60000, 70000, 80000 or 90000).
In the preceding excerpt from an INF file, the following REG_BINARY data is provided for customization:
The periodicity of 8ms is represented in HNSTIME units as 80000. In hexadecimal notation this value is represented
as 0x013880. When this hexadecimal value is written four bits (nibbles) at a time, with least significant bits first, the
result is 80,38,01. This is the value that is provided as a REG_BINARY data type.
Periodicity is specified as a VT_BLOB data type. This is represented by a decimal value of 65. In hexadecimal format
65 is represented by the value 41 and the preceding INF file excerpt shows the REG_BINARY data sequence with its
first value of 41.
PKEY_CompositeFX_EndpointEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows release 1803 and later, the PKEY_CompositeFX_EndpointEffectClsid property key identifies the
end point effects (EFX) in place. The driver developer should specify the list of supported processing modes that
their driver supports.
This property key is identical to the PKEY_FX_EndpointEffectClsid property key, but it is a composite that is
expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instruct audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies the default format for an audio endpoint device in the add-registry sections for that device. The
following INF example shows the strings and add-registry section that loads the APO for endpoint effects into the
registry.

[Strings]
PKEY_CompositeFX_EndpointEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},15"
...

SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_EndpointEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 Version 1803 and later, the PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid property


key identifies the keyword detector end point effect (EFX) in place. The driver developer should specify the single
supported processing mode that their driver supports for the keyword detector pin.
This property key is identical to the PKEY_FX_KeywordDetector_EndpointEffectClsid property key, but it is a composite
that is expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instruct audio endpoint builder to set the CLSIDs for endpoint APOs into the effects property
store. This information is used to build the audio graph that will be used to inform upper level apps what effects are in
place.

INF File Sample


An INF file specifies the default format for an audio endpoint device in the add-registry sections for that device. The
following INF example shows the strings and add-registry section that loads the APO for an endpoint keyword
detector effects into the registry.

[Strings]
PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},18"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_KeywordDetector_EndpointEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLS
ID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_KeywordDetector_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 Version 1803 and later, the PKEY_CompositeFX_KeywordDetector_ModeEffectClsid property


key identifies the mode effect (MFX) supported by the driver for the keyword detector pin. The driver developer
should specify the single supported processing mode that their driver supports for the keyword detector pin.
This property key is identical to the PKEY_FX_KeywordDetector_ModeEffectClsid property key, but it is a composite
that is expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio mode effects in the add-registry section for that device. The following INF
example shows the strings and add-registry section that loads the APO for a keyword detector mode effects into
the registry.

[Strings]
PKEY_CompositeFX_KeywordDetector_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},17"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_KeywordDetector_ModeEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLS
ID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_KeywordDetector_StreamEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 Version 1803 and later, the PKEY_CompositeFX_KeywordDetector_StreamEffectClsid


property key identifies the stream effect (SFX) supported for the keyword detector by the driver. The driver
developer should specify the single stream effects that their driver supports for the keyword detector pin.
This property key is identical to the PKEY_FX_KeywordDetector_StreamEffectClsid property key, but it is a
composite that is expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio endpoint device in the add-registry section for that device. The following
INF example shows the strings and add-registry sections that loads the APO for a keyword detector stream effect
into the registry.

[Strings]
PKEY_CompositeFX_KeywordDetector_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},16"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_KeywordDetector_StreamEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_C
LSID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 Version 1803 and later, the PKEY_CompositeFX_ModeEffectClsid property key identifies the
mode effect (MFX) supported by the driver. The driver developer should specify the list of supported processing
modes that their driver supports.
This property key is identical to the PKEY_FX_ModeEffectClsid property key, but it is a composite that is expressed
as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio mode effect in the add-registry section for that device. The following INF
example shows the strings and add-registry section that loads the APO for a mode effect into the registry.

[Strings]
PKEY_CompositeFX_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},14"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_ModeEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_Offload_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10, version 1803 and later, the PKEY_CompositeFX_Offload_ModeEffectClsid key identifies the
mode effect (MFX) supported by the driver that will be loaded during offload playback. The driver developer
should specify the list of supported processing modes that their driver supports.
This property key is identical to the PKEY_FX_Offload_ModeEffectClsid property key, but it is a composite that is
expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for mode APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the loads the APO for a mode effect
to be used during offload playback into the registry.

[Strings]
PKEY_CompositeFX_Offload_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},20"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_Offload_ModeEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_Offload_StreamEffectClsid
1/8/2020 • 2 minutes to read • Edit Online

In Windows 10, version 1803 and later, the PKEY_CompositeFX_Offload_StreamEffectClsid property key
identifies the stream effect (SFX) supported by the driver that will be loaded during offload playback. The driver
developer should specify the list of supported stream effects that their driver supports for the offload pin.
This property key is identical to the PKEY_FX_Offload_StreamEffectClsid property key, but it is a composite that is
expressed as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for stream-effect APOs into the
effects property store for offload. This information is used to build the audio graph that will be used to inform
upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the streaming processing modes
supported into the registry.

[Strings]
PKEY_CompositeFX_Offload_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},19"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_Offload_StreamEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_CompositeFX_StreamEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 version 1803 and later, the PKEY_CompositeFX_StreamEffectClsid property key identifies the
stream effect (SCompositeFX) supported by the driver. The driver developer should specify the list of supported
stream effects that their driver supports.
This property key is identical to the PKEY_FX_StreamEffectClsid property key, but it is a composite that is expressed
as a reg multistring in the registry to allow multiple effects in a single position.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio endpoint device in the add-registry section for that device. The following
INF example shows the strings and add-registry sections that loads the APO for a stream effect into the registry.

[Strings]
PKEY_CompositeFX_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},13"
...
; Driver developers should replace this CLSIDs with that of their own APO
SWAP_FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
DELAY_FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...

[SWAPAPO.I.Association0.AddReg]
HKR,FX\0,%PKEY_CompositeFX_StreamEffectClsid%,0x00010000,%SWAP_FX_MODE_CLSID%,%DELAY_FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_Devices_AudioDevice_Microphone_IsFarField
2/20/2019 • 2 minutes to read • Edit Online

In Windows 10 19H1 and later, the PKEY_Devices_AudioDevice_Microphone_IsFarField property key


indicates if the microphone will capture far field audio.
Starting in Windows 10 19H1, using the PKEY_Devices_AudioDevice_Microphone_IsFarField property is a
requirement for systems that support far field audio, typically for use by a voice assistant.
A value of 1 indicates that the microphone will capture far field audio, which will make the microphone a preferred
endpoint for a voice assistant.
A value of 0 or no property key indicates that the microphone does not support far field or support is unknown, so
the endpoint will not be prioritized for use by a voice assistant.
The property should be set via INF, and preferably an extension INF provided by the OEM as opposed to the base
INF for the audio device. For more information about extension INF files, see Creating a componentized audio
driver installation and Using an Extension INF File.

INF File Sample


The sysvad sample ComponentizedAudioSampleExtension.inf file includes this property. The sample shows the
value set to 0x1 indicating the microphone does capture far field audio.

;HKR,EP\1,%PKEY_Devices_AudioDevice_Microphone_IsFarField%,0x00010001,0x1

Requirements

Minimum supported client Windows 10 Version 19H1

Header Ksmedia.h

Related topics
Media-Class INF Extensions
PKEY_FX_KeywordDetector_StreamEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_FX_KeywordDetector_StreamEffectClsid property key identifies the stream
effect (SFX) supported for the keyword detector by the driver. The driver developer should specify the single
stream effects that their driver supports for the keyword detector pin.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio endpoint device in the add-registry section for that device. The following
INF example shows the strings and add-registry sections that loads the APO for a keyword detector stream effect
into the registry.

[Strings]
PKEY_FX_KeywordDetector_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},8"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_KEYWORD_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.AddReg]
HKR,"FX\\0",%PKEY_FX_KeywordDetector_StreamEffectClsid%,,%FX_KEYWORD_STREAM_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_KeywordDetector_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_FX_KeywordDetector_ModeEffectClsid property key identifies the mode
effect (MFX) supported by the driver for the keyword detector pin. The driver developer should specify the single
supported processing mode that their driver supports for the keyword detector pin.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio mode effect in the add-registry section for that device. The following INF
example shows the strings and add-registry section that loads the APO for a keyword detector mode effect into the
registry.

[Strings]
PKEY_FX_KeywordDetector_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},9"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_KEYWORD_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.I.Association0.AddReg]
HKR,"FX\\0",%PKEY_FX_KeywordDetector_ModeEffectClsid%,,%FX_KEYWORD_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_KeywordDetector_EndpointEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_FX_KeywordDetector_EndpointEffectClsid property key identifies the


keyword detector end point effect (EFX) in place. The driver developer should specify the single supported
processing mode that their driver supports for the keyword detector pin.
The INF file property key instruct audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies the default format for an audio endpoint device in the add-registry sections for that device.
The following INF example shows the strings and add-registry section that loads the APO for an endpoint keyword
detector effect into the registry.

[Strings]
PKEY_FX_KeywordDetector_EndpointEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},10"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_KEYWORD_ENDPOINT_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.I.Association0.AddReg]
HKR,"FX\\0",%PKEY_FX_KeywordDetector_EndpointEffectClsid%,,%FX_KEYWORD_ENDPOINT_CLSID%

Related topics
Media-Class INF Extensions
PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_SFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming property key identifies the
keyword detector streaming processing modes supported by the driver. The driver developer should list the processing modes supported for
streaming that their driver supports for the keyword detector pin.
This list only includes signal processing modes where the APO actually processes the audio signal during streaming. This list must not include any
signal processing modes supported by the APO for discovery purposes only.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property store. This information is used to
build the audio graph that will be used to inform upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The following INF example shows the
strings and add-registry sections that loads the mode effect processing modes for the keyword detector pin into the registry.

[Strings]
PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},8"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS = "{98951333-B9CD-48B1-A0A3-FF40682D73F7}"
...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired modes:
HKR,"FX\\0",%PKEY_SFX_KeywordDetector_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIG
NALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Related topics
Media-Class INF Extensions
PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_MFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming property key identifies the
keyword detector mode effect processing modes supported for streaming supported by the driver. The driver developer should list the keyword
detector mode effect processing modes supported for streaming that their driver supports for the keyword detector pin.
This list only includes signal processing modes where the APO actually processes the audio signal during streaming. This list must not include any
signal processing modes supported by the APO for discovery purposes only.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property store. This information is used to
build the audio graph that will be used to inform upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The following INF example shows the
strings and add-registry sections that loads the keyword detector mode effect processing modes into the registry.

[Strings]
PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},9"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS = "{98951333-B9CD-48B1-A0A3-FF40682D73F7}"
...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired modes:
HKR,"FX\\0",%PKEY_MFX_KeywordDetector_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNA
LPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Related topics
Media-Class INF Extensions
PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10 and later, the PKEY_EFX_KeywordDetector_ProcessingModes_Suppor ted_For_Streaming property key identifies the end
point keyword detector processing modes supported for streaming supported by the driver. The driver developer should list the end point
processing modes supported for streaming that their driver supports for the keyword detector pin.
This list only includes signal processing modes where the APO actually processes the audio signal during streaming. This list must not include any
signal processing modes supported by the APO for discovery purposes only.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property store. This information is used to
build the audio graph that will be used to inform upper level apps what effects are in place.
Because end point effects (EFX) are after the sum or before the tee, there cannot be multiple modes associated with endpoint processing. For this
reason, only a single mode, AUDIO_SIGNALPROCESSINGMODE_DEFAULT, can be specified.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The following INF example shows the
strings and add-registry sections that loads the keyword detector streaming processing modes supported into the registry.

[Strings]
PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},10"
...
[SWAPAPO.I.Association0.AddReg]
; This line shows how to set the default processing mode for streaming.
HKR,FX\0,%PKEY_EFX_KeywordDetector_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%

Related topics
Media-Class INF Extensions
PKEY_FX_EndpointEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_FX_EndpointEffectClsid property key identifies the end point effect (EFX) in
place. The driver developer should specify the list of supported processing modes that their driver supports.
The INF file property key instruct audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies the default format for an audio endpoint device in the add-registry sections for that device.
The following INF example shows the strings and add-registry section that loads the APO for an endpoint effect
into the registry.

[Strings]
PKEY_FX_EndpointEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},7"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_ENDPOINT_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.I.Association0.AddReg]
HKR,"FX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_ENDPOINT_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_FX_ModeEffectClsid property key identifies the mode effect (MFX)
supported by the driver. The driver developer should specify the list of supported processing modes that their
driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio mode effect in the add-registry section for that device. The following INF
example shows the strings and add-registry section that loads the APO for a mode effect into the registry.

[Strings]
PKEY_FX_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},6"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.I.Association0.AddReg]
HKR,"FX\\0",%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_StreamEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_FX_StreamEffectClsid property key identifies the stream effect (SFX)
supported by the driver. The driver developer should specify the list of supported stream effects that their driver
supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for endpoint APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio endpoint device in the add-registry section for that device. The following
INF example shows the strings and add-registry sections that loads the APO for a stream effect into the registry.

[Strings]
PKEY_FX_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},5"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.AddReg]
HKR,"FX\\0",%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_Offload_ModeEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10, version 1511 and later, the PKEY_FX_Offload_ModeEffectClsid key identifies the mode effect
(MFX) supported by the driver that will be loaded during offload playback. The driver developer should specify the
list of supported processing modes that their driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for mode APOs into the effects
property store. This information is used to build the audio graph that will be used to inform upper level apps what
effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the loads the APO for a mode effect
to be used during offload playback into the registry.

[Strings]
PKEY_FX_Offload_ModeEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},12"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_MODE_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.I.Association0.AddReg]
HKR,"FX\\0",%PKEY_FX_Offload_ModeEffectClsid%,,%FX_MODE_CLSID%

Related topics
Media-Class INF Extensions
PKEY_FX_Offload_StreamEffectClsid
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10, version 1511 and later, the PKEY_FX_Offload_StreamEffectClsid property key identifies the
stream effect (SFX) supported by the driver that will be loaded during offload playback. The driver developer
should specify the list of supported stream effects that their driver supports for the offload pin.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for stream-effect APOs into the
effects property store for offload. This information is used to build the audio graph that will be used to inform
upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the streaming processing modes
supported into the registry.

[Strings]
PKEY_FX_Offload_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},11"
...
; Driver developers should replace this CLSIDs with that of their own APO
FX_STREAM_CLSID = "{00000000-0000-0000-0000-000000000000}"
...
[SWAPAPO.AddReg]
HKR,"FX\\0",% PKEY_FX_Offload_StreamEffectClsid %,,%FX_STREAM_CLSID%

Related topics
Media-Class INF Extensions
PKEY_SFX_Offload_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10, version 1511 and later, the PKEY_SFX_Offload_ProcessingModes_Suppor ted_For_Streaming property
key identifies the offload streaming processing modes supported by the driver. The driver developer should list the processing
modes supported for offloaded streaming that their driver supports for the offload pin.
This list only includes signal processing modes where the APO actually processes the audio signal during offloaded streaming.
This list must not include any signal processing modes supported by the APO for discovery purposes only.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for offload APOs into the effects property store.
This information is used to build the audio graph that will be used to inform upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The following INF
example shows the strings and add-registry sections that loads the streaming processing modes supported for the offload pin
into the registry.

[Strings]
PKEY_SFX_Offload_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},11"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_MEDIA = "{4780004E-7133-41D8-8C74-660DADD2C0EE}"
...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for offload streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired modes:
HKR,"FX\\0",%PKEY_SFX_Offload_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%
AUDIO_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%

Related topics
Media-Class INF Extensions
PKEY_MFX_Offload_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 10, version 1511 and later, the PKEY_MFX_Offload_ProcessingModes_Suppor ted_For_Streaming property key
identifies the mode effect processing modes supported for offload streaming supported by the driver. The driver developer should
list the mode effect processing modes supported for offloaded streaming that their driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property store. This
information is used to build the audio graph that will be used to inform upper level apps what effects are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The following INF
example shows the strings and add-registry sections that loads the offload streaming processing modes supported into the
registry.

[Strings]
PKEY_MFX_Offload_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},12"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_MEDIA = "{4780004E-7133-41D8-8C74-660DADD2C0EE}"

...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired modes:
HKR,"FX\\0",%PKEY_MFX_Offload_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNA
LPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%

Related topics
Media-Class INF Extensions
PKEY_EFX_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_EFX_ProcessingModes_Suppor ted_For_Streaming property key


identifies the end point processing modes supported for streaming supported by the driver. The driver developer
should list the end point processing modes supported for streaming that their driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property
store. This information is used to build the audio graph that will be used to inform upper level apps what effects
are in place.
Because end point effects (EFX) are after the sum or before the tee, there cannot be multiple modes associated with
endpoint processing. For this reason, only a single mode, AUDIO_SIGNALPROCESSINGMODE_DEFAULT, can be
specified.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the streaming processing modes
supported into the registry.

[Strings]
PKEY_EFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},7"
...
[SWAPAPO.I.Association0.AddReg]
; This line shows how to set the default processing mode for streaming.
HKR,FX\0,%PKEY_EFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%

Related topics
Media-Class INF Extensions
PKEY_MFX_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_MFX_ProcessingModes_Suppor ted_For_Streaming property key


identifies the mode effect processing modes supported for streaming supported by the driver. The driver developer
should list the mode effect processing modes supported for streaming that their driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property
store. This information is used to build the audio graph that will be used to inform upper level apps what effects
are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the mode effect processing modes
into the registry.

[Strings]
PKEY_MFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},6"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS = "{98951333-B9CD-48B1-A0A3-FF40682D73F7}"
...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired
modes:
HKR,"FX\\0",%PKEY_MFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDI
O_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Related topics
Media-Class INF Extensions
PKEY_SFX_ProcessingModes_Supported_For_Streaming
12/5/2018 • 2 minutes to read • Edit Online

In Windows 8.1 and later, the PKEY_SFX_ProcessingModes_Suppor ted_For_Streaming property key


identifies the streaming processing modes supported by the driver. The driver developer should list the processing
modes supported for streaming that their driver supports.
The INF file property key instructs the audio endpoint builder to set the CLSIDs for APOs into the effects property
store. This information is used to build the audio graph that will be used to inform upper level apps what effects
are in place.

INF File Sample


An INF file specifies settings for an audio processing mode effect in the add-registry section for that device. The
following INF example shows the strings and add-registry sections that loads the mode effect processing modes
into the registry.

[Strings]
PKEY_SFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},5"
...
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"
AUDIO_SIGNALPROCESSINGMODE_MOVIE = "{B26FEB0D-EC94-477C-9494-D1AB8E753F6E}"
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS = "{98951333-B9CD-48B1-A0A3-FF40682D73F7}"
...
[SWAPAPO.I.Association0.AddReg]
;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the desired
modes:
HKR,"FX\\0",%PKEY_SFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDI
O_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Related topics
Media-Class INF Extensions
UsePositionLock
10/23/2019 • 2 minutes to read • Edit Online

The UsePositionLock registry value changes how PortCls serializes its I/O. Enabling this setting may be helpful if
your audio driver suffers from glitches attributed to the global device lock that portcls uses for serialization. Be
aware that when UsePositionLock is enabled, it will be up to the audio driver to apply any serialization between the
listed callbacks below and other property callbacks (if needed). This flag is not enabled by default. Before turning it
on, make sure to review your driver for any race conditions between your driver’s callbacks.
Use the following INF setting to enable this behavior.

[MyAudioDevice.AddReg]
HKR, DispatchSettings, UsePositionLock, 3, 01, 00, 00, 00

This INF setting creates the following registry value. The media GUID of {4d36e96c-e325-11ce-bfc1-
08002be10318} and the <instance#> of your audio device are used in the registry entry path.

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e96c-e325-11ce-bfc1-08002be10318}\
<instance#>\DispatchSettings\UsePositionLock

When this value is set to 1 or above, portcls uses the streaming position lock to serialize the callbacks listed below.
If it is not present or set to zero, the default behavior is to use the global device lock. This value is read the first
time the device is added.
The UsePositionLock setting is only supported on WaveRT and Topology filters. Portcls reads this registry value at
device-add time and the setting persists until the functional device object (FDO) is removed.
If portcls detects that this flag is on, it does not serialize the following properties with the global device lock.
{KSPROPSETID_RtAudio, KSPROPERTY_RTAUDIO_GETREADPACKET }
{KSPROPSETID_RtAudio, KSPROPERTY_RTAUDIO_SETWRITEPACKET }
{KSPROPSETID_RtAudio, KSPROPERTY_RTAUDIO_PRESENTATION_POSITION }
{KSPROPSETID_RtAudio, KSPROPERTY_RTAUDIO_PACKETCOUNT }
{KSPROPSETID_Audio,KSPROPERTY_AUDIO_POSITION }
{KSPROPSETID_Audio, KSPROPERTY_AUDIO_POSITIONEX }
This means that the following miniport’s callbacks are not serialized with the other property requests (including
set-state requests).
IMinipor tWaveRTInputStream::GetReadPacket
IMinipor tWaveRTOutputStream::SetWritePacket
IMinipor tWaveRTOutputStream::GetOutputStreamPresentationPosition
IMinipor tWaveRTOutputStream::GetPacketCount
IMinipor tWaveRTStream::GetPosition
Port Class Audio Driver Reference
10/23/2019 • 2 minutes to read • Edit Online

This section describes the following:


The functions that are implemented by the PortCls system driver.
The interfaces that port and miniport drivers use to communicate with each other.
For a list of which versions of the operating system support the various PortCls functions and interfaces, see
PortCls Support by Operating System.
This section presents the following topics:
Audio Port Class Functions
Audio Helper Object Interfaces
Audio Port Object Interfaces
Audio Miniport Object Interfaces
Audio Miniport Auxiliary Interfaces
Audio Stream Object Interfaces
DirectMusic User-Mode Synth and Synth Sink Interfaces
Audio Power Management Interfaces
Audio Port Class Structures
Macro Definitions for Obsolete Functions
Audio Port Class Functions
10/23/2019 • 2 minutes to read • Edit Online

This section describes, in alphabetic order, the general functions that the PortCls system driver (portcls.sys)
provides. These functions do not belong to any interface. They are used by audio miniport drivers to perform
operations of general utility such as registering with the PortCls and installing subdevices.
For a list of which versions of the operating system support the various PortCls functions, see PortCls Support by
Operating System.
PortCls implements the following functions:
PcAddAdapterDevice
PcAddContentHandlers
PcCompleteIrp
PcCompletePendingProper tyRequest
PcCreateContentMixed
PcDestroyContent
PcDispatchIrp
PcFor wardContentToDeviceObject
PcFor wardContentToFileObject
PcFor wardContentToInterface
PcFor wardIrpSynchronous
PcGetContentRights
PcGetDeviceProper ty
PcGetPhysicalDeviceObject
PcGetTimeInter val
PcInitializeAdapterDriver
PcNewDmaChannel
PcNewInterruptSync
PcNewMinipor t
PcNewPor t
PcNewRegistr yKey
PcNewResourceList
PcNewResourceSublist
PcNewSer viceGroup
PcRegisterAdapterPowerManagement
PcRegisterIoTimeout
PcRegisterPhysicalConnection
PcRegisterPhysicalConnectionFromExternal
PcRegisterPhysicalConnectionToExternal
PcRegisterSubdevice
PcRequestNewPowerState
PcUnregisterAdapterPowerManagement
PcUnregisterIoTimeout
Audio Helper Object Interfaces
10/23/2019 • 2 minutes to read • Edit Online

The Port Class Library (portcls.sys) implements a variety of helper objects that provide functionality that is of
general use to adapter drivers. These helper objects provide mechanisms for managing DMA channels, interrupt
requests, registry access, resource lists, digital rights, and hardware events. This section provides details on the
interfaces that are exposed by those objects.
The following interfaces are described in this section:
IDrmPort
Helps a miniport driver keep track of composite DRM rights.
IDrmPort2
Helps a miniport driver keep track of composite DRM rights. This is an extended version of IDrmPor t .
IInterruptSync
A synchronization mechanism for coordinating shared access to interrupt service requests.
IMasterClock
Provides DirectMusic streams with access to the current reference time from the master clock.
IPor tClsEtwHelper
Used by a miniport driver to access Event Tracing for Windows (ETW) helper functions. IPortClsVersion
Identifies the version of the Microsoft Windows operating system that the driver is running on.
IPortEvents
Used by a miniport driver to notify a port driver of hardware events.
IPreFetchOffset
Sets the prefetch offset, which is the number of bytes of data separating the write cursor from the play cursor in a
Microsoft DirectSound hardware buffer.
IRegistryKey
Provides read/write access to a registry key and its subkeys.
IResourceList
Specifies a list of resources such as I/O ports, DMA channels, and interrupts.
IServiceGroup
Used to demultiplex interrupt service requests to a list of objects with IServiceSink interfaces.
IServiceSink
Represents the target of an interrupt service request.
IUnregisterPhysicalConnection
Deletes the registration of a physical connection between two subdevices in the same audio adapter or in two
different adapters.
IUnregisterSubdevice
Deletes the registration of a dynamic subdevice in an audio adapter.
Audio Port Object Interfaces
10/23/2019 • 2 minutes to read • Edit Online

This section describes the audio port object interfaces. These include the following:
IPor t , which is the base type from which all other audio port object interfaces are derived
The audio port object provides an interface for the DMus, MIDI, Topology, WaveCyclic, WavePci and WaveRT
port drivers (see Supporting a Device), which are derived from IPor t
The audio port object interface is the primary interface that a port driver presents to a miniport driver. An adapter
driver forms a KS filter for an audio device by binding together the port and miniport drivers for that device. The
binding is accomplished by calling the audio port object's IPor t::Init method and passing a reference to the audio
miniport object as a call parameter. The code example in Subdevice Creation illustrates this process.
This section describes the following audio port object interfaces:
IPort
IPortClsPower
IPortDMus
IPortMidi
IPortTopology
IPortWaveCyclic
IPortWavePci
IPortWaveRT
IPortWMIRegistration
Audio Miniport Object Interfaces
10/23/2019 • 2 minutes to read • Edit Online

This section describes the audio miniport object interfaces. These include the following:
IMinipor t , which is the base type from which all other audio miniport object interfaces are derived
The audio miniport object provides an interface for the DMus, MIDI, Topology, WaveCyclic, WavePci and
WaveRT miniport drivers (see Supporting a Device), which are derived from IMinipor t
The audio miniport object interface is the primary interface that a miniport driver presents to a port driver. An
adapter driver forms a KS filter for an audio device by binding together the port and miniport drivers for that
device. The binding is accomplished by calling the audio port object's IPor t::Init method and passing a reference
to the audio miniport object as a call parameter. The code example in Subdevice Creation illustrates this process.
This section discusses the following audio miniport object interfaces:
IMiniport
IMiniportDMus
IMiniportMidi
IMiniportTopology
IMiniportWaveCyclic
IMiniportWavePci
IMiniportWaveRT
Audio Miniport Auxiliary Interfaces
10/23/2019 • 2 minutes to read • Edit Online

Some miniport drivers support auxiliary interfaces that are optional and provide access to specialized miniport
driver capabilities. This section describes the auxiliary interfaces that are implemented by a miniport driver and
exposed to the port driver.
The following interfaces are discussed in this section:
IMusicTechnology- Used to change the DirectMusic synthesizer technology that is specified in the data ranges for
the DMus miniport driver's pins.
IPinCount - Provides a means for the miniport driver to dynamically monitor and manipulate its pin counts.
IPinName - Allows the port driver to dynamically update the name of an endpoint.
IAdapterPnpManagement - Allows adapters to register to receive PnP management messages.
Audio Stream Object Interfaces
10/23/2019 • 2 minutes to read • Edit Online

This section describes audio stream object interfaces. These interfaces are associated with the wave and MIDI
streams that flow into and from the pins of wave, MIDI, and DirectMusic filters. Some of these interfaces are
implemented by the miniport driver and exposed to the port driver. Others are implemented by the port driver and
exposed to the miniport driver.
This section discusses the following audio stream object interfaces:
Manages buffer storage for DirectMusic streams. Implemented by the DMus port driver.
Assigns digital rights management (DRM) protection to the digital content in an audio stream. Implemented by a
WaveCyclic, WavePci, or WaveRT miniport driver.
Represents the MIDI stream that flows through a pin on a MIDI filter. Implemented by a MIDI miniport driver.
Represents the wave stream that flows through a pin on a WaveCyclic filter. Implemented by a WaveCyclic miniport
driver.
Represents the wave stream that flows through a pin on a WavePci filter. Implemented by a WavePci miniport
driver.
Represents the wave stream that flows through a pin on a WaveRT filter. Implemented by a WaveRT miniport dirver.
Augments the IMinipor tWaveRTStream interface, providing additional methods for DMA driver event
notifications.
Represents the MIDI stream that flows through a MIDI or DirectMusic pin on a DirectMusic filter. Implemented by a
DMus miniport driver.
Provides mapping services to a WavePci miniport driver's stream objects. Implemented by the WavePci port driver.
Handles wave output for a DirectMusic synthesizer device. Implemented by a DMus miniport driver and used by
the DMus port driver's wave sink.
IAllocatorMXF
IDrmAudioStream
IMiniportMidiStream
IMiniportWaveCyclicStream
IMiniportWavePciStream
IMiniportWaveRTStream
IMiniportWaveRTStreamNotofication
IMXF
IPortWavePciStream
ISynthSinkDMus
DirectMusic User-Mode Synth and Synth Sink
Interfaces
6/25/2019 • 2 minutes to read • Edit Online

This section describes the DirectMusic user-mode interfaces for synths and synth sinks. As described in User Mode
Versus Kernel Mode, these interfaces can be useful for developing driver code in user mode that can later be
ported to kernel mode. For information, see Synthesizers and Wave Sinks.
This section presents the following two user-mode interfaces:
Interface for a user-mode synth
Interface for a user-mode synth sink
IDirectMusicSynth
IDirectMusicSynthSink
Audio Power Management Interfaces
10/23/2019 • 2 minutes to read • Edit Online

This section describes the interfaces that the Port Class Library (portcls.sys) uses to manage power in a WDM audio
adapter. These interfaces are implemented by the adapter driver and exposed to the PortCls system driver.
The following two interfaces are discussed:
Implemented by an adapter driver and exposed to PortCls for power management of an audio adapter card.
Implemented by an adapter driver and exposed to PortCls. This interface provides power managent messages
about the audio adapter and the system.
An optional interface that a miniport driver can expose if it requires advance notification of impending power-state
changes.
IAdapterPowerManagement
IAdapterPowermanagement2
IAdapterPowerManagement3
IPowerNotify
Macro Definitions for Obsolete Functions
12/5/2018 • 2 minutes to read • Edit Online

The header file portcls.h defines a number of macros that aid in compiling legacy driver code without requiring
edits to source files. These macros conveniently replace calls to obsolete PortCls and kernel-mode driver functions
with calls to the new PortCls and kernel-mode driver functions. If you have old source code that contains
references to the obsolete functions, you can use the macros in portcls.h to recompile the source files to create
executable code that calls the new functions.
The following topics are discussed:
Obsolete Port Class Functions
Obsolete Kernel-Mode Driver-Support Functions
Obsolete Port Class Functions
10/23/2019 • 2 minutes to read • Edit Online

The header file portcls.hdefines macros that contain the names of obsolete PortCls functions that have been
replaced by new PortCls functions. These macros allow old source code that contains references to obsolete PortCls
function names to be recompiled to use the new PortCls functions without requiring any edits to the source files.
When compiling source code that uses the obsolete names, define the parameter name PC_OLD_NAMES. This
parameter can be defined by the compiler command-line argument "-DPC_OLD_NAMES" if that is more
convenient than introducing the statement #define PC_OLD_NAMES into the source files themselves.
The following table lists the obsolete PortCls function names in the left column. For each obsolete name, the center
column contains the name of the new PortCls function that replaces it.

O B SO L ET E F UN C T IO N N A M E N EW F UN C T IO N N A M E DID A RGUM EN T S C H A N GE?

AddAdapterDevice PcAddAdapterDevice YES

CompletePendingPropertyRequest PcCompletePendingProper tyRe no


quest

GetTimeInterval PcGetTimeInter val no

InitializeAdapterDriver PcInitializeAdapterDriver YES

NewDmaChannel PcNewDmaChannel no

NewMiniport PcNewMinipor t no

NewPort PcNewPor t no

NewResourceList PcNewResourceList no

NewResourceSublist PcNewResourceSublist no

NewServiceGroup PcNewSer viceGroup no

RegisterPhysicalConnection PcRegisterPhysicalConnection YES

RegisterPhysicalConnectionFromExt PcRegisterPhysicalConnectionF YES


ernal romExternal
O B SO L ET E F UN C T IO N N A M E N EW F UN C T IO N N A M E DID A RGUM EN T S C H A N GE?

RegisterPhysicalConnectionToExtern PcRegisterPhysicalConnectionT YES


al oExternal

RegisterSubdevice PcRegisterSubdevice YES

In some cases, the change amounts to no more than a simple name change: The qualifier Pc is inserted at the
beginning of the name to indicate that the function is implemented in PortCls. In other cases, however, the
argument list has changed in addition to the name of the function. The right column in the preceding table
indicates whether the arguments have changed.
In cases in which the arguments changed, the macros in portcls.hconvert the argument lists for the obsolete
PortCls functions to the equivalent arguments for the new PortCls functions. The following macros contain
argument conversions:

#define InitializeAdapterDriver(c1,c2,a) \
PcInitializeAdapterDriver(PDRIVER_OBJECT(c1),PUNICODE_STRING(c2),PDRIVER_ADD_DEVICE(a))
#define AddAdapterDevice(c1,c2,s,m) \
PcAddAdapterDevice(PDRIVER_OBJECT(c1),PDEVICE_OBJECT(c2),s,m,0)
#define RegisterSubdevice(c1,c2,n,u) \
PcRegisterSubdevice(PDEVICE_OBJECT(c1),n,u)
#define RegisterPhysicalConnection(c1,c2,fs,fp,ts,tp) \
PcRegisterPhysicalConnection(PDEVICE_OBJECT(c1),fs,fp,ts,tp)
#define RegisterPhysicalConnectionToExternal(c1,c2,fs,fp,ts,tp) \
PcRegisterPhysicalConnectionToExternal(PDEVICE_OBJECT(c1),fs,fp,ts,tp)
#define RegisterPhysicalConnectionFromExternal(c1,c2,fs,fp,ts,tp) \
PcRegisterPhysicalConnectionFromExternal(PDEVICE_OBJECT(c1),fs,fp,ts,tp)
Obsolete Kernel-Mode Driver-Support Functions
10/23/2019 • 2 minutes to read • Edit Online

The header file portcls.hdefines four macros that contain the names of obsolete kernel-mode driver-support
functions. These macros allow old source code that contains references to the obsolete function names to be
recompiled to use the new kernel functions without requiring any edits to the source files.
When compiling source code that uses the obsolete names, define the parameter name PC_OLD_NAMES. This
parameter can be defined by the compiler command-line argument "-DPC_OLD_NAMES" if that is more
convenient than introducing the statement #define PC_OLD_NAMES into the source files themselves.
The following table lists the obsolete kernel-mode driver-support function names in the left column. For each
obsolete name, the right column contains the name of the new kernel function that replaces it. In each case, the
macro definition amounts to a simple name change. The argument lists for the obsolete function and the new
function are identical.

O B SO L ET E F UN C T IO N N A M E N EW F UN C T IO N N A M E

WIN95COMPAT_ReadPortUChar READ_PORT_UCHAR

WIN95COMPAT_WritePortUChar WRITE_PORT_UCHAR

WIN95COMPAT_ReadPortUShort READ_PORT_USHORT

WIN95COMPAT_WritePortUShort WRITE_PORT_USHORT
Ks.h
12/5/2018 • 2 minutes to read • Edit Online

This section contains reference topics for the Ks.h header.

In this section
TO P IC DESC RIP T IO N

KSEVENT_PINCAPS_FORMATCHANGE The KSEVENT_PINCAPS_FORMATCHANGE event indicates to


the audio stack that the audio data format for the audio
device has changed.

KSEVENT_PINCAPS_JACKINFOCHANGE The KSEVENT_PINCAPS_JACKINFOCHANGE event indicates


to the audio stack that the jack information for the audio
device has changed.
KSEVENT_PINCAPS_FORMATCHANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_PINCAPS_FORMATCHANGE event indicates to the audio stack that the audio data format for the audio
device has changed.
Usage Summary Table
TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Pin KSEVENT KSEVENTDATA

The event value type (operation data) is a KSEVENTDATA structure that specifies the notification method to use
for this event.

Remarks
When an audio port driver calls the EventHandler routine for its miniport driver, it passes a
PCEVENT_REQUEST structure. This structure contains a pointer to a PCEVENT_ITEM structure that is used to
describe an event that is supported by a filter, pin, or node.
So, for example, a driver that supports the KSEVENT_PINCAPS_FORMATCHANGE event must populate a PCEVENT_ITEM
structure as follows:

static PCEVENT_ITEM FormatChangePinEvent[] = {


{
&KSEVENTSETID_PinCapsChange,
KSEVENT_PINCAPS_FORMATCHANGE,
KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
MyEventHandler
}
};

In the preceding code example, the MyEventHandler custom event handler must monitor the
KSEVENT_PINCAPS_FORMATCHANGE event and register it with Portcls when KSEVENT_PINCAPS_FORMATCHANGE is
triggered. The miniport driver must call the IPor tEvents::AddEventToEventList method to register the event.
To obtain a description of the pins, nodes, connections and properties supported by the miniport driver, the port
driver calls the IMinipor t::GetDescription method. This method call returns a PCFILTER_DESCRIPTOR
structure that points to an automation table (PCAUTOMATION_TABLE ). The PCAUTOMATION_TABLE structure
has an Events member. This member points to an array of the events that are associated with the filter that the
miniport driver supports. So you must set the Events member to point to the event array that contains the
PCEVENT_ITEM structure for the KSEVENT_PINCAPS_FORMATCHANGE event.
When the miniport driver detects a dynamic format change, it must call the IPor tEvents::GenerateEventList
method to signal the KSEVENT_PINCAPS_FORMATCHANGE event.

Requirements
Version Available in Windows 7 and later versions of the Windows
operating systems.

Header Ks.h (include Ks.h)

See also
EventHandler
IMinipor t::GetDescription
IPor tEvents::AddEventToEventList
IPor tEvents::GenerateEventList
KSEVENT
KSEVENTDATA
PCAUTOMATION_TABLE
PCEVENT_ITEM
PCEVENT_REQUEST
PCFILTER_DESCRIPTOR
KSEVENT_PINCAPS_JACKINFOCHANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_PINCAPS_JACKINFOCHANGE event indicates to the audio stack that the jack information for the audio
device has changed.
Usage Summary Table
TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Pin KSEVENT KSEVENTDATA

The event value type (operation data) is a KSEVENTDATA structure that specifies the notification method to use
for this event.

Remarks
For information about how to implement support for the KSEVENT_PINCAPS_JACKINFOCHANGE event, see the Remarks
section of the KSEVENT_PINCAPS_FORMATCHANGE topic.

Requirements
Version Available in Windows 7 and later versions of the Windows
operating systems.

Header Ks.h (include Ks.h)

See also
KSEVENT
KSEVENTDATA
KSEVENT_PINCAPS_FORMATCHANGE
Ksmedia.h
10/23/2019 • 14 minutes to read • Edit Online

This section contains reference topics for the Ksmedia.h header.

In this section
TO P IC DESC RIP T IO N

KSEVENT_CONTROL_ The Pin KSE_NODE KSEVENTDATA


CHANGE KSEVENT_CONTROL_
CHANGE event
indicates that a
change in control
value has occurred at
a node that
represents a hardware
volume-control knob,
mute switch, or other
type of manual
control. The event
value type (operation
data) is a
KSEVENTDATA
structure that
specifies the type of
notification to use for
an event.

KSEVENT_LOOPEDSTR The
EAMING_POSITION KSEVENT_LOOPEDSTR
EAMING_POSITION
event indicates that
the audio stream has
reached a specified
position in a looped
buffer.

KSEVENT_SOUNDDET The
ECTOR_MATCHDETEC KSEVENT_SOUNDDET
TED ECTOR_MATCHDETEC
TED event is
generated by the
audio driver to notify
the OS whenever a
match is detected.

KSJACK_DESCRIPTIO The
N KSJACK_DESCRIPTIO
N structure specifies
the physical attributes
of an audio jack.
TO P IC DESC RIP T IO N

KSJACK_DESCRIPTIO The
N2 KSJACK_DESCRIPTIO
N2 structure specifies
the capabilities and
the current state of a
jack that supports
jack presence
detection.

KSPROPERTY_AC3_AL The
TERNATE_AUDIO KSPROPERTY_AC3_AL
TERNATE_AUDIO
property specifies
whether the two
mono channels in an
AC-3-encoded stream
should be interpreted
as a stereo pair or as
two independent
program channels.

KSPROPERTY_AC3_BI The
T_STREAM_MODE KSPROPERTY_AC3_BI
T_STREAM_MODE
property specifies the
bit-stream mode,
which is the type of
audio service that is
encoded into an AC-3
stream.

KSPROPERTY_AC3_DI The
ALOGUE_LEVEL KSPROPERTY_AC3_DI
ALOGUE_LEVEL
property specifies the
average volume level
of spoken dialog
within the audio
program in an AC-3-
encoded stream.

KSPROPERTY_AC3_D The
OWNMIX KSPROPERTY_AC3_D
OWNMIX property
specifies whether the
program channels in
an AC-3-encoded
stream need to be
downmixed to
accommodate the
speaker configuration.
TO P IC DESC RIP T IO N

KSPROPERTY_AC3_ER The
ROR_CONCEALMENT KSPROPERTY_AC3_ER
ROR_CONCEALMENT
property specifies the
manner in which
errors in the AC-3-
encoded stream
should be concealed
during playback.

KSPROPERTY_AC3_LA The
NGUAGE_CODE KSPROPERTY_AC3_LA
NGUAGE_CODE
property specifies the
language code of the
AC-3-encoded
stream.

KSPROPERTY_AC3_R The
OOM_TYPE KSPROPERTY_AC3_R
OOM_TYPE property
specifies the type and
calibration of the
mixing room in which
the final audio session
was produced.

KSPROPERTY_AEC_M The
ODE KSPROPERTY_AEC_M
ODE property is used
to control an AEC
node's mode of
operation. This is an
optional property of
an AEC node
(KSNODETYPE_ACOU
STIC_ECHO_CANCEL).

KSPROPERTY_AEC_N The
OISE_FILL_ENABLE KSPROPERTY_AEC_N
OISE_FILL_ENABLE
property is used to
enable and disable
background noise
filling. This is an
optional property of
an AEC node
(KSNODETYPE_ACOU
STIC_ECHO_CANCEL).
TO P IC DESC RIP T IO N

KSPROPERTY_AEC_ST The
ATUS KSPROPERTY_AEC_ST
ATUS property is used
to monitor the status
of an AEC node
(KSNODETYPE_ACOU
STIC_ECHO_CANCEL).
This is an optional
property of an AEC
node.

KSPROPERTY_AUDIO_ The
3D_INTERFACE KSPROPERTY_AUDIO_
3D_INTERFACE
property specifies the
3D algorithm to use
to process the data in
the sound buffer.

KSPROPERTY_AUDIO_ The
AGC KSPROPERTY_AUDIO_
AGC property
specifies the state of
the AGC (automatic
gain control) for a
channel in an AGC
node
(KSNODETYPE_AGC).

KSPROPERTY_AUDIO_ The
ALGORITHM_INSTAN KSPROPERTY_AUDIO_
CE ALGORITHM_INSTAN
CE property specifies
the digital signal
processing (DSP)
algorithm that is used
to achieve the third-
party effect that the
node applies to the
audio data stream.
The effects that are
defined for this
property include
acoustic echo
cancellation and noise
suppression.

KSPROPERTY_AUDIO_ The
BASS KSPROPERTY_AUDIO_
BASS property
specifies the bass level
for a channel in a
tone node
(KSNODETYPE_TONE).
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
BASS_BOOST KSPROPERTY_AUDIO_
BASS_BOOST
property enables and
disables bass boost
for a channel in a
tone node
(KSNODETYPE_TONE).

KSPROPERTY_AUDIO_ The
BUFFER_DURATION KSPROPERTY_AUDIO_
BUFFER_DURATION
property allows the
size of the client
application buffer to
be reported as time
duration.

KSPROPERTY_AUDIO_ The
CHANNEL_CONFIG KSPROPERTY_AUDIO_
CHANNEL_CONFIG
property specifies the
actual spatial
placement of channels
in the audio stream
that a node outputs.

KSPROPERTY_AUDIO_ The
CHORUS_LEVEL KSPROPERTY_AUDIO_
CHORUS_LEVEL
property specifies the
chorus level. This is a
property of a chorus
node
(KSNODETYPE_CHOR
US).

KSPROPERTY_AUDIO_ The
CHORUS_MODULATI KSPROPERTY_AUDIO_
ON_DEPTH CHORUS_MODULATI
ON_DEPTH property
specifies the chorus
modulation depth.
This is a property of a
chorus node
(KSNODETYPE_CHOR
US).

KSPROPERTY_AUDIO_ The
CHORUS_MODULATI KSPROPERTY_AUDIO_
ON_RATE CHORUS_MODULATI
ON_RATE property
specifies the chorus
modulation rate. This
is a property of a
chorus node
(KSNODETYPE_CHOR
US).
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
COPY_PROTECTION KSPROPERTY_AUDIO_
COPY_PROTECTION
property specifies the
copy-protection
status of an audio
stream.

KSPROPERTY_AUDIO_ The
CPU_RESOURCES KSPROPERTY_AUDIO_
CPU_RESOURCES
property specifies
whether a node's
functionality is
implemented in
hardware or is
emulated in software
that runs on the host
CPU.

KSPROPERTY_AUDIO_ The
DELAY KSPROPERTY_AUDIO_
DELAY property
indicates the time lag
that a delay node
(KSNODETYPE_DELAY
) introduces into a
specified channel.

KSPROPERTY_AUDIO_ The
DEMUX_DEST KSPROPERTY_AUDIO_
DEMUX_DEST
property specifies the
destination stream to
which a demultiplexer
directs its input
stream. This is a
property of a DEMUX
node
(KSNODETYPE_DEMU
X).

KSPROPERTY_AUDIO_ The
DEV_SPECIFIC KSPROPERTY_AUDIO_
DEV_SPECIFIC
property is used to
access a device-
specific property in a
device-specific node
(KSNODETYPE_DEV_S
PECIFIC).
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
DYNAMIC_RANGE KSPROPERTY_AUDIO_
DYNAMIC_RANGE
property specifies the
dynamic range of the
audio stream that is
output from a
loudness node
(KSNODETYPE_LOUD
NESS).

KSPROPERTY_AUDIO_ The
DYNAMIC_SAMPLIN KSPROPERTY_AUDIO_
G_RATE DYNAMIC_SAMPLIN
G_RATE property is
used to enable and
disable dynamic
tracking of a node's
sampling rate.

KSPROPERTY_AUDIO_ The
EQ_BANDS KSPROPERTY_AUDIO_
EQ_BANDS property
specifies the set of
frequency bands from
an equalization table.
This is a get-only
property of a channel
in an EQ node
(KSNODETYPE_EQUA
LIZER).

KSPROPERTY_AUDIO_ The
EQ_LEVEL KSPROPERTY_AUDIO_
EQ_LEVEL property
specifies the
equalization levels for
an equalization table
that contains entries
for n frequency
bands. This is a
property of a channel
in an EQ node
(KSNODETYPE_EQUA
LIZER).

KSPROPERTY_AUDIO_ The
FILTER_STATE KSPROPERTY_AUDIO_
FILTER_STATE
property is used to
query a GFX filter for
a list of the property
sets that it supports.
The list is retrieved in
the form of an array
of property-set
GUIDs.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
LATENCY KSPROPERTY_AUDIO_
LATENCY property is
used to report the
delay (or amount of
audio buffering) that
is associated with the
stream.

KSPROPERTY_AUDIO_ The
LINEAR_BUFFER_POSI KSPROPERTY_AUDIO_
TION LINEAR_BUFFER_POSI
TION property
request retrieves a
number that
represents the
number of bytes that
the DMA has fetched
from the audio buffer
since the beginning of
the stream.

KSPROPERTY_AUDIO_ The
LOUDNESS KSPROPERTY_AUDIO_
LOUDNESS property
specifies whether
loudness (overall
dynamic range and
bass boost) is enabled
or disabled for a
channel in a loudness
node
(KSNODETYPE_LOUD
NESS).

KSPROPERTY_AUDIO_ This parameter name


MANUFACTURE_GUI is reserved for future
D use.

KSPROPERTY_AUDIO_ The
MIC_ARRAY_GEOMET KSPROPERTY_AUDIO_
RY MIC_ARRAY_GEOMET
RY property specifies
the geometry of the
microphone array.

KSPROPERTY_AUDIO_ The
MIC_SENSITIVITY KSPROPERTY_AUDIO_
MIC_SENSITIVITY
property specifies the
microphone
sensitivity in decibels
relative to full scale
(dBFS) units.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
MIC_SNR KSPROPERTY_AUDIO_
MIC_SNR property
specifies the
microphone signal to
noise ratio (SNR)
measure in dB units.

KSPROPERTY_AUDIO_ The
MID KSPROPERTY_AUDIO_
MID property
specifies the mid-
frequency level of a
channel in a tone
node
(KSNODETYPE_TONE).

KSPROPERTY_AUDIO_ The
MIX_LEVEL_CAPS KSPROPERTY_AUDIO_
MIX_LEVEL_CAPS
property specifies the
mix-level capabilities
of a supermixer node
(KSNODETYPE_SUPER
MIX). A single get-
property request
retrieves information
for all combinations of
input and output
channels.

KSPROPERTY_AUDIO_ The
MIX_LEVEL_TABLE KSPROPERTY_AUDIO_
MIX_LEVEL_TABLE
property specifies the
mix levels for a
supermixer node
(KSNODETYPE_SUPER
MIX). It provides
information for all
input and output
channels.

KSPROPERTY_AUDIO_ The
MUTE KSPROPERTY_AUDIO_
MUTE property
specifies whether a
channel on a mute
node
(KSNODETYPE_MUTE)
is muted or not.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
MUX_SOURCE KSPROPERTY_AUDIO_
MUX_SOURCE
property specifies the
source for the output
stream of a
multiplexer. This is a
property of a MUX
node
(KSNODETYPE_MUX).

KSPROPERTY_AUDIO_ The
NUM_EQ_BANDS KSPROPERTY_AUDIO_
NUM_EQ_BANDS
property is used to
retrieve the number
of frequency bands in
the equalization table.
This is a get-only
property of a channel
in an EQ node
(KSNODETYPE_EQUA
LIZER).

KSPROPERTY_AUDIO_ The
PEAKMETER KSPROPERTY_AUDIO_
PEAKMETER property
retrieves the
maximum audio
signal level that
occurred at a
peakmeter node
(KSNODETYPE_PEAK
METER) since the last
time the peakmeter
node was reset.

KSPROPERTY_AUDIO_ Windows 8 introduces


PEAKMETER2 the
KSPROPERTY_AUDIO_
PEAKMETER2
property that reports
the maximum audio
signal level that
occurred at a
peakmeter node
(KSNODETYPE_PEAK
METER) since the last
time the peakmeter
node was reset.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
POSITION KSPROPERTY_AUDIO_
POSITION property
specifies the current
positions of the play
and write cursors in
the sound buffer for
the pin's audio
stream.

KSPROPERTY_AUDIO_ The
POSITIONEX KSPROPERTY_AUDIO_
POSITIONEX property
provides the caller
with the stream
position and the
associated timestamp
information for a
kernel streaming (KS)-
based audio driver.

KSPROPERTY_AUDIO_ The
PREFERRED_STATUS KSPROPERTY_AUDIO_
PREFERRED_STATUS
property informs a
device that it is the
system's preferred
audio device.

KSPROPERTY_AUDIO_ The
PRESENTATION_POSIT KSPROPERTY_AUDIO_
ION PRESENTATION_POSIT
ION property request
retrieves a structure
that specifies the
current position
within the audio data
being rendered to the
endpoint.

KSPROPERTY_AUDIO_ This parameter name


PRODUCT_GUID is reserved for future
use.

KSPROPERTY_AUDIO_ The
QUALITY KSPROPERTY_AUDIO_
QUALITY property
specifies the quality
level of a node's
output stream. This is
a property of an SRC
node
(KSNODETYPE_SRC).
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
REVERB_LEVEL KSPROPERTY_AUDIO_
REVERB_LEVEL
property specifies the
current reverberation
level. This is a
property of a reverb
node
(KSNODETYPE_REVER
B).

KSPROPERTY_AUDIO_ The
REVERB_TIME KSPROPERTY_AUDIO_
REVERB_TIME
property specifies the
reverberation time.
This is a property of a
reverb node
(KSNODETYPE_REVER
B).

KSPROPERTY_AUDIO_ The
SAMPLING_RATE KSPROPERTY_AUDIO_
SAMPLING_RATE
property specifies the
rate at which a node
samples its input
stream in order to
produce its output
stream.

KSPROPERTY_AUDIO_ This parameter name


STEREO_ENHANCE is reserved for future
use.

KSPROPERTY_AUDIO_ The
STEREO_SPEAKER_GE KSPROPERTY_AUDIO_
OMETRY STEREO_SPEAKER_GE
OMETRY property is
used in combination
with
KSPROPERTY_AUDIO_
CHANNEL_CONFIG to
implement the
DirectSound speaker-
configuration
property for
hardware-accelerated
3D audio. This is an
optional property of
DAC nodes
(KSNODETYPE_DAC)
and 3D nodes
(KSNODETYPE_3D_EF
FECTS).
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
SURROUND_ENCODE KSPROPERTY_AUDIO_
SURROUND_ENCODE
property specifies
whether the filter's
surround encoder is
enabled or disabled. A
surround-encoder
node
(KSNODETYPE_PROL
OGIC_ENCODER)
performs Dolby
Surround Pro Logic
encoding.

KSPROPERTY_AUDIO_ The
TREBLE KSPROPERTY_AUDIO_
TREBLE property
specifies the treble
level for a channel in a
tone node
(KSNODETYPE_TONE).

KSPROPERTY_AUDIO_ The
VOLUMELEVEL KSPROPERTY_AUDIO_
VOLUMELEVEL
property specifies the
volume level of a
channel in a volume
node
(KSNODETYPE_VOLU
ME).

KSPROPERTY_AUDIO_ KSPROPERTY_AUDIO_
VOLUMELIMIT_ENGA VOLUMELIMIT_ENGA
GED GED, is a new KS
property that has
been added into the
KSPROPSETID_Audio
property set in
Windows 8.1.

KSPROPERTY_AUDIO_ The
WAVERT_CURRENT_W KSPROPERTY_AUDIO_
RITE_POSITION WAVERT_CURRENT_W
RITE_POSITION
property request
specifies the current
write position of the
WaveRT buffer in
bytes. The offload
driver can use this
write position
information to know
how much valid data
is in the WaveRT
buffer.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO_ The
WAVERT_CURRENT_W KSPROPERTY_AUDIO_
RITE_LASTBUFFER_PO WAVERT_CURRENT_W
SITION RITE_LASTBUFFER_PO
SITION property is
used for indicating
the last valid byte in
the audio buffer.

KSPROPERTY_AUDIO_ This parameter name


WIDE_MODE is reserved for future
use.

KSPROPERTY_AUDIO_ The
WIDENESS KSPROPERTY_AUDIO_
WIDENESS property
specifies the wideness
(apparent width) of
the stereo image.

KSPROPERTY_AUDIO The properties


ENGINE contained in the
KSPROPSETID_AudioE
ngine property set
are defined by this
enumeration and
must be supported
by a
KSNODETYPE_AUDIO
_ENGINE node.

KSPROPERTY_AUDIO The
ENGINE_BUFFER_SIZE KSPROPERTY_AUDIO
_RANGE ENGINE_BUFFER_SIZE
_RANGE property
indicates the
minimum and
maximum size of
buffer that the
hardware audio
engine can support
for a given data
format, at the
instance when it is
called. The buffer size
is specified in bytes.

KSPROPERTY_AUDIO The audio driver for


ENGINE_DESCRIPTOR the offload-capable
hardware solution
uses
KSPROPERTY_AUDIO
ENGINE_DESCRIPTOR
to provide
information about the
node that represents
the hardware audio
engine.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO The
ENGINE_DEVICEFOR KSPROPERTY_AUDIO
MAT ENGINE_DEVICEFOR
MAT property request
retrieves or alters the
state of the audio
engine node,
regarding its device
format setting.

KSPROPERTY_AUDIO The
ENGINE_GFXENABLE KSPROPERTY_AUDIO
ENGINE_GFXENABLE
property request
allows the audio
driver to retrieve or
alter the state of the
audio engine node,
regarding its global
effect processing
abilities.

KSPROPERTY_AUDIO The
ENGINE_LFXENABLE KSPROPERTY_AUDIO
ENGINE_LFXENABLE
property request
retrieves or alters the
state of the audio
engine node,
regarding its local
effect processing
abilities.

KSPROPERTY_AUDIO The
ENGINE_LOOPBACK_ KSPROPERTY_AUDIO
PROTECTION ENGINE_LOOPBACK_
PROTECTION
property request
allows the audio
driver to set the
loopback protection
status of the audio
engine node.

KSPROPERTY_AUDIO The
ENGINE_MIXFORMAT KSPROPERTY_AUDIO
ENGINE_MIXFORMAT
property request
retrieves the setting
of the mixer in the
hardware audio
engine.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO The
ENGINE_SUPPORTED KSPROPERTY_AUDIO
DEVICEFORMATS ENGINE_SUPPORTED
DEVICEFORMATS
property request
retrieves the device
formats that are
supported by the
hardware audio
engine.

KSPROPERTY_AUDIO The
ENGINE_VOLUMELEV KSPROPERTY_AUDIO
EL ENGINE_VOLUMELEV
EL property specifies
the volume level of a
channel in a given
stream.

KSPROPERTY_AUDIO The
GFX_CAPTURETARGET KSPROPERTY_AUDIO
DEVICEID GFX_CAPTURETARGET
DEVICEID property is
used to inform a GFX
filter of the Plug and
Play device ID of the
audio device that is
the source of the
capture stream.

KSPROPERTY_AUDIO The
GFX_RENDERTARGET KSPROPERTY_AUDIO
DEVICEID GFX_RENDERTARGET
DEVICEID property is
used to inform a GFX
filter of the Plug and
Play device ID of the
audio device that
renders the final
audio mix.

KSPROPERTY_AUDIO The
MODULE KSPROPERTY_AUDIO
MODULE
enumeration defines
constants that are
used by audio drivers
to communicate
information about
partner defined audio
modules.
TO P IC DESC RIP T IO N

KSPROPERTY_AUDIO The
SIGNALPROCESSING KSPROPERTY_AUDIO
SIGNALPROCESSING
enumeration defines a
constant that is used
by audio drivers in
connection with audio
processing modes on
pins.

KSPROPERTY_AUDIO The
SIGNALPROCESSING_ KSPROPERTY_AUDIO
MODES SIGNALPROCESSING_
MODES property
returns the list of
audio signal
processing modes
supported by a pin
factory.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_AL KSPROPERTY_DIRECT
L SOUND3DBUFFER_AL
L property is used to
get or set all the
DirectSound 3D-
buffer properties for
the specified buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_C KSPROPERTY_DIRECT
ONEANGLES SOUND3DBUFFER_C
ONEANGLES property
specifies the inside
and outside cone
angles of the sound
projection cone for a
3D sound buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_C KSPROPERTY_DIRECT
ONEORIENTATION SOUND3DBUFFER_C
ONEORIENTATION
property specifies the
orientation of the
sound-projection
cone for a 3D sound
buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_C KSPROPERTY_DIRECT
ONEOUTSIDEVOLUM SOUND3DBUFFER_C
E ONEOUTSIDEVOLUM
E property specifies
the cone-outside
sound volume for a
3D sound buffer.
TO P IC DESC RIP T IO N

KSPROPERTY_DIRECT The
SOUND3DBUFFER_M KSPROPERTY_DIRECT
AXDISTANCE SOUND3DBUFFER_M
AXDISTANCE
property specifies the
maximum distance for
a 3D sound buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_MI KSPROPERTY_DIRECT
NDISTANCE SOUND3DBUFFER_MI
NDISTANCE property
specifies the minimum
distance for a 3D
sound buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_M KSPROPERTY_DIRECT
ODE SOUND3DBUFFER_M
ODE property
specifies the
processing mode of a
3D sound buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_P KSPROPERTY_DIRECT
OSITION SOUND3DBUFFER_P
OSITION property
specifies the position
of a 3D sound buffer.

KSPROPERTY_DIRECT The
SOUND3DBUFFER_VE KSPROPERTY_DIRECT
LOCITY SOUND3DBUFFER_VE
LOCITY property
specifies the velocity
of a 3D sound buffer.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
ALL SOUND3DLISTENER_
ALL property is used
to set or get all the
DirectSound 3D-
listener properties for
the specified listener
ID.
TO P IC DESC RIP T IO N

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
ALLOCATION SOUND3DLISTENER_
ALLOCATION
property is used to
tell the driver when to
allocate and free the
storage for its listener
data. Storage is
allocated when the
listener is created, and
freed when the
listener is deleted.
This property can also
be used to query the
driver whether
listener data is
currently allocated.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
BATCH SOUND3DLISTENER_
BATCH property
specifies the batch-
mode setting for a 3D
listener.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
DISTANCEFACTOR SOUND3DLISTENER_
DISTANCEFACTOR
property specifies the
distance factor that
should be applied to
any distance values.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
DOPPLERFACTOR SOUND3DLISTENER_
DOPPLERFACTOR
property specifies the
Doppler factor for a
3D listener.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
ORIENTATION SOUND3DLISTENER_
ORIENTATION
property specifies the
orientation of a 3D
listener.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
POSITION SOUND3DLISTENER_
POSITION property
specifies the position
of a 3D listener.
TO P IC DESC RIP T IO N

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
ROLLOFFFACTOR SOUND3DLISTENER_
ROLLOFFFACTOR
property specifies the
rolloff factor for a 3D
listener.

KSPROPERTY_DIRECT The
SOUND3DLISTENER_ KSPROPERTY_DIRECT
VELOCITY SOUND3DLISTENER_
VELOCITY property
specifies the velocity
vector of a 3D listener.

KSPROPERTY_FMRX_ The
ANTENNAENDPOINTI KSTOPOLOGY_ENDP
D OINTID property
contains information
about the endpoint to
be used as FM
antenna.

KSPROPERTY_FMRX_E The
NDPOINTID KSTOPOLOGY_ENDP
OINTID property
contains the endpoint
ID for the FM radio
output/render
endpoint.

KSPROPERTY_FMRX_ The
VOLUME KSPROPERTY_FMRX_
VOLUME property
controls the volume
of the FM radio.

KSPROPERTY_HRTF3D The
_FILTER_FORMAT KSPROPERTY_HRTF3D
_FILTER_FORMAT
property retrieves the
filter format used by
the HRTF algorithm.

KSPROPERTY_HRTF3D The
_INITIALIZE KSPROPERTY_HRTF3D
_INITIALIZE property
specifies the
parameter values to
use to initialize the
HRTF algorithm.

KSPROPERTY_HRTF3D The
_PARAMS KSPROPERTY_HRTF3D
_PARAMS property
applies a set of 3-D
parameter values to
the HRTF algorithm.
TO P IC DESC RIP T IO N

KSPROPERTY_ITD3D_ The
PARAMS KSPROPERTY_ITD3D_
PARAMS property is
used to set the
parameters used by a
3D node's ITD
algorithm.

KSPROPERTY_JACK The
KSPROPERTY_JACK
enumeration defines
new property IDs that
are used by audio jack
structures.

KSPROPERTY_JACK_C The
ONTAINERID KSPROPERTY_JACK_C
ONTAINERID
property is
implemented as a
pin-wise property
that is accessed by
using the filter handle.

KSPROPERTY_JACK_D The
ESCRIPTION KSPROPERTY_JACK_D
ESCRIPTION property
is implemented as a
multi-item, pin-wise
property that is
accessed through the
filter handle.

KSPROPERTY_JACK_D The
ESCRIPTION2 KSPROPERTY_JACK_D
ESCRIPTION2
property is
implemented as a
pin-wise property
that is accessed by
using the filter handle.

KSPROPERTY_JACK_SI The
NK_INFO KSPROPERTY_JACK_SI
NK_INFO property is
implemented as a
pin-wise property
that is accessed by
using the filter handle.

KSPROPERTY_ONESH The
OT_DISCONNECT KSPROPERTY_ONESH
OT_DISCONNECT
property is used to
prompt the audio
driver to disconnect
from the Bluetooth
audio device.
TO P IC DESC RIP T IO N

KSPROPERTY_ONESH The
OT_RECONNECT KSPROPERTY_ONESH
OT_RECONNECT
property is used to
prompt the audio
driver to attempt to
connect to the
Bluetooth audio
device.

KSPROPERTY_RTAUDI The
O_BUFFER KSPROPERTY_RTAUDI
O_BUFFER property
specifies a driver-
allocated cyclic buffer
for audio data.

KSPROPERTY_RTAUDI The
O_BUFFER_WITH_NO KSPROPERTY_RTAUDI
TIFICATION O_BUFFER_WITH_NO
TIFICATION property
specifies a driver-
allocated cyclic buffer
for audio data and
identifies event
notification
requirements.

KSPROPERTY_RTAUDI The
O_CLOCKREGISTER KSPROPERTY_RTAUDI
O_CLOCKREGISTER
property maps the
wall clock register of
the audio device into
a virtual memory
location that the
client can access.

KSPROPERTY_RTAUDI KSPROPERTY_RTAUDI
O_GETREADPACKET O_GETREADPACKET
returns information
about captured audio
packets.

KSPROPERTY_RTAUDI The
O_HWLATENCY KSPROPERTY_RTAUDI
O_HWLATENCY
property retrieves a
description of the
stream latency of the
audio hardware and
its associated data
path.
TO P IC DESC RIP T IO N

KSPROPERTY_RTAUDI KSPROPERTY_RTAUDI
O_PACKETCOUNT O_PACKETCOUNT
returns the (1-based)
count of packets
completely
transferred from the
WaveRT buffer into
hardware.

KSPROPERTY_RTAUDI The
O_POSITIONREGISTE KSPROPERTY_RTAUDI
R O_POSITIONREGISTE
R property maps the
position register of an
audio device for a
particular stream into
a virtual memory
location that the
client can access.

KSPROPERTY_RTAUDI KSPROPERTY_RTAUDI
O_PRESENTATION_PO O_PRESENTATION_PO
SITION SITION returns
stream presentation
information.

KSPROPERTY_RTAUDI The client application


O_QUERY_NOTIFICAT uses the
ION_SUPPORT KSPROPERTY_RTAUDI
O_QUERY_NOTIFICAT
ION_SUPPORT
property to
determine whether
the audio driver can
notify the client
application when a
process that is
performed on the
submitted buffer is
completed.

KSPROPERTY_RTAUDI The
O_REGISTER_NOTIFIC KSPROPERTY_RTAUDI
ATION_EVENT O_REGISTER_NOTIFIC
ATION_EVENT
property registers a
user-mode event for
DMA-driven event
notification. Events
must be registered
after successfully
calling
KSPROPERTY_RTAUDI
O_BUFFER_WITH_NO
TIFICATION.
TO P IC DESC RIP T IO N

KSPROPERTY_RTAUDI KSPROPERTY_RTAUDI
O_SETWRITEPACKET O_SETWRITEPACKET
informs the driver
that the OS has
written valid data to
the WaveRT buffer.

KSPROPERTY_RTAUDI The
O_UNREGISTER_NOTI KSPROPERTY_RTAUDI
FICATION_EVENT O_UNREGISTER_NOTI
FICATION_EVENT
property unregisters
a user-mode event
from DMA-driven
event notification.

KSPROPERTY_SOUND The
DETECTOR KSPROPERTY_SOUND
DETECTOR
enumeration defines
constants that are
used to register a
filter for an audio
capture device that
also supports a
detector.

KSPROPERTY_SOUND The
DETECTOR_ARMED KSPROPERTY_SOUND
DETECTOR_ARMED
property is the
current arming state
of the detector.

KSPROPERTY_SOUND The
DETECTOR_MATCHRE KSPROPERTY_SOUND
SULT DETECTOR_MATCHRE
SULT property holds
the result data for a
match.

KSPROPERTY_SOUND The
DETECTOR_PATTERNS KSPROPERTY_SOUND
DETECTOR_PATTERNS
property is set by the
operating system to
configure the
keywords to be
detected.

KSPROPERTY_SOUND The
DETECTOR_SUPPORT KSPROPERTY_SOUND
EDPATTERNS DETECTOR_SUPPORT
EDPATTERNS property
is used to get a list of
GUIDs that identify
the types of
supported patterns.
TO P IC DESC RIP T IO N

KSPROPERTY_SYSAU The
DIO_ATTACH_VIRTUA KSPROPERTY_SYSAU
L_SOURCE DIO_ATTACH_VIRTUA
L_SOURCE property
attaches a virtual
source to a pin
instance on a virtual
audio device.

KSPROPERTY_SYSAU The
DIO_COMPONENT_I KSPROPERTY_SYSAU
D DIO_COMPONENT_I
D property retrieves
the component ID
from the wave-
rendering device that
the specified virtual
audio device uses.

KSPROPERTY_SYSAU The
DIO_CREATE_VIRTUA KSPROPERTY_SYSAU
L_SOURCE DIO_CREATE_VIRTUA
L_SOURCE property
creates a new virtual
source.

KSPROPERTY_SYSAU The
DIO_DEVICE_COUNT KSPROPERTY_SYSAU
DIO_DEVICE_COUNT
property retrieves a
count specifying the
number of virtual
audio devices that a
DirectSound
application program
has to choose from.

KSPROPERTY_SYSAU The
DIO_DEVICE_FRIENDL KSPROPERTY_SYSAU
Y_NAME DIO_DEVICE_FRIENDL
Y_NAME property
retrieves a Unicode
string containing the
friendly name of the
virtual audio device.

KSPROPERTY_SYSAU The
DIO_DEVICE_INSTAN KSPROPERTY_SYSAU
CE DIO_DEVICE_INSTAN
CE property specifies
the current instance
of a virtual audio
device.
TO P IC DESC RIP T IO N

KSPROPERTY_SYSAU The
DIO_DEVICE_INTERFA KSPROPERTY_SYSAU
CE_NAME DIO_DEVICE_INTERFA
CE_NAME property
retrieves a Unicode
string containing the
Plug and Play device
interface name for the
specified virtual audio
device.

KSPROPERTY_SYSAU The
DIO_INSTANCE_INFO KSPROPERTY_SYSAU
DIO_INSTANCE_INFO
property opens a
virtual audio device
and specifies the
configuration flags for
that device.

KSPROPERTY_SYSAU The
DIO_SELECT_GRAPH KSPROPERTY_SYSAU
DIO_SELECT_GRAPH
property is used to
explicitly include an
optional node in the
graph that SysAudio
builds for a pin
instance on a virtual
audio device.

KSPROPERTY_TELEPH The
ONY_CALLCONTROL KSPROPERTY_TELEPH
ONY_CALLCONTROL
property is used to
start and terminate a
phone call.

KSPROPERTY_TELEPH The
ONY_CALLHOLD KSPROPERTY_TELEPH
ONY_CALLHOLD
property is used to
control the hold state
of a phone call.

KSPROPERTY_TELEPH The
ONY_CALLINFO KSPROPERTY_TELEPH
ONY_CALLINFO
property is used to
retrieve current call
information, such as
call state and call
type.
TO P IC DESC RIP T IO N

KSPROPERTY_TELEPH The
ONY_ENDPOINTIDPAI KSPROPERTY_TELEPH
R ONY_ENDPOINTIDPAI
R property contains
the render and
capture endpoints for
cellular audio routing.

KSPROPERTY_TELEPH The
ONY_MUTE_TX KSPROPERTY_TELEPH
ONY_MUTE_TX
property is used to
control whether to
mute the data being
transmitted from the
local microphone to
the remote end.

KSPROPERTY_TELEPH The
ONY_PROVIDERCHA KSPROPERTY_TELEPH
NGE ONY_PROVIDERCHA
NGE property is used
to communicate to
the audio driver that
single-radio voice call
continuity (SRVCC) is
beginning or ending.

KSPROPERTY_TELEPH The
ONY_PROVIDERID KSPROPERTY_TELEPH
ONY_PROVIDERID
property is used by
the audio driver to
associate a provider
identifier to a wave
filter.

KSPROPERTY_TELEPH The
ONY_VOLUME KSPROPERTY_TELEPH
ONY_VOLUME
property is used to
control the volume
for all cellular calls.

KSPROPERTY_TOPOL The
OGYNODE_ENABLE KSPROPERTY_TOPOL
OGYNODE_ENABLE
property is used to
turn on or off the
topology nodes in an
already built topology.

KSPROPERTY_TOPOL The
OGYNODE_RESET KSPROPERTY_TOPOL
OGYNODE_RESET
property resets the
node completely,
restoring it to its
initial state.
TO P IC DESC RIP T IO N

KSRTAUDIO_BUFFER_ The
PROPERTY KSRTAUDIO_BUFFER_
PROPERTY structure
appends a buffer base
address and
requested buffer size
to a KSPROPERTY
structure. This
structure is used by
the client to request
allocation of the audio
buffer via
KSPROPERTY_RTAUDI
O_BUFFER.
KSEVENT_CONTROL_CHANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_CONTROL_CHANGE event indicates that a change in control value has occurred at a node that
represents a hardware volume-control knob, mute switch, or other type of manual control.
Usage Summar y Table

TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Pin KSE_NODE KSEVENTDATA

The event value type (operation data) is a KSEVENTDATA structure that specifies the type of notification to use for
an event.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSE_NODE
KSEVENTDATA
PCEVENT_ITEM
PCEVENT_REQUEST
IPortEvents
KSEVENT_LOOPEDSTREAMING_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_LOOPEDSTREAMING_POSITION event indicates that the audio stream has reached a specified
position in a looped buffer.
Usage Summar y Table

TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Pin KSEVENT LOOPEDSTREAMING_POSITIO


N_EVENT_DATA

The event value type (operation data) is a LOOPEDSTREAMING_POSITION_EVENT_DATA structure that contains the
following information:
The type of notification that the system will send to the client when the position event occurs.
The buffer position that triggers the event.
This event is intended only for internal use by the system.

Remarks
In Windows Server 2003, Windows XP, Windows 2000, Windows Me, and Windows 98, the WavePci and
WaveCyclic port drivers contain their own built-in handlers for KSEVENT_LOOPEDSTREAMING_POSITION events.
WavePci and WaveCyclic miniport drivers should not implement handlers for these events.
In Windows Vista, none of the WaveXxx port drivers implement event handlers or other support for
KSEVENT_LOOPEDSTREAMING_POSITION events.
A looped buffer is a data buffer for an audio stream of type KSINTERFACE_STANDARD_LOOPED_STREAMING .
When a play or record cursor reaches the end of a looped buffer, the cursor wraps around to the start of the buffer.
For more information about looped buffers, buffer positions, and play and record cursors, see Audio Position
Property.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSEVENT
KSINTERFACE_STANDARD_LOOPED_STREAMING
LOOPEDSTREAMING_POSITION_EVENT_DATA
KSEVENT_SOUNDDETECTOR_MATCHDETECTED
10/23/2019 • 2 minutes to read • Edit Online

The KSEVENT_SOUNDDETECTOR_MATCHDETECTED event is generated by the audio driver to notify the OS


whenever a match is detected.
Usage Summary Table
TA RGET EVEN T DESC RIP TO R T Y P E EVEN T VA L UE T Y P E

Filter KSEVENT KSEVENTDATA

Remarks
When this event is triggered, the OS reads the KSPROPERTY_SOUNDDETECTOR_MATCHRESULT property. The
audio driver must disarm the sound detector after a match has been detected. The OS rearms the device once it is
ready to wait again.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h

See also
KSEVENTDATA
KSEVENT
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
KSJACK_DESCRIPTION structure
12/5/2018 • 3 minutes to read • Edit Online

The KSJACK_DESCRIPTION structure specifies the physical attributes of an audio jack.

Syntax
typedef struct {
DWORD ChannelMapping;
DWORD Color;
EPcxConnectionType ConnectionType;
EPcxGeoLocation GeoLocation;
EPcxGenLocation GenLocation;
EPxcPortConnection PortConnection;
BOOL IsConnected;
} KSJACK_DESCRIPTION, *PKSJACK_DESCRIPTION;

Members
ChannelMapping
Specifies the mapping of the audio channels to the corresponding speaker positions. ChannelMapping is a
bitmask of the KSAUDIO_SPEAKER_XXX flags (for example, SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT),
which are defined in the header file Ksmedia.h. ChannelMapping should be nonzero only for analog rendering
pins. For capture pins or for digital rendering pins, set this member to 0.
> [!Note] > Devicetopology.h originally defined ChannelMapping as an enumeration of type
EChannelMapping . The EChannelMapping enumeration has since been deprecated and is no longer used in
Windows Vista and later versions of the Windows operating systems.
Color
Specifies the jack color. The color is expressed as a 32-bit RGB value that is formed by concatenating the 8-bit blue,
green, and red color components. The blue component occupies the 8 least-significant bits (bits 0-7), the green
component occupies bits 8-15, and the red component occupies bits 16-23. The 8 most-significant bits are zeros. If
the jack color is unknown or the physical connector has no identifiable color, the value of this member is
0x00000000, which represents black.
ConnectionType
Specifies the physical connection type for this jack. The value of this member is one of the EPcxConnectionType
enumeration values shown in the following table.

VA L UE C O N N EC TO R T Y P E

eConnTypeUnknown Unknown

eConnType3Point5mm 3.5 mm minijack

eConnTypeQuarter 1/4-inch jack


VA L UE C O N N EC TO R T Y P E

eConnTypeAtapiInternal ATAPI internal connector

eConnTypeRCA RCA jack

eConnTypeOptical Optical connector

eConnTypeOtherDigital Generic digital connector

eConnTypeOtherAnalog Generic analog connector

eConnTypeMultichannelAnalogDIN Multichannel analog DIN connector

eConnTypeXlrProfessional XLR connector

eConnTypeRJ11Modem RJ11 modem connector

eConnTypeCombination Connector combination

GeoLocation
The geometric location of the jack. The value of this member is one of the EPcxGeoLocation enumeration values
shown in the following table.

VA L UE GEO M ET RIC LO C AT IO N

eGeoLocRear Rear

eGeoLocFront Front

eGeoLocLeft Left

eGeoLocRight Right

eGeoLocTop Top

eGeoLocBottom Bottom

eGeoLocRearPanel Rear slide-open or pull-open panel

eGeoLocRiser Riser card


VA L UE GEO M ET RIC LO C AT IO N

eGeoLocInsideMobileLid Inside lid of mobile computer

eGeoLocDrivebay Drive bay

eGeoLocHDMI HDMI connector

eGeoLocOutsideMobileLid Outside lid of mobile computer

eGeoLocATAPI ATAPI connector

eGeoLocNotApplicable Not applicable. See Remarks section.

GenLocation
Specifies the general location of the jack. The value of this member is one of the EPcxGenLocation enumeration
values shown in the following table.

VA L UE GEN ERA L LO C AT IO N

eGenLocPrimaryBox On primary chassis

eGenLocInternal Inside primary chassis

eGenLocSeparate On separate chassis

eGenLocOther Other location

Por tConnection
Specifies the type of port represented by the jack. The value of this member is one of the EPxcPor tConnection
enumeration values shown in the following table.

VA L UE P O RT C O N N EC T IO N T Y P E

ePortConnJack Jack

ePortConnIntegratedDevice Slot for an integrated device

ePortConnBothIntegratedAndJack Both a jack and a slot for an integrated device

ePortConnUnknown Unknown

IsConnected
Indicates whether there is an external device connected to the jack. If the audio controller supports jack detection
on this pin, the value of IsConnected should accurately indicate whether the jack is occupied by a plug at any
given time. This value should always be set to TRUE for devices that do not support jack detection.

Remarks
This structure is used by the KSPROPERTY_JACK_DESCRIPTION property in Windows Vista and later. It
describes an audio jack that is part of a connection between an endpoint device and a hardware device in an audio
adapter. When a user needs to plug an endpoint device into a jack or unplug it from a jack, an audio application
can use the descriptive information in the structure to help the user to find the jack.
When an audio device does not expose a physically accessible jack, the audio device uses the
eGeoLocNotApplicable value to indicate to Windows and Windows-based apps that there is no physical jack. As
such, there is no geometric location either. For example, the audio device can be integrated into the motherboard,
without any accessible jacks.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY_JACK_DESCRIPTION
KSJACK_DESCRIPTION2 structure
6/25/2019 • 2 minutes to read • Edit Online

The KSJACK_DESCRIPTION2 structure specifies the capabilities and the current state of a jack that supports jack
presence detection.

Syntax
typedef struct _tagKSJACK_DESCRIPTION2 {
DWORD DeviceStateInfo;
DWORD JackCapabilities;
} KSJACK_DESCRIPTION2, *PKSJACK_DESCRIPTION2;

Members
DeviceStateInfo
Specifies the lower 16 bits of the DWORD parameter. This parameter indicates whether the jack is currently active,
streaming, idle, or hardware not ready.
JackCapabilities
Specifies the lower 16 bits of the DWORD parameter. This parameter is a flag and it indicates the capabilities of the
jack. This flag can be set to one of the values in the following table.

Flag Meaning

JACKDESC2_PRESENCE_DETECT_CAPABILITY Jack supports jack presence detection.


(0x00000001)

JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY Jack supports dynamic format change.


(0x00000002)

For more information about dynamic format change, see Dynamic Format Change.

Remarks
If an audio device lacks jack presence detection, the IsConnected member of the KSJACK_DESCRIPTION
structure must always be set to TRUE . To remove the ambiguity that results from this dual meaning of the TRUE
value for IsConnected , a client application can call IKsJackDescription2::GetJackDescription2 to read the
JackCapabilities flag of the KSJACK_DESCRIPTION2 structure. If this flag has the
JACKDESC2_PRESENCE_DETECT_CAPABILITY bit set, it indicates that the endpoint does in fact support jack
presence detection. In that case, the return value of the IsConnected member can be interpreted to accurately
reflect the insertion status of the jack.

Requirements
Version Available in Windows 7 and later Windows operating
systems.

Header Ksmedia.h (include Ksmedia.h)

See also
KSJACK_DESCRIPTION
IKsJackDescription2::GetJackDescription2
KSPROPERTY_AC3_ALTERNATE_AUDIO
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_ALTERNATE_AUDIO property specifies whether the two mono channels in an AC-3-
encoded stream should be interpreted as a stereo pair or as two independent program channels.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSPROPERTY KSAC3_ALTERN


ATE_AUDIO

The property value (operation data) is a KSAC3_ALTERNATE_AUDIO structure that specifies how the two mono
channels should be interpreted.
Return Value
A KSPROPERTY_AC3_ALTERNATE_AUDIO property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_ALTERNATE_AUDIO
KSPROPERTY_AC3_BIT_STREAM_MODE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_BIT_STREAM_MODE property specifies the bit-stream mode, which is the type of audio
service that is encoded into an AC-3 stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAC3_BIT_STR


EAM_MODE

The property value (operation data) is a KSAC3_BIT_STREAM_MODE structure that specifies the bit-stream mode.
Return Value
A KSPROPERTY_AC3_BIT_STREAM_MODE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_BIT_STREAM_MODE
KSPROPERTY_AC3_DIALOGUE_LEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_DIALOGUE_LEVEL property specifies the average volume level of spoken dialog within the
audio program in an AC-3-encoded stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAC3_DIALOG


UE_LEVEL

The property value (operation data) is a KSAC3_DIALOGUE_LEVEL structure that specifies the average dialog level.
Return Value
A KSPROPERTY_AC3_DIALOGUE_LEVEL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_DIALOGUE_LEVEL
KSPROPERTY_AC3_DOWNMIX
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_DOWNMIX property specifies whether the program channels in an AC-3-encoded stream
need to be downmixed to accommodate the speaker configuration.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSPROPERTY KSAC3_DOWN


MIX

The property value (operation data) is a KSAC3_DOWNMIX structure that specifies whether the program channels
should be downmixed.
Return Value
A KSPROPERTY_AC3_DOWNMIX property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Downmixing is required if the number of channels being output by the decoder is less than the number of
channels encoded in the AC-3 stream.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_DOWNMIX
KSPROPERTY_AC3_ERROR_CONCEALMENT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_ERROR_CONCEALMENT property specifies the manner in which errors in the AC-3-
encoded stream should be concealed during playback.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSPROPERTY KSAC3_ERROR_


CONCEALMENT

The property value (operation data) is a KSAC3_ERROR_CONCEALMENT structure that specifies how AC-3 blocks
containing errors should be concealed.
Return Value
A KSPROPERTY_AC3_ERROR_CONCEALMENT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_ERROR_CONCEALMENT
KSPROPERTY_AC3_LANGUAGE_CODE
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_LANGUAGE_CODE property specifies the language code of the AC-3-encoded stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAC3_L ANGU


AGE_CODE

The property value (operation data) is a KSAC3_LANGUAGE_CODE structure that specifies the language code.
Return Value
A KSPROPERTY_AC3_LANGUAGE_CODE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_L ANGUAGE_CODE
KSPROPERTY_AC3_ROOM_TYPE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AC3_ROOM_TYPE property specifies the type and calibration of the mixing room in which the
final audio session was produced.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAC3_ROOM_


TYPE

The property value (operation data) is a KSAC3_ROOM_TYPE structure that specifies the type of mixing room in
which the AC-3-encoded stream was produced.
Return Value
A KSPROPERTY_AC3_ROOM_TYPE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property provides information about the production environment of the AC-3-encoded stream. The property
value is not typically used by the AC-3 decoder, but might be used by other audio components.
If the encoded stream does not specify a room type, the property request returns an error code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAC3_ROOM_TYPE
KSPROPERTY_AEC_MODE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AEC_MODE property is used to control an AEC node's mode of operation. This is an optional
property of an AEC node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPERTY ULONG

The property value (operation data) is of type ULONG and can be set to one of the following mode constants from
header file Ksmedia.h:
AEC_MODE_PASS_THROUGH
In pass-through mode, the AEC node allows capture and render data to simply pass through the node
without being modified.
AEC_MODE_HALF_DUPLEX
The AEC algorithm is running in half-duplex mode, which is similar in operation to a speaker phone. In this
mode, the speaker volume is muted whenever the local person's speech has a higher volume level than the
remote person's.
AEC_MODE_FULL_DUPLEX
The AEC algorithm is running in full-duplex mode.
Pass-through mode is the default. When the filter containing the AEC node is created or the node is reset, the node
is initially configured to operate in pass-through mode.
In the initial release of Windows XP, the AEC algorithm that the AEC system filter uses does not support the half-
duplex mode.
Return Value
A KSPROPERTY_AEC_MODE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSPROPERTY_AEC_NOISE_FILL_ENABLE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AEC_NOISE_FILL_ENABLE property is used to enable and disable background noise filling. This
is an optional property of an AEC node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL. Setting this value to TRUE enables background noise filling.
When enabled, the node inserts background noise into the capture stream. Setting this value to FALSE disables
background noise filling.
Return Value
A KSPROPERTY_AEC_NOISE_FILL_ENABLE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
An AEC node inserts background comfort noise into the capture stream in order to avoid the unnatural silence
that occurs when the captured data stream is set to zero after perfect echo cancellation.
When the filter containing the AEC node is created or the node is reset, background noise filling is disabled by
default.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSPROPERTY_AEC_STATUS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AEC_STATUS property is used to monitor the status of an AEC node


(KSNODETYPE_ACOUSTIC_ECHO_CANCEL ). This is an optional property of an AEC node.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG. This is a status value that can be set to the bitwise OR of
one or more of the flag bits in the left column of the following table, which are defined in header file Ksmedia.h.
The corresponding DSCFX_AEC_STATUS flags from header file Dsound.h are shown in the right column of the
table. See the Microsoft Windows SDK documentation for information about these flags.

A EC STAT US F L A G VA L UE DSC F X_A EC _STAT US F L A G

AEC_STATUS_FD_HISTORY_UNINITI 0x0 DSCFX_AEC_STATUS_HISTORY_UNI


ALIZED NITIALIZED

AEC_STATUS_FD_HISTORY_CONTIN 0x1 DSCFX_AEC_STATUS_HISTORY_CON


UOUSLY_CONVERGED TINUOUSLY_CONVERGED

AEC_STATUS_FD_HISTORY_PREVIO 0x2 DSCFX_AEC_STATUS_HISTORY_PRE


USLY_DIVERGED VIOUSLY_DIVERGED

AEC_STATUS_FD_CURRENTLY_CON 0x8 DSCFX_AEC_STATUS_CURRENTLY_C


VERGED ONVERGED

Return Value
A KSPROPERTY_AEC_STATUS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The three least significant bits in the AEC status flags (see preceding table) represent the convergence history (CH)
of the AEC algorithm. The CH status bits can be used by a Microsoft DirectSound application to determine whether
the algorithm has converged and also whether it has remained in the converged state since the time that it started
processing data. Depending on the audio hardware, the AEC algorithm might fail to converge, in which case the
resulting capture buffer is likely to include the echo from the speakers.
When the filter containing the AEC node is created or the node is reset, the AEC algorithm initially sets the three
CH status bits to zero. This setting represents the uninitialized state, AEC_STATUS_FD_HISTORY_UNINITIALIZED.
After the AEC algorithm converges, the CH status switches to the converged state,
AEC_STATUS_FD_HISTORY_CONTINUOUSLY_CONVERGED. If the AEC algorithm ever loses convergence, the CH
status switches to the diverged state, AEC_STATUS_FD_HISTORY_PREVIOUSLY_DIVERGED. Although the status is
most likely to switch to the diverged state from the converged state, it might also switch directly from the
uninitialized state to the diverged state. After the CH status has switched to the diverged state, it will remain in that
state until the algorithm is reset or starvation is detected.
When the AEC system filter detects starvation at any of its four pins--capture in, capture out, render in, or render
out--it resets its internal state, including the convergence history.
Note that bit 2 of the three CH status bits is not currently used.
As an alternative to using the CH status bits, the application can monitor the real-time convergence status by
checking the AEC_STATUS_FD_CURRENTLY_CONVERGED flag bit. If this bit is set, the algorithm is currently
converged. The algorithm can lose convergence temporarily when changes occur in the acoustic path. The real-
time convergence flag is filtered to prevent such momentary losses from inappropriately switching the CH status
bits to the DSCFX_AEC_STATUS_FD_HISTORY_PREVIOUSLY_DIVERGED state.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSPROPERTY_AUDIO_3D_INTERFACE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_3D_INTERFACE property specifies the 3D algorithm to use to process the data in the
sound buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE GUID


RTY

The property value (operation data) is a GUID that specifies a 3D algorithm. This value can be one of the following
GUIDs from header file Dsound.h:
DS3DALG_DEFAULT
DS3DALG_NO_VIRTUALIZATION
DS3DALG_HRTF_FULL
DS3DALG_HRTF_LIGHT
For more information about these GUIDs, see the description of the guid3dAlgorithm member of the
DSBUFFERDESC structure in the Microsoft Windows SDK documentation.
Return Value
A KSPROPERTY_AUDIO_3D_INTERFACE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_3D_EFFECTS
KSPROPERTY_AUDIO_AGC
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_AGC property specifies the state of the AGC (automatic gain control) for a channel in an
AGC node (KSNODETYPE_AGC ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY BOOL


_AUDIO_CHANNEL

The property value (operation data) is of type BOOL and indicates whether AGC is turned on or off. A value of
TRUE indicates that the AGC is on. FALSE indicates that it is off.
Return Value
A KSPROPERTY_AUDIO_AGC property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_AGC
KSPROPERTY_AUDIO_ALGORITHM_INSTANCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_ALGORITHM_INSTANCE property specifies the digital signal processing (DSP) algorithm
that is used to achieve the third-party effect that the node applies to the audio data stream. The effects that are
defined for this property include acoustic echo cancellation and noise suppression.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE GUID


RTY

The property value (operation data) is a GUID that identifies the effect that the pin applies to its data stream. This
value can be one of the following GUIDs from header file Ksmedia.h:
KSALGORITHMINSTANCE_SYSTEM_AGC
Reserved for future use
KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL
System default acoustic echo cancellation algorithm
KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR
Reserved for future use
KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS
System default noise suppression algorithm
Return Value
A KSPROPERTY_AUDIO_ALGORITHM_INSTANCE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to control the DSP algorithm that is performed by an AEC node
(KSNODETYPE_ACOUSTIC_ECHO_CANCEL ) or noise suppression node (KSNODETYPE_NOISE_SUPPRESS ).
The algorithm-instance GUID matches the value in the guidDSCFXInstance member of a DSCEFFECTDESC
structure that a caller passes to the IDirectSoundCapture::CreateCaptureBuffer method or
DirectSoundFullDuplexCreate function. For more information, see the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_NOISE_SUPPRESS
KSPROPERTY_AUDIO_BASS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_BASS property specifies the bass level for a channel in a tone node
(KSNODETYPE_TONE ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY LONG


_AUDIO_CHANNEL

The property value (operation data) is of type LONG and specifies the bass level. Bass-level values use the
following scale:
-2147483648 is -Infinity decibels (attenuation),
-2147483647 is -32767.99998474 decibels (attenuation), and
+2147483647 is +32767.99998474 decibels (gain).
A decibel range represented by integer values -2147483648 to +2147483647, where
This scale has a resolution of 1/65536 decibel.
Return Value
A KSPROPERTY_AUDIO_BASS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The filter will succeed a KSPROPERTY_AUDIO_BASS set-property request that specifies a value that is beyond the
range of the filter but will clamp the value to the supported range. In a subsequent request to get this property,
however, it will output the actual value used.
A tone node can support properties for controlling treble level, mid-frequency level, bass level, and bass boost. For
more information, see KSNODETYPE_TONE .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_TONE
KSPROPERTY_AUDIO_BASS_BOOST
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_BASS_BOOST property enables and disables bass boost for a channel in a tone node
(KSNODETYPE_TONE ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY BOOL


_AUDIO_CHANNEL

The property value (operation data) is of type BOOL and indicates whether bass boost is turned on or off. A value
of TRUE indicates that the bass boost is on for the specified channel. FALSE indicates that it is off.
Return Value
A KSPROPERTY_AUDIO_BASS_BOOST property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
A tone node can support properties for controlling treble level, mid-frequency level, bass level, and bass boost. For
more information, see KSNODETYPE_TONE .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_TONE
KSPROPERTY_AUDIO_BUFFER_DURATION
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_BUFFER_DURATION property allows the size of the client application buffer to be
reported as time duration.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSPROPERTY ULONG

The property value is of type ULONG and represents the client buffer duration that is measured in milliseconds.
Return Value
A KSPROPERTY_AUDIO_BUFFER_DURATION property request returns STATUS_SUCCESS to indicate that the
property request has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
You can adjust the duration of the request for isochronous audio data capture to help improve the performance of
your USB audio device. A shorter duration reduces latency but it also means that the USB audio stack must make
more frequent deferred procedure calls (DPC), which may cause degraded performance.

Requirements
Version Available in Windows 7 and later versions of Windows.

Header Ksmedia.h (include Ksmedia.h)


KSPROPERTY_AUDIO_CHANNEL_CONFIG
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_CHANNEL_CONFIG property specifies the actual spatial placement of channels in the
audio stream that a node outputs.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter/Pin KSNODEPROPERTY KSAUDIO_CHA


NNEL_CONFIG

The property value (operation data) is a structure of type KSAUDIO_CHANNEL_CONFIG. This structure specifies
the channels that are contained in the output stream and the assignment of those channels to speakers.
Return Value
A KSPROPERTY_AUDIO_CHANNEL_CONFIG property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
When used as a property of a DAC node (KSNODETYPE_DAC ) or 3D node (KSNODETYPE_3D_EFFECTS ), the
KSPROPERTY_AUDIO_CHANNEL_CONFIG property specifies the DirectSound speaker configuration. For stereo
speaker configurations, this property is used in conjunction with the
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY property, which distinguishes between headphones
and several stereo speaker configurations. For more information about speaker configurations, see DirectSound
Speaker-Configuration Settings.
DirectSound also uses the KSPROPERTY_AUDIO_CHANNEL_CONFIG property to query a "pan" node for its
channel configuration. A pan node is the second volume node (KSNODETYPE_VOLUME ) on a mixer pin that
meets the DirectSound node-ordering requirements. DirectSound implementation of the
IDirectSoundBuffer ::SetPan method (described in the Microsoft Windows SDK documentation) uses the pan
node's KSPROPERTY_AUDIO_VOLUMELEVEL property to control panning.
DirectSound treats KSPROPERTY_AUDIO_CHANNEL_CONFIG as a filter property on a DAC node, and as a pin
property on volume and 3D nodes.
Clients also use this property to select the format of the stream that a KSNODETYPE_PROLOGIC_DECODER
node outputs.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSAUDIO_CHANNEL_CONFIG
KSNODETYPE_DAC
KSNODETYPE_3D_EFFECTS
KSNODETYPE_VOLUME
KSNODETYPE_PROLOGIC_DECODER
KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
KSPROPERTY_AUDIO_VOLUMELEVEL
KSPROPERTY_AUDIO_CHORUS_LEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_CHORUS_LEVEL property specifies the chorus level. This is a property of a chorus node
(KSNODETYPE_CHORUS ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY ULONG

The property value (operation data) is of type ULONG and specifies the chorus level. Chorus-level values follow a
linear range from 0 to 100*(65536-1/65536) percent:
The value 0x00010000 represents 100 percent.
The value 0xFFFFFFFF represents 100*(65536-1/65536) percent.
Return Value
A KSPROPERTY_AUDIO_CHORUS_LEVEL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to get and set the volume level of the chorus echo.
Chorus is a voice-doubling effect that is created by echoing the original sound with a slight delay and slightly
modulating the delay of the echo. For more information, see the description of the IDirectSoundFXChorus
interface in the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_CHORUS
KSNODEPROPERTY
KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH property specifies the chorus modulation depth. This is


a property of a chorus node (KSNODETYPE_CHORUS ).
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERT ULONG


Y

The property value is of type ULONG and it specifies the chorus modulation depth. It is expressed in milliseconds
and sets the speed (frequency) of the modulator. The value can range from 0 to 255.9961 in 1/256th increments. To
accommodate this, the property value should be expressed as a fixed point 16.16 value, where the following is true:
The value 0x00010000 represents 1 ms
The value 0xFFFFFFFF represents (65536-1/65536) ms
Return Value
A KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows Vista

Header Ksmedia.h

See also
KSNODETYPE_CHORUS
KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE property specifies the chorus modulation rate. This is a


property of a chorus node (KSNODETYPE_CHORUS ).
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERT ULONG


Y

The property value is of type ULONG and it specifies the chorus modulation rate. It is expressed in Hz. The value
can range from 0 to 255.9961 in 1/256th increments. To accommodate this, the property value should be
expressed as a fixed-point 16.16 value, where the following is true:
The value 0x00010000 represents 1Hz
The value 0xFFFFFFFF represents (65536-1/65536) Hz
Return Value
A KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows Vista

Header Ksmedia.h

See also
KSNODETYPE_CHORUS
KSPROPERTY_AUDIO_COPY_PROTECTION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_COPY_PROTECTION property specifies the copy-protection status of an audio stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY KSAUDIO_COP


Y_PROTECTION

The property value (operation data) is a structure of type KSAUDIO_COPY_PROTECTION. The structure specifies
whether a stream is copyrighted; it also specifies whether the stream is an original stream or a copy of the original
stream.
Return Value
A KSPROPERTY_AUDIO_COPY_PROTECTION property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The KSPROPERTY_AUDIO_COPY_PROTECTION property is a property of an audio device that supports a protection
scheme similar to the Serial Copy Management System (SCMS). The property indicates whether a digital stream is
protected by copyright and whether it is an original stream or a copy.
SCMS can provide three levels of protection of audio content:
Level 0: Unrestricted copying of a stream that either lacks a copyright or does not assert a copyright.
Level 1: Restriction of copying to first-generation streams. Users can make copies of the original copyrighted
stream, but they cannot make copies of copies of the stream.
Level 2: No copying at all of the stream.
The KSPROPERTY_AUDIO_COPY_PROTECTION property is separate from and unrelated to the implementation of
Digital Rights Management (DRM) and the Secure Audio Path (SAP) for Windows Media. For information about
SAP, see the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAUDIO_COPY_PROTECTION
KSPROPERTY_AUDIO_CPU_RESOURCES
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_CPU_RESOURCES property specifies whether a node's functionality is implemented in


hardware or is emulated in software that runs on the host CPU.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and indicates whether the node's functionality is
implemented in hardware or software. The miniport driver sets this value to one of the following two constants
from header file Ksmedia.h:
KSAUDIO_CPU_RESOURCES_HOST_CPU
This node implements its functionality in software that runs on the host CPU.
KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU
This node implements its functionality in hardware.
Return Value
A KSPROPERTY_AUDIO_CPU_RESOURCES property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to determine whether the following node types are implemented in hardware or software:
AEC node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL )
Noise-suppression node (KSNODETYPE_NOISE_SUPPRESS )
Peakmeter node (KSNODETYPE_PEAKMETER )

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_NOISE_SUPPRESS
KSNODETYPE_PEAKMETER
KSPROPERTY_AUDIO_DELAY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_DELAY property indicates the time lag that a delay node (KSNODETYPE_DEL AY )
introduces into a specified channel.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE KSTIME


RTY_AUDIO_CH
ANNEL

The property value (operation data) is a structure of type KSTIME, which specifies the amount of time lag.
Return Value
A KSPROPERTY_AUDIO_DELAY property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSTIME
KSNODETYPE_DEL AY
KSPROPERTY_AUDIO_DEMUX_DEST
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_DEMUX_DEST property specifies the destination stream to which a demultiplexer directs
its input stream. This is a property of a DEMUX node (KSNODETYPE_DEMUX ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG. This value is the pin ID of the selected output pin on the
DEMUX node.
Return Value
A KSPROPERTY_AUDIO_DEMUX_DEST property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The pin ID identifies a logical pin on the DEMUX node. For a discussion of pin IDs for logical pins on a node inside
a filter, see PCCONNECTION_DESCRIPTOR .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_DEMUX
KSNODEPROPERTY
PCCONNECTION_DESCRIPTOR
KSPROPERTY_AUDIO_DEV_SPECIFIC
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_DEV_SPECIFIC property is used to access a device-specific property in a device-specific node


(KSNODETYPE_DEV_SPECIFIC ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

<device-specific> <device-specific> <device-specific> <device-specific> <device-specific>

The property value (operation data) is expressed in a device-specific format.


Whether the property supports get- or set-property requests is also device-specific.
Return Value
This property returns either STATUS_SUCCESS or a device specific value determined by the third-party provider of
the audio driver.

Remarks
In Windows Vista and later versions of Windows, an additional tab (labeled Custom ) is provided in the Sound
applet in Control Panel . The Custom tab displays controls for automatic gain control (AGC) and device-specific
properties. The following table shows the controls that are exposed in the Sound applet for the various
KSPROPERTY_AUDIO_DEV_SPECIFIC property and data type combinations.

K SP RO P ERT Y DATA T Y P E C O N T RO L

KSPROPERTY_AUDIO_AGC BOOL Check box

KSPROPERTY_AUDIO_DEV_SPECIFI BOOL Check box


C

KSPROPERTY_AUDIO_DEV_SPECIFI LONG Slider


C

KSPROPERTY_AUDIO_DEV_SPECIFI ULONG Slider


C

KSPROPERTY_AUDIO_AGC must be used to expose actual AGC functionality in the device. Other device-specific
functionality must be exposed by using KSPROPERTY_AUDIO_DEV_SPECIFIC .
To see the Custom tab, select an audio render or capture device in the Sound applet and then click Properties.
For an example of how to implement a property handler for the KSPROPERTY_AUDIO_DEV_SPECIFIC property, see the
CMinipor tTopologyMSVAD::Proper tyHandlerDevSpecific method in the Basetopo.cpp file.
Requirements
Version Available in Windows Vista and later versions of the
Windows operating systems.

Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_DEV_SPECIFIC
KSPROPERTY_AUDIO_AGC
KSPROPERTY_AUDIO_DYNAMIC_RANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_DYNAMIC_RANGE property specifies the dynamic range of the audio stream that is
output from a loudness node (KSNODETYPE_LOUDNESS ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE KSAUDIO_DYN


RTY AMIC_RANGE

The property value (operation data) is a structure of type KSAUDIO_DYNAMIC_RANGE, which specifies the
dynamic range for the loudness node's output stream.
Return Value
A KSPROPERTY_AUDIO_DYNAMIC_RANGE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
By default, the values for the QuietCompression and LoudCompression members of the
KSAUDIO_DYNAMIC_RANGE structure are set to zero percent. This produces the full dynamic range of the audio
stream. The miniport driver sets the property to its default value when it instantiates the pin whose data path
contains the node.
Some devices might not support changes to QuietCompression and LoudCompression . If the client attempts
to change a value that the device does not support, the miniport driver should return an error.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_LOUDNESS
KSAUDIO_DYNAMIC_RANGE
KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE property is used to enable and disable dynamic tracking of


a node's sampling rate.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL and specifies whether dynamic tracking is enabled or
disabled on the node. The value is TRUE when dynamic tracking of the sampling rate is enabled. In this mode, the
input stream's sampling rate can be varied explicitly by setting the rate through
KSPROPERTY_AUDIO_SAMPLING_RATE or implicitly by setting the rate through the time stamps on the input
stream.
Return Value
A KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to control dynamic tracking in the following node types:
ADC node (KSNODETYPE_ADC )
DAC node (KSNODETYPE_DAC )
SRC node (KSNODETYPE_SRC )

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_AUDIO_SAMPLING_RATE
KSNODETYPE_ADC
KSNODETYPE_DAC
KSNODETYPE_SRC
KSPROPERTY_AUDIO_EQ_BANDS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_EQ_BANDS property specifies the set of frequency bands from an equalization table.
This is a get-only property of a channel in an EQ node (KSNODETYPE_EQUALIZER ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSNODEPROPE ULONG array


RTY_AUDIO_C
HANNEL

The property value (operation data) is an array of ULONG elements:

ULONG CenterFreqVal[N];

If the channel's equalization table contains entries for N frequency bands, the array contains N elements and each
array element specifies the center frequency of the corresponding band. The miniport driver writes into each
element an integer frequency value that is expressed in hertz (Hz). The assignment of equalization bands to array
elements is shown in the following table.
Array Element Description CenterFreqVal[0]
The center frequency (in Hz) for equalization band 0.
CenterFreqVal[1]
The center frequency (in Hz) for equalization band 1.
...
CenterFreqVal[N-1]
The center frequency (in Hz) for equalization band N-1.
Return Value
A KSPROPERTY_AUDIO_EQ_BANDS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The number of equalization bands can be determined by first submitting a
KSPROPERTY_AUDIO_NUM_EQ_BANDS request.
The equalization levels for the frequency bands are specified by the KSPROPERTY_AUDIO_EQ_LEVEL property.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_EQUALIZER
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_EQ_LEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_EQ_LEVEL property specifies the equalization levels for an equalization table that
contains entries for n frequency bands. This is a property of a channel in an EQ node
(KSNODETYPE_EQUALIZER ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE LONG array


RTY_AUDIO_C
HANNEL

The property value (operation data) is an array of LONG elements:

LONG Level[N];

If the channel's equalization table contains entries for N frequency bands, the array contains N elements and each
element specifies the level for one of the bands in the equalization table. The assignment of bands to array
elements is shown in the following table.
Array Element Description Level[0]
Level for band 0.
Level[1]
Level for band 1.
...
Level[N-1]
Level for band N-1.
Level values use the following scale:
-2147483648 is -Infinity decibels (attenuation),
-2147483647 is -32767.99998474 decibels (attenuation), and
+2147483647 is +32767.99998474 decibels (gain).
A decibel range represented by integer values -2147483648 to +2147483647, where
This scale has a resolution of 1/65536 decibel.
Return Value
A KSPROPERTY_AUDIO_EQ_LEVEL property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.
Remarks
The filter will succeed a KSPROPERTY_AUDIO_EQ_LEVEL set-property request that specifies a value that is beyond
the range of the filter but will clamp the value to the supported range. In a subsequent request to get this
property, however, it will output the actual value used.
The number of equalization bands can be determined by first submitting a
KSPROPERTY_AUDIO_NUM_EQ_BANDS request.
The center frequencies of the equalization bands are specified by the KSPROPERTY_AUDIO_EQ_BANDS
property.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_EQUALIZER
KSPROPERTY_AUDIO_NUM_EQ_BANDS
KSPROPERTY_AUDIO_EQ_BANDS
KSPROPERTY_AUDIO_FILTER_STATE
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_FILTER_STATE property is used to query a GFX filter for a list of the property sets that it
supports. The list is retrieved in the form of an array of property-set GUIDs.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY Array of GUIDs

The property data (operation data) is an array of GUIDs. Each GUID in the array specifies a property set that the
filter supports.
Return Value
A KSPROPERTY_AUDIO_FILTER_STATE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The size of the array of GUIDs that this property returns depends on the number of property sets that the filter
supports. Before retrieving the array, a client first queries the size of the property's GUID array by sending the
miniport driver's property handler a KSPROPERTY_AUDIO_FILTER_STATE get-property request with a zero-length
property-value buffer. The handler responds by returning the required buffer size and the status code
STATUS_BUFFER_OVERFLOW. For more information, see Audio Property Handlers.
With the array of GUIDs from a KSPROPERTY_AUDIO_FILTER_STATE get-property request, the operating system
can serially interrogate the properties within each property set. This information enables the operating system to
restore the state of a GFX filter object at the time that the filter is instantiated, and also to save the state of a GFX
filter object at the time that the filter is destroyed. When saving or restoring the state of the GFX filter, the operating
system serializes its requests for the properties in each property set, as described in KS Properties. The purpose for
saving and restoring the GFX filter's state is to preserve any changes the user has made to the filter's settings, and
to make the settings persistent across successive instantiations of the filter. .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_AUDIO_LATENCY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_LATENCY property is used to report the delay (or amount of audio buffering) that is
associated with the stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSTIME

The property value (operation data) is a structure of type KSTIME that specifies the stream latency.
Return Value
A KSPROPERTY_AUDIO_LATENCY property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to query the stream latency of a pin on an AEC filter. For more information, see Exposing
Hardware-Accelerated Capture Effects.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSTIME
KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION property request retrieves a number that represents the


number of bytes that the DMA has fetched from the audio buffer since the beginning of the stream.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via Pin KSP_NODE ULONGULONG


instance

Return Value
The KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Requirements
Version Windows 8

Header Ksmedia.h
KSPROPERTY_AUDIO_LOUDNESS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_LOUDNESS property specifies whether loudness (overall dynamic range and bass
boost) is enabled or disabled for a channel in a loudness node (KSNODETYPE_LOUDNESS ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE BOOL


RTY_AUDIO_CH
ANNEL

The property value (operation data) is of type BOOL and specifies whether loudness is turned on or off. The value
TRUE indicates that loudness is on. FALSE indicates that it is off.
Return Value
A KSPROPERTY_AUDIO_LOUDNESS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_LOUDNESS
KSPROPERTY_AUDIO_MANUFACTURE_GUID
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.

Usage Summary Table


KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property specifies the geometry of the microphone array.


Usage Summary Table
Usage Summary Table

Get Set Target Property Property value


descriptor type type

Yes No Filter KSP_PIN KSAUDIO_MIC_AR


RAY_GEOMETRY

The property value (operation data) is of type KSAUDIO_MIC_ARRAY_GEOMETRY. See the definition of the
KSAUDIO_MIC_ARRAY_GEOMETRY structure for details.
Return Value
A KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property request returns a STATUS_SUCCESS upon successful
completion of the request.
If the pin indicated by the PinId member of the KSP_PIN structure does not support a mic array request, the
property request will return STATUS_NOT_SUPPORTED.
If the buffer size of the request is set to zero, the property request will return a STATUS_BUFFER_OVERFLOW status.
Additionally, the request will use the return status block to indicate the size of the
KSAUDIO_MIC_ARRAY_GEOMETRY structure supported by the pin.
If the buffer size of the request is set to any buffer size that is too small to accommodate the returned structure, the
request returns a status of STATUS_BUFFER_TOO_SMALL. The request will then use the return status block to
indicate the size of the KSAUDIO_MIC_ARRAY_GEOMETRY structure that is supported by the pin.

Remarks
The KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property only supports KSPROPERTY_TYPE_GET requests. In
order for the client to determine the correct size of buffer necessary to accommodate the entire geometry
structure, it must first make the request with a zero buffer size. The client can then use the value returned in the
status block to set the buffer size correctly and then make another property request with the correctly sized buffer.
For more information about how to process a microphone array in Windows, refer to the following resources:
Microphone Array Support in Windows (white paper)
Microphone Array Geometry Property

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSAUDIO_MIC_ARRAY_GEOMETRY
KSP_PIN
KSPROPERTY_AUDIO_MIC_SENSITIVITY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIC_SENSITIVITY property specifies the microphone sensitivity in decibels relative to


full scale (dBFS) units.

NOTE
KSPROPERTY_AUDIO_MIC_SENSITIVITY is deprecated starting with Windows 10 Version 1803. Use
KSPROPERTY_AUDIO_MIC_SENSITIVITY2 instead.

Usage Summary Table

Get Set Target Property Property value


descriptor type type

Yes No Pin Instance KSP_PIN LONG

The property value (operation data) is of type LONG and contains sensitivity information in decibels relative to
dBFS units. The sensitivity value uses the following scale. The value uses fixed point decimal representation. The
data is stored as a 16.16 fixed point value. The upper 16 bits are used for the whole number of the value and the
lower 16 bits are used for the fractional portion of the value.
Return Value
A KSPROPERTY_AUDIO_MIC_SENSITIVITY property request returns a STATUS_SUCCESS upon successful
completion of the request. Otherwise, the request returns an appropriate error status code.

Remarks
The audio driver can obtain microphone sensitivity for each microphone. This property allows this information to
be retrieved from driver.
For Windows 10 voice recognition experiences such as Cortana to accurately detect and analyze user’s voice on
various devices with different microphones, the OS needs to know certain characteristics of the input signal. Based
on that information, the OS can calculate effective sensitivity and apply appropriate gain to enhance input signal.
For more information, see Voice Activation.
KSPROPERTY_AUDIO_MIC_SENSITIVITY is available beginning with Windows 10, version 1607.

Requirements
Header Ksmedia.h (include Ksmedia.h)
KSPROPERTY_AUDIO_MIC_SENSITIVITY2
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIC_SENSITIVITY2 property specifies the microphone sensitivity in decibels relative to


full scale (dBFS) units including any hardware gain. This value includes any hardware integration that impacts mic
sensitivity, prior to any software gain. The KSPROPERTY_AUDIO_MIC_SENSITIVITY2 property does not include any
software gain that is applied from the audio stack.
Usage Summary Table

Get Set Target Property Property value


descriptor type type

Yes No Pin Instance KSP_PIN LONG

The property value (operation data) is of type LONG and contains sensitivity information in decibels relative to
dBFS units. The sensitivity value uses the following scale. The value uses fixed point decimal representation. The
data is stored as a 16.16 fixed point value. The upper 16 bits are used for the whole number of the value and the
lower 16 bits are used for the fractional portion of the value.
Return Value
A KSPROPERTY_AUDIO_MIC_SENSITIVITY2 property request returns a STATUS_SUCCESS upon successful
completion of the request. Otherwise, the request returns an appropriate error status code.

Remarks
The audio driver can obtain microphone sensitivity for each microphone. This property allows this information to
be retrieved from driver.
For Windows 10 voice recognition experiences, such as Cortana, to accurately detect and analyze a user's voice on
various devices with different microphones, the OS needs to know certain characteristics of the input signal. Based
on that information, the OS can calculate effective sensitivity and apply appropriate gain to enhance the input
signal. For more information, see Voice Activation.
KSPROPERTY_AUDIO_MIC_SENSITIVITY2 is available beginning with Windows 10 Version 1803 and supersedes
KSPROPERTY_AUDIO_MIC_SENSITIVITY.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See Also
KSPROPERTY_AUDIO_MIC_SENSITIVITY
KSPROPERTY_AUDIO_MIC_SNR
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIC_SNR property specifies the microphone signal to noise ratio (SNR) measured in dB
units.
Usage Summary Table
Usage Summary Table

Get Set Target Property Property value


descriptor type type

Yes No Pin Instance KSP_PIN LONG

The property value (operation data) is of type LONG and contains the SNR information in dB units. The value uses
fixed point decimal representation. The data is stored as a 16.16 fixed point value. The upper 16 bits are used for
the whole number of the value and the lower 16 bits are used for the fractional portion of the value.
Return Value
A KSPROPERTY_AUDIO_MIC_SNR property request returns a STATUS_SUCCESS upon successful completion of the
request. Otherwise, the request returns an appropriate error status code.

Remarks
The audio driver can obtain microphone SNR for each microphone. This property allows this information to be
retrieved from driver.
For Windows 10 voice recognition experiences such as Cortana to accurately detect and analyze user’s voice on
various devices with different microphones, the OS needs to know certain characteristics of the input signal. Based
on that information, the OS can calculate effective sensitivity and apply appropriate gain to enhance input signal.
For more information, see Voice Activation.
KSPROPERTY_AUDIO_MIC_SNR is available beginning with Windows 10, version 1607.

Requirements
Header Ksmedia.h (include Ksmedia.h)
KSPROPERTY_AUDIO_MID
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MID property specifies the mid-frequency level of a channel in a tone node
(KSNODETYPE_TONE ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE LONG


RTY_AUDIO_CH
ANNEL

The property value (operation data) is of type LONG and specifies the mid-frequency level. Level values use the
following scale:
-2147483648 is -Infinity decibels (attenuation),
-2147483647 is -32767.99998474 decibels (attenuation), and
+2147483647 is +32767.99998474 decibels (gain).
A decibel range represented by integer values -2147483648 to +2147483647, where
This scale has a resolution of 1/65536 decibel.
Return Value
A KSPROPERTY_AUDIO_MID property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The filter will succeed a KSPROPERTY_AUDIO_MID set-property request that specifies a value that is beyond the
range of the filter but will clamp the value to the supported range. In a subsequent request to get this property,
however, it will output the actual value used.
A tone node can support properties for controlling treble level, mid-frequency level, bass level, and bass boost. For
more information, see KSNODETYPE_TONE .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_TONE
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIX_LEVEL_CAPS property specifies the mix-level capabilities of a supermixer node


(KSNODETYPE_SUPERMIX ). A single get-property request retrieves information for all combinations of input
and output channels.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE KSAUDIO_MIX


RTY CAP_TABLE

The property value (operation data) is a structure of type KSAUDIO_MIXCAP_TABLE, which specifies the capabilities
of all m*n input-output pathways in a supermixer node with m input channels and n output channels.
Return Value
A KSPROPERTY_AUDIO_MIX_LEVEL_CAPS property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSAUDIO_MIXCAP_TABLE
KSNODETYPE_SUPERMIX
KSPROPERTY_AUDIO_MIX_LEVEL_TABLE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MIX_LEVEL_TABLE property specifies the mix levels for a supermixer node
(KSNODETYPE_SUPERMIX ). It provides information for all input and output channels.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE Array of


RTY KSAUDIO_MIXL
EVEL structures

The property value (operation data) is an array of KSAUDIO_MIXLEVEL structures that specifies the mix levels for
all M*N input-output paths in a supermixer node with M input channels and N output channels. The array contains
M*N elements:

KSAUDIO_MIXLEVEL MixLevel[M*N];

The following table shows the mapping of array elements to the supermixer node's M*N input-output paths.

A RRAY EL EM EN T IN P UT - O UT P UT PAT H

MixLevel[0] Input channel 0 to output channel 0

MixLevel[1] Input channel 0 to output channel 1

MixLevel[N-1] Input channel 0 to output channel N-1

MixLevel[N] Input channel 1 to output channel 0

MixLevel[N+1] Input channel 1 to output channel 1

MixLevel[2N-1] Input channel 1 to output channel N-1

MixLevel[M*N-1] Input channel M-1 to output channel N-1

The following figure illustrates the mapping of MixLevel array elements to input-output paths. The index of the
MixLevel array element controlling each input-output path is shown in square brackets.
If no path connects input channel i to output channel j, the filter should set the Mute member of array element
MixLevel[i*N+j] to TRUE .
The size of the KSAUDIO_MIXLEVEL array is calculated from the KSAUDIO_MIXCAP_TABLE structure that is
retrieved from KSPROPERTY_AUDIO_MIX_LEVEL_CAPS . If the structure's InputChannels and
OutputChannels members contain the values m and n, the array size is
m * n * sizeof (KSAUDIO_MIXLEVEL)
Return Value
A KSPROPERTY_AUDIO_MIX_LEVEL_TABLE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The filter will succeed a KSPROPERTY_AUDIO_MIX_LEVEL_TABLE set-property request that specifies a mix-level
value (Level member of KSAUDIO_MIXLEVEL) that is beyond the range of the filter but will (silently) clamp the
value to the supported range. In a subsequent request to get this property, however, the filter will output the actual
value used.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSAUDIO_MIXCAP_TABLE
KSPROPERTY_AUDIO_MIX_LEVEL_CAPS
KSAUDIO_MIXLEVEL
KSNODETYPE_SUPERMIX
KSPROPERTY_AUDIO_MUTE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MUTE property specifies whether a channel on a mute node (KSNODETYPE_MUTE ) is


muted or not.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via Filter or KSNODEPROPERTY BOOL


Pin instance _AUDIO_CHANNEL

The property value is of type BOOL and indicates whether the channel of a given stream is muted. A value of
TRUE indicates that the channel is muted. FALSE indicates that it is not muted.
Return Value
A KSPROPERTY_AUDIO_MUTE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_MUTE
KSPROPERTY_AUDIO_MUX_SOURCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_MUX_SOURCE property specifies the source for the output stream of a multiplexer. This
is a property of a MUX node (KSNODETYPE_MUX ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY ULONG

The property value (operation data) is of type ULONG. This value is the pin ID of the selected input pin on the MUX
node.
Return Value
A KSPROPERTY_AUDIO_MUX_SOURCE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The pin ID identifies a logical pin on the MUX node. For a discussion of pin IDs for logical pins on a node inside a
filter, see PCCONNECTION_DESCRIPTOR .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_MUX
KSNODEPROPERTY
PCCONNECTION_DESCRIPTOR
KSPROPERTY_AUDIO_NUM_EQ_BANDS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_NUM_EQ_BANDS property is used to retrieve the number of frequency bands in the
equalization table. This is a get-only property of a channel in an EQ node (KSNODETYPE_EQUALIZER ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSNODEPROPERTY ULONG


_AUDIO_CHANNEL

The property value (operation data) is of type ULONG and specifies the number of frequency bands in the node's
equalization table.
Return Value
A KSPROPERTY_AUDIO_NUM_EQ_BANDS property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used in conjunction with the KSPROPERTY_AUDIO_EQ_BANDS and
KSPROPERTY_AUDIO_EQ_LEVEL properties to determine the lengths of the arrays that contain the values for
those properties.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_EQUALIZER
KSPROPERTY_AUDIO_EQ_BANDS
KSPROPERTY_AUDIO_EQ_LEVEL
KSPROPERTY_AUDIO_PEAKMETER
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_PEAKMETER property retrieves the maximum audio signal level that occurred at a
peakmeter node (KSNODETYPE_PEAKMETER ) since the last time the peakmeter node was reset.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via Filter or KSNODEPROPERTY LONG


Pin instance _AUDIO_CHANNEL

The property value (operation data) is of type LONG and specifies the peak sample value at the node. If the peak
value is negative, its absolute value is used.
Return Value
A KSPROPERTY_AUDIO_PEAKMETER property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code. The following table shows a possible
error status code.

STAT US C O DE M EA N IN G

STATUS_NOT_IMPLEMENTED The KS filter cannot return the current value of the


peakmeter.

Remarks
A KS audio filter handles this property request synchronously. If the request succeeds, it resets the peakmeter,
which initializes the accumulated peak value to zero. If the request does not succeed, the peakmeter is not
changed.
The system sends an IOCTL_KS_PROPERTY request for the KSPROPERTY_AUDIO_PEAKMETER property at IRQL
PASSIVE_LEVEL.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_PEAKMETER
KSPROPERTY_AUDIO_PEAKMETER2
10/23/2019 • 2 minutes to read • Edit Online

Windows 8 introduces the KSPROPERTY_AUDIO_PEAKMETER2 property that reports the maximum audio signal
level that occurred at a peakmeter node (KSNODETYPE_PEAKMETER) since the last time the peakmeter node was
reset.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via Filter or KSNODEPROPERTY LONG


Pin instance _AUDIO_CHANNEL

The property value (operation data) is of type LONG and specifies the peak sample value at the node. If the peak
value is negative, its absolute value is used.
Return Value
A KSPROPERTY_AUDIO_PEAKMETER2 property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code. The following table shows a possible
error status code.

STAT US C O DE M EA N IN G

STATUS_NOT_IMPLEMENTED The KS filter cannot return the current value of the


peakmeter.

Remarks
The KSPROPERTY_AUDIO_PEAKMETER2 property is almost identical to the KSPROPERTY_AUDIO_PEAKMETER
property. The KSPROPERTY_AUDIO_PEAKMETER2 property was introduced with Windows 8 and later operating
systems to provide improved hardware metering of a pin topology. The legacy KSPROPERTY_AUDIO_PEAKMETER
property has been retained for backward compatibility.
SignedMinimum must be set to LONG_MIN (instead of 0x8000), and SignedMaximum must be set to LONG_MAX
(instead of 0x7fff). And also, note that peak meter values are relative to this scale and the scale is linear in
amplitude.
So if, for example, you have a waveform with negative and positive peaks at -1 and +1 respectively (on a scale that
goes from -1 to +1), then a peak meter value of LONG_MAX accurately reports the maximum waveform value for
a given time window. Conversely, a peak meter value of zero (0) should be used to report silence, where all the
waveform’s values are zero. But in the case of a waveform whose peak values are between zero (0) and
LONG_MAX, the reported waveform values would be linearly reduced from the originals.
Therefore, in the case of the waveform that swings between -0.5 and +0.5 (on a scale that goes from -1 to +1), the
peak meter value must be set to LONG_MAX/2.
A KS audio filter handles this property request synchronously. If the request succeeds, it resets the peakmeter,
which initializes the accumulated peak value to zero. If the request does not succeed, the peakmeter is not changed.
The system sends an IOCTL_KS_PROPERTY request for the KSPROPERTY_AUDIO_PEAKMETER property at IRQL
PASSIVE_LEVEL.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_PEAKMETER
KSPROPERTY_AUDIO_PEAKMETER
KSPROPERTY_AUDIO_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_POSITION property specifies the current positions of the play and write cursors in the
sound buffer for the pin's audio stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSPROPERTY KSAUDIO_POSI


TION

The property value (operation data) is a structure of type KSAUDIO_POSITION that specifies a render stream's play
and write positions or a capture stream's record and read positions.
Return Value
A KSPROPERTY_AUDIO_POSITION property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound uses the KSPROPERTY_AUDIO_POSITION property to implement the
IDirectSoundBuffer ::GetCurrentPosition and IDirectSoundBuffer ::SetCurrentPosition methods. The
Windows multimedia functions waveInGetPosition and waveOutGetPosition also use this property. For more
information about DirectSound and the Windows multimedia functions, see the Microsoft Windows SDK
documentation.
WaveCyclic and WavePci miniport drivers do not need to implement property handlers for
KSPROPERTY_AUDIO_POSITION because the WaveCyclic and WavePci port drivers handle this property on behalf
of miniport drivers. To obtain the play position in a render stream or record position in a capture stream, the
property handler in the port driver calls the miniport driver's IMinipor tWaveCyclicStream::GetPosition or
IMinipor tWavePciStream::GetPosition method.
For more information, see Audio Position Property.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAUDIO_POSITION
IMinipor tWaveCyclicStream::GetPosition
IMinipor tWavePciStream::GetPosition
KSPROPERTY_AUDIO_POSITIONEX
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_POSITIONEX property provides the caller with the stream position and the associated
timestamp information for a kernel streaming (KS)-based audio driver.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAUDIO_POSI


TIONEX

The property value (operation data) is a structure of type KSAUDIO_POSITIONEX that receives the position
information from the property handler. The position information that is specified by the KSAUDIO_POSITIONEX
structure is the position information for the pin that was selected by the caller.
Return Value
The KSPROPERTY_AUDIO_POSITIONEX property request returns S_OK if the call was successful. Otherwise, it
returns the appropriate HRESULT error code.

Remarks
Typically, audio applications must monitor the current position of an audio stream. This position is specified as a
byte offset from the beginning of the stream. There are two possible interpretations of the stream position
information:
In the case of a rendering stream, the stream position is the byte offset of the audio frame that is currently
playing through the digital-to-analog converters (DACs).
In the case of a capture stream, the stream position is the byte offset of the audio frame that is currently
being recorded through the analog-to-digital converters (ADCs).
A driver that supports the KSPROPERTY_AUDIO_POSITIONEX property generates a timestamp window for the
stream position value. The timestamp window is the interval between the timestamp that is sampled before
stream position is determined and the timestamp that is taken after the stream position is determined. The caller
then determines whether it can use the timestamp window.

Requirements
Version Available in Windows Vista and later versions of Windows.

Header Ksmedia.h (include Ksmedia.h)

See also
KSAUDIO_POSITIONEX
KSPROPERTY
KSPROPERTY_AUDIO_PREFERRED_STATUS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_PREFERRED_STATUS property informs a device that it is the system's preferred audio
device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY KSAUDIO_PREF


ERRED_STATUS

The property value (operation data) is a structure of type KSAUDIO_PREFERRED_STATUS that specifies the type of
preferred device and whether the device is selected or deselected as the preferred device for that device type.
Return Value
A KSPROPERTY_AUDIO_PREFERRED_STATUS property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The SysAudio system driver uses this property to inform a wave playback, wave record, MIDI, or mixer device
when it is selected to be the new preferred device, or when a previously selected preferred device is deselected.
For information about preferred devices, see SetupPreferredAudioDevices .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSAUDIO_PREFERRED_STATUS
SetupPreferredAudioDevices
KSPROPERTY_AUDIO_PRESENTATION_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_PRESENTATION_POSITION property request retrieves a structure that specifies the


current position within the audio data being rendered to the endpoint.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via Pin KSP_NODE KSAUDIO_PRES


instance ENTATION_POS
ITION

Return Value
The KSPROPERTY_AUDIO_PRESENTATION_POSITION property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Requirements
Version Windows 8

Header Ksmedia.h

See also
KSAUDIO_PRESENTATION_POSITION
KSPROPERTY_AUDIO_PRODUCT_GUID
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSPROPERTY_AUDIO_QUALITY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_QUALITY property specifies the quality level of a node's output stream. This is a
property of an SRC node (KSNODETYPE_SRC ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPERTY ULONG

The property value (operation data) is of type ULONG and indicates the output stream's quality level. This value
should be set to one of the following constants from header file Ksmedia.h:
KSAUDIO_QUALITY_WORST
Worst quality
KSAUDIO_QUALITY_PC
Standard computer quality (with no constraints)
KSAUDIO_QUALITY_BASIC
Basic (low-end) consumer audio quality (default value)
KSAUDIO_QUALITY_ADVANCED
Advanced (high-end) consumer audio quality
Return Value
A KSPROPERTY_AUDIO_QUALITY property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For information about the types of sample-rate conversion that the KMixer system driver performs, see KMixer
Driver Sample Rate Conversion and Mixing Policy.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_SRC
KSNODEPROPERTY
KSPROPERTY_AUDIO_REVERB_LEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_REVERB_LEVEL property specifies the current reverberation level. This is a property of a
reverb node (KSNODETYPE_REVERB ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and specifies the reverberation level. Reverb values follow a
linear range from 0 to 100*(65536-1/65536) percent:
The value 0x00010000 represents 100 percent.
The value 0xFFFFFFFF represents 100*(65536-1/65536) percent.
Return Value
A KSPROPERTY_AUDIO_REVERB_LEVEL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODETYPE_REVERB
KSNODEPROPERTY
KSPROPERTY_AUDIO_REVERB_TIME
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_REVERB_TIME property specifies the reverberation time. This is a property of a reverb
node (KSNODETYPE_REVERB ).
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERT ULONG


Y

The property value is of type ULONG, and it specifies the number of seconds for which the reverberation will
continue. It is expressed in seconds and the value can range from 0 through 255.9961 in 1/256th increments. To
accommodate this, the property value should be expressed as a fixed point 16.16 value, where the following is
true:
The value 0x00010000 represents 1 second
The value 0xFFFFFFFF represents (65536-1/65536) seconds
Return Value
A KSPROPERTY_AUDIO_REVERB_TIME property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows Vista

Header Ksmedia.h

See also
KSNODETYPE_REVERB
KSPROPERTY_AUDIO_SAMPLING_RATE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_SAMPLING_RATE property specifies the rate at which a node samples its input stream
in order to produce its output stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and specifies sampling rate. This rate is expressed as the
number of samples per second (the sampling frequency in Hz).
Return Value
A KSPROPERTY_AUDIO_SAMPLING_RATE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The miniport driver should return an error on a set-property request if the node does not support the specified
sampling rate.
This property is used to control the sampling rate for the following node types:
ADC node (KSNODETYPE_ADC )
DAC node (KSNODETYPE_DAC )
SRC node (KSNODETYPE_SRC )

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ADC
KSNODETYPE_DAC
KSNODETYPE_SRC
KSPROPERTY_AUDIO_STEREO_ENHANCE
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.


KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY property is used in combination with


KSPROPERTY_AUDIO_CHANNEL_CONFIG to implement the DirectSound speaker-configuration property for
hardware-accelerated 3D audio. This is an optional property of DAC nodes (KSNODETYPE_DAC ) and 3D nodes
(KSNODETYPE_3D_EFFECTS ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin/Filter KSNODEPROPE LONG


RTY

The property value (operation data) is of type LONG and specifies the speaker geometry. This value can be set to
one of the following constants, which are defined in header file Ksmedia.h:
KSAUDIO_STEREO_SPEAKER_GEOMETRY_HEADPHONES
KSAUDIO_STEREO_SPEAKER_GEOMETRY_MIN
KSAUDIO_STEREO_SPEAKER_GEOMETRY_NARROW
KSAUDIO_STEREO_SPEAKER_GEOMETRY_WIDE
KSAUDIO_STEREO_SPEAKER_GEOMETRY_MAX
The preceding parameters are equivalent in meaning (but not equal in value) to the following values, which are
used by the IDirectSound::GetSpeakerConfig method (see the Microsoft Windows SDK documentation) and
are defined in header file Dsound.h:
DSSPEAKER_HEADPHONE
DSSPEAKER_STEREO | DSSPEAKER_GEOMETRY_MIN
DSSPEAKER_STEREO | DSSPEAKER_GEOMETRY_NARROW
DSSPEAKER_STEREO | DSSPEAKER_GEOMETRY_WIDE
DSSPEAKER_STEREO | DSSPEAKER_GEOMETRY_MAX
Return Value
A KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound treats KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY as a filter property on a DAC node, and
as a pin property on a 3D node.
For additional information, see DirectSound Speaker-Configuration Settings.
Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY_AUDIO_CHANNEL_CONFIG
KSNODETYPE_DAC
KSNODETYPE_3D_EFFECTS
KSNODEPROPERTY
KSPROPERTY_AUDIO_SURROUND_ENCODE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_SURROUND_ENCODE property specifies whether the filter's surround encoder is


enabled or disabled. A surround-encoder node (KSNODETYPE_PROLOGIC_ENCODER ) performs Dolby
Surround Pro Logic encoding.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL and indicates whether the surround-encoder node is enabled
or not. A value of TRUE indicates that the surround-encoder node is enabled. FALSE indicates that it is disabled.
Return Value
A KSPROPERTY_AUDIO_SURROUND_ENCODE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
In Microsoft Windows XP and later, the KMixer system driver supports the
KSPROPERTY_AUDIO_SURROUND_ENCODE property.
If enabled, the surround-encoder node encodes the four-channel input stream (with channels for left, right, center,
and back speakers) to a surround-encoded stereo output stream. This output stream can be decoded by a
KSNODETYPE_PROLOGIC_DECODER node, for example. It can also be played through the audio device's
analog stereo outputs, which can be connected to an external surround decoder that directly drives left, right,
center, and back speakers.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_PROLOGIC_ENCODER
KSNODETYPE_PROLOGIC_DECODER
KSPROPERTY_AUDIO_TREBLE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_TREBLE property specifies the treble level for a channel in a tone node
(KSNODETYPE_TONE ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY LONG


_AUDIO_CHANNEL

The property value (operation data) is of type LONG and specifies the treble-level setting for the channel. Treble-
level values use the following scale:
-2147483648 is -Infinity decibels (attenuation),
-2147483647 is -32767.99998474 decibels (attenuation), and
+2147483647 is +32767.99998474 decibels (gain).
A decibel range represented by integer values -2147483648 to +2147483647, where
This scale has a resolution of 1/65536 decibel.
The filter will succeed a set-property request that specifies a value that is beyond the range of the filter but will
clamp the value to the supported range. In a subsequent request to get this property, however, it will return the
actual value used.
Return Value
A KSPROPERTY_AUDIO_TREBLE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
A tone node can support properties for controlling treble level, mid-frequency level, bass level, and bass boost. For
more information, see KSNODETYPE_TONE .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_TONE
KSPROPERTY_AUDIO_VOLUMELEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_VOLUMELEVEL property specifies the volume level of a channel in a volume node
(KSNODETYPE_VOLUME ).

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via Filter or KSNODEPROPE LONG


Pin instance RTY_AUDIO_C
HANNEL

The property value is of type LONG and specifies the volume level of a channel in a given stream. Volume-level
values use the following scale:
-2147483648 is -infinity decibels (attenuation),
-2147483647 is -32767.99998474 decibels (attenuation), and
+2147483647 is +32767.99998474 decibels (gain).
> [!Note] > The decibel range is represented by integer values from -2147483648 to +2147483647, where this
scale has a resolution of 1/65536 decibel.
If a value is specified beyond the range of the filter, the request to set this property will still be successful. But the
actual value that was applied to the filter can only be determined by a subsequent Get call to this property.
Return Value
A KSPROPERTY_AUDIO_VOLUMELEVEL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The property descriptor for this property specifies a channel number. If the stream that passes through the
volume node contains n channels, the channels are numbered 0 through n-1. For more information, see Exposing
Multichannel Nodes.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
Customizing Default Audio Volume Settings
Default Audio Volume Settings
KSNODEPROPERTY_AUDIO_CHANNEL
KSNODETYPE_VOLUME
KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED
12/5/2018 • 2 minutes to read • Edit Online

KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED, is a new KS property that has been added into the


KSPROPSETID_Audio property set in Windows 8.1.
The KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED property request passes an end user’s volume level limit
preference to the underlying driver. The scope of this property is per pin (or per audio endpoint, from an end-
user’s point of view).
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin instance KSP_PIN BOOL

The property value is of type BOOL, and it indicates whether an end-user allows the max volume to be over a
certain limit. A value of TRUE indicates that an end-user has allowed the volume level to be over the posted limit,
whereas FALSE indicates the opposite. In the case of a child account, the value will always be FALSE.
The driver stores the value of this property in an internal variable and initializes the value to TRUE during startup.
While this property is TRUE, the driver limits the maximum volume level. When the property is set to FALSE the
driver can remove these limits.
The driver can also change the value of this property automatically. For example, the driver can automatically
switch the property value from TRUE to FALSE, and then begin limiting the volume level after some amount of
time above certain sound levels has elapsed.
Whenever the value of the property changes, regardless of whether it is automatic or due to a caller setting the
property value, the driver should generate the KSEVENT_PINCAPS_VOLUMELIMITCHANGE event.
Return Value
The KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED property request returns STATUS_SUCCESS when the request
is successful.

Requirements
Version Windows 8.1

Header Ksmedia.h (include Ksmedia.h)


KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION property request specifies the current write position of the
WaveRT buffer in bytes. The offload driver can use this write position information to know how much valid data is in the
WaveRT buffer.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

No Yes Node via Pin KSP_NODE ULONG


instance

Return Value
The KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
To better understand how to interpret the information provided by this property request, assume a circular buffer of size n
bytes. The initial write position, before any data is written, is 0. Data is written to the buffer in chunks that are a multiple of
WAVEFORMATEX.nBlockAlign bytes.
For example, the buffer might contain 20 ms of 16-bit PCM stereo data, sampled at 48000 Hz. So based on the description for
the nBlockAlign member of the WAVEFORMATEX structure, in this example nBlockAlign = 2 * 16 / 8 = 4 bytes. This means
that the length of the buffer would be 48000 * 20 / 1000 = 960 frames, or 960 * 4 = 3840 bytes.
The first Set request will specify the number of bytes were written to the buffer. And since the “write position” is expressed in
bytes, a value of 1920 would specify half the buffer size, whereas a value of 3840 would indicate the full buffer size. To
determine the number of new bytes written, for making subsequent Set requests, the following pseudo code shows how the
calculation is performed:

if new write position > old write position:


bytes written = new write position – old write position
if new write position < old write position, we’ve wrapped:
bytes written = (new write position + buffer size) – old write position
if new write position = old write position, we’ve had a glitch
log a "duplicate write position" glitch event

Requirements
Version Windows 8

Header Ksmedia.h

See also
WAVEFORMATEX
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION property is used for indicating the last valid byte in the audio buffer.
Usage Summary Table
GET SET TA RGET P RO P ERT Y DESC RIP TO R T Y P E P RO P ERT Y VA L UE T Y P E

No Yes Node via Pin instance KSP_NODE ULONG

The property value is of type ULONG and represents the last valid byte in the WaveRT audio buffer.
Return Value
The KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
If a client app uses the KSPROPERTY_TYPE_BASICSUPPORT flag when it sends a
KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION property request to the audio driver and STATUS_SUCCESS is returned, it
confirms that the driver supports the newly added KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION property.
When a client app performs the very last write operation to the audio buffer to be processed by the audio driver of an offloaded stream, the audio
driver calls the SetStreamCurrentWritePositionForLastBuffer method. The SetStreamCurrentWritePositionForLastBuffer method indicates
the “write position” of the very last buffer in a stream. Note that this last buffer could be only partially filled.
If you develop an audio driver that was not designed to work with the audio port class driver (Portcls), then you have to implement your own property
handler for the this new KS property.

Requirements
Minimum supported client Windows 8.1

Minimum supported server Windows Server 2012 R2

Header Ksmedia.h

See also
SetStreamCurrentWritePositionForLastBuffer
KSPROPERTY_AUDIO_WIDE_MODE
12/5/2018 • 2 minutes to read • Edit Online

This parameter name is reserved for future use.

Usage Summary Table


KSPROPERTY_AUDIO_WIDENESS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIO_WIDENESS property specifies the wideness (apparent width) of the stereo image.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPERTY ULONG

The property value (operation data) is of type ULONG and specifies the wideness. Wideness is expressed as an
unsigned, fixed-point value with a 16-bit fraction. Wideness values follow a linear range from zero to 0xFFFFFFFF:
The value 0x00010000 represents unity (100 percent), which indicates that the width of the stereo image
should coincide with the region that is framed by the left and right speakers.
For a value greater than unity, the stereo image should appear to extend outside the region that is framed
by the left and right speakers.
For a value less than unity, the perceived width of the stereo image should be smaller than the space
between the left and right speakers.
A value of zero indicates that the sound should appear to originate from a position midway between the left
and right speakers.
The apparent width of the stereo image should increase linearly with linear increases in the wideness value.
Return Value
A KSPROPERTY_AUDIO_WIDENESS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This is a property of a wideness node (KSNODETYPE_STEREO_WIDE ). A wideness node can add spaciousness to
an existing stereo (two-channel) stream. To achieve this effect, the node processes the stream to make some
sounds appear to originate from positions outside the region that is framed by the left and right speakers.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_STEREO_WIDE
KSPROPERTY_AUDIOENGINE enumeration
12/5/2018 • 2 minutes to read • Edit Online

The properties contained in the KSPROPSETID_AudioEngine property set are defined by this enumeration and
must be supported by a KSNODETYPE_AUDIO_ENGINE node.

Syntax
typedef enum {
KSPROPERTY_AUDIOENGINE_LFXENABLE = 0,
KSPROPERTY_AUDIOENGINE_GFXENABLE = 1,
KSPROPERTY_AUDIOENGINE_MIXFORMAT = 2,
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT = 4,
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS = 5,
KSPROPERTY_AUDIOENGINE_DESCRIPTOR = 6,
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE = 7,
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION = 8,
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL = 9
} KSPROPERTY_AUDIOENGINE;

Constants
KSPROPERTY_AUDIOENGINE_LFXENABLE
Specifies the ID for the KSPROPERTY_AUDIOENGINE_LFXENABLE property.
KSPROPERTY_AUDIOENGINE_GFXENABLE
Specifies the ID for the KSPROPERTY_AUDIOENGINE_GFXENABLE property.
KSPROPERTY_AUDIOENGINE_MIXFORMAT
Specifies the ID for the KSPROPERTY_AUDIOENGINE_MIXFORMAT property.
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT
Specifies the ID for the KSPROPERTY_AUDIOENGINE_DEVICEFORMAT property.
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
Specifies the ID for the KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS property.
KSPROPERTY_AUDIOENGINE_DESCRIPTOR
Specifies the ID for the KSPROPERTY_AUDIOENGINE_DESCRIPTOR property.
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
Specifies the ID for the KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE property.
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION
Specifies the ID for the KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION property.
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL
Specifies the ID for the KSPROPERTY_AUDIOENGINE_VOLUMELEVEL property.

Requirements
Minimum supported client Windows 8
Minimum supported server Windows Server 2012

Header Ksmedia.h

See also
KSNODETYPE_AUDIO_ENGINE
KSPROPSETID_AudioEngine
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE property indicates the minimum and maximum size


of buffer that the hardware audio engine can support for a given data format, at the instance when it is called. The
buffer size is specified in bytes.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via filter KSP_NODE KSAUDIOENGI


NE_BUFFER_SIZ
E_RANGE

Return Value
A KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE property request returns STATUS_SUCCESS to
indicate that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
It is important to note that before a caller calls the KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE
property, the caller fills in the fields of a KSDATAFORMAT_WAVEFORMATEX structure. So when
KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE is called, the audio driver receives a KSP_NODE
followed by a filled-in KSDATAFORMAT_WAVEFORMATEX structure from the caller. The driver uses the data
format information in this structure to determine the min and max buffer sizes to accommodate the specified data
format. Upon a successful call to this property, the kernel streaming (KS) filter then fills in the MinBufferBytes
and MaxBufferBytes fields of the KSAUDIOENGINE_BUFFER_SIZE_RANGE structure.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSAUDIOENGINE_BUFFER_SIZE_RANGE
KSDATAFORMAT_WAVEFORMATEX
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_DESCRIPTOR
10/23/2019 • 2 minutes to read • Edit Online

The audio driver for the offload-capable hardware solution uses KSPROPERTY_AUDIOENGINE_DESCRIPTOR
to provide information about the node that represents the hardware audio engine.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via filter KSP_NODE KSAUDIOENGI


NE_DESCRIPTO
R

The property value is of type KSAUDIOENGINE_DESCRIPTOR and it indicates the static properties of the audio
engine node.
Return Value
The KSPROPERTY_AUDIOENGINE_DESCRIPTOR property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSAUDIOENGINE_DESCRIPTOR
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_DEVICEFORMAT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_DEVICEFORMAT property request retrieves or alters the state of the audio
engine node, regarding its device format setting.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via filter KSP_NODE KSDATAFORMA


T

Return Value
The KSPROPERTY_AUDIOENGINE_DEVICEFORMAT property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSDATAFORMAT
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_GFXENABLE
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_GFXENABLE property request allows the audio driver to retrieve or alter
the state of the audio engine node, regarding its global effect processing abilities.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via filter KSP_NODE BOOL

The property value is of type BOOL and indicates whether global effect processing in the audio engine node is
enabled. A value of TRUE indicates that processing is enabled. FALSE indicates that it is disabled.
Return Value
The KSPROPERTY_AUDIOENGINE_GFXENABLE property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_LFXENABLE
KSPROPERTY_AUDIOENGINE_LFXENABLE
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_LFXENABLE property request retrieves or alters the state of the audio
engine node, regarding its local effect processing abilities.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via Pin KSP_NODE BOOL


instance

The property value is of type BOOL and indicates whether local effect processing on the specified stream is
enabled. A value of TRUE indicates that processing is enabled. FALSE indicates that it is disabled.
Return Value
The KSPROPERTY_AUDIOENGINE_LFXENABLE property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_GFXENABLE
KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION property request allows the audio driver to set the
loopback protection status of the audio engine node.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Node via Pin KSP_NODE ULONG


instance

Return Value
The KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The input buffer that is associated with this property call is populated with an enumeration value of type
CONSTRICTOR_OPTION. So the input buffer is either set to CONSTRICTOR_OPTION_DISABLE or
CONSTRICTOR_OPTION_MUTE.
If there are any active streams with CONSTRICTOR_OPTION_MUTE in effect, then the KS loopback tap for this audio
output will emit silence. If all the active streams have CONSTRICTOR_OPTION_DISABLE in effect (which is the default
state), then and only then does the loopback tap contain meaningful data.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_MIXFORMAT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_MIXFORMAT property request retrieves the setting of the mixer in the
hardware audio engine.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Node via filter KSP_NODE KSDATAFORMA


T_WAVEFORMA
TEX

Return Value
The KSPROPERTY_AUDIOENGINE_MIXFORMAT property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The mix format that is set on the audio engine node at any point in time must also be supported by the offload pin
factory.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSDATAFORMAT_WAVEFORMATEX
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS property request retrieves the device formats that are
supported by the hardware audio engine.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes No Node via filter KSP_NODE A


KSMULTIPLE_ITE
M structure,
followed by a
sequence of
KSDATAFORMAT_
WAVEFORMATEX
structures

Return Value
The KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS property request returns STATUS_SUCCESS to
indicate that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Windows 8

Header Ksmedia.h

See also
KSDATAFORMAT_WAVEFORMATEX
KSMULTIPLE_ITEM
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL
KSPROPERTY_AUDIOENGINE_VOLUMELEVEL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOENGINE_VOLUMELEVEL property specifies the volume level of a channel in a given


stream.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Node via Pin KSNODEPROPE LONG (for a Get


instance RTY_AUDIO_C request) and
HANNEL KSAUDIOENGI
NE_VOLUMELE
VEL (for a Set
request).

For a Get request, the property value is of type LONG, and it specifies the volume level of a channel in a given a
stream. Volume-level values use the following scale and can be bounded by the minimum and maximum values
supplied in the Basic Support response for this property:
-2147483648 (0x80000000 in hexadecimal, or LONG_MIN) is -Infinity decibels (attenuation),
-2147483647 (0x80000001 in hexadecimal, or LONG_MIN + 1) is -32767.99998474 decibels (attenuation), and
+2147483647 (0x7FFFFFFF in hexadecimal, or LONG_MAX) is +32767.99998474 decibels (gain).
> [!Note] > The decibel range is represented by integer values from -2147483648 to +2147483647, where this
scale has a resolution of 1/65536 decibel.
For a Set request, the property value is of type KSAUDIOENGINE_VOLUMELEVEL , and it specifies the desired
volume level of a channel in a given stream, as well as a curve type and curve duration to be applied as the
volume level is set. If a value is specified beyond the range of the filter, the request to set this property will still be
successful. But the actual value that was applied to the filter can only be determined by a subsequent Get call to
this property.
Return Value
The KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS property request returns
STATUS_SUCCESS to indicate that it has completed successfully. Otherwise, the request returns an appropriate
error status code.

Remarks
The property descriptor for KSPROPERTY_AUDIOENGINE_VOLUMELEVEL specifies a channel number. If the
stream that passes through the audio engine node contains n channels, the channels are numbered 0 through n-1.
Also note that a channel value of 0xFFFFFFFF indicates that the request applies to all channels. If a property
request is made while the stream is not in a running state, the volume level is immediately set to the requested
level. If the stream leaves the run state while a volume level ramp is in progress, the volume level of the stream is
immediately set to the target level of the current fade. If a new property request is made while an existing volume
level ramp is in progress, the new ramp request must begin from the current volume level - the level that the
volume had reached when the new request arrived.
Requirements
Version Windows 8

Header Ksmedia.h

See also
KSAUDIOENGINE_VOLUMELEVEL
KSNODEPROPERTY_AUDIO_CHANNEL
KSPROPERTY_AUDIOENGINE
KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS
KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID property is used to inform a GFX filter of the Plug and
Play device ID of the audio device that is the source of the capture stream.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY WCHAR array

The property value (operation data) is a WCHAR array that contains the device ID. The device ID is a null-
terminated string of Unicode characters.
Return Value
A KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The target for this set-only property request is a GFX filter that is configured for use as either a capture- or
render/capture-GFX filter.
To determine the size of the buffer needed to hold the property value, see Basic Support Queries for Audio
Properties.
For additional information about device IDs, see Device Identification Strings.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID property is used to inform a GFX filter of the Plug and
Play device ID of the audio device that renders the final audio mix.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY WCHAR array

The property value (operation data) is a WCHAR array that contains the device ID. The device ID is a null-
terminated string of Unicode characters.
Return Value
A KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The target for this set-only property request is a GFX filter that is configured for use as either a render- or
render/capture-GFX filter.
To determine the size of the buffer needed to hold the property value, see Basic Support Queries for Audio
Properties.
For additional information about device IDs, see Device Identification Strings.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_AUDIOMODULE enumeration
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOMODULE enumeration defines constants that are used by audio drivers to communicate
information about partner defined audio modules.
For more information about audio modules, see Implementing Audio Module Discovery.

Syntax
typedef enum {
KSPROPERTY_AUDIOMODULE_DESCRIPTORS = 1,
KSPROPERTY_AUDIOMODULE_COMMAND = 2,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID = 3
} KSPROPERTY_AUDIOMODULE;

Constants
KSPROPERTY_AUDIOMODULE_DESCRIPTORS
Specifies the ID for the KSPROPERTY_AUDIOMODULE_DESCRIPTORS property.
KSPROPERTY_AUDIOMODULE_COMMAND
Specifies the ID for the KSPROPERTY_AUDIOMODULE_COMMAND property.
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID
Specifies the ID for the KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID property.

Remarks
All KS Property calls must be non-blocking because the hardware effects are part of the processing chain and
should not wait.

Requirements
Minimum supported client Windows 10, version 1703

Minimum supported server None supported

Header Ksmedia.h

See also
KSPROPSETID_AudioModule
KSPROPERTY_AUDIOSIGNALPROCESSING
enumeration
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOSIGNALPROCESSING enumeration defines a constant that is used by audio drivers in


connection with audio processing modes on pins.

Syntax
typedef enum _KSPROPERTY_AUDIOSIGNALPROCESSING {
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
} KSPROPERTY_AUDIOSIGNALPROCESSING;

Constants
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
Specifies the ID for the KSPROPERTY_AUDIOSIGNALPROCESSING_MODES property.

Requirements
Minimum supported client Windows 8.1

Minimum supported server Windows Server 2012 R2

Header Ksmedia.h

See also
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
KSPROPSETID_AudioSignalProcessing
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_AUDIOSIGNALPROCESSING_MODES property returns the list of audio signal processing


modes supported by a pin factory.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin factory (via KSP_PIN KSMULTIPLE_ITE


Filter instance) M

The property value is a structure, followed by zero (0) or more GUIDs.


Return Value
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES returns a KSMULTIPLE_ITEM followed by zero (0) or
more GUIDS. The KSMULTIPLE_ITEM.Count member contains the number of GUIDs. The KSMULTIPLE_ITEM.Size
member contains the total size of the property value. Each GUID identifies a signal processing mode supported by
the audio driver for the Pin ID specified in the PinId member of the KSP_PIN structure.
In Windows 8.1 there were two defined audio signal processing modes,
AUDIO_SIGNALPROCESSINGMODE_DEFAULT and AUDIO_SIGNALPROCESSINGMODE_RAW.
In Windows 10, five additional mode are defined.
AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS AUDIO_SIGNALPROCESSINGMODE_SPEECH
AUDIO_SIGNALPROCESSINGMODE_MEDIA AUDIO_SIGNALPROCESSINGMODE_MOVIE
AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION For more information, see Audio Signal Processing Modes.

Remarks
The basic support handler for KSPROPERTY_AUDIOSIGNALPROCESSING_MODES should be handed a
KSP_PIN structure, and should advertise support only on non-loopback streaming pins. Audio drivers should
support signal processing modes only on host and offload pins. For loopback or bridge pins the audio driver
should still support the property, but return a KSMULTIPLE_ITEM structure with its Count parameter set to zero
(0).
Any audio miniport driver that is developed to work with the Microsoft audio port Class driver (Portcls) can
implement the IMinipor tAudioSignalProcessing::GetModes method.

Requirements
Version Windows 8.1

Header Ksmedia.h

See also
IMinipor tAudioSignalProcessing::GetModes
KSMULTIPLE_ITEM
KSP_PIN
KSPROPERTY_DIRECTSOUND3DBUFFER_ALL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_ALL property is used to get or set all the DirectSound 3D-buffer
properties for the specified buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPERTY KSDS3D_BUFFE


R_ALL

The property value (operation data) is a structure of type KSDS3D_BUFFER_ALL that specifies the 3D
characteristics of the buffer.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_ALL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The KSDS3D_BUFFER_ALL structure is similar to the DS3DBUFFER structure, which is described in the Microsoft
Windows SDK documentation.
DirectSound uses this property to implement the IDirectSound3DBuffer ::GetAllParameters and
IDirectSound3DBuffer ::SetAllParameters methods, which are described in the Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_BUFFER_ALL
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES property specifies the inside and outside cone angles of
the sound projection cone for a 3D sound buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPERTY KSDS3D_BUFFE


R_CONE_ANGLE
S

The property value (operation data) is a structure of type KSDS3D_BUFFER_CONE_ANGLES that specifies the inside
and outside cone angles.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For more information about the inside and outside cone angles of the sound projection cone for a DirectSound 3D
buffer, see the following in the Microsoft Windows SDK documentation:
The dwInsideConeAngle and dwOutsideConeAngle members of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetConeAngles and IDirectSound3DBuffer ::SetConeAngles methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_BUFFER_CONE_ANGLES
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION property specifies the orientation of the sound-projection


cone for a 3D sound buffer.

Usage Summary Table


P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPERTY DS3DVECTOR

The property value (operation data) is a structure of type DS3DVECTOR that specifies the orientation of the sound-projection
cone.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For more information about the orientation of the sound projection cone for a DirectSound 3D buffer, see the following in the
Microsoft Windows SDK documentation:
The vConeOrientation member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetConeOrientation and IDirectSound3DBuffer ::SetConeOrientation methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
DS3DVECTOR
KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME property specifies the cone-outside sound volume for a 3D


sound buffer.

Usage Summary Table


P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPERTY LONG

The property value (operation data) is of type LONG and specifies the cone-outside volume level. The volume level is expressed in units
of 1/100ths of a decibel.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For more information about the cone-outside sound volume for a DirectSound 3D buffer, see the following in the Microsoft Windows
SDK documentation:
The lConeOutsideVolume member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetOutsideVolume and IDirectSound3DBuffer ::SetOutsideVolume methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE property specifies the maximum distance for a 3D sound


buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPERTY FLOAT

The property value (operation data) is of type FLOAT and specifies the maximum distance. For information about
distance units, see KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR .
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
At a distance that exceeds the maximum distance from a sound source, the sound from that source is reduced to
silence. For more information about the maximum distance for a DirectSound 3D buffer, see the following in the
Microsoft Windows SDK documentation:
The flMaxDistance member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetMaxDistance and IDirectSound3DBuffer ::SetMaxDistance methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE property specifies the minimum distance for a 3D sound


buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE FLOAT


RTY

The property value (operation data) is of type FLOAT and specifies the minimum distance. For information about
distance units, see KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR .
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
At a distance less than the minimum distance from a sound source, the sound volume no longer increases as the
distance decreases. For more information about the minimum distance for a DirectSound 3D buffer, see the following
in the Microsoft Windows SDK documentation:
The flMinDistance member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetMinDistance and IDirectSound3DBuffer ::SetMinDistance methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DBUFFER_MODE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_MODE property specifies the processing mode of a 3D sound buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE ULONG


RTY

The property value (operation data) is of type ULONG and specifies the sound buffer's processing mode. The mode
can have one of the following values, which are defined in header file Dsound.h:
DS3DMODE_NORMAL
DS3DMODE_HEADRELATIVE
DS3DMODE_DISABLE
The meaning of these parameters is explained in the Microsoft Windows SDK documentation.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_MODE property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For additional information about the processing mode for a DirectSound 3D buffer, see the following in the
Windows SDK documentation:
The dwMode member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetMode and IDirectSound3DBuffer ::SetMode methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION property specifies the position of a 3D sound buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE DS3DVECTOR


RTY

The property value (operation data) is a structure of type DS3DVECTOR that specifies the buffer position. For
information about position units, see KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR .
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For more information about the position of a DirectSound 3D buffer, see the following in the Microsoft Windows
SDK documentation:
The vPosition member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetPosition and IDirectSound3DBuffer ::SetPosition methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
DS3DVECTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY property specifies the velocity of a 3D sound buffer.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE DS3DVECTOR


RTY

The property value (operation data) is a structure of type DS3DVECTOR that specifies the buffer velocity. Velocity is
expressed in units of one meter per second by default, but the units can be changed through the
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR property.
Return Value
A KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
For more information about the velocity of a DirectSound 3D buffer, see the following in the Microsoft Windows
SDK documentation:
The vVelocity member of the DS3DBUFFER structure.
The IDirectSound3DBuffer ::GetVelocity and IDirectSound3DBuffer ::GetVelocity methods.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
DS3DVECTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_ALL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_ALL property is used to set or get all the DirectSound 3D-listener
properties for the specified listener ID.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE KSDS3D_LISTE


RTY NER_ALL

The property value (operation data) is a structure of type KSDS3D_LISTENER_ALL that specifies all the properties
of a 3D listener. This structure is similar to the DS3DBUFFER structure, which is described in the Microsoft
Windows SDK documentation.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_ALL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound uses this property to implement the IDirectSound3DBuffer ::GetAllParameters and
IDirectSound3DBuffer ::SetAllParameters methods, which are described in the Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_LISTENER_ALL
KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION property is used to tell the driver when to allocate and
free the storage for its listener data. Storage is allocated when the listener is created, and freed when the listener is
deleted. This property can also be used to query the driver whether listener data is currently allocated.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPER BOOL


TY

The property value (operation data) is of type BOOL. For a set-property request, this value specifies whether the driver
should allocate or free the storage for its listener data:
A value of TRUE directs the driver to allocate storage for its listener data.
A value of FALSE tells the driver to free the listener data.
For a get-property request, a value of TRUE or FALSE indicates whether the driver currently holds a storage allocation
for listener data.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH property specifies the batch-mode setting for a 3D listener.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL and specifies the batch-mode setting:
When the value of this property is TRUE , the miniport driver should cache all changes to the listener
properties and all associated buffer properties.
When the value is FALSE , changes to the listener properties and buffer properties take effect immediately.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
When this property transitions from TRUE to FALSE the miniport driver should put all cached properties into
effect immediately. If possible, any cached properties should be put into effect simultaneously.
For more information about batch-mode settings for 3D listeners, see the description of the
IDirectSound3DListener ::CommitDeferredSettings method in the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR property specifies the distance factor that should be applied
to any distance values.

Usage Summary Table


P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPERT FLOAT


Y

The property value (operation data) is of type FLOAT and specifies the distance factor.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Distances for KSPROPSETID_DirectSound3DBuffer and KSPROPSETID_DirectSound3DListener properties are expressed in units
of meters times a distance factor.
By default, the distance factor is 1 and distances are therefore expressed in meters. (Also, the default velocity units are meters
per second.)
A client can change the distance units for the KSPROPSETID_DirectSound3DBuffer and
KSPROPSETID_DirectSound3DListener properties by sending a
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR set-property request that specifies a different distance factor.
DirectSound uses this property to implement the IDirectSound3DListener ::GetDistanceFactor and
IDirectSound3DListener ::SetDistanceFactor methods, which are described in the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR property specifies the Doppler factor for a 3D listener.

Usage Summary Table


P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPERT FLOAT


Y

The property value (operation data) is of type FLOAT and specifies the Doppler factor. The Doppler factor can range from
DS3D_MINDOPPLERFACTOR to DS3D_MAXDOPPLERFACTOR, which are defined as 0.0 and 10.0 respectively. The default factor
is DS3D_DEFAULTDOPPLERFACTOR, which is defined as 1.0.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property specifies the Doppler factor that is applied to both the 3D listener and 3D sound buffer.
A Doppler factor of zero means that no Doppler shift is applied to a sound regardless of the velocity of the listener or sound
buffer. Factors larger than 1 exaggerate the amount of Doppler shift that would occur in the real world.
DirectSound uses this property to implement the IDirectSound3DListener ::GetDopplerFactor and
IDirectSound3DListener ::SetDopplerFactor methods, which are described in the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION property specifies the orientation of a 3D listener.

Usage Summary Table


P RO P ERT Y
GET SET TA RGET DESC RIP TO R T Y P E P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPER KSDS3D_LISTEN


TY ER_ORIENTATIO
N

The property value (operation data) is a structure of type KSDS3D_LISTENER_ORIENTATION that specifies the listener's
orientation.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound uses this property to implement the IDirectSound3DListener ::GetOrientation and
IDirectSound3DListener ::SetOrientation methods, which are described in the Microsoft Windows SDK
documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_LISTENER_ORIENTATION
KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION property specifies the position of a 3D listener.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE DS3DVECTOR


RTY

The property value (operation data) is a structure of type DS3DVECTOR that specifies the listener's position.
Position coordinates are expressed in the current distance units. For information about distance units, see
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR .
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound uses this property to implement the IDirectSound3DListener ::GetPosition and
IDirectSound3DListener ::SetPosition methods, which are described in the Microsoft Windows SDK
documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
DS3DVECTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR
KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR property specifies the rolloff factor for a 3D listener.

Usage Summary Table


P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSNODEPROPERT FLOAT


Y

The property value (operation data) is of type FLOAT and specifies the rolloff factor. The rolloff factor can range from
DS3D_MINROLLOFFFACTOR to DS3D_MAXROLLOFFFACTOR, which are defined as 0.0 and 10.0 respectively. The default rolloff
factor is DS3D_DEFAULTROLLOFFFACTOR, which is defined as 1.0.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Rolloff is the amount of attenuation that is applied to sounds, based on the listener's distance from the sound source. A rolloff
factor of zero means that no attenuation is applied to a sound regardless of its distance from the listener. Factors larger than 1
exaggerate the real-world attenuation of sound with distance.
DirectSound uses this property to implement the IDirectSound3DListener ::GetRolloffFactor and
IDirectSound3DListener ::SetRolloffFactor methods, which are described in the Microsoft Windows SDK documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY property specifies the velocity vector of a 3D listener.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin KSNODEPROPE DS3DVECTOR


RTY

The property value (operation data) is a structure of type DS3DVECTOR that specifies the velocity vector. Velocity is
expressed in distance units per second. The default distance unit is a meter. The distance unit can be changed by
sending a KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR set-property request.
Return Value
A KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound uses this property to implement the IDirectSound3DListener ::GetVelocity and
IDirectSound3DListener ::SetVelocity methods, which are described in the Microsoft Windows SDK
documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
DS3DVECTOR
KSPROPERTY_FMRX_ANTENNAENDPOINTID
10/23/2019 • 2 minutes to read • Edit Online

The KSTOPOLOGY_ENDPOINTID property contains information about the endpoint to be used as FM antenna.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY KSTOPOLOGY_


ENDPOINTID

The property value is of type KSTOPOLOGY_ENDPOINTID and specifies the name and the pin ID of the topology
endpoint associated with FM radio receive antenna.

Return Value
A KSPROPERTY_FMRX_ANTENNAENDPOINTID property request returns the name and the pin id of the endpoint
to be used as FM radio antenna.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_FMRX_ENDPOINTID
10/23/2019 • 2 minutes to read • Edit Online

The KSTOPOLOGY_ENDPOINTID property contains the endpoint ID for the FM radio output/render endpoint.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY KSTOPOLOGY_


ENDPOINTID

The property value is of type KSTOPOLOGY_ENDPOINTID and specifies the name and the pin ID of the
topology endpoint associated with FM radio.
Return Value
A KSPROPERTY_FMRX_ENDPOINTID property request returns the name and the pin ID of the current render
endpoint for the FM radio.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Client Windows 10 Mobile

Header Ksmedia.h

See also
KSPROPSETID_FMRXTopology
KSPROPERTY_FMRX_VOLUME
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_FMRX_VOLUME property controls the volume of the FM radio.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY LONG

The property value is of type LONG and specifies the FM radio volume.
Return Value
A KSPROPERTY_FMRX_VOLUME property request returns the volume of the FM radio.

Remarks
The FM volume and routing (endpoint selection) is controlled by the KSPROPERTY_FMRX_VOLUME and
KSPROPERTY_FMRX_ENDPOINTID properties on the topology filter. Basic support for the
KSPROPERTY_FMRX_VOLUME property should return the minimum volume, maximum volume, and the
volume ranges.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_HRTF3D_FILTER_FORMAT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_HRTF3D_FILTER_FORMAT property retrieves the filter format used by the HRTF algorithm.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSNODEPROPE KSDS3D_HRTF_


RTY FILTER_FORMA
T_MSG

The property value (operation data) is a structure of type KSDS3D_HRTF_FILTER_FORMAT_MSG that specifies the
HRTF algorithm's filter method and coefficient format.
Return Value
A KSPROPERTY_HRTF3D_FILTER_FORMAT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_HRTF_FILTER_FORMAT_MSG
KSPROPERTY_HRTF3D_INITIALIZE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_HRTF3D_INITIALIZE property specifies the parameter values to use to initialize the HRTF
algorithm.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSNODEPROPE KSDS3D_HRTF_


RTY INIT_MSG

The property value (operation data) is a structure of type KSDS3D_HRTF_INIT_MSG that specifies the initialization
values.
Return Value
A KSPROPERTY_HRTF3D_INITIALIZE property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_HRTF_INIT_MSG
KSPROPERTY_HRTF3D_PARAMS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_HRTF3D_PARAMS property applies a set of 3-D parameter values to the HRTF algorithm.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSNODEPROPE KSDS3D_HRTF_


RTY PARAMS_MSG

The property value (operation data) is a structure of type KSDS3D_HRTF_PARAMS_MSG that specifies the
parameter values.
Return Value
A KSPROPERTY_HRTF3D_PARAMS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_HRTF_PARAMS_MSG
KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION property provides additional information about the


interleaving of loopback audio and capture audio.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes No Pin KS_PIN INTERLEAVED_AUDIO_F


ORMAT_INFORMATION

Return Value
For the get, KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION returns an
INTERLEAVED_AUDIO_FORMAT_INFORMATION structure which contains additional information about the interleaving of
loopback audio and capture audio in the audio stream.
Starting in Windows 10 19H1, setting the KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION property key is a
requirement for systems that support the Hardware Keyword Spotter (HW KWS) that combine microphone and loopback
audio into a single stream, in order to use an AEC APO on the keyword burst output. For more information, see Voice
Activation.

Remarks
This property is intended only for the Hardware Keyword Spotter pin and provides a way to include loopback audio
interleaved with the microphone audio. This is done by interleaving the Hardware Keyword Spotter pin audio and loopback
audio together into a single PCM audio stream and then communicating, via this property, the channels containing loopback
vs. microphone audio.
A sample APO is available that makes use of this property. It is on GitHub as part of the sysvad sample driver and is called
KWSApo. The sample APO simply strips out the loopback audio, providing only the primary microphone audio upstream.

Requirements

Minimum supported client Windows 10 Version 19H1

Header Ksmedia.h

See also
KSPROPSETID_INTERLEAVEDAUDIO
KS_PIN
INTERLEAVED_AUDIO_FORMAT_INFORMATION
KSPROPERTY_ITD3D_PARAMS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_ITD3D_PARAMS property is used to set the parameters used by a 3D node's ITD algorithm.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSNODEPROPE KSDS3D_ITD_P


RTY ARAMS_MSG

The property value (operation data) is a structure of type KSDS3D_ITD_PARAMS_MSG that specifies the
parameters for the ITD algorithm.
Return Value
A KSPROPERTY_ITD3D_PARAMS property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSDS3D_ITD_PARAMS_MSG
KSPROPERTY_JACK enumeration
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_JACK enumeration defines new property IDs that are used by audio jack structures.

Syntax
typedef enum {
KSPROPERTY_JACK_DESCRIPTION = 1,
KSPROPERTY_JACK_DESCRIPTION2 = 2,
KSPROPERTY_JACK_SINK_INFO = 3,
KSPROPERTY_JACK_CONTAINERID
} KSPROPERTY_JACK;

Constants
KSPROPERTY_JACK_DESCRIPTION
Specifies the ID for the KSPROPERTY_JACK_DESCRIPTION property.
KSPROPERTY_JACK_DESCRIPTION2
Specifies the ID for the KSPROPERTY_JACK_DESCRIPTION2 property.
KSPROPERTY_JACK_SINK_INFO
Specifies the ID for the KSPROPERTY_JACK_SINK_INFO property.
KSPROPERTY_JACK_CONTAINERID
Specifies the ID for the KSPROPERTY_JACK_CONTAINERID property.

Remarks
None

Requirements
Version Available in Windows 7 and later Windows operating
systems.

Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY_JACK_DESCRIPTION
KSPROPERTY_JACK_CONTAINERID
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_JACK_CONTAINERID property is implemented as a pin-wise property that is accessed by using


the filter handle.
This property can be supported on any bridge pin that is associated with one or more physical jacks, or other
wired or wireless connection.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin factory (via KSP_PIN GUID


filter handle)

The property value (instance data) is a GUID.


Return Value
KSPROPERTY_JACK_CONTAINERID property request returns a GUID that has the container ID of the device that is
associated with the physical jack, or other wired or wireless connection.

Remarks
The audio driver should support this property if and only if the following are true:
The container ID of the associated audio device is different from the container ID of the device node for
which the audio driver is loaded.
The driver can obtain the correct container ID through other means.
The KSPROPERTY_JACK_CONTAINERID property only needs to be populated if the audio endpoint is in a different
piece of plastic from the audio adapter. By default the audio endpoint will inherit the container ID of its parent.

Requirements
Minimum supported client Windows 8

Minimum supported server Windows Server 2012

Header Ksmedia.h

See also
BTHHFP_DESCRIPTOR
IOCTL_BTHHFP_DEVICE_GET_CONTAINERID
KSPROPERTY_JACK_DESCRIPTION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_JACK_DESCRIPTION property is implemented as a multi-item, pin-wise property that is


accessed through the filter handle.
In Windows Vista and later, this property can be supported on any bridge pin that is associated with one or more
physical jacks. It is used to get a description of the physical characteristics and usage of a particular jack.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin factory (via KSP_PIN KSMULTIPLE_IT


Filter handle) EM followed by
an array of
KSJACK_DESCR
IPTION
structures

The property value (instance data) is a KSMULTIPLE_ITEM, followed by an array of KSJACK_DESCRIPTION


structures.
Return Value
A KSPROPERTY_JACK_DESCRIPTION property request returns a KSMULTIPLE_ITEM followed by an array of N
KSJACK_DESCRIPTION structures, where N = the number of jacks associated with the specified bridge pin. The
members returned by the property request would thus be:
KSMULTIPLE_ITEM.Size = sizeof(KSMULTIPLE_ITEM) + N * sizeof(KSJACK_DESCRIPTION)
KSMULTIPLE_ITEM.Count = N
KSJACK_DESCRIPTION[0]
...
KSJACK_DESCRIPTION[N-1]

Remarks
Each KSJACK_DESCRIPTION structure must have information about one jack. For example, an output bridge pin
that supports 5.1 audio over three stereo jacks, would require a data buffer of size
sizeof(KSMULTIPLE_ITEM) + 3 * sizeof(KSJACK_DESCRIPTION)
and each KSJACK_DESCRIPTION structure would have a two-bit ChannelMapping value.

Requirements
Minimum supported client Windows Vista
Minimum supported server Windows Server 2003

Header Ksmedia.h

See also
KSJACK_DESCRIPTION
KSMULTIPLE_ITEM
KSPROPERTY
KSPROPERTY_JACK_DESCRIPTION2
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_JACK_DESCRIPTION2 property is implemented as a pin-wise property that is accessed by using


the filter handle.
In Windows 7 and later Windows operating systems, this property can be supported on any bridge pin that is
associated with one or more physical jacks. KSPROPERTY_JACK_DESCRIPTION2 is used to get the state and the
jack-related capabilities of the device.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin factory (via KSP_PIN KSMULTIPLE_IT


filter handle) EM followed by
an array of
KSJACK_DESCRI
PTION2
structures

The property value (instance data) is a KSMULTIPLE_ITEM, followed by an array of KSJACK_DESCRIPTION2


structures.
Return Value
A KSPROPERTY_JACK_DESCRIPTION2 property request returns a KSMULTIPLE_ITEM followed by an array of N
KSJACK_DESCRIPTION2 structures, where N = the number of jacks that are associated with the specified bridge
pin. The following list shows the items that are returned by the property request.
KSMULTIPLE_ITEM.Size = sizeof(KSMULTIPLE_ITEM) + N * sizeof(KSJACK_DESCRIPTION2)
KSMULTIPLE_ITEM.Count = N
KSJACK_DESCRIPTION2[0]
...
KSJACK_DESCRIPTION2[N-1]

Remarks
Each KSJACK_DESCRIPTION2 structure must only contain information about one jack.

Requirements
Minimum supported client Windows 7

Minimum supported server Windows Server 2008


Header Ksmedia.h

See also
KSJACK_DESCRIPTION2
KSMULTIPLE_ITEM
KSPROPERTY_JACK_SINK_INFO
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_JACK_SINK_INFO property is implemented as a pin-wise property that is accessed by using the
filter handle.
In Windows 7 and later operating systems, this property can be supported on any bridge pin that is associated
with one or more physical jacks. KSPROPERTY_JACK_SINK_INFO is used to get the description and capabilities of a
jack sink for a display-related digital audio device, such as an HDMI device or a display port.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin factory (via KSP_PIN KSJACK_SINK_I


filter handle) NFORMATION

The property value (instance data) is a KSJACK_SINK_INFORMAITON structure.


Return Value
A KSPROPERTY_JACK_SINK_INFO property request returns information in a KSJACK_SINK_INFORMATION
structure.

Requirements
Minimum supported client Windows 7

Minimum supported server Windows Server 2008

Header Ksmedia.h

See also
KSJACK_SINK_INFORMATION
KSPROPERTY_ONESHOT_DISCONNECT
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_ONESHOT_DISCONNECT property is used to prompt the audio driver to disconnect from
the Bluetooth audio device.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY NULL

No property value is sent with this property request.


Return Value
The KSPROPERTY_ONESHOT_DISCONNECT property returns STATUS_SUCCESS if the request is successful.
> [!Note] > A successful request means that the driver made an attempt to disconnect from the Bluetooth audio
device, but does not necessarily mean that the attempt was successful.

Remarks
You can implement the KSPROPERTY_JACK_DESCRIPTION pin property in your driver. This implementation
allows you to check the connection status of the endpoint after you make a
KSPROPERTY_ONESHOT_DISCONNECT property request.

Requirements
Version Available in Windows 7 and later versions of Windows.

Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_JACK_DESCRIPTION
KSPROPERTY_ONESHOT_RECONNECT
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_ONESHOT_RECONNECT property is used to prompt the audio driver to attempt to connect
to the Bluetooth audio device.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY NULL

No property value is sent with this property request.


Return Value
The KSPROPERTY_ONESHOT_RECONNECT property returns STATUS_SUCCESS if the request is successful.
> [!Note] > A successful request means that the driver made an attempt to connect to the Bluetooth audio device,
but does not necessarily mean that the attempt was successful.

Remarks
You can implement the KSPROPERTY_JACK_DESCRIPTION pin property in your driver. This implementation
allows you to check the connection status of the endpoint after you make a
KSPROPERTY_ONESHOT_RECONNECT property request.

Requirements
Version Available in Windows 7 and later versions of Windows.

Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_JACK_DESCRIPTION
KSPROPERTY_RTAUDIO_BUFFER
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_BUFFER property specifies a driver-allocated cyclic buffer for audio data.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSRTAUDIO_BU KSRTAUDIO_BU


FFER_PROPERT FFER
Y

The property descriptor (instance data) consists of a KSRTAUDIO_BUFFER_PROPERTY structure that contains a
KSPROPERTY structure along with other members. The client writes its requested buffer size into the structure. If
the client does not have to work with a specific base address, it must specify the base address as NULL .
The property value (operation data) is a structure of type KSRTAUDIO_BUFFER. The driver fills this structure with
the actual buffer size, base address, and memory barrier flag for the cyclic buffer that it has allocated.
Return Value
A KSPROPERTY_RTAUDIO_BUFFER property request returns STATUS_SUCCESS to indicate that it has completed
successfully. Otherwise, the request returns an appropriate failure status code. The following table shows some of
the possible failure status codes.

STAT US C O DE M EA N IN G

STATUS_UNSUCCESSFUL A cyclic buffer with the specified combination of buffer


attributes cannot be allocated.

STATUS_INSUFFICIENT_RESOURCES Memory for the buffer cannot be allocated.

STATUS_DEVICE_NOT_READY The device is not ready

Remarks
The base address is the virtual memory address at the start of the cyclic buffer. The client can directly access the
buffer at this address. The buffer is contiguous in virtual memory. The decision whether to make the buffer
contiguous in physical memory is left up to the driver.
The client should set the base address in the property descriptor to NULL . The driver sets the base address in the
property value to the virtual address of the allocated audio buffer.
Typically, audio hardware requires the audio buffer either to begin and end on sample boundaries or meet other
types of hardware-dependent alignment constraints. If sufficient memory is available, the actual size of the buffer
is the requested size rounded (up or down) to the nearest sample or other hardware-constrained boundary. The
actual size must be at least the requested size; otherwise, the Audio Session API (WASAPI) audio engine won't use
the buffer, and stream creation will fail.
If a KSPROPERTY_RTAUDIO_BUFFER property request is successful, the property value, which is a structure of type
KSRTAUDIO_BUFFER, contains the address and size of the driver-allocated buffer.
Closing the pin automatically frees the buffer that was allocated through this property.
If you want event notifications, you must call KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION instead
of KSPROPERTY_RTAUDIO_BUFFER.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSRTAUDIO_BUFFER
KSRTAUDIO_BUFFER_PROPERTY
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION property specifies a driver-allocated cyclic buffer for


audio data and identifies event notification requirements.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSRTAUDIO_BU KSRTAUDIO_BU


FFER_PROPERT FFER
Y_WITH_NOTIFI
CATION

The property descriptor (instance data) consists of a KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION


structure that contains a KSPROPERTY structure along with other members. The client writes its requested buffer
size into the structure. The client must specify the base address as NULL unless a specific base address is needed.
This property is used when you want DMA-driven event notification. Based on the NotificationCount member,
registered events are signaled once (at the end) or twice (at the mid-point and the end) per cycle through the cyclic
buffer. Events are registered using KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT after
successfully calling KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION.
The property value (operation data) is a structure of type KSRTAUDIO_BUFFER . The driver fills this structure with
the actual buffer size, base address, and memory barrier flag for the cyclic buffer that it has allocated.
Return Value
A KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate failure status code. The following
table shows some of the possible failure status codes.

STAT US C O DE M EA N IN G

STATUS_UNSUCCESSFUL A cyclic buffer with the specified combination of buffer


attributes cannot be allocated.

STATUS_INSUFFICIENT_RESOURCES Memory for the buffer cannot be allocated.

STATUS_DEVICE_NOT_READY The device is not ready.

Remarks
The base address is the virtual memory address at the start of the cyclic buffer. The client can directly access the
buffer at this address. The buffer is contiguous in virtual memory. The driver determines whether the buffer is
contiguous in physical memory.
The client sets the base address in the property descriptor to NULL . The driver sets the base address in the
property value to the virtual address of the allocated audio buffer.
Typically, audio hardware requires that either the audio buffer begins and ends on sample boundaries or it meets
other types of hardware-dependent alignment constraints. If sufficient memory is available, the actual size of the
buffer is the requested size rounded (up or down) to the nearest sample or other hardware-constrained boundary.
Otherwise, the actual size can be less than the requested size.
If a KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION property request succeeds, the property value, which is
a structure of type KSRTAUDIO_BUFFER, contains the address and size of the driver-allocated buffer.
Closing the pin automatically frees the buffer that was allocated through this property.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPERTY
KSRTAUDIO_BUFFER
KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT
KSPROPERTY_RTAUDIO_CLOCKREGISTER
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_CLOCKREGISTER property maps the wall clock register of the audio device into a
virtual memory location that the client can access.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSRTAUDIO_H KSRTAUDIO_H


WREGISTER_PR WREGISTER
OPERTY

The property descriptor (instance data) consists of a KSRTAUDIO_HWREGISTER_PROPERTY structure that contains
a KSPROPERTY structure. Before sending the request, the client loads the KSRTAUDIO_HWREGISTER_PROPERTY
structure with values that indicate the preferred base address for the clock register.
The property value (operation data) is a pointer to a KSRTAUDIO_HWREGISTER structure into which the property
handler writes the register address and the register-update frequency. This register address is the user-mode or
kernel-mode virtual address into which the hardware register is mapped. The client can directly read the register
from this address.
Return Value
A KSPROPERTY_RTAUDIO_CLOCKREGISTER property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an error code that indicates a failure.

Remarks
Some audio devices contain clock registers. A clock register is a wall clock counter that starts running when the
hardware powers up and stops when the hardware powers down. Software uses clock registers to synchronize
between two or more controller devices by measuring the relative drift between the hardware clocks of the device.
If successful, the property request maps the clock register to a virtual memory address that is accessible from
either user-mode or kernel-mode, as specified by the client. Thereafter, the client reads from this address to obtain
the current value of the clock register.
The property request fails if the audio hardware does not support a clock register that can be mapped to virtual
memory.
The mapping of the clock register is destroyed when the pin closes. The client can map the register only once in the
lifetime of a pin instance, and any subsequent call to map the clock register again for that instance fails.
It is typically faster to read a clock register than it is to send a KSPROPERTY_CLOCK_TIME request, which
requires transitions between user-mode and kernel-mode for user-mode clients.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSRTAUDIO_HWREGISTER_PROPERTY
KSRTAUDIO_HWREGISTER
KSPROPERTY_RTAUDIO_GETREADPACKET
10/23/2019 • 2 minutes to read • Edit Online

KSPROPERTY_RTAUDIO_GETREADPACKET returns information about captured audio packets.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSRTAUDIO_GETREA


DPACKET_INFO

The property descriptor (instance data) is a KSPROPERTY structure. Before sending the request, the client loads
the structure with values that indicate the packet number, packet length and other information.
The property value is a variable of type KSRTAUDIO_GETREADPACKET_INFO .
Return Value
A KSPROPERTY_RTAUDIO_GETREADPACKET property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate failure status code.
STATUS_DEVICE_NOT_READY - The driver returns this error if no new data is available.

Remarks
Before reading captured audio data from the WaveRT buffer, the OS calls this routine to get information about the
available data.
The packet number identifies a packet within the stream. This resets to zero when the stream is in KSSTATE_STOP.
The number advances with each captured buffer. From the packet number the OS can derive the packet location
within the WaveRT buffer and can also derive the stream position of the packet relative to start of stream.
The packet size is the WaveRT buffer size divided by the NotificationCount passed to
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION . The OS may call this routine at any time. In normal
operation, the OS calls this routine after the driver sets the buffer notification event or after a previous call returns
true for MoreData. When the OS calls this routine, the driver may assume that the OS has finished reading all
previous packets. If the hardware has captured enough data, the driver may immediately burst the next complete
packet to the WaveRT buffer and set the buffer event again. In the case of capture overflow (when the OS does not
read data quickly enough) the audio driver may drop or overwrite some audio data. The audio driver drops or
overwrites oldest data first, The audio driver may continue to advance its internal packet counter even though the
OS may not have read the data.

Requirements
Version Available in Windows 10 and later Windows operating
systems.

Header Ksmedia.h
See also
KSPROPERTY_RTAUDIO_SETWRITEPACKET
UsePositionLock
KSPROPERTY_RTAUDIO_HWLATENCY
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_HWLATENCY property retrieves a description of the stream latency of the audio
hardware and its associated data path.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSRTAUDIO_H


WL ATENCY

Return Value
A KSPROPERTY_RTAUDIO_HWLATENCY property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate failure status code.

Remarks
After the WaveRT miniport driver has allocated the cyclic buffer (see KSPROPERTY_RTAUDIO_BUFFER ) the
client can send a KSPROPERTY_RTAUDIO_HWLATENCY property request to the driver for hardware-latency
information.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPERTY
KSRTAUDIO_HWL ATENCY
KSPROPERTY_RTAUDIO_BUFFER
WaveRT minipor t driver
KSPROPERTY_RTAUDIO_PACKETCOUNT
6/25/2019 • 2 minutes to read • Edit Online

KSPROPERTY_RTAUDIO_PACKETCOUNT returns the (1-based) count of packets completely transferred from the
WaveRT buffer into hardware.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY ULONG

The property descriptor (instance data) is a KSPROPERTY structure. Before sending the request, the client loads
the structure with the (1-based) count of packets completely transferred from the WaveRT buffer into hardware.
The property value is a variable of type ULONG.
Return Value
A KSPROPERTY_RTAUDIO_PACKETCOUNT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate failure status code.

Remarks
From the packet count, the OS can derive the stream position of the packets it writes into the WaveRT buffer. The
OS can also derive the WaveRT buffer position of the next packet to write within the WaveRT buffer. For WaveRT
drivers, the driver signals a single notification event as it transfers data from each packet of the WaveRT buffer.
Therefore the event alone cannot indicate which packet within the WaveRT buffer is being transferred. In normal
operation this is not a concern but in underflow cases correction is more easily achieved by querying the packet
count from which the OS can determine which packet to write next.
The returned PacketCount indicates the (1-based) count of packets completely transferred from the WaveRT buffer
into hardware. From this, the OS can determine the 0-based number of the packet currently being transferred, and
ensure that it writes ahead of that packet. For example, if the packet count is 5, then 5 packets have completely
transferred. That is, packets 0-4 have completely transferred. Therefore packet 5 is in progress, and the OS should
write packet 6. If the notification count for the WaveRT buffer is 2, then packet 6 would be at offset 0 within the
WaveRT buffer (because 6 modulo 2 is 0, and 0 times the packet size is 0).
The OS may get this property at any time. However it generally gets this property only periodically or after the
driver returns a dataflow error (STATUS_DATA_LATE_ERROR, STATUS_DATA_OVERRUN) from SetWritePacket() in
order to resynchronize with the driver.
The driver should reset the packet count to 0 when the stream is in KSSTATE_STOP.

Requirements
Version Available in Windows 10 and later Windows operating
systems.
Header Ksmedia.h

See also
KSPROPSETID_RTAudio
KSPROPERTY_RTAUDIO_POSITIONREGISTER
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_POSITIONREGISTER property maps the position register of an audio device for a
particular stream into a virtual memory location that the client can access.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSRTAUDIO_H KSRTAUDIO_H


WREGISTER_PR WREGISTER
OPERTY

The property descriptor (instance data) is a KSRTAUDIO_HWREGISTER_PROPERTY structure, which contains a


KSPROPERTY structure. Before sending the request, the client loads the structure with values that indicate the
preferred base address for the register.
The property value (operation data) is a KSRTAUDIO_HWREGISTER structure into which the property handler
writes the virtual address to which it has mapped the hardware position register. The client can directly read the
register from this address. The KSRTAUDIO_HWREGISTER structure also specifies the rate at which the position
register increments itself.
Return Value
A KSPROPERTY_RTAUDIO_POSITIONREGISTER property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate failure status code.

Remarks
Typically, audio applications must monitor the current position of an audio stream. This position is specified as a
byte offset from the beginning of the stream:
In the case of a rendering stream, the stream's position is the byte offset of the audio frame that is currently
playing through the digital-to-analog converters (DACs).
In the case of a capture stream, the stream's position is the byte offset of the audio frame that is currently
being recorded through the analog-to-digital converters (ADCs).
Some audio devices contain position registers that increment continually while the stream is running. For an audio
device that incorporates all digital and analog functions into a single chip, the position register typically indicates
the current stream position directly.
However, for a chipset that divides digital and analog functions into separate bus-controller and codec chips, the
position register is typically located in the bus-controller chip and indicates the following:
In the case of a rendering stream, the position register indicates the byte offset of the last audio frame that
the bus controller wrote to the codec.
In the case of a capture stream, the position register indicates the byte offset of the last audio frame that the
bus controller read from the codec.
In both cases, the position register value does not include the delay through the codec. If the client has determined
the codec delay, it can add this delay to the position register value to estimate the true stream position (at the DACs
or ADCs). For a CodecDelay value that specifies the worst-case delay through the codec, you can query the
KSPROPERTY_RTAUDIO_HWL ATENCY property.
If successful, a KSPROPERTY_RTAUDIO_POSITIONREGISTER property request maps the position register to a
virtual memory address that is accessible to the client from either user-mode or kernel-mode, as specified by the
client. Thereafter, the client reads from this address to obtain the current value of the position register.
The property request fails if the audio hardware does not support a position register that can be mapped to a
virtual address. In this case, the client must determine the position from the KSPROPERTY_AUDIO_POSITION
property.
The mapping of the position register is destroyed when the pin closes. The client can map the register only once in
the lifetime of an opened pin, and any subsequent call to remap the position register for the pin fails.
It is typically faster to read the position register than it is to send a KSPROPERTY_AUDIO_POSITION request, which
requires transitions between user-mode and kernel-mode for user-mode clients.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPERTY
KSRTAUDIO_HWREGISTER
KSRTAUDIO_HWREGISTER_PROPERTY
KSPROPERTY_AUDIO_POSITION
KSPROPERTY_RTAUDIO_HWL ATENCY
KSPROPERTY_RTAUDIO_PRESENTATION_POSITION
10/23/2019 • 2 minutes to read • Edit Online

KSPROPERTY_RTAUDIO_PRESENTATION_POSITION returns stream presentation information.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Pin KSPROPERTY KSAUDIO_PRES


ENTATION_POS
ITION

The property descriptor (instance data) is a KSPROPERTY structure. Before sending the request, the client loads
the structure with values that describe the current cursor position in audio data stream.
The property value is a KSAUDIO_PRESENTATION_POSITION structure that represents a recent presentation
position in the audio data stream.
Return Value
A KSPROPERTY_RTAUDIO_PRESENTATION_POSITION property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate failure status code.

Remarks
The OS may periodically get this property from the driver to retrieve recent presentation position information
from the driver in order to allow upper layers to synchronize video or other activity with the audio stream.
The value returned in the u64PositionInBlocks member of KSAUDIO_PRESENTATION_POSITION should be
consistent with the packet count returned by KSPROPERTY_RTAUDIO_PACKETCOUNT and the driver’s
interpretation of the packet number passed to SetWritePacket. In other words, the first sample of packet 0 is block
0.
This does not mean that KSPROPERTY_RTAUDIO_PACKETCOUNT and
KSPROPERTY_RTAUDIO_PRESENTATION_POSITION, if called simultaneously, would return values that refer to the
same sample. KSPROPERTY_RTAUDIO_PACKETCOUNT returns information about the samples transferred from the
WaveRT buffer to the hardware, while KSPROPERTY_RTAUDIO_PRESENTATION_POSITION returns information
about samples presented at the output of the system. These are two different pieces of information.

Requirements
Version Available in Windows 10 and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPSETID_RTAudio
KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT
6/25/2019 • 2 minutes to read • Edit Online

The client application uses the KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT property to determine whether the audio
driver can notify the client application when a process that is performed on the submitted buffer is completed.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes No Pin KSPROPERTY BOOL

The property value is a variable of type BOOL.


Return Value
In response to a KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT property request, the driver returns a TRUE or FALSE
value. This value depends on whether the driver supports the property.

Remarks
None

Requirements
Version Available in Windows 7 and later versions of the Windows
operating systems.

Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT property registers a user-mode event for DMA-driven


event notification. Events must be registered after successfully calling
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION .
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y
GET SET TA RGET DESC RIP TO R T Y P E P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSRTAUDIO_NOT NULL


IFICATION_EVEN
T_PROPERTY

The property descriptor (instance data) consists of a KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY structure that


contains a KSPROPERTY structure along with a user-mode event handle.
The property value (operation data) for this property is NULL because no operation data is returned.
Return Value
A KSPROPERTY_ RTAUDIO_REGISTER_NOTIFICATION_EVENT property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate failure status code. The following table
shows some of the possible failure status codes.

STAT US C O DE M EA N IN G

STATUS_NOT_SUPPORTED Event notifications are not supported.

STATUS_INSUFFICIENT_RESOURCES Memory for the buffer cannot be allocated.

STATUS_DEVICE_NOT_READY The device is not ready.

Remarks
This property is used to register user-mode events for DMA-driven event notification.
When the pin is placed into the run state (KSSTATE_RUN) the registered events are signaled once or twice per cycle of the
cyclic audio buffer, depending on the notification count requested when
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION was called. For more information about KSSTATERUN, see the
State Transitions topic.
After you stop the pin, and prior to the time when you close it, each registered event is unregistered via a call to
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT .

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPERTY
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT
State Transitions
KSPROPERTY_RTAUDIO_SETWRITEPACKET
10/23/2019 • 2 minutes to read • Edit Online

KSPROPERTY_RTAUDIO_SETWRITEPACKET informs the driver that the OS has written valid data to the WaveRT
buffer.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Pin KSPROPERTY KSRTAUDIO_SETWRIT


EPACKET_INFO

The property descriptor (instance data) is a KSPROPERTY structure. Before sending the request, the client loads
the structure with values that include the packet number, packet length and other information.
The property value is a structure of type KSRTAUDIO_SETWRITEPACKET_INFO .
Return Value
A KSPROPERTY_RTAUDIO_SETWRITEPACKET property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate failure status code.

Remarks
If this KSPROPERTY is supported, the driver may optionally use the provided information to optimize the hardware
transfer. For example, the driver might optimize DMA transfers, or program hardware to stop transfer at the end of
the specified packet in case the OS does not call this routine again to inform the driver of another packet. This can
mitigate audible effects of underflow, for example introducing an audible gap rather than repeating a circular
buffer. The driver however is still obligated to increase its internal packet counter and signal notification events at a
nominal real time rate.
Except when the OS specifies the KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM flag, the packet size is the
WaveRT buffer size divided by the NotificationCount passed to
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION .
Depending on hardware capabilities, if the KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM flag is specified, the
driver may silence-fill a portion of the WaveRT buffer that follows the EOS packet in case the hardware transfers
data beyond the EOS position.

Requirements
Version Available in Windows 10 and later Windows operating
systems.

Header Ksmedia.h

See also
KSPROPERTY_RTAUDIO_GETREADPACKET
UsePositionLock
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT property unregisters a user-mode event from DMA-driven


event notification.
The following table summarizes the features of this property.
Usage Summary Table
P RO P ERT Y DESC RIP TO R
GET SET TA RGET TYPE P RO P ERT Y VA L UE T Y P E

Yes Yes Pin KSRTAUDIO_NOTI NULL


FICATION_EVENT_
PROPERTY

The property descriptor (instance data) consists of a KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY structure that contains a
KSPROPERTY structure along with a user-mode event handle.
The property value (operation data) for this property is NULL because no operation data is returned.
Return Value
A KSPROPERTY_ RTAUDIO_UNREGISTER_NOTIFICATION_EVENT property request returns STATUS_SUCCESS to indicate that it
has completed successfully. Otherwise, the request returns an appropriate failure status code. The following table shows some
of the possible failure status codes.

STAT US C O DE M EA N IN G

STATUS_NOT_SUPPORTED Event notifications are not supported.

STATUS_INSUFFICIENT_RESOURCES Memory for the buffer cannot be allocated.

STATUS_DEVICE_NOT_READY The device is not ready.

Remarks
This property is used to unregister user-mode events from DMA-driven event notification.
When the pin is placed into the run state (KSSTATE_RUN) the registered events are signaled once or twice per cycle of the cyclic
audio buffer, depending on the notification count requested when KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
was called. For more information about KSSTATE_RUN, see the State Transitions topic.
After you stop the pin and prior to the step where you close it, each registered event must be unregistered via a call to
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT.

Requirements
Version Available in Windows Vista and later Windows operating systems.

Header Ksmedia.h

See also
KSPROPERTY
KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT
KSPROPERTY_SOUNDDETECTOR enumeration
12/5/2018 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR enumeration defines constants that are used to register a filter for an
audio capture device that also supports a detector.

Syntax
typedef enum {
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS = 1,
KSPROPERTY_SOUNDDETECTOR_PATTERNS,
KSPROPERTY_SOUNDDETECTOR_ARMED,
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
} KSPROPERTY_SOUNDDETECTOR;

Constants
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
Specifies the ID for the KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS property.
KSPROPERTY_SOUNDDETECTOR_PATTERNS
Specifies the ID for the KSPROPERTY_SOUNDDETECTOR_PATTERNS property.
KSPROPERTY_SOUNDDETECTOR_ARMED
Specifies the ID for the KSPROPERTY_SOUNDDETECTOR_ARMED property.
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
Specifies the ID for the KSPROPERTY_SOUNDDETECTOR_MATCHRESULT property.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h

See also
KSPROPSETID_SoundDetector
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSPROPERTY_SOUNDDETECTOR_ARMED
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
KSPROPERTY_SOUNDDETECTOR_ARMED
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_ARMED property is the current arming state of the detector.


Usage Summary Table - KSPROPSETID_SoundDetector
This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY BOOL

When called by KSPROPSETID_SoundDetector, the driver resets this to false when:


The filter interface is disabled.
The KSPROPERTY_SOUNDDETECTOR_PATTERNS property is set.
A keyword is detected.
Usage Summary Table - KSPROPSETID_SoundDetector2
This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector2

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSSOUNDDETE BOOL


CTORPROPERT
Y

When called with KSPROPSETID_SoundDetector2 the arm state will not be reset when a keyword is detected.
It is reset to false when:
The filter interface is disabled.
The KSPROPERTY_SOUNDDETECTOR_PATTERNS property is set
Return Value
The property value is a BOOL indicating the arming state of the detector.

Remarks
The OS sets this true to engage the detector.
Setting this true while no keyword patterns are set (KSPROPERTY_SOUNDDETECTOR_PATTERNS is empty)
has no effect.
Note: If this property is true, subsequently setting KSPROPERTY_SOUNDDETECTOR_PATTERNS automatically
resets this to false, as mentioned above.
Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h

See also
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSPROPERTY
KSSOUNDDETECTORPROPERTY
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_MATCHRESULT property holds the result data for a match.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY SOUNDDETECT


OR_PATTERNHE
ADER

Return Value
A SOUNDDETECTOR_PATTERNHEADER structure followed by the result data payload.

Remarks
The result data includes a SOUNDDETECTOR_PATTERNHEADER identifying the format of the result data as
well as the OEMDLLCOM object to process the result data.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h

See also
SOUNDDETECTOR_PATTERNHEADER
KSPROPERTY
KSPROPERTY_SOUNDDETECTOR_PATTERNS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_PATTERNS property is set by the operating system to configure the


keywords to be detected.
The OS sets the keyword patterns or may set this to an empty value.
When the OS sets this property, the driver automatically disarms the detector if was previously armed.
If the driver cannot satisfy a “set” request due to insufficient resources, the driver fails the request with
STATUS_INSUFFICIENT_RESOURCES .
Usage Summary Table - KSPROPSETID_SoundDetector
This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY KSMULTIPLE_I


TEM

Usage Summary Table - KSPROPSETID_SoundDetector2


This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector2

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSSOUNDDETE KSMULTIPLE_I


CTORPROPERT TEM
Y

Return Value
The property value is a KSMULTIPLE_ITEM structure followed by a sequence of 64-bit aligned detection
patterns. Each pattern starts with a SOUNDDETECTOR_PATTERNHEADER followed by the pattern payload.

Remarks
The driver shall not complete the “set” request until:
The detector is disarmed and subsequent “get” requests on KSPROPERTY_SOUNDDETECTOR_ARMED
return false.
Subsequent “get” requests on KSPROPERTY_SOUNDDETECTOR_MATCHRESULT return no data.
The new keyword patterns are established and the keyword detector is operating on the new patterns.
The driver may keep the request pending until the above conditions are met. Also, if the device requires
measurable initialization time, the driver may keep this request pending until the device is ready and the can
process the request.
The OS requires this behavior to avoid race conditions between a detected a keyword and updating keyword
patterns (e.g. if a keyword was detected and the KSEVENT_SOUNDDETECTOR generated an instant before the
OS updates the keywords).
The OS waits at least 2 seconds for this request to complete.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h

See also
SOUNDDETECTOR_PATTERNHEADER
SOUNDDETECTOR_PATTERNS
KSPROPERTY_SOUNDDETECTOR_ARMED
KSPROPERTY_SOUNDDETECTOR_MATCHRESULT
KSPROPERTY
KSMULTIPLE_ITEM
KSPROPERTY_SOUNDDETECTOR_RESET
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_RESET property resets the detector to an unarmed state with no pattern
set.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSSOUNDDETE BOOL


CTORPROPERT
Y

Return Value
The property value is a BOOL. True indicates to reset, false is ignored.

Remarks
The OS calls reset with a value of true when it would like to:
Unarm the keyword detector.
Clear any KSPROPERTY_SOUNDDETECTOR_PATTERNS that have been set.
Setting this true while no keyword patterns are set (KSPROPERTY_SOUNDDETECTOR_PATTERNS is empty)
has no effect.

Requirements
Minimum supported client Windows 10 Version 1903

Header Ksmedia.h

See also
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSSOUNDDETECTORPROPERTY
KSPROPERTY_SOUNDDETECTOR_STREAMINGSUPPORT
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_STREAMINGSUPPORT property indicates whether or not streaming is


supported.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSSOUNDDETEC BOOL


TORPROPERTY

Return Value
The property value is a BOOL indicating whether or not streaming is supported.
A driver which supports this read property and returns false is indicating that only voice onset is supported without
the associated burst audio stream.
A driver which does not support this property, or supports this property and returns true, is indicating that it supports
bursting the audio data which triggered the keyword detection.
All detectors must support buffering and burst streaming the audio data which triggered the hardware keyword
detection, and fail this request or set this value to true.

Remarks
This property is for future use. There is currently no OS support for detectors which do voice onset only.

Requirements
Minimum supported client Windows 10 Version 1903

Header Ksmedia.h

See also
KSPROPERTY_SOUNDDETECTOR_PATTERNS
KSSOUNDDETECTORPROPERTY
KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS property is used to get a list of GUIDs that identify


the types of supported patterns.
Usage Summary Table - KSPROPSETID_SoundDetector
This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY KSMULTIPLE_ITE


M

Usage Summary Table - KSPROPSETID_SoundDetector2


This usage table summarizes when KSPROPERTY_SOUNDDETECTOR_ARMED is called with
KSPROPSETID_SoundDetector2

P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSSOUNDDETEC KSMULTIPLE_ITE


TORPROPERTY M

Return Value
The property value is a KSMULTIPLE_ITEM structure followed by a sequence of GUIDs.

Remarks
The pattern GUID has these characteristics:
It is generated by the OEM.
The operating system uses it as the class identifier (CLSID) to instantiate the counterpart OEM DLL COM class
that is used to interact with the driver.
It implies a format for the pattern data defined by the OEM.
It implies a format for the result data defined by the OEM.

Requirements
Minimum supported client Windows 10

Minimum supported server Windows Server 2016

Header Ksmedia.h
See also
KSPROPERTY
KSMULTIPLE_ITEM
KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE property attaches a virtual source to a pin instance on a


virtual audio device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Pin SYSAUDIO_ATT None


ACH_VIRTUAL_
SOURCE

The property descriptor (instance data) is a structure of type SYSAUDIO_ATTACH_VIRTUAL_SOURCE that specifies
the property and a virtual source index.
Return Value
A KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property attaches a virtual source to a pin instance on the virtual audio device. For more information, see
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE .

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
SYSAUDIO_ATTACH_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_COMPONENT_ID
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_COMPONENT_ID property retrieves the component ID from the wave-rendering


device that the specified virtual audio device uses.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY +U KSCOMPONEN


LONG TID

The property descriptor (instance data) is a structure of type KSPROPERTY followed by a ULONG variable
containing a device ID that identifies a virtual audio device. If SysAudio enumerates n virtual audio devices (see
KSPROPERTY_SYSAUDIO_DEVICE_COUNT ), then valid device IDs range from 0 to n-1.
The property value (operation data) is a structure of type KSCOMPONENTID that specifies the manufacturer,
product, and other hardware-specific information about the wave-rendering device that is used by the specified
virtual audio device.
Return Value
A KSPROPERTY_SYSAUDIO_COMPONENT_ID property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
DirectSound does not communicate directly with the miniport driver for the audio hardware that underlies each of
SysAudio's virtual audio devices. Thus, DirectSound is unable to query the wave-rendering device directly for its
component-ID information. The KSPROPERTY_SYSAUDIO_COMPONENT_ID property provides a means for
DirectSound to obtain this information indirectly through SysAudio.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSCOMPONENTID
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE property creates a new virtual source.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter SYSAUDIO_CRE ULONG


ATE_VIRTUAL_S
OURCE

The property descriptor (instance data) is a structure of type SYSAUDIO_CREATE_VIRTUAL_SOURCE that specifies
the pin-category and pin-name GUIDs for the virtual source.
The property value (operation data) is a ULONG variable containing the virtual source index. SysAudio generates
this index to identify the new virtual source.
Return Value
A KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is used to create a mixer-line virtual source such as a volume or mute control.
If SysAudio has already created a virtual source with the same pin-category and pin-name GUIDs, a
KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE get-property request retrieves the index for the existing
virtual source. Otherwise, the request generates a new virtual source index and outputs that value.
After SysAudio has assigned an index to a virtual source, a
KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE set-property request can be used to attach that virtual
source to a pin instance on the virtual audio device.
The user controls the volume levels of various audio sources through the SndVol32 application. These sources
include the wave-output device, MIDI synthesizer, CD player, and line-in jack. SndVol32 uses the Windows
multimedia waveOut Xxx, midiOut Xxx, and aux Xxx functions to control the volume levels for these sources. For
more information about Windows multimedia functions, see the Microsoft Windows SDK documentation.
SysAudio intercepts volume changes made to these devices and applies them to its virtual sources. For example, if
a software MIDI synthesizer that converts a MIDI file to wave data is connected to one of the virtual audio device's
wave-rendering pins, SysAudio applies midiOutXxx volume changes to the pin (instead of waveOut Xxx volume
changes). Similarly, if the Redbook system driver, which converts digital audio from a CD player to wave data, is
connected to one of the virtual audio device's wave-rendering pins, SysAudio applies AUXCAPS_CDAUDIO volume
changes to the pin. For more information about the AUXCAPS_CDAUDIO structure, see the Windows SDK
documentation.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
SYSAUDIO_CREATE_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_DEVICE_COUNT property retrieves a count specifying the number of virtual audio
devices that a DirectSound application program has to choose from.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY ULONG

The property value (operation data) is a ULONG variable into which SysAudio writes a count specifying the
number of virtual audio devices to choose from. If SysAudio enumerates n virtual audio devices, these devices
are identified by device IDs 0 through n-1.
Return Value
A KSPROPERTY_SYSAUDIO_DEVICE_COUNT property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
SysAudio enumerates a unique virtual audio device for each enabled hardware device in the system that
performs wave rendering. In each instance, the virtual audio device is composed of the hardware device, the
KMixer system driver, and other audio components. A DirectSound application program selects a particular
hardware device by selecting the virtual audio device that incorporates the hardware device.
For example, if three audio cards are plugged into the system bus and each contains a wave-rendering device
with a WaveCyclic or WavePci miniport driver, SysAudio enumerates three virtual audio devices with device IDs 0,
1, and 2.
SysAudio maintains its list of virtual audio devices in the system registry under the category
KSCATEGORY_AUDIO_DEVICE. This category is reserved exclusively for use by SysAudio. DirectSound does not
directly access information about the virtual audio devices from the system registry. Instead, it queries SysAudio
for the properties of the virtual audio devices.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME property retrieves a Unicode string containing the


friendly name of the virtual audio device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY +U LPWSTR


LONG

The property descriptor (instance data) consists of a KSPROPERTY structure followed by a ULONG variable
containing a device ID that identifies a virtual audio device. If SysAudio enumerates n virtual audio devices (see
KSPROPERTY_SYSAUDIO_DEVICE_COUNT ), then valid device IDs range from 0 to n-1. Also, a device ID value
of -1 can be used to indicate the current device, which is the last virtual audio device opened by a
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE or KSPROPERTY_SYSAUDIO_INSTANCE_INFO set-property
request.
The property value (operation data) is a pointer to a null-terminated string of Unicode characters that contains the
device's friendly name.
Return Value
A KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE
KSPROPERTY_SYSAUDIO_INSTANCE_INFO
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE property specifies the current instance of a virtual audio device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY ULONG

The property value (operation data) is of type ULONG and specifies the device ID of a virtual audio device. If
SysAudio enumerates n virtual audio devices (see KSPROPERTY_SYSAUDIO_DEVICE_COUNT ), then valid
device IDs range from 0 to n-1.
Return Value
A KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
A KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE set-property request opens the virtual audio device specified by
the device ID contained in the property value. The last device to be opened is referred to as the current device.
Some SysAudio properties allow the current device to be identified by a null device ID of -1 rather than by a valid
device ID in the range 0 to n-1, where n is the number of available virtual audio devices. These properties include
KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME and
KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME .
A get-property request retrieves the device ID of the current (last opened) virtual audio device.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME
KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME property retrieves a Unicode string containing the Plug


and Play device interface name for the specified virtual audio device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY +U LPWSTR


LONG

The property descriptor (instance data) consists of a KSPROPERTY structure followed by a ULONG variable
containing a device ID that identifies a virtual audio device. If SysAudio enumerates n virtual audio devices (see
KSPROPERTY_SYSAUDIO_DEVICE_COUNT ), then valid device IDs range from 0 to n-1. Also, a device ID value
of -1 can be used to indicate the current device, which is the last virtual audio device opened by a
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE or KSPROPERTY_SYSAUDIO_INSTANCE_INFO set-property
request.
The property value (operation data) is a pointer to a null-terminated string of Unicode characters that contains the
device's interface name.
Return Value
A KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME property request returns STATUS_SUCCESS to indicate
that it has completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSPROPERTY
KSPROPERTY_SYSAUDIO_DEVICE_COUNT
KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE
KSPROPERTY_SYSAUDIO_INSTANCE_INFO
KSPROPERTY_SYSAUDIO_INSTANCE_INFO
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_INSTANCE_INFO property opens a virtual audio device and specifies the
configuration flags for that device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter SYSAUDIO_INS None


TANCE_INFO

The property descriptor (instance data) is a structure of type SYSAUDIO_INSTANCE_INFO that specifies which
virtual audio device to open and also specifies the configuration flags for that device.
No property value (operation data) is defined for this property. Specify the property value pointer as NULL , and
the property value size as zero.
Return Value
A KSPROPERTY_SYSAUDIO_INSTANCE_INFO property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
SYSAUDIO_INSTANCE_INFO
KSPROPERTY_SYSAUDIO_SELECT_GRAPH
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_SYSAUDIO_SELECT_GRAPH property is used to explicitly include an optional node in the graph
that SysAudio builds for a pin instance on a virtual audio device.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter SYSAUDIO_SEL None


ECT_GRAPH

The property descriptor (instance data) is a structure of type SYSAUDIO_SELECT_GRAPH that specifies the
property, pin ID, and node ID. The property is specified by an embedded structure of type KSPROPERTY . The pin
ID is an index identifying a pin factory in the KS filter that wraps the virtual audio device. The node ID is an index
identifying an optional node in the specified pin's data path. For more information, see the following Remarks
section.
No property value (operation data) is defined for this property. Specify the property value's buffer pointer as
NULL and its size as zero.
Return Value
A KSPROPERTY_SYSAUDIO_SELECT_GRAPH property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
This property is typically used to force an AEC node into the graph for a pin instance.
When instantiating a rendering pin on the filter for a virtual audio device, SysAudio starts at the pin and by default
selects the graph that represents the simplest path through the filter. This graph excludes any optional nodes such
as AEC controls.
You can override SysAudio's default behavior by first sending SysAudio a
KSPROPERTY_SYSAUDIO_SELECT_GRAPH set-property request that specifies the optional node that is to be
included in the graph. When SysAudio subsequently creates the pin instance, the pin's graph will include the
optional node that was specified in the request.
A KSPROPERTY_SYSAUDIO_SELECT_GRAPH set-property request affects only pin instances that are created after
the request. The request has no effect on any previously instantiated pins.

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
SYSAUDIO_SELECT_GRAPH
KSPROPERTY
KSPROPERTY_TELEPHONY_CALLCONTROL
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_CALLCONTROL property is used to start and terminate a phone call.


Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY KSTELEPHONY_


CALLCONTROL

Return Value
A KSPROPERTY_TELEPHONY_CALLCONTROL property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
KSPROPERTY_TELEPHONY_CALLCONTROL contains information about CallType and CallControlOp.
TELEPHONY_CALLCONTROLOP_ENABLE will start cellular call from audio driver perspective, update jack state for
associated cellular bidi endpoint to active, save call type and update the call state to Enabled.
TELEPHONY_CALLCONTROLOP_DISABLE will terminate cellular call from audio driver perspective, update jack
state for associated cellular bidi endpoint to unplugged and update call state to Disabled. Call type is ignored in
this case.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_CALLHOLD
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_CALLHOLD property is used to control the hold state of a phone call.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY BOOL

The property value is of type BOOL and specifies whether the phone call is on hold.
Return Value
A KSPROPERTY_TELEPHONY_CALLHOLD property request returns TRUE if the call in on hold; otherwise, it
returns FALSE .

Remarks
If you set the KSPROPERTY_TELEPHONY_CALLHOLD property with a value of TRUE , the phone call will be
placed on hold. The expected behavior is that both transmission and reception will be muted. No data will be sent
or received in this case. The audio driver will update the call state (TELEPHONY_CALLSTATE ) to
TELEPHONY_CALLSTATE_HOLD . If you set the KSPROPERTY_TELEPHONY_CALLHOLD property with a value
of FALSE , the phone call will be taken off of hold state, and the call state will be updated to
TELEPHONY_CALLSTATE_ENABLED .

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_CALLINFO
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_CALLINFO property is used to retrieve current call information, such as call
state and call type.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY KSTELEPHONY_


CALLINFO

The property value is of type KSTELEPHONY_CALLINFO , which specifies the state and the type of the phone call.
Return Value
A KSPROPERTY_TELEPHONY_CALLINFO property request returns a KSTELEPHONY_CALLINFO structure,
which contains the call type (LTE packet-switched, WLAN packet-switched, or circuit-switched) and the call state
(enabled, disabled, held, or in provider transition).

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR property contains the render and capture endpoints for
cellular audio routing.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY KSTOPOLOGY_


ENDPOINTIDPA
IR

The property value is of type KSTOPOLOGY_ENDPOINTIDPAIR , which specifies the render and capture
endpoints.
Return Value
A KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR property request returns the render and capture endpoints
for cellular audio routing.

Remarks
Cellular routing is controlled by KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR property on the topology filter.
This property takes a pair of KSTOPOLOGY_ENDPOINTID structures for the requested endpoint combination.
KSTOPOLOGY_ENDPOINTID contains a reference string for the topology filter of an endpoint and a topology
filter pin ID to which the endpoint is connected. The driver provides basic support for this property and returns all
of the valid pairs of render and capture endpoints that can be used for cellular audio routing. It is the driver’s
responsibility to handle moving both render and capture cellular audio to this new endpoint combination, meeting
whatever constraints are necessary for the hardware. This property must be settable even when there is no active
phone call in the system.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_MUTE_TX
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_MUTE_TX property is used to control whether to mute the data being
transmitted from the local microphone to the remote end.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY BOOL

The property value is of type BOOL and specifies whether the data transmitted from the local microphone and the
data rendered on the remote end is being muted.
Return Value
A KSPROPERTY_TELEPHONY_MUTE_TX property request returns TRUE if the phone call is muted; it returns
FALSE if the phone call is unmuted.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_PROVIDERCHANGE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_PROVIDERCHANGE property is used to communicate to the audio driver that


single-radio voice call continuity (SRVCC) is beginning or ending.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSPROPERTY KSTELEPHONY_


PROVIDERCHA
NGE

The property value is of type KSTELEPHONY_PROVIDERCHANGE , which specifies the phone call type and the
type of provider change operation.
Return Value
A KSPROPERTY_TELEPHONY_PROVIDERCHANGE property request returns STATUS_SUCCESS to indicate that
it has completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
The audio stack uses the KSTELEPHONY_PROVIDERCHANGE property to indicate the start and the end of
SRVCC to the audio driver. This property communicates the call type (LTE packet-switched, WLAN packet-switched,
or circuit-switched) and the provider change operation (begin, end, or cancel) to driver. The call type is ignored
when the provider operation is for ending the SRVCC.
When the provider change operation is TELEPHONY_PROVIDERCHANGEOP_BEGIN , the driver updates that
provider’s call state to TELEPHONY_CALLSTATE_PROVIDERTRANSITION . When the provider change
operation is TELEPHONY_PROVIDERCHANGEOP_END , the driver updates that provider’s call state to
TELEPHONY_CALLSTATE_ENABLED . During SRVCC, the driver must continue to use the associated
KSNODETYPE_TELEPHONY_BIDI endpoint, and it does not change the jack states of this endpoint. When the
provider change operation is TELEPHONY_PROVIDERCHANGEOP_CANCEL , SRVCC is being canceled, and the
driver should revert back to a pre-SRVCC call.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_PROVIDERID
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_PROVIDERID property is used by the audio driver to associate a provider


identifier to a wave filter.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes No Filter KSPROPERTY UINT

The property value is of type UINT and specifies the provider ID.
Return Value
A KSPROPERTY_TELEPHONY_PROVIDERID property request returns a UINT value that represents the provider
ID that the audio driver associates to the wave filter.

Remarks
The radio stack has a concept of provider ID (executor ID) and call type (packet or circuit-switched) to connect the
phone call instance to a specific hardware path. This concept will continue to be used to communicate to the audio
driver which path in hardware to use.
This hardware path will be controlled by sending properties on a wave filter for each provider. The audio driver
will associate a provider ID to the wave filter. This provider ID will also be set on the associated cellular streaming
endpoints. The provider ID for the wave filter must not change at runtime. The audio stack will query the provider
ID from the driver by using the KSPROPERTY_TELEPHONY_PROVIDERID property . After this provider ID is
discovered, all the calls for that provider ID will be sent to the particular wave filter.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TELEPHONY_VOLUME
6/25/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TELEPHONY_VOLUME property is used to control the volume for all cellular calls.
Usage Summary Table
P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSPROPERTY LONG

The property value is of type LONG and specifies the cellular call volume.
Return Value
A KSPROPERTY_TELEPHONY_VOLUME property request returns the cellular call volume.

Remarks
For cellular calls, only this volume is applicable to cellular data, and the endpoint volume has no effect. This
property must be settable even when there is no active phone call in the system. Basic support for this property
should return the minimum volume, the maximum volume, and the volume ranges.

Requirements
Minimum supported client Windows 10

Minimum supported server None supported

Client Windows 10 Mobile

Header Ksmedia.h
KSPROPERTY_TOPOLOGYNODE_ENABLE
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TOPOLOGYNODE_ENABLE property is used to turn on or off the topology nodes in an already
built topology.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

Yes Yes Filter KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL and specifies whether the node is turned on or off. A value of
TRUE indicates that the node is turned on. FALSE indicates that the node is turned off.
Return Value
A KSPROPERTY_TOPOLOGYNODE_ENABLE property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Remarks
Enabling an already enabled node or disabling an already disabled node has no effect, but should not be treated
as an error.
Disabling a node turns off the transformation that the node performs on the stream that passes through the node.
In the case of an AEC, AGC, or noise-suppression node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL ,
KSNODETYPE_AGC , or KSNODETYPE_NOISE_SUPPRESS ), for example, a disabled node operates in pass-
through mode (that is, it performs no operation on the stream as it flows from the node's input pin to its output
pin).

Requirements
Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSNODETYPE_ACOUSTIC_ECHO_CANCEL
KSNODETYPE_AGC
KSNODETYPE_NOISE_SUPPRESS
KSPROPERTY_TOPOLOGYNODE_RESET
10/23/2019 • 2 minutes to read • Edit Online

The KSPROPERTY_TOPOLOGYNODE_RESET property resets the node completely, restoring it to its initial state.

Usage Summary Table


P RO P ERT Y P RO P ERT Y VA L UE
GET SET TA RGET DESC RIP TO R T Y P E TYPE

No Yes Filter KSNODEPROPE BOOL


RTY

The property value (operation data) is of type BOOL and indicates whether the node should be reset. A value of
TRUE resets the node to its default initial state at the time of creation. A value of FALSE has no effect, but should
not be treated as an error.
Return Value
A KSPROPERTY_TOPOLOGYNODE_RESET property request returns STATUS_SUCCESS to indicate that it has
completed successfully. Otherwise, the request returns an appropriate error status code.

Requirements
Version Supported in Microsoft Windows XP and later operating
systems.

Header Ksmedia.h (include Ksmedia.h)

See also
KSNODEPROPERTY
KSRTAUDIO_BUFFER_PROPERTY structure
10/23/2019 • 2 minutes to read • Edit Online

The KSRTAUDIO_BUFFER_PROPERTY structure appends a buffer base address and requested buffer size to a
KSPROPERTY structure. This structure is used by the client to request allocation of the audio buffer via
KSPROPERTY_RTAUDIO_BUFFER .

Syntax
typedef struct {
KSPROPERTY Property;
PVOID BaseAddress;
ULONG RequestedBufferSize;
} KSRTAUDIO_BUFFER_PROPERTY, *PKSRTAUDIO_BUFFER_PROPERTY;

Members
Proper ty
A KSPROPERTY structure that the client initializes appropriately prior to calling KSPROPERTY_RTAUDIO_BUFFER.
BaseAddress
Specifies the desired buffer base address. Unless the client specifies a base address, this parameter is set to NULL .
RequestedBufferSize
Specifies the desired buffer size in bytes. The driver returns the actual size of the allocated buffer in the
KSRTAUDIO_BUFFER structure that it returns.

Remarks
The KSPROPERTY_RTAUDIO_BUFFER request uses the KSRTAUDIO_BUFFER_PROPERTY structure to describe the
cyclic buffer that the client requests. The driver returns a KSRTAUDIO_BUFFER structure to describe the buffer that
was actually allocated.
The value that the client writes into the RequestedBufferSize member is not binding on the driver. However, the
driver must specify a buffer size that is as close as possible to the requested size, taking into account the buffer
size constraints on the driver itself. The driver allocates a buffer of a different size if the hardware cannot handle
the requested size or the system is low on memory. For example, a driver allocates a buffer no smaller than a
memory page, or it rounds the buffer size down to the next whole sample block. Also, if the system is running low
on memory, the driver allocates a buffer that is smaller than the requested size.

Requirements
Version Available in Windows Vista and later Windows operating
systems.

Header Ksmedia.h

You might also like