2 * $Logfile: /Freespace2/code/Sound/rsx_lib.cpp $
7 * C module for RSX sound lib
10 * Revision 1.2 2002/05/07 03:16:52 theoddone33
11 * The Great Newline Fix
13 * Revision 1.1.1.1 2002/05/03 03:28:10 root
17 * 2 10/07/98 10:54a Dave
20 * 1 10/07/98 10:51a Dave
22 * 3 10/14/97 11:33p Lawrance
25 * 1 10/14/97 12:58p Lawrance
27 * 1 10/14/97 10:35a Lawrance
40 // gloabl variable to keep track of initalized status for RSX
41 int rsx_initialized = 0;
43 ////////////////////////////////////////////
45 ////////////////////////////////////////////
49 IRSXDirectListener *lpDL;
51 RSXENVIRONMENT rsxEnv;
53 IRSXCachedEmitter *lpCE[MAX_SOUNDS];
55 // initialize the listener. Return -1 if failed to init listener, otherwise return 0
56 int rsx_init_listener()
60 // Create a listener and save the IRSXDirectListener interface
61 RSXDIRECTLISTENERDESC rsxDL; // listener description
63 rsxDL.cbSize = sizeof(RSXDIRECTLISTENERDESC);
64 // rsxDL.hMainWnd = NULL;
65 rsxDL.hMainWnd = (HWND)os_get_window();
70 hr = CoCreateInstance(CLSID_RSXDIRECTLISTENER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXDirectListener, (void **) &lpDL);
71 if ( SUCCEEDED(hr) ) {
72 hr = lpDL->Initialize(&rsxDL, lpRSXUnk);
76 Warning(LOCATION,"Unable to create the RSX listener\n");
80 Warning(LOCATION,"Unable to create the RSX listener\n");
85 if( SUCCEEDED(lpRSX->CreateDirectListener(&rsxDL, &lpDL, NULL)) ) {
92 // initialize the environment. lpRSX must be non-null. Return -1 if there is
93 // an error, otherwise return 0
94 int rsx_init_environment()
96 Assert(lpRSX != NULL);
98 rsxEnv.cbSize = sizeof(RSXENVIRONMENT);
99 rsxEnv.dwFlags = RSXENVIRONMENT_SPEEDOFSOUND;
100 rsxEnv.fSpeedOfSound = 200.0f;
101 if ( lpRSX->SetEnvironment(&rsxEnv) == S_OK )
107 // init the RSX sound system. Return -1 if a failure occurs, otherwise return 0
113 if ( rsx_initialized )
116 // Initialize COM Library
117 hr = CoInitialize(NULL);
119 // Specify the class Id for RSX and the interface ID for the IRSX2 interface (use IID_IRSX20 if using IRSX)
120 hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IRSX20, (void **) &lpRSX);
121 if ( !SUCCEEDED(hr) ) {
122 Warning(LOCATION,"Unable to create the RSX interface\n");
126 // hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **) &lpRSXUnk);
127 // Query the object for an IUnknown interface
128 hr = lpRSX->QueryInterface(IID_IUnknown, (void**)&lpRSXUnk);
129 if ( !SUCCEEDED(hr) ) {
130 Warning(LOCATION,"Unable to create the RSX Unknown interface\n");
135 if ( rsx_init_environment() == -1 ) {
136 Warning(LOCATION,"Unable to initialize the RSX environment\n");
140 if ( rsx_init_listener() == -1 ) {
141 Warning(LOCATION,"Unable to initialize the RSX direct listener\n");
145 for ( i = 0; i < MAX_SOUNDS; i++ ) {
146 if ( lpCE[i] != NULL ) {
156 // called once per frame to update the listener position and orientation
157 void rsx_update_listener(vector *pos, matrix *orient)
162 if ( !rsx_initialized )
168 hr = lpDL->SetPosition(&u);
170 Warning(LOCATION,"Unable to set position for the RSX listener\n");
172 u.x = orient->fvec.x;
173 u.y = orient->fvec.y;
174 u.z = orient->fvec.z;
176 v.x = orient->uvec.x;
177 v.y = orient->uvec.y;
178 v.z = orient->uvec.z;
180 hr = lpDL->SetOrientation(&u, &v);
182 Warning(LOCATION,"Unable to set orientation for the RSX listener\n");
185 // uninitialize the RSX sound system
190 for(i = 0; i < MAX_SOUNDS; i++){
191 if ( lpCE[i] != NULL) {
197 // TODO: release the channels
199 // Release the listener
214 // return index into lpCE[] array, this is the Sounds[].sid member used to link the game-level
215 // description of the sound to the low-level cached emitter
216 int rsx_create_cached_emitter(char *filename, int is_3d, int use_doppler, int min, int max, float max_volume)
218 RSXCACHEDEMITTERDESC rsxCE;
219 RSXEMITTERMODEL rsxModel;
223 ZeroMemory(&rsxCE, sizeof(RSXCACHEDEMITTERDESC));
224 rsxCE.cbSize = sizeof(RSXCACHEDEMITTERDESC);
225 strcpy(rsxCE.szFilename, filename);
227 ZeroMemory(&rsxModel, sizeof(RSXEMITTERMODEL));
228 rsxModel.cbSize = sizeof(RSXEMITTERMODEL);
230 for ( ce_index = 0; ce_index < MAX_SOUNDS; ce_index++ ) {
231 if ( lpCE[ce_index] == NULL )
235 if ( ce_index == MAX_SOUNDS ) {
236 Warning(LOCATION, "RSX has exceeded the maximum number of sounds\n");
241 rsxCE.dwFlags |= RSXEMITTERDESC_NOREVERB; // no reverb by default
243 rsxCE.dwFlags |= RSXEMITTERDESC_NODOPPLER;
245 rsxModel.fIntensity = max_volume;
246 // rsxModel.fIntensity = 1.0f;
247 rsxModel.fMinBack = i2fl(min);
248 rsxModel.fMinFront = i2fl(min);
249 rsxModel.fMaxBack = i2fl(max);
250 rsxModel.fMaxFront = i2fl(max);
252 rsxCE.dwFlags = RSXEMITTERDESC_NOSPATIALIZE | RSXEMITTERDESC_NOATTENUATE | RSXEMITTERDESC_NODOPPLER | RSXEMITTERDESC_NOREVERB;
253 rsxModel.fIntensity = max_volume;
257 hr = CoCreateInstance(CLSID_RSXCACHEDEMITTER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXCachedEmitter, (void **) &lpCE[ce_index]);
259 Warning(LOCATION, "Creating an RSX cached emitter failed\n");
263 hr = lpCE[ce_index]->Initialize(&rsxCE, lpRSXUnk);
265 Warning(LOCATION, "Initialization of an RSX cached emitter failed\n");
270 if( !SUCCEEDED(lpRSX->CreateCachedEmitter(&rsxCE, &lpCE[ce_index], NULL)) ) {
271 Warning(LOCATION, "Could not create a RSX cached emitter\n");
275 lpCE[ce_index]->SetModel(&rsxModel);
279 int rsx_play_3d(int sid, float priority, float volume, vector *pos, vector *sound_fvec)
281 RSXQUERYMEDIAINFO qmi;
282 qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
283 lpCE[sid]->QueryMediaState(&qmi);
285 if ( qmi.dwControl == RSX_PLAY )
288 lpCE[sid]->SetPosition((RSXVECTOR3D*)pos);
289 // lpCE[sid]->SetOrientation((RSXVECTOR3D*)sound_fvec);
290 lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
294 int rsx_play( int sid, float priority, float volume)
296 RSXQUERYMEDIAINFO qmi;
299 qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
300 lpCE[sid]->QueryMediaState(&qmi);
302 if ( qmi.dwControl == RSX_PLAY )
305 hr = lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
307 Warning(LOCATION, "rsx_play() failure\n");
314 void rsx_unload_buffer(int sid)
317 if ( lpCE[sid] != NULL ) {
318 lpCE[sid]->Release();