Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
Listing 9-2: Enumerating audio output devices
    {the user-defined enumeration function. note that the stdcall keyword must be

     used before Windows can call this function correctly}

    function EnumSoundDevices(lpGuid: PGUID;               // the device GUID

                              lpstrDescription: PAnsiChar; // the description

                              lpstrModule: PAnsiChar;      // the module name

                              lpContext: Pointer           // the user-defined info

                              ): BOOL; stdcall;            // stdcall must be used

    begin

      {add the description and the module name of the enumerated driver to the

       list box. the first one will be the primary sound driver, and will not

       contain a module name}

      Form1.lbxSoundDevices.Items.Add(‘lpstrDescription+’ - +lpstrModule);

      {indicate that we wish to continue enumeration}

      Result := TRUE;

    end;

    procedure TForm1.FormCreate(Sender: TObject);

    begin

      {begin enumerating all available audio drivers}

      DirectSoundEnumerate(EnumSoundDevices, nil);

    end;
Figure 9-3: The list of drivers retrieved from DirectSoundEnumerate Creating the DirectSound Object To begin actually using DirectSound functionality, a DirectSound object must be created. This is accomplished by calling the DirectSoundCreate function. The DirectSoundCreate function is defined as:
    function DirectSoundCreate(

    lpGuid: PGUID;                // the sound device GUID

    out ppDS: IDirectSound;       // the IDirectSound object to be instantiated

    pUnkOuter: IUnknown           // unused

    ): HResult;                   // returns a DirectX error code
The first parameter is a pointer to the GUID of the desired audio device (retrieved through enumeration as explained above, or set to nil to indicate the primary sound driver). The second parameter is an IDirectSound interface which will be instantiated when the function returns. The final parameter is used for COM aggregation and should be set to nil.
| Caution: It is possible to create multiple DirectSound objects, but this is unadvisable. When an additional DirectSound object is created, its cooperative level (explained below) overrides that of any previously created objects. A single DirectSound object should be created for the duration of the application.
Setting the Cooperative Level Once the DirectSound object is created, the application should immediately set its cooperative level. The cooperative level determines how the audio device will be shared between the current application and others, as well as access to certain functionality. The cooperative level is set by calling the SetCooperativeLevel method of the IDirectSound interface. The SetCooperativeLevel method is defined as:
    function SetCooperativeLevel(

    hwnd: HWND;                     // a window handle

    dwLevel: DWORD                  // the cooperative level flags

    ): HResult;                     // returns a DirectX error code
The first parameter is a handle to the application’s main window. The second parameter contains a series of flags indicating the desired cooperative level. The flags indicating each cooperative level are described in the table below. Most applications will use the Normal cooperative level, as this allows the most compatible operation with other applications that use the sound card. However, games will normally use the Priority or Exclusive levels, as these allow for the most efficient and optimized use of audio hardware. The cooperative levels below are listed in ascending order, and each level has the abilities of all levels below it.
Table 9-1: DirectSound cooperative levels
Level | Flag | Abilities | Restrictions
Normal | DSSCL_NORMAL | Can play secondary sound buffers. | Cannot set the format of the primary sound buffer, cannot write to the primary sound buffer, and cannot call the Compact method.
Priority | DSSCL_PRIORITY | Can change the format of the primary buffer, has first rights to hardware resources, and can call the Compact method. |
Exclusive | DSSCL_EXCLUSIVE | Mutes all sound output from background applications. |
Write Primary | DSSCL_WRITEPRIMARY | Can write directly to the primary sound buffer. | Cannot play secondary sound buffers.
| Note: When using DirectDraw in conjunction with DirectSound, the window handle passed to the SetCooperativeLevel method of the IDirectSound object must also be sent to the SetCooperativeLevel of the IDirectDraw4 object.
Retrieving Audio Device Capabilities Most applications will be concerned with simply creating a DirectSound object and several secondary buffers, and outputting sound, letting DirectSound take care of the details. However, when creating high-performance, CPU-intensive games, it may be necessary to take a more active role in defining how the system will use available hardware resources. This is where the GetCaps method of the IDirectSound object comes in handy. The GetCaps method is defined as:
    function GetCaps(

    var lpDSCaps: TDSCaps                  // a TDSCaps structure

    ): HResult;                            // returns a DirectX error code
The only parameter for this function is a TDSCaps structure that is initialized with the capabilities of the audio device when the function returns. Several members of this structure, such as the dwMaxHwMixingAllBuffers, dwMaxHwMixingStaticBuffers, and dwTotalHwMemBytes members, can be used to optimize performance by determining what sounds can be placed in hardware buffers in the most efficient manner. Unfortunately, some members of this structure may not be universally supported by all drivers, and the values returned by some members may just be estimates. The best way to use the GetCaps method is to call it after creating each hardware sound buffer.
| Note: The dwSize member of the TDSCaps structure must be initialized to SizeOf(TDSCaps) before calling the GetCaps method.
Previous | Table of Contents | Next

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.