DirectSound

digital sound –

    recording – create your sound originals with 16bit samples at 22kHz, mono. DirectSound works best with mono sound.

 

components:

·       a run-time .dll,

·       the compile-time library  DSOUND.LIB 

·       and the header DSOUND.H.

 

To use you need to :

·       create a DirectSound object, a number of secondary sound buffers,

·       load them with sounds,

·       then play any sound you want.

 

create DS object

HRESULT DirectSoundCreate(<ptr soundCard>,// null = default                

                                                   <DS obj>,NULL)

 

LPDIRECTSOUND lpds;  // DS ptr

if (DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK)

{   // error

}

// after you’re done using release

lpds->Release();

 

Set the cooperation level:

Normal Coop: most cooperative of all settings. While your app. has focus it can share the sound system with other apps. (use this most of the time)

Priority Coop: you have first access to all hardware. (only necessary if you need to reset the data format of the primary buffer)

Exclusive Coop: same as priority, but only when you have the focus will your app will be audible.

Write_Primary Coop: highest priority. You have total control & must control the primary buffer yourself to hear anything. (don’t use)

 

lpds->SetCooperativeLevel(<hwnd>,<level>);

 DSSCL_NORMAL/PRIORITY/EXCLUSIVE/WRITEPRIMARY

 

returns DS_OK if it works

 

The primary buffer represents the hardware itself and as long as you don’t select DSSCL_ WRITEPRIMARY, directSound will take care of everything (even creating the primary buffer).

 

Secondary buffers represent the actual sounds to be played.

They can be any size. Can be stored on sound card(SRAM)  or in RAM. Sounds stored in SRAM buffers take less system resources.

 

2 kinds of sound buffers

Static sound buff: sounds you plan to keep around & play over and over. (good candidate for SRAM)

streaming sound buff: play whole CD (not enough RAM/SRAM) read in chunks and stream it out. Ring buffer is used w/read & write ptrs.

 

Create a direct sound descriptor

 

typedef struct

{ DWORD dwSize;

   DWORD dwFlags;  // control flags

   DWORD dwBufferBytes; // size of buf in bytes

   DWORD dwReserved;     // unused

   LPWAVEFORMATEX plwfxFormat;

} DSBUFFERDESC, *LPDSBUFFERDESC;

 

BUFFER CREATION flags

DSBCAPS_CTRALL

have all control capabilities

   _CTRLDEFAULT

have default control options. Same as setting CTRLPAN, CTRLVOLUME, CTRLFREQUENCY

   _CTRLFREQUENCY

have freq control

   _CTRLPAN

have pan-control capability

   _CTRLVOLUME

volume control

   _STATIC

static sound buff

   _LOCHARDWARE

use hardware mixing & memory  if memory is available

   _LOCSOFTWARE

forces memory storage & software mixing even if STATIC is specified

   _PRIMARYBUFFER

(don’t use)

 

 

 

In general use: _CTRLDEFAULT | _STATIC |  _LOCSOFTWARE

 

 

WAVEFORMATEX

Contains info about the sound

 

typedef struct // DESCRIPTION OF THE SOUND

{ WORD wFormatTag;           // always WAVE_FORMAT_PCM

   WORD nChannels;               // # of audio channels 1 or 2

   DWORD nSamplesPerSec;  // samples per second

   DWORD nAvgBytesPerSec;// avg data rate

   WORD nBlockAlign;           // nchannels * bytespersample

   WORD wBitsPerSample;     // bits per sample

   WORD cbSize;                     // set to 0

} WAVEFORMATEX;

 

Clear the structure & the fill it with the values to be used, just like a DD structure.

 

LPDIRECTSOUNDBUFFER lpdsbuffer;

DSBUFFERDESC  dsbd;

 

CreateSoundBuffer(<buf desc ptr>, &lpdsbuffer, NULL);

 

Create with:

    lpdsbuffer->(&dsbd, &lpdsbuffer, NULL);

 

as always Release() when done

 

Before you can use it, you must load it with a sound.

 

Since buffer is circular it must be locked.

Lock(<write pos>,<lock size>,<chunk1 ptr>,<len1>,<chunk2 ptr>,

          <len2>, <flags>);

 

example:

// lock 1000 byte buff & write 100 bytes

UCHAR * audio1, * audio2;

int  audioLen1, audioLen2;

// audio2 = &buff  audio1 = audio2+100, len1=100, len2=900

 

// lock whole buffer

if (lpdsbuffer->Lock(0,1000,(void**) &audio1, audioLen1,

      (void**) &audio2, audioLen2, DSBLOCK_ENTIREBUFFER)

          != DS_OK)  // ERROR

where:  UCHAR audio1, audio2;  // ptrs to sound bits

 

// copy sound into loc audio1

 

// unlock

lpdsbuffer->Unlock(audio1, audioLen1,audio2, audioLen2)

 

Playing a sound

lpdsbufferLaser->Play(0,0, <flags>);  //parm1&2 always 0

// flags = DBSPLAY_LOOPING or 0 to play once

 

lpdsbufferLaser->Stop();  // dah!

 

VOLUME

HRESULT SetVolume(LONG lVolume); // attenuation in decibels

 

lVolume works backwards 0 = max, -10,000 = off

 

// trick to set to 0 – 100 (inaudible – max)

#define DSVOLUME(vol)((dword)(-30*(100-vol)))

 

lpdsbuffer->SetVolume(DSVOLUME(50));  // 50% volume

 

 

FREQUENCY – setting the pitch (speed of play)

HRESULT SetFrequency(DWORD FREQ);

// freq = 100 – 100,000 hz

 

PANNING – raising/lowering volume in left/right speaker to sim movement

HRESULT SetPan(LONG pan); // pan = -10,000 – 10,000

-10,000 all right, 0 even, 10,000 all left

 

unfortunately DirectSound has no call to load a sound file, the users must write their own .wav or .voc (creative labs format) loaders

 

 


// Loading and playing a voc file

// with real-time manipulation

 

// INCLUDES

#define WIN32_LEAN_AND_MEAN 

#include <windows.h>   // include important windows stuff

 

#include <dsound.h>

#define NVB_SIZE      6 // size of new voice block in bytes

 

// this structure holds a loaded sound

typedef struct VOC_FILE_TYP

{

   int sampleRate; // sample rate of sound

   int length;      // length of sound data

   LPDIRECTSOUNDBUFFER lpdsbuffer; // ptr to sound buffer

} VOC_FILE, *VOC_FILE_PTR;

 

int LoadVOC(char *vocFile, VOC_FILE_PTR vocData);

 

LPDIRECTSOUND           lpds;           // directsound interface ptr

DSBUFFERDESC            dsbd;           // directsound description

DSCAPS                  dscaps;         // directsound caps

HRESULT                 dsresult;       // general directsound result

DSBCAPS                 dsbcaps;        // directsound buffer caps

LPDIRECTSOUNDBUFFER     lpdsbprimary,   // won't need this normally

                    lpdsbsecondary;  // the sound buffers

WAVEFORMATEX        pcmwf;          // generic waveformat structure

VOC_FILE            workVoc;        // a working voc file

HWND                freqHwnd,      // window handles for controls

                    volumeHwnd,

                    panHwnd;

 

LRESULT CALLBACK WindowProc(HWND hwnd,

                            UINT msg,

                            WPARAM wparam,

                            LPARAM lparam)

{

  // this is the main message handler of the system

  PAINTSTRUCT     ps;            // used in WM_PAINT

  HDC             hdc;     // handle to a device context

 

  // what is the message

  switch(msg)

  {  

      case WM_CREATE:

    {

            // do initialization stuff here

            return(0);

      } break;

 

    case WM_PAINT:

    {

         // start painting

         hdc = BeginPaint(hwnd,&ps);

       

         // first the static text

         // set the color

         SetTextColor(hdc,RGB(0,0,255));

         SetBkColor(hdc,RGB(0,0,0));

         SetBkMode(hdc,OPAQUE);

 

         TextOut(hdc,160-5*7,40-20,"VOLUME ",strlen("VOLUME "));

         TextOut(hdc,160-5*13,100-20,"PLAYBACK RATE",strlen(

                  "PLAYBACK RATE"));

         TextOut(hdc,160-5*14,160-20,

                  "STEREO PANNING  ",strlen("STEREO PANNING   "));

         // end painting

         EndPaint(hwnd,&ps);

         return(0);

    } break;

 

    case WM_HSCROLL:

    case WM_VSCROLL:

      {

        int nscrollcode    = (int)LOWORD(wparam); // scroll bar value

        int npos           = (int)HIWORD(wparam); // scroll box pos

        HWND hwndscrollbar = (HWND)lparam;        // scroll bar

 

        // get the dc for printing

        hdc = GetDC(hwnd);

       

        // set the color

        SetTextColor(hdc,RGB(0,0,255));

        SetBkColor(hdc,RGB(0,0,0));

        SetBkMode(hdc,OPAQUE);

               

        // make sure that the scroll bar is being tracked

        if (nscrollcode==SB_THUMBPOSITION ||

            nscrollcode==SB_THUMBTRACK)

        {

          // what scroll bar sent message

          if (hwndscrollbar==volumeHwnd)

           {

             // re-position scroll bar

             SetScrollPos(volumeHwnd, SB_CTL,npos,TRUE);

             sprintf(buffer,"VOLUME=%d       ",-npos);

          

             // output text

             TextOut(hdc,160-5*7,40-20,buffer,strlen(buffer));

 

             // set the volume

             workVoc.lpdsbuffer->SetVolume(-npos);

          }

          else if (hwndscrollbar==freqHwnd)

          {

             // re-position scroll bar

             SetScrollPos(freqHwnd, SB_CTL,npos,TRUE);

             sprintf(buffer,"PLAYBACK RATE=%d      ",npos);

    

             // output text

             TextOut(hdc,160-5*13,100-20,buffer,strlen(buffer));

 

             // set the frequency

             workVoc.lpdsbuffer->SetFrequency(npos);

          }

         

          else if (hwndscrollbar==panHwnd)

          {

             // re-position scroll bar

             SetScrollPos(panHwnd, SB_CTL,npos,TRUE);

             sprintf(buffer,"STEREO PANNING=%d      ",-(npos-10000));

          

             // output text

             TextOut(hdc,160-5*14,160-20,buffer,strlen(buffer));

 

             // set the stereo panning

             workVoc.lpdsbuffer->SetPan(-(npos-10000));

              } // end if

        } // end if

 

        // release the dc

        ReleaseDC(hwnd,hdc);

 

        // message has been processed

        return(0);

      } break;

 

      case WM_DESTROY:

      {

            // kill the application            

            PostQuitMessage(0);

            return(0);

      } break;

 

      default:break;

   } // end switch

 

  // process any messages that we didn't take care of

  return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

 

// WINMAIN

 

int WINAPI WinMain(     HINSTANCE hinstance,

                        HINSTANCE hprevinstance,

                        LPSTR lpcmdline,

                        int ncmdshow)

{

  WNDCLASS winclass;    // this will hold the class we create

  HWND      hwnd;            // generic window handle

  MSG       msg;       // generic message

  HDC        hdc;       // generic dc

  PAINTSTRUCT ps;     // generic paintstruct

 

  // first fill in the window class stucture

  winclass.style              = CS_DBLCLKS | CS_OWNDC |

                                CS_HREDRAW | CS_VREDRAW;

  winclass.lpfnWndProc  = WindowProc;

  winclass.cbClsExtra         = 0;

  winclass.cbWndExtra         = 0;

  winclass.hInstance          = hinstance;

  winclass.hIcon              = LoadIcon(NULL, IDI_APPLICATION);

  winclass.hCursor            = LoadCursor(NULL, IDC_ARROW);

  winclass.hbrBackground      = (HBRUSH)GetStockObject(BLACK_BRUSH);

  winclass.lpszMenuName       = NULL;

  winclass.lpszClassName      = WINDOW_CLASS_NAME;

 

  // register the window class

  if (!RegisterClass(&winclass))

      return(0);

 

  // create the window, note the use of WS_POPUP

  if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class

                          "WinX Game Console - 2001", // title

                          WS_OVERLAPPEDWINDOW | WS_VISIBLE,

                          0,0,         // x,y

                          WINDOW_WIDTH,  // width

                          WINDOW_HEIGHT, // height

                          NULL,        // handle to parent

                          NULL,        // handle to menu

                          hinstance,// instance

                          NULL)))   // creation parms

       return(0);

  // save the window handle and instance in a global

  mainWindowHandle = hwnd;

  mainInstance      = hinstance;

 

  // create some scroll controls to change volume, frequency

  // and panning

 

  // create the volume control scroller

  volumeHwnd = CreateWindow("SCROLLBAR", // class

                          "",     // title

                          WS_CHILD | WS_VISIBLE,

                          80,40,        // x,y

                          160,       // width

                          16,      // height

                          hwnd,         // handle to parent

                          NULL,         // handle to menu

                          hinstance,// instance

                          NULL);    // creation parms

 

  // create the frequency control scroller

  freqHwnd = CreateWindow("SCROLLBAR", // class

                          "",     // title

                          WS_CHILD | WS_VISIBLE,

                          80,100,       // x,y

                          160,       // width

                          16,      // height

                          hwnd,         // handle to parent

                          NULL,         // handle to menu

                          hinstance,// instance

                          NULL);    // creation parms

 

  // create the stereo panning control scroller

  panHwnd = CreateWindow("SCROLLBAR", // class

                          "",     // title

                          WS_CHILD | WS_VISIBLE,

                          80,160,   // x,y

                          160,      // width

                          16,       // height

                          hwnd,         // handle to parent

                          NULL,         // handle to menu

                          hinstance,// instance

                          NULL);    // creation parms

 

 

  // set range and value of each scroll bar

  SetScrollRange(volumeHwnd, SB_CTL, 0, 4000,TRUE);

  SetScrollPos(volumeHwnd, SB_CTL,0,TRUE);

 

  SetScrollRange(freqHwnd, SB_CTL, 0, 50000,TRUE);

  SetScrollPos(freqHwnd, SB_CTL,11000,TRUE);

 

  SetScrollRange(panHwnd, SB_CTL, 0, 20000,TRUE);

  SetScrollPos(panHwnd, SB_CTL,10000,TRUE);

 

  // perform all game console specific initialization

  // start up the directsound sound

  GameInit();

 

  // enter main event loop

  while(1)

  {

      if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

      {

        // test if this is a quit

        if (msg.message == WM_QUIT)

           break;

     

        // translate any accelerator keys

        TranslateMessage(&msg);

 

        // send the message to the window proc

        DispatchMessage(&msg);

      } // end if

   

    // main game processing goes here

    GameMain();

  } // end while

 

  // shutdown game and release all resources

  GameShutdown();

 

  // return to Windows like this

  return(msg.wParam);

} // end WinMain

 

// WINX GAME PROGRAMMING CONSOLE FUNCTIONS

int GameInit(void *parms)

{

  // this function is where you do all the initialization

  // for your game

 

  // create a directsound object

  if (DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK )

      return(0);

 

  // set cooperation level

  if (lpds->SetCooperativeLevel(mainWindowHandle,DSSCL_NORMAL)!=DS_OK)

      return(0);

 

  // load a voc file in

  if (LoadVOC("DAVE.VOC",&workVoc))

  {

    // start the voc playing in looping mode

    workVoc.lpdsbuffer->Play(0,0,DSBPLAY_LOOPING);

  } // end if

 

  // return success

  return(1);

} // end GameInit

 

int GameShutdown(void *parms)

{

  // this function is where you shutdown your game and

  // release all resources that you allocated

 

  // release the directsoundobject

  if (lpds!=NULL)

     lpds->Release();

 

  // release the sound buffer

  if (workVoc.lpdsbuffer)

     workVoc.lpdsbuffer->Release();

 

  // return success

  return(1);

} // end GameShutdown

 

int GameMain(void *parms)

{

  // this is the workhorse of your game it will be called

  // continuously in real-time this is like main() in C

  // all the calls for you game go here!

 

  // check of user is trying to exit

  if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))

     PostMessage(mainWindowHandle, WM_DESTROY,0,0);

 

  // return success

  return(1);

} // end GameMain

 

int LoadVOC(char *filename,VOC_FILE_PTR vocData)

{

  // this function creates a sound from the send voc_file_ptr

  // description and returns a pointer to it

 

  int  dataOffset,   // working var

       playbackRate, // temp playback rate

       dataLength;   // used to hold data length

 

  ULONG     bytesread = 0; // actual size of total file

  HANDLE    fileHandle;   // file handle

  UCHAR     *sndBuffer;   // temporary sound buffer to hold voc data

 

  UCHAR     *audioPtr1=NULL, // pointer to lock

            *audioPtr2=NULL;

 

  DWORD     audioLength1=0,  // lengths to lock

            audioLength2=0;

 

  // load the voc file off disk

  if (!(fileHandle = CreateFile(filename,

            GENERIC_READ,           // access (read-write) mode

            0,                      // share mode

            NULL,                   // pointer to security descriptor

            OPEN_EXISTING,          // how to create

            FILE_ATTRIBUTE_NORMAL,  // file attributes

            NULL)))                 // file with attributes to copy 

      return(0);

 

  // allocate a large enough temporary buffer (hold 50 secs)

  sndBuffer = (UCHAR *)malloc(640000);

 

  // now read in the data

  ReadFile(fileHandle, sndBuffer, 640000, &bytesread, NULL);

 

  // access all values

  dataOffset      = sndBuffer[20];

  playbackRate    = (-1000000/(sndBuffer[dataOffset+4]-256));

  dataLength      = ((*(int *)(sndBuffer+dataOffset)) >> 8);

 

  // set rate and size in data structure

  vocData->sampleRate  = playbackRate;

  vocData->length      = dataLength;

 

  // close the file

  CloseHandle(fileHandle);

 

  // step three: create the sound buffer and copy voc data into buffer

  // set up the format data structure

  memset(&pcmwf, 0, sizeof(WAVEFORMATEX));

 

  pcmwf.wFormatTag      = WAVE_FORMAT_PCM;

  pcmwf.nChannels       = 1;

  pcmwf.nSamplesPerSec  = 11025;

  pcmwf.nBlockAlign     = 1;

  pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;

  pcmwf.wBitsPerSample  = 8;

  pcmwf.cbSize          = 0;

 

  // create the sound buffer

  dsbd.dwSize           = sizeof(DSBUFFERDESC);

  dsbd.dwFlags          = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | 

                          DSBCAPS_CTRLFREQUENCY

                          | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE ;

  dsbd.dwBufferBytes    = dataLength - NVB_SIZE;

  dsbd.lpwfxFormat      = &pcmwf;

 

  if (lpds->CreateSoundBuffer(&dsbd,&(vocData->lpdsbuffer),NULL)!=DS_OK)

      return(0);

 

  // copy data into sound buffer

  if ((vocData->lpdsbuffer)->Lock(0, dataLength - NVB_SIZE,            

            (void **) &audioPtr1, &audioLength1, (void **)&audioPtr2,

            &audioLength2, DSBLOCK_FROMWRITECURSOR)!=DS_OK)

       return(0);

 

 

  // copy first section of circular buffer

  memcpy(audioPtr1, sndBuffer+dataOffset+NVB_SIZE, audioLength1);

 

  // copy last section of circular buffer

  memcpy(audioPtr2, sndBuffer+dataOffset+ NVB_SIZE + audioLength1),

         audioLength2);

 

  // unlock the buffer

  if ((vocData->lpdsbuffer)->Unlock(audioPtr1, audioLength1, audioPtr2,

                                    audioLength2)!=DS_OK)

        return(0);

 

  // release the temp buffer

  free(sndBuffer);

 

  // return success

  return(1);

} // end LoadVoc

 


 

        if (scan_buffer[scan_x] == scan_color)

            return(1);

        } // end for x

 

      // move down a line

      scan_buffer+=scan_lpitch;

    } // end for y

 

  // return failure

  return(0);

} // end Color_Scan

 

// WINX GAME PROGRAMMING CONSOLE FUNCTIONS

int GameInit(void *parms)

{

  // this function is where you do all the initialization

  // for your game

 

  int index;         // looping var

  char filename[80]; // used to build up files names

 

  // initialize directdraw

  DD_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);

 

  // keyboard creation section

  // first create the direct input object

  if (DirectInputCreate(mainInstance,DIRECTINPUT_VERSION,&lpdi,NULL)!=DI_OK)

      return(0);

 

  // create a keyboard device 

  if (lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey, NULL)!=DI_OK)

     return(0);

 

  // set cooperation level

  if (lpdikey->SetCooperativeLevel(mainWindowHandle,

                 DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)

      return(0);

 

  // set data format

  if (lpdikey->SetDataFormat(&c_dfDIKeyboard)!=DI_OK)

     return(0);

 

 

Loading Sounds from disk

Use the authors:

   Int  DSound_Load_Wav(<filename>, <flags>);

 

This routine loads a .wav, sets up a sound buff & loads it into memory. Return value is the SoundID.

 

 

T3DLIB3 Sound lib support

 

#define DM_NUM_SEGMENTS 64 // number of midi segments that can be cached in memory

 

// midi object state defines

#define MIDI_NULL     0   // this midi object is not loaded

#define MIDI_LOADED   1   // this midi object is loaded

#define MIDI_PLAYING  2   // this midi object is loaded and playing

#define MIDI_STOPPED  3   // this midi object is loaded, but stopped

 

 

#define MAX_SOUNDS     256 // max number of sounds in system at once

 

// digital sound object state defines

#define SOUND_NULL     0 // " "

#define SOUND_LOADED   1

#define SOUND_PLAYING  2

#define SOUND_STOPPED  3

 

// directx 7.0 compatibility

 

#ifndef DSBCAPS_CTRLDEFAULT

#define DSBCAPS_CTRLDEFAULT (DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME )

#endif

 

// MACROS /////////////////////////////////////////////////

 

#define DSVOLUME_TO_DB(volume) ((DWORD)(-30*(100 - volume)))

 

// Convert from multibyte format to Unicode using the following macro:

#define MULTI_TO_WIDE( x,y )  MultiByteToWideChar( CP_ACP,MB_PRECOMPOSED, y,-1,x,_MAX_PATH);

 

// initializes a direct draw struct

#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

 

 

// TYPES //////////////////////////////////////////////////

 

// this holds a single sound

typedef struct pcm_sound_typ

      {

      LPDIRECTSOUNDBUFFER dsbuffer;   // the ds buffer containing the sound

      int state;                      // state of the sound

      int rate;                       // playback rate

      int size;                       // size of sound

      int id;                         // id number of the sound

      } pcm_sound, *pcm_sound_ptr;

 

// directmusic MIDI segment

typedef struct DMUSIC_MIDI_TYP

{

IDirectMusicSegment        *dm_segment;  // the directmusic segment

IDirectMusicSegmentState   *dm_segstate; // the state of the segment

int                        id;           // the id of this segment              

int                        state;        // state of midi song

 

} DMUSIC_MIDI, *DMUSIC_MIDI_PTR;

 

 

// PROTOTYPES /////////////////////////////////////////////

 

// directsound

int DSound_Load_WAV(char *filename, int control_flags = DSBCAPS_CTRLDEFAULT);

int DSound_Replicate_Sound(int source_id);

int DSound_Play(int id, int flags=0, int volume=0, int rate=0, int pan=0);

int DSound_Stop_Sound(int id);

int DSound_Stop_All_Sounds(void);

int DSound_Init(void);

int DSound_Shutdown(void);

int DSound_Delete_Sound(int id);

int DSound_Delete_All_Sounds(void);

int DSound_Status_Sound(int id);

int DSound_Set_Volume(int id,int vol);

int DSound_Set_Freq(int id,int freq);

int DSound_Set_Pan(int id,int pan);

 

// directmusic

int DMusic_Load_MIDI(char *filename);

int DMusic_Play(int id);

int DMusic_Stop(int id);

int DMusic_Shutdown(void);

int DMusic_Delete_MIDI(int id);

int DMusic_Delete_All_MIDI(void);

int DMusic_Status_MIDI(int id);

int DMusic_Init(void);

 

// directmusic

 

// GLOBALS ////////////////////////////////////////////////

 

 

// EXTERNALS //////////////////////////////////////////////

 

extern HWND main_window_handle; // save the window handle

extern HINSTANCE main_instance; // save the instance

 

extern LPDIRECTSOUND          lpds;           // directsound interface pointer

extern DSBUFFERDESC                 dsbd;           // directsound description

extern DSCAPS                       dscaps;         // directsound caps

extern HRESULT                      dsresult;       // general directsound result

extern DSBCAPS                      dsbcaps;        // directsound buffer caps

 

extern LPDIRECTSOUNDBUFFER    lpdsbprimary;   // the primary mixing buffer

extern pcm_sound              sound_fx[MAX_SOUNDS];    // the array of secondary sound buffers

 

extern WAVEFORMATEX                 pcmwf;          // generic waveformat structure

 

// direct music globals

extern IDirectMusicPerformance    *dm_perf ;    // the directmusic performance manager

extern IDirectMusicLoader         *dm_loader;  // the directmusic loader

 

// this hold all the directmusic midi objects

extern DMUSIC_MIDI                dm_midi[DM_NUM_SEGMENTS];

extern int dm_active_id;                               // currently active midi segment

 

 

The functions:

 

·       initialize DirectSound

o      int DSound_Init(void);

·       release resources when done

o      int DSound_Shutdown(void);

·       load a sound from disk

o      int DSound_Load_WAV(char *filename, int control_flags = DSBCAPS_CTRLDEFAULT);

·       replicate w/o duplicating memory. Used to blay back-to-back

o      int DSound_Replicate_Sound(int source_id);

·       play a previously loaded sound. Send the SoundID returned by DSound_Load()

o      int DSound_Play(int id, int flags=0, int volume=0, int rate=0, int pan=0);

·       stop playing sound, SoundID

o      int DSound_Stop_Sound(int id);

·       stop playing all sounds

o      int DSound_Stop_All_Sounds(void);

·       to free up resources when you are done use:

o      int DSound_Delete_Sound(int id);

o      int DSound_Delete_All_Sounds(void);

·       to check a sounds status (DSBSTATUS_LOOPING, DSBSTATUS_PLAYING) any other value means not playing

o      int DSound_Status_Sound(int id);

·       other functions:

o      int DSound_Set_Volume(int id,int vol);

o      int DSound_Set_Freq(int id,int freq);

o      int DSound_Set_Pan(int id,int pan);