www.pudn.com > 3DÓÎÏ·Source.rar > demo10_2.cpp


// DEMO10_2.CPP - Making a simple sound with DirectSound 
// makes a 100hz pure sine tone, try changing it for fun! 
 
// INCLUDES /////////////////////////////////////////////// 
 
#define WIN32_LEAN_AND_MEAN   
 
#include    // include important windows stuff 
#include   
#include  
#include  // include important C/C++ stuff 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
#include   // directX includes 
#include  
 
// directx 7.0+ compatibility 
 
#ifndef DSBCAPS_CTRLDEFAULT 
#define DSBCAPS_CTRLDEFAULT (DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME ) 
#endif 
 
// DEFINES //////////////////////////////////////////////// 
 
// defines for windows  
#define WINDOW_CLASS_NAME "WINCLASS1"  // class name 
 
#define WINDOW_WIDTH  400              // size of window 
#define WINDOW_HEIGHT 400 
#define SCREEN_WIDTH  640              // size of screen 
#define SCREEN_HEIGHT 480 
#define SCREEN_BPP    8                // bits per pixel 
 
// MACROS ///////////////////////////////////////////////// 
 
// these read the keyboard asynchronously 
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
#define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) 
 
// TYPES ////////////////////////////////////////////////// 
 
typedef unsigned short USHORT; 
typedef unsigned short WORD; 
typedef unsigned char  UCHAR; 
typedef unsigned char  BYTE; 
 
// PROTOTYPES ///////////////////////////////////////////// 
 
int Game_Init(void *parms=NULL); 
int Game_Shutdown(void *parms=NULL); 
int Game_Main(void *parms=NULL); 
 
// GLOBALS //////////////////////////////////////////////// 
 
HWND main_window_handle = NULL; // save the window handle 
HINSTANCE main_instance = NULL; // save the instance 
char buffer[80];                // used to print text 
 
LPDIRECTSOUND		lpds;           // directsound interface pointer 
DSBUFFERDESC		dsbd;           // directsound description 
DSCAPS				dscaps;         // directsound caps 
HRESULT				dsresult;       // general directsound result 
DSBCAPS             dsbcaps;        // directsound buffer caps 
 
LPDIRECTSOUNDBUFFER	lpdsbprimary,    // you won't need this normally 
                    lpdsbsecondary;  // the sound buffers 
 
WAVEFORMATEX        pcmwf;          // generic waveformat structure 
               
// FUNCTIONS ////////////////////////////////////////////// 
 
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); 
 
         // end painting 
         EndPaint(hwnd,&ps); 
         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 
						  "DirectSound 100hz Tone Demo",	 // 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 
main_window_handle = hwnd; 
main_instance      = hinstance; 
 
// perform all game console specific initialization 
// start up the directsound sound 
Game_Init(); 
 
// 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 
    Game_Main(); 
 
	} // end while 
 
// shutdown game and release all resources 
Game_Shutdown(); 
 
// return to Windows like this 
return(msg.wParam); 
 
} // end WinMain 
 
// WINX GAME PROGRAMMING CONSOLE FUNCTIONS //////////////// 
 
int Game_Init(void *parms) 
{ 
// this function is where you do all the initialization  
// for your game 
 
// this example does everything: it sets up directsound 
// creates a secondary buffer, loads it with a synthesizer 
// sine wave and plays it 
 
void 	*audio_ptr_1 = NULL,   // used to lock memory 
		*audio_ptr_2 = NULL; 
 
DWORD	dsbstatus;              // status of sound buffer 
 
DWORD	audio_length_1    = 0,  // length of locked memory 
		audio_length_2    = 0, 
		snd_buffer_length = 64000; // working buffer 
 
// allocate memory for buffer 
UCHAR *snd_buffer_ptr = (UCHAR *)malloc(snd_buffer_length); 
 
// we need some data for the buffer, you could load a .VOC or .WAV 
// but as an example, lets synthesize the data 
 
// fill buffer with a synthesized 100hz sine wave 
for (int index=0; index < (int)snd_buffer_length; index++) 
	snd_buffer_ptr[index] = 127*sin(6.28*((float)(index%110))/(float)110); 
 
// note the math, 127 is the scale or amplitude 
// 6.28 is to convert to radians 
// (index % 110) read below 
// we are playing at 11025 hz or 11025 cycles/sec therefore, in 1 sec 
// we want 100 cycles of our synthesized sound, thus 11025/100 is approx. 
// 110, thus we want the waveform to repeat each 110 clicks of index, so 
// normalize to 110 
 
 
// create a directsound object 
if (DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK ) 
	return(0); 
 
// set cooperation level 
if (lpds->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK) 
	return(0); 
 
// 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 secondary buffer (no need for a primary) 
memset(&dsbd,0,sizeof(DSBUFFERDESC)); 
dsbd.dwSize			= sizeof(DSBUFFERDESC); 
dsbd.dwFlags		= DSBCAPS_CTRLDEFAULT | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE; 
dsbd.dwBufferBytes	= snd_buffer_length+1; 
dsbd.lpwfxFormat	= &pcmwf; 
 
if (lpds->CreateSoundBuffer(&dsbd,&lpdsbsecondary,NULL)!=DS_OK) 
	return(0); 
 
// copy data into sound buffer 
if (lpdsbsecondary->Lock(0,					  
					  snd_buffer_length,			 
    				  &audio_ptr_1,  
					  &audio_length_1, 
					  &audio_ptr_2,  
					  &audio_length_2, 
					  DSBLOCK_FROMWRITECURSOR)!=DS_OK) 
  return(0); 
 
// copy first section of circular buffer 
CopyMemory(audio_ptr_1, snd_buffer_ptr, audio_length_1); 
 
// copy last section of circular buffer 
CopyMemory(audio_ptr_2, (snd_buffer_ptr+audio_length_1),audio_length_2); 
 
// unlock the buffer 
if (lpdsbsecondary->Unlock(audio_ptr_1,  
						   audio_length_1,  
						   audio_ptr_2,  
						   audio_length_2)!=DS_OK) 
	return(0); 
 
// play the sound in looping mode 
if (lpdsbsecondary->Play(0,0,DSBPLAY_LOOPING )!=DS_OK) 
	return(0); 
 
// release the memory since DirectSound has made a copy of it 
free(snd_buffer_ptr); 
 
// return success 
return(1); 
 
} // end Game_Init 
 
/////////////////////////////////////////////////////////// 
 
int Game_Shutdown(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(); 
 
 
// return success 
return(1); 
} // end Game_Shutdown 
 
/////////////////////////////////////////////////////////// 
 
int Game_Main(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(main_window_handle, WM_DESTROY,0,0); 
 
// return success 
return(1); 
} // end Game_Main 
 
///////////////////////////////////////////////////////////