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-8: Using the DuplicateSoundBuffer method
    var

      DXSound: IDirectSound;

      Sound: IDirectSoundBuffer;

      {the array of duplicated sound buffers}

      SoundArray: array[0..5] of IDirectSoundBuffer;

      {stores the current index into the array}

      CurSound: Integer;

    procedure TForm1.FormCreate(Sender: TObject);

    var

      iCount: Integer;

    begin

      {create the DirectSound object}

      DirectSoundCreate(nil, DXSound, nil);

      {set its cooperative level}

      DXSound.SetCooperativeLevel(Handle, DSSCL_NORMAL);

      {load in the example sound}

      Sound := DSLoadSound(DXSound, ExtractFilePath(ParamStr(0))+‘Sample.wav’,

                           FALSE);

      {create several duplicates of the original sound}

      for iCount := 0 to 5 do

        DXSound.DuplicateSoundBuffer(Sound, SoundArray[iCount]);

      {set the index to the first element}

      CurSound := 0;

    end;

    procedure TForm1.Button1Click(Sender: TObject);

    begin

      {simply play the original buffer from the beginning. results in a stutter

       if played rapidly}

      Sound.SetCurrentPosition(0);

      Sound.Play(0, 0, 0);

    end;

    procedure TForm1.Button2Click(Sender: TObject);

    begin

      {increment the index and wrap it around if necessary}

      Inc(CurSound);

      if CurSound>5 then

        CurSound := 0;

      {play a duplicated buffer from the beginning}

      SoundArray[CurSound].SetCurrentPosition(0);

      SoundArray[CurSound].Play(0, 0, 0);

    end;
Buffer Controls The IDirectSoundBuffer interface contains several methods by which the application can control certain aspects of the sound. Specifically, an application can control pan, frequency, and volume. This allows a developer to implement several special sound effects that can greatly enhance a game. For example, the pan control can be used to move the sound of an engine whine from side to side as a spaceship crosses the screen. Volume could be used to reduce and finally eliminate an engine whine as a ship moves farther away. The frequency could even be adjusted up or down to indicate the speed of an engine, or perhaps even damage. Specifically, pan is controlled through the GetPan and SetPan methods, frequency is controlled through the GetFrequency and SetFrequency methods, and volume is controlled through the GetVolume and SetVolume methods. All methods take but a single parameter. Pan and volume are expressed in relative terms, but frequency is expressed in hertz. All attributes have an acceptable range, and pan and volume have a neutral value, which is illustrated in Table 9-2. The desired sound buffer controls are specified when the IDirectSoundBuffer object is created. As mentioned previously, the dwFlags member of the TDSBufferDesc structure can be set to a combination of values that indicate the memory location of the sound buffer and other attributes. The three flags used to give control of a buffer’s pan, frequency, and volume are illustrated in Table 9-2. Additionally, the DBSCAPS_CTRLALL or the DBSCAPS_CTRLDEFAULT flags can be used to indicate that the buffer has access to all controls or the pan, frequency, and volume controls, respectively.
| Caution: As an issue of performance, buffers with additional controls require additional processing time for real-time modification of the sound data. Therefore, it is suggested that only the specific control flags truly needed for a buffer be used, and the DBSCAPS_CTRLALL or DBSCAPS_CTRLDEFAULT flags should only be used for buffers that actually need all controls.
Table 9-2: Pan, frequency, and volume ranges and neutral values
Control | Flag | Neutral Value | Range
Frequency | DSBCAPS_CTRLFREQUENCY | None | Software buffers: DSBFREQUENCY_MIN to DSBFREQUENCY_MAX. Hardware buffers: dwMinSecondarySample rate to dwMaxSecondarySampleRate (see the GetCaps method)
Pan | DSBCAPS_CTRLPAN | DSBPAN_CENTER | DSBPAN_LEFT to DSBPAN_RIGHT
Volume | DSBCAPS_CTRLVOLUME | DSBVOLUME_MAX | DSBVOLUME_MIN to DSBVOLUME_MAX
The following example demonstrates how to create a sound buffer using the pan, volume, and frequency controls, retrieve their settings, and modify their values in real time. Listing 9-9: Using buffer controls for special effects
    procedure TForm1.FormCreate(Sender: TObject);

    var

      Audio: PByte;

      Junk: Pointer;

      NumBytesLocked: DWORD;

      JunkBytes: DWORD;

      WaveFormat: PWaveFormatEx;

      mmioHndle: HMMIO;

      ChunkInfo,

      ChunkInfoParent: TMMCKInfo;

      BufDesc: TDSBufferDesc;

      Pos: LongInt;

      FreqPos: DWORD;

    begin

      {create the DirectSound object}

      DirectSoundCreate(nil, DXSound, nil);

      {set its cooperative level high enough to allow the application to

       change the format of the primary buffer}

      DXSound.SetCooperativeLevel(Handle, DSSCL_NORMAL);

      {open the WAV file}

      WaveOpenFile(PChar(ExtractFilePath(ParamStr(0))+‘Example.wav’), mmioHndle,

                   WaveFormat, @ChunkInfoParent);

      {begin reading WAV file data}

      WaveStartDataRead(mmioHndle, @ChunkInfo, @ChunkInfoParent);

      {initialize the sound buffer description structure, indicating the

       controls we wish to use}

      FillMemory(@BufDesc, SizeOf(TDSBufferDesc), 0);

      BufDesc.dwSize := SizeOf(TDSBufferDesc);

      BufDesc.dwFlags := DSBCAPS_STATIC or DSBCAPS_CTRLFREQUENCY or

                         DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME;

      BufDesc.dwBufferBytes := ChunkInfo.cksize;

      BufDesc.lpwfxFormat := WaveFormat;

      {create the sound buffer}

      DXCheck( DXSound.CreateSoundBuffer(BufDesc, Sound, nil) );

      {copy the sound data into the buffer}

      DXCheck( Sound.Lock(0, 0, Pointer(Audio), NumBytesLocked, Junk, JunkBytes,

                          DSBLOCK_ENTIREBUFFER) );

      WaveReadFile(mmioHndle, NumBytesLocked, Audio, @ChunkInfo, JunkBytes);

      DXCheck( Sound.Unlock(Audio, NumBytesLocked, nil, 0) );

      {close the WAV file}

      WaveCloseReadFile(mmioHndle, WaveFormat);

      {initialize the Pan trackbar}

      tbrPan.Min := DSBPAN_LEFT;

      tbrPan.Max := DSBPAN_RIGHT;

      Sound.GetPan(Pos);

      tbrPan.Position := Pos;

      {initialize the Volume trackbar}

      tbrVolume.Min := DSBVOLUME_MIN;

      tbrVolume.Max := DSBVOLUME_MAX;

      Sound.GetVolume(Pos);

      tbrVolume.Position := Pos;

      {initialize the Frequency trackbar}

      tbrFrequency.Max := DSBFREQUENCY_MAX;

      tbrFrequency.Min := DSBFREQUENCY_MIN;

      Sound.GetFrequency(FreqPos);

      tbrFrequency.Position := FreqPos;

      {begin playing the sound}

      Sound.Play(0, 0, DSBPLAY_LOOPING);

    end;

    procedure TForm1.tbrPanChange(Sender: TObject);

    begin

      {set the Pan position}

      Sound.SetPan(tbrPan.Position);

    end;

    procedure TForm1.tbrVolumeChange(Sender: TObject);

    begin

      {set the Volume position}

      Sound.SetVolume(tbrVolume.Position);

    end;

    procedure TForm1.tbrFrequencyChange(Sender: TObject);

    begin

      {set the Frequency}

      Sound.SetFrequency(tbrFrequency.Position);

    end;
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.