This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/WATCOM/samples/directx/cpp/dsound/dsound.cpp

348 lines
9.2 KiB
C++

//---------------------------------------------------------------------------------------
//
// Simple Windows DirectSound Example Code
//
// Jim Shaw 12/3/2004
//
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// Always include windows.h for windows programs
//---------------------------------------------------------------------------------------
#include <windows.h>
#include <dsound.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
//---------------------------------------------------------------------------------------
// Windows variables
//---------------------------------------------------------------------------------------
HWND game_window;
char game_class[]="DSNDCPPWindow";
//---------------------------------------------------------------------------------------
// DirectSound variables
//---------------------------------------------------------------------------------------
IDirectSound8 *dsound=NULL;
IDirectSoundBuffer *dsprimarybuffer=NULL;
IDirectSoundBuffer8 *sfxbuffer8=NULL;
//---------------------------------------------------------------------------------------
// Prototypes
//---------------------------------------------------------------------------------------
int init_dsound(void);
int load_wav(char *);
void shutdown_dsound(void);
//---------------------------------------------------------------------------------------
// Main Windows function
//---------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char filename[_MAX_PATH];
OPENFILENAME ofn;
BOOL res;
WNDCLASSEX clas;
int style;
RECT rect;
MSG msg;
HDC hdc;
//Here we create the Class we named above
clas.cbSize = sizeof(WNDCLASSEX);
clas.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
clas.lpfnWndProc = DefWindowProc;
clas.cbClsExtra = 0;
clas.cbWndExtra = 0;
clas.hInstance = hInstance;
clas.hIcon = NULL;
clas.hCursor = NULL;
clas.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//<- background colour of window
clas.lpszMenuName = NULL;
clas.lpszClassName = game_class;//<- the class name
clas.hIconSm = 0;
//do it!
RegisterClassEx(&clas);
//style of the window - what boxes do we need (close minimised etc)
style = WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX;
//create the window
game_window = CreateWindowEx(0, game_class, "DirectSound", style, CW_USEDEFAULT, CW_USEDEFAULT, 1,1, NULL, NULL, hInstance, 0);
//adjust the window size so that a 200 x 40 window will fit inside its frame
rect.left = rect.top = 0;
rect.right = 200;
rect.bottom = 40;
AdjustWindowRectEx(&rect, style , FALSE, 0);
SetWindowPos(game_window, NULL, 0,0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE|SWP_NOZORDER);
//show the window on the desktop
ShowWindow(game_window, nCmdShow);
filename[0] = '\0';
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.hInstance = NULL;
ofn.lpstrFilter = "WAV Files\0*.wav\0";
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = filename;
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = "Select Audio File";
ofn.Flags = OFN_FILEMUSTEXIST|OFN_EXPLORER;
ofn.nFileOffset=0;
ofn.nFileExtension=0;
ofn.lpstrDefExt="bin";
ofn.lCustData=0;
ofn.lpfnHook=NULL;
ofn.lpTemplateName="";
res = GetOpenFileName(&ofn);
if (res == 0)
return 0;
if (init_dsound() != 0)
{
MessageBox(NULL, "A problem occurred initialising DirectSound.\nCheck your sound drivers and "
"DirectX version.\nThis demo requires DirectX9.0 or better.", "DirectX Initialisation Error", MB_ICONWARNING|MB_OK);
shutdown_dsound();
return 0;
}
if (load_wav(filename) != 0)
{
MessageBox(NULL, "A problem occurred loading the WAV file\n",
"File Loading Error", MB_ICONWARNING|MB_OK);
shutdown_dsound();
return 0;
}
hdc = GetDC(game_window);
TextOut(hdc, 10,10, "Close me to stop sound!", 23);
ReleaseDC(game_window, hdc);
while (GetMessage(&msg, game_window, 0,0) >= 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
shutdown_dsound();
return 0;
}
//---------------------------------------------------------------------------------------
// Initialise DirectSound
//---------------------------------------------------------------------------------------
int init_dsound(void)
{
HRESULT err;
DSCAPS dsoundcaps;
DSBUFFERDESC dsbdesc;
WAVEFORMATEX wfx;
err = DirectSoundCreate8(NULL, &dsound, NULL);
if (err != DS_OK)
return 1;
err = dsound->SetCooperativeLevel(game_window, DSSCL_EXCLUSIVE);
if (err != DS_OK)
return 1;
memset(&dsoundcaps, 0, sizeof dsoundcaps);
dsoundcaps.dwSize = sizeof dsoundcaps;
err = IDirectSound8_GetCaps(dsound, &dsoundcaps);
if (err != DS_OK)
return 1;
// Create and set primary buffer format
memset(&dsbdesc, 0, sizeof dsbdesc);
dsbdesc.dwSize = sizeof dsbdesc;
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
err = dsound->CreateSoundBuffer(&dsbdesc, &dsprimarybuffer, NULL);
if (err != DS_OK)
return 1;
memset(&wfx, 0, sizeof wfx);
wfx.cbSize = sizeof wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
err = dsprimarybuffer->SetFormat(&wfx);
if (err != DS_OK)
return 1;
//force dsound to ALWAYS keep DMA active
err = dsprimarybuffer->Play(0, 0, DSBPLAY_LOOPING);
if (err != DS_OK)
return 1;
return 0;
}
//---------------------------------------------------------------------------------------
// Shutdown DirectSound
//---------------------------------------------------------------------------------------
void shutdown_dsound()
{
if (sfxbuffer8)
{
sfxbuffer8->Stop();
sfxbuffer8->Release();
}
if (dsprimarybuffer)
{
dsprimarybuffer->Stop();
dsprimarybuffer->Release();
}
if (dsound) dsound->Release();
}
//---------------------------------------------------------------------------------------
// Convert linear volume to DirectSound db scale
//---------------------------------------------------------------------------------------
int vol_to_db(int vol)
{
if (vol)
return (int)(20.0 * 100.0 * log10((double)vol/127.0));
return -10000;
}
//---------------------------------------------------------------------------------------
// Make a WAV FOURCC
//---------------------------------------------------------------------------------------
#define MRIFFID(a,b,c,d) (((d)<<24)|((c)<<16)|((b)<<8)|(a))
//---------------------------------------------------------------------------------------
// Load and play the given wav file
//---------------------------------------------------------------------------------------
int load_wav(char *filename)
{
unsigned int *riff;
FILE *f;
long len;
void *sfx;
// Read in the supplied file
f = fopen(filename, "rb");
if (!f)
return 1;
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
sfx = malloc(len);
if (!sfx)
{
fclose(f);
return 1;
}
fread(sfx, 1, len, f);
fclose(f);
riff = (unsigned int *)sfx;
// Check it's a RIFF WAV file
if (*riff == MRIFFID('R','I','F','F'))
{
IDirectSoundBuffer *sfxbuffer;
DSBUFFERDESC dsbufferdesc;
void *data1, *data2;
DWORD size1, size2;
unsigned char *wav_data;
unsigned int wav_size;
WAVEFORMATEX *wav_hdr;
HRESULT err;
// Strip through the WAV header looking for the WAVEFORMAT data
riff += 3;//skip length and id
while (*riff != MRIFFID('f','m','t',' '))
riff = (unsigned int *)((unsigned char *)riff + 8 + *(riff+1));
wav_hdr = (WAVEFORMATEX *)(riff+2);
// Strip through the WAV header looking for the sample data
riff = (unsigned int *)((unsigned char *)riff + 8 + *(riff+1));
while (*riff != MRIFFID('d','a','t','a'))
riff = (unsigned int *)((unsigned char *)riff + 8 + *(riff+1));
wav_data = (unsigned char *)(riff+2);
wav_size = *(riff+1);
// Create a suitable buffer
memset(&dsbufferdesc, 0, sizeof dsbufferdesc);
dsbufferdesc.dwSize = sizeof dsbufferdesc;
dsbufferdesc.dwFlags = DSBCAPS_STATIC|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN;
dsbufferdesc.dwBufferBytes = wav_size;
dsbufferdesc.lpwfxFormat = wav_hdr;
err = dsound->CreateSoundBuffer(&dsbufferdesc, &sfxbuffer, NULL);
if (err != DS_OK)
{
free(sfx);
return 1;
}
// Get the DirectSound8 interface to the buffer
err = sfxbuffer->QueryInterface(IID_IDirectSoundBuffer8, (void **)&sfxbuffer8);
if (sfxbuffer8 == NULL)
{
free(sfx);
return 1;
}
// Release the base object
err = sfxbuffer->Release();
// Lock the buffer
err = sfxbuffer8->Lock(0, 0, (void **)&data1, &size1, (void **)&data2, &size2, DSBLOCK_ENTIREBUFFER);
if (err != DS_OK)
{
free(sfx);
return 1;
}
// Copy wav data from file into DirectSound buffer
memcpy(data1, wav_data, wav_size);
err = sfxbuffer8->Unlock(data1, size1, data2, size2);
// Set the sfx volume
err = sfxbuffer8->SetVolume(vol_to_db(127));
// Play the sound
err = sfxbuffer8->Play(0,0,0);
if (err != DS_OK)
{
free(sfx);
return 1;
}
}
// Tidy up
free(sfx);
return 0;
}