The first step in implementing Microsoft DirectSound in an application is to create a Device object, which represents a sound device.

This section describes how your application can enumerate available sound devices, create the Device object, and use the methods of the object to set the cooperative level, retrieve the capabilities of the device, create sound buffers, set the configuration of the system's speakers, and compact hardware memory.

Enumeration of Sound Devices

For an application that is simply going to play sounds through the user's preferred playback device, you do not need to enumerate the available devices. For more information, see Creating the Device Object.

If you are looking for a particular kind of device, want to offer the user a choice of devices, or need to work with two or more devices, you must enumerate the devices available on the system.

Enumeration serves three purposes.

  • Reports what hardware is available.
  • Supplies a globally unique identifier (GUID) for each device.
  • Enables you to create a temporary Device object for each device as it is enumerated, so that you can check the capabilities of the device.

To enumerate devices, instantiate a DevicesCollection object, and use its methods and properties to query for the available devices. The description, driver GUID, and module name of each device can be obtained from the properties of the DeviceInformation structure.

The following C# sample code retrieves the available devices. The same procedure can be used to identify available capture devices by substituting CaptureDevicesCollection for DevicesCollection.
[C#]using Microsoft.DirectX.DirectSound;
public class wfEnum : System.Windows.Forms.Form
private DevicesCollection myDevices = null;
private struct myDeviceDescription
    public DeviceInformation info;
    public override string ToString()
        return info.Description;
        public myDeviceDescription(DeviceInformation di)
            info = di;
public wfEnum()
    // Retrieve the available DirectSound devices
    myDevices = new DevicesCollection();
    foreach (DeviceInformation dev in myDevices)
        myDeviceDescription dd = new myDeviceDescription(dev);
        // Use DevicesCollection and DeviceInformation to query for devices.

Note: The first device enumerated is always called the Primary Sound Driver. This device represents the preferred playback device set by the user in Control Panel. It is enumerated separately to make it easy for the application to add "Primary Sound Driver" to a list when presenting the user with a choice of devices. The primary device is also enumerated with its proper name and GUID.

Creating the Device Object

The following C# example show how to create a Device object for the default device.
[C#]private Device dsDevice = null;
dsDevice = new Device();

The following C# example creates a device from a GUID, represented by the deviceGuid variable. This GUID can be obtained by enumeration of devices.
[C#]dsDevice = new Device(deviceGuid);

You can also use one of the following values to specify a default device.

DSoundHelper.DefaultPlaybackDeviceThe default system audio device. This is the same as the device created when no parameter is passed to the Device constructor.
DSoundHelper.DefaultVoicePlaybackDeviceThe default voice communications device. Typically this is a secondary device such as a USB headset with microphone.

The object cannot be created if there is no sound device or, under VxD virtual device drivers, if the sound device is under the control of an application using the standard Microsoft Win32 waveform-audio functions.

See also Capturing Waveforms.

Cooperative Levels

Because Windows is a multitasking environment, more than one application can be working with a device driver at any one time. Through the use of cooperative levels, Microsoft DirectX makes sure that each application does not gain access to the device in the wrong way or at the wrong time. Each DirectSound application has a cooperative level that determines the extent to which it is allowed to access the device.

After creating a Device object, you must set the cooperative level for the device by using the Device.SetCooperativeLevel method before you can play sounds.

DirectSound defines three cooperative levels for sound devices, represented by the values of the CooperativeLevel enumeration.

Normal Cooperative Level

At the normal cooperative level, the application cannot set the format of the primary buffer, write to the primary buffer, or compact the on-board memory of the device. All applications at this cooperative level use a primary buffer format of 22 kHz, stereo sound, and 8-bit samples, so that the device can switch between applications as smoothly as possible.

Priority Cooperative Level

When using a DirectSound device with the priority cooperative level, the application has first rights to hardware resources, such as hardware mixing, and can set the format of the primary sound buffer and compact the on-board memory of the device.

Game applications should use the priority cooperative level in almost all circumstances. This level gives the most robust behavior while allowing the application control over sampling rate and bit depth. The priority cooperative level also allows audio from other applications, such as IP telephony, to be heard along with the audio from the game.

Write-primary Cooperative Level

The highest cooperative level is write-primary. When using a DirectSound device with this cooperative level, your application has direct access to the primary sound buffer. In this mode, the application must write directly to the primary buffer. Secondary buffers cannot be played while this is happening.

An application must be set to the write-primary level in order to obtain direct write access to the audio samples in the primary buffer. If the application is not set to this level, then all calls to the Buffer.Write or the Buffer.Read method will fail.

When your application is set to the write-primary cooperative level and gains the foreground, all secondary buffers for other applications are stopped and marked as lost. When your application in turn moves to the background, its primary buffer is marked as lost and must be restored when the application again moves to the foreground.

You cannot set the write-primary cooperative level if a DirectSound driver is not present on the user's system. To determine whether this is the case, check the Caps.EmulateDriver property of Device.Caps. If EmulateDriver is true, the DirectSound driver is being emulated for the device, and the write-primary level cannot be set.

Device Capabilities

DirectSound enables your application to retrieve the hardware capabilities of the sound device. Most applications will not need to do this, because DirectSound automatically takes advantage of any available hardware acceleration. However, high-performance applications can use the information to scale their sound requirements to the available hardware. For example, an application might choose to play more sounds if hardware mixing is available than if it is not.

After creating a Device object, your application can retrieve the capabilities of the sound device from the Device.Caps property. The Caps structure contains information about the performance and resources of the sound device, including the maximum resources of each type and the resources that are currently available.

If your application scales to hardware capabilities, you should check the Caps property after every buffer allocation to determine if there are enough resources to create the next buffer.

Speaker Configuration

DirectSound uses the speaker configuration-that is, the position of the speakers relative to the listener-to optimize 3-D effects for the user's sound system.

In Microsoft Windows 98, Windows 2000, and later operating systems, the speaker configuration can be set by the user in Control Panel. An application can retrieve this value from the Device.SpeakerConfig property. Although this property can be set, applications should not do so, as this is a global setting that affects other users and applications.

Compacting Hardware Memory

As long as it has at least the priority cooperative level, your application can use the Device.Compact method to move any on-board sound memory into a contiguous block to make the largest portion of free memory available. This method is not useful on most modern sound cards, which use system memory.