# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

listener_dsound.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "stddsound.h"
00027 
00028 #include "listener_dsound.h"
00029 #include "sound_driver_dsound.h"
00030 
00031 
00032 using namespace NLMISC;
00033 
00034 
00035 namespace NLSOUND {
00036 
00037 
00038 // The instance of the singleton
00039 CListenerDSound *CListenerDSound::_Instance = NULL;
00040 
00041 
00042 /*
00043  * Constructor
00044  */
00045 CListenerDSound::CListenerDSound(LPDIRECTSOUND3DLISTENER dsoundListener) //: IListener()
00046 {
00047         _Pos = CVector::Null;
00048         if ( _Instance == NULL )
00049         {
00050                 _Instance = this;
00051         _Listener = dsoundListener;
00052 
00053                 setRolloffFactor(DS3D_MINROLLOFFFACTOR);
00054         }
00055         else
00056         {
00057                 //nlerror( "Listener singleton instanciated twice" );
00058         }
00059 }
00060 
00061 
00062 CListenerDSound::~CListenerDSound()
00063 {
00064         nldebug("Destroying DirectSound listener");
00065 
00066     release();
00067         _Instance = NULL;
00068 }
00069 
00070 
00071 /*
00072  *      Release all DirectSound resources
00073  */
00074 void CListenerDSound::release()
00075 {
00076     if (_Listener != NULL)
00077     {
00078         _Listener->Release();
00079                 _Listener = NULL;
00080     }
00081 }
00082 
00083 
00084 /*
00085  * Set the position vector (default: (0,0,0)) (3D mode only)
00086  */
00087 void CListenerDSound::setPos( const NLMISC::CVector& pos )
00088 {
00089 
00090         _Pos = pos;
00091         // Coordinate system: conversion from NeL to OpenAL/GL:
00092     if (_Listener != NULL)
00093     {
00094         if (FAILED(_Listener->SetPosition(pos.x, pos.z, pos.y, DS3D_DEFERRED)))
00095                 {
00096                         nlwarning("SetPosition failed");
00097                 }
00098                 else
00099                 {
00100                         //nlwarning ("set listener NEL(p:%.2f/%.2f/%.2f) DS(p:%.2f/%.2f/%.2f)", pos.x, pos.y, pos.z, pos.x, pos.z, pos.y);
00101                 }
00102         }
00103 }
00104 
00105 
00109 const NLMISC::CVector &CListenerDSound::getPos() const
00110 {
00111         return _Pos;
00112 /*      return;
00113         // Coordinate system: conversion from NeL to OpenAL/GL:
00114     if (_Listener != NULL)
00115         {
00116                 D3DVECTOR v;
00117         if (FAILED(_Listener->GetPosition(&v)))
00118                 {
00119                         nlwarning("GetPosition failed");
00120                         pos.set(0.0f, 0.0f, 0.0f);
00121                 }
00122                 else
00123                 {
00124                         pos.set(v.x, v.z, v.y);
00125                 }
00126     }
00127         else
00128         {
00129                 pos.set(0, 0, 0);
00130         }
00131 */
00132 }
00133 
00134 
00135 /*
00136  * Set the velocity vector (3D mode only)
00137  */
00138 void CListenerDSound::setVelocity( const NLMISC::CVector& vel )
00139 {
00140     if (_Listener != NULL)
00141     {
00142         if (FAILED(_Listener->SetVelocity(vel.x, vel.z, vel.y, DS3D_DEFERRED)))
00143                 {
00144                         nlwarning("SetVelocity failed");
00145                 }
00146     }
00147 }
00148 
00149 
00150 /*
00151  * Get the velocity vector
00152  */
00153 void CListenerDSound::getVelocity( NLMISC::CVector& vel ) const
00154 {
00155     if (_Listener != NULL)
00156         {
00157                 D3DVECTOR v;
00158         if (FAILED(_Listener->GetVelocity(&v)))
00159                 {
00160                         nlwarning("GetVelocity failed");
00161                         vel.set(0.0f, 0.0f, 0.0f);
00162                 }
00163                 else
00164                 {
00165                         vel.set(v.x, v.z, v.y);
00166                 }
00167     }
00168         else
00169         {
00170                 vel.set(0, 0, 0);       
00171         }
00172 }
00173 
00174 
00175 /*
00176  * Set the orientation vectors (3D mode only)
00177  */
00178 void CListenerDSound::setOrientation( const NLMISC::CVector& front, const NLMISC::CVector& up )
00179 {
00180     if (_Listener != NULL)
00181     {
00182         if (FAILED(_Listener->SetOrientation(front.x, front.z, front.y, up.x, up.z, up.y, DS3D_DEFERRED)))
00183                 {
00184                         nlwarning("SetOrientation failed");
00185                 }
00186                 else
00187                 {
00188                         //nlwarning ("NLSOUND: set listener orientation NEL(f:%.2f/%.2f/%.2f up:%.2f/%.2f/%.2f) DS(f:%.2f/%.2f/%.2f up:%.2f/%.2f/%.2f)", front.x, front.y, front.z, up.x, up.y, up.z, front.x, front.z, front.y, up.x, up.z, up.y);
00189                 }
00190     }
00191 }
00192 
00193 
00194 /*
00195  * Get the orientation vectors
00196  */
00197 void CListenerDSound::getOrientation( NLMISC::CVector& front, NLMISC::CVector& up ) const
00198 {
00199     if (_Listener != NULL)
00200         {
00201                 D3DVECTOR vfront, vtop;
00202         if (FAILED(_Listener->GetOrientation(&vfront, &vtop)))
00203                 {
00204                         nlwarning("GetOrientation failed");
00205                         front.set(0.0f, 0.0f, 1.0f);
00206                         up.set(0.0f, 1.0f, 0.0f);
00207                 }
00208                 else
00209                 {
00210                         front.set(vfront.x, vfront.z, vfront.y);
00211                         up.set(vtop.x, vtop.z, vtop.y);
00212                 }
00213     }
00214         else
00215         {
00216                 front.set(0, 0, 1);
00217                 up.set(0, 1, 0);
00218         }
00219 }
00220 
00221 
00222 /* Set the gain (volume value inside [0 , 1]). (default: 1)
00223  * 0.0 -> silence
00224  * 0.5 -> -6dB
00225  * 1.0 -> no attenuation
00226  * values > 1 (amplification) not supported by most drivers
00227  */
00228 void CListenerDSound::setGain( float gain )
00229 {
00230         CSoundDriverDSound::instance()->setGain(gain);
00231 }
00232 
00233 
00234 /*
00235  * Get the gain
00236  */
00237 float CListenerDSound::getGain() const
00238 {
00239     return CSoundDriverDSound::instance()->getGain();
00240 }
00241 
00242 
00243 /*
00244  * Set the doppler factor (default: 1) to exaggerate or not the doppler effect
00245  */
00246 void CListenerDSound::setDopplerFactor( float f )
00247 {
00248     if (_Listener != NULL)
00249     {
00250                 if (f > DS3D_MAXDOPPLERFACTOR)
00251                 {
00252                         f = DS3D_MAXDOPPLERFACTOR;
00253                 }
00254                 else if (f < DS3D_MINDOPPLERFACTOR)
00255                 {
00256                         f = DS3D_MINDOPPLERFACTOR;
00257                 }
00258 
00259         if (FAILED(_Listener->SetDopplerFactor(f, DS3D_DEFERRED)))
00260                 {
00261                         nlwarning("SetDopplerFactor failed");
00262                 }
00263     }
00264 }
00265 
00266 
00267 /*
00268  * Set the rolloff factor (default: 1) to scale the distance attenuation effect
00269  */
00270 void CListenerDSound::setRolloffFactor( float f )
00271 {
00272     if (_Listener != NULL)
00273     {
00274                 //clamp(f, DS3D_MINROLLOFFFACTOR, DS3D_MAXROLLOFFFACTOR);
00275 
00276                 // VOLUMETEST: Don't use the rolloff factor. We manage the
00277                 // volumes ourselves
00278                 f = DS3D_MINROLLOFFFACTOR;
00279 
00280         
00281                 if (FAILED(_Listener->SetRolloffFactor(f, DS3D_DEFERRED)))
00282                 {
00283                         nlwarning("SetRolloffFactor failed");
00284                 }
00285     }
00286 }
00287 
00288 
00289 float CListenerDSound::getRolloffFactor()
00290 {   
00291         if (_Listener != NULL)
00292     {
00293                 float f;
00294                 _Listener->GetRolloffFactor(&f);
00295                 return f;
00296     }
00297         else
00298         {
00299                 return 1.0;
00300         }
00301 }
00302 
00303 
00304 void CListenerDSound::commit3DChanges()
00305 {
00306     if (_Listener != NULL)
00307     {
00308                 _Listener->CommitDeferredSettings();
00309         }
00310 }
00311 
00312 
00313 /*
00314  * Set DSPROPERTY_EAXLISTENER_ENVIRONMENT and DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE if EAX available (see EAX listener properties)
00315  */
00316 void CListenerDSound::setEnvironment( uint env, float size )
00317 {
00318 #ifdef EAX_AVAILABLE
00319         if ( EAXSetProp != NULL )
00320         {
00321                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, 0, &env, sizeof(unsigned long) );
00322                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, 0, &size, sizeof(float) );
00323         }
00324 #endif
00325 }
00326 
00327 
00328 /*
00329  * Set any EAX listener property if EAX available
00330  */
00331 void CListenerDSound::setEAXProperty( uint prop, void *value, uint valuesize )
00332 {
00333 #ifdef EAX_AVAILABLE
00334         if ( EAXSetProp != NULL )
00335         {
00336                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, prop, 0, value, valuesize );
00337         }
00338 #endif
00339 }
00340 
00341 
00342 } // NLSOUND