2 * $Logfile: /Freespace2/code/Sound/rsx_lib.cpp $
7 * C module for RSX sound lib
10 * Revision 1.1 2002/05/03 03:28:10 root
14 * 2 10/07/98 10:54a Dave
17 * 1 10/07/98 10:51a Dave
19 * 3 10/14/97 11:33p Lawrance
22 * 1 10/14/97 12:58p Lawrance
24 * 1 10/14/97 10:35a Lawrance
37 // gloabl variable to keep track of initalized status for RSX
38 int rsx_initialized = 0;
40 ////////////////////////////////////////////
42 ////////////////////////////////////////////
46 IRSXDirectListener *lpDL;
48 RSXENVIRONMENT rsxEnv;
50 IRSXCachedEmitter *lpCE[MAX_SOUNDS];
52 // initialize the listener. Return -1 if failed to init listener, otherwise return 0
53 int rsx_init_listener()
57 // Create a listener and save the IRSXDirectListener interface
58 RSXDIRECTLISTENERDESC rsxDL; // listener description
60 rsxDL.cbSize = sizeof(RSXDIRECTLISTENERDESC);
61 // rsxDL.hMainWnd = NULL;
62 rsxDL.hMainWnd = (HWND)os_get_window();
67 hr = CoCreateInstance(CLSID_RSXDIRECTLISTENER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXDirectListener, (void **) &lpDL);
68 if ( SUCCEEDED(hr) ) {
69 hr = lpDL->Initialize(&rsxDL, lpRSXUnk);
73 Warning(LOCATION,"Unable to create the RSX listener\n");
77 Warning(LOCATION,"Unable to create the RSX listener\n");
82 if( SUCCEEDED(lpRSX->CreateDirectListener(&rsxDL, &lpDL, NULL)) ) {
89 // initialize the environment. lpRSX must be non-null. Return -1 if there is
90 // an error, otherwise return 0
91 int rsx_init_environment()
93 Assert(lpRSX != NULL);
95 rsxEnv.cbSize = sizeof(RSXENVIRONMENT);
96 rsxEnv.dwFlags = RSXENVIRONMENT_SPEEDOFSOUND;
97 rsxEnv.fSpeedOfSound = 200.0f;
98 if ( lpRSX->SetEnvironment(&rsxEnv) == S_OK )
104 // init the RSX sound system. Return -1 if a failure occurs, otherwise return 0
110 if ( rsx_initialized )
113 // Initialize COM Library
114 hr = CoInitialize(NULL);
116 // Specify the class Id for RSX and the interface ID for the IRSX2 interface (use IID_IRSX20 if using IRSX)
117 hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IRSX20, (void **) &lpRSX);
118 if ( !SUCCEEDED(hr) ) {
119 Warning(LOCATION,"Unable to create the RSX interface\n");
123 // hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **) &lpRSXUnk);
124 // Query the object for an IUnknown interface
125 hr = lpRSX->QueryInterface(IID_IUnknown, (void**)&lpRSXUnk);
126 if ( !SUCCEEDED(hr) ) {
127 Warning(LOCATION,"Unable to create the RSX Unknown interface\n");
132 if ( rsx_init_environment() == -1 ) {
133 Warning(LOCATION,"Unable to initialize the RSX environment\n");
137 if ( rsx_init_listener() == -1 ) {
138 Warning(LOCATION,"Unable to initialize the RSX direct listener\n");
142 for ( i = 0; i < MAX_SOUNDS; i++ ) {
143 if ( lpCE[i] != NULL ) {
153 // called once per frame to update the listener position and orientation
154 void rsx_update_listener(vector *pos, matrix *orient)
159 if ( !rsx_initialized )
165 hr = lpDL->SetPosition(&u);
167 Warning(LOCATION,"Unable to set position for the RSX listener\n");
169 u.x = orient->fvec.x;
170 u.y = orient->fvec.y;
171 u.z = orient->fvec.z;
173 v.x = orient->uvec.x;
174 v.y = orient->uvec.y;
175 v.z = orient->uvec.z;
177 hr = lpDL->SetOrientation(&u, &v);
179 Warning(LOCATION,"Unable to set orientation for the RSX listener\n");
182 // uninitialize the RSX sound system
187 for(i = 0; i < MAX_SOUNDS; i++){
188 if ( lpCE[i] != NULL) {
194 // TODO: release the channels
196 // Release the listener
211 // return index into lpCE[] array, this is the Sounds[].sid member used to link the game-level
212 // description of the sound to the low-level cached emitter
213 int rsx_create_cached_emitter(char *filename, int is_3d, int use_doppler, int min, int max, float max_volume)
215 RSXCACHEDEMITTERDESC rsxCE;
216 RSXEMITTERMODEL rsxModel;
220 ZeroMemory(&rsxCE, sizeof(RSXCACHEDEMITTERDESC));
221 rsxCE.cbSize = sizeof(RSXCACHEDEMITTERDESC);
222 strcpy(rsxCE.szFilename, filename);
224 ZeroMemory(&rsxModel, sizeof(RSXEMITTERMODEL));
225 rsxModel.cbSize = sizeof(RSXEMITTERMODEL);
227 for ( ce_index = 0; ce_index < MAX_SOUNDS; ce_index++ ) {
228 if ( lpCE[ce_index] == NULL )
232 if ( ce_index == MAX_SOUNDS ) {
233 Warning(LOCATION, "RSX has exceeded the maximum number of sounds\n");
238 rsxCE.dwFlags |= RSXEMITTERDESC_NOREVERB; // no reverb by default
240 rsxCE.dwFlags |= RSXEMITTERDESC_NODOPPLER;
242 rsxModel.fIntensity = max_volume;
243 // rsxModel.fIntensity = 1.0f;
244 rsxModel.fMinBack = i2fl(min);
245 rsxModel.fMinFront = i2fl(min);
246 rsxModel.fMaxBack = i2fl(max);
247 rsxModel.fMaxFront = i2fl(max);
249 rsxCE.dwFlags = RSXEMITTERDESC_NOSPATIALIZE | RSXEMITTERDESC_NOATTENUATE | RSXEMITTERDESC_NODOPPLER | RSXEMITTERDESC_NOREVERB;
250 rsxModel.fIntensity = max_volume;
254 hr = CoCreateInstance(CLSID_RSXCACHEDEMITTER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXCachedEmitter, (void **) &lpCE[ce_index]);
256 Warning(LOCATION, "Creating an RSX cached emitter failed\n");
260 hr = lpCE[ce_index]->Initialize(&rsxCE, lpRSXUnk);
262 Warning(LOCATION, "Initialization of an RSX cached emitter failed\n");
267 if( !SUCCEEDED(lpRSX->CreateCachedEmitter(&rsxCE, &lpCE[ce_index], NULL)) ) {
268 Warning(LOCATION, "Could not create a RSX cached emitter\n");
272 lpCE[ce_index]->SetModel(&rsxModel);
276 int rsx_play_3d(int sid, float priority, float volume, vector *pos, vector *sound_fvec)
278 RSXQUERYMEDIAINFO qmi;
279 qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
280 lpCE[sid]->QueryMediaState(&qmi);
282 if ( qmi.dwControl == RSX_PLAY )
285 lpCE[sid]->SetPosition((RSXVECTOR3D*)pos);
286 // lpCE[sid]->SetOrientation((RSXVECTOR3D*)sound_fvec);
287 lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
291 int rsx_play( int sid, float priority, float volume)
293 RSXQUERYMEDIAINFO qmi;
296 qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
297 lpCE[sid]->QueryMediaState(&qmi);
299 if ( qmi.dwControl == RSX_PLAY )
302 hr = lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
304 Warning(LOCATION, "rsx_play() failure\n");
311 void rsx_unload_buffer(int sid)
314 if ( lpCE[sid] != NULL ) {
315 lpCE[sid]->Release();