# 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_al.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 "stdopenal.h"
00027 
00028 #include "listener_al.h"
00029 
00030 
00031 using namespace NLMISC;
00032 
00033 
00034 namespace NLSOUND {
00035 
00036 
00037 // The instance of the singleton
00038 CListenerAL     *CListenerAL::_Instance = NULL;
00039 
00040 
00041 /*
00042  * Constructor
00043  */
00044 CListenerAL::CListenerAL() : IListener()
00045 {
00046         if ( _Instance == NULL )
00047         {
00048                 _Instance = this;
00049         }
00050         else
00051         {
00052                 nlerror( "Listener singleton instanciated twice" );
00053         }
00054 }
00055 
00056 
00057 /*
00058  * Set the position vector (default: (0,0,0)) (3D mode only)
00059  */
00060 void                                    CListenerAL::setPos( const NLMISC::CVector& pos )
00061 {
00062         _Pos = pos;
00063         // Coordinate system: conversion from NeL to OpenAL/GL:
00064         alListener3f( AL_POSITION, pos.x, pos.z, -pos.y );
00065         TestALError();
00066 }
00067 
00068 
00072 const NLMISC::CVector &CListenerAL::getPos() const
00073 {
00074         return _Pos;
00075 
00076 // Currently, the OpenAL headers are different between Windows and Linux versions !
00077 // alGetListener3f() is part of the spec, though.
00078 /*
00079 #ifdef NL_OS_WINDOWS
00080         // Coordsys conversion
00081         float glposz;
00082         alGetListener3f( AL_POSITION, &pos.x, &pos.z, &glposz );
00083         pos.y = -glposz;
00084 #else
00085         float posarray [3];
00086         alGetListenerfv( AL_POSITION, posarray );
00087         // Coordsys conversion
00088         pos.set( posarray[0], -posarray[2], posarray[1] );
00089 #endif
00090         TestALError();
00091 */
00092 }
00093 
00094 
00095 /*
00096  * Set the velocity vector (3D mode only)
00097  */
00098 void                                    CListenerAL::setVelocity( const NLMISC::CVector& vel )
00099 {
00100         // Coordsys conversion
00101         alListener3f( AL_VELOCITY, vel.x, vel.z, -vel.y );
00102         TestALError();
00103 }
00104 
00105 
00106 /*
00107  * Get the velocity vector
00108  */
00109 void                                    CListenerAL::getVelocity( NLMISC::CVector& vel ) const
00110 {
00111 #ifdef NL_OS_WINDOWS
00112         // Coordsys conversion
00113         float glposz;
00114         alGetListener3f( AL_VELOCITY, &vel.x, &vel.z, &glposz );
00115         vel.y = - glposz;
00116 #else
00117         float velarray [3];
00118         alGetListenerfv( AL_VELOCITY, velarray );
00119         // Coordsys conversion
00120         vel.set( velarray[0], -velarray[2], velarray[1] );
00121 #endif
00122         TestALError();
00123 }
00124 
00125 
00126 /*
00127  * Set the orientation vectors (3D mode only)
00128  */
00129 void                                    CListenerAL::setOrientation( const NLMISC::CVector& front, const NLMISC::CVector& up )
00130 {
00131         // Forward then up
00132         ALfloat v[6];
00133         // Coordsys conversion
00134         v[0] = front.x;
00135         v[1] = front.z;
00136         v[2] = -front.y;
00137         v[3] = up.x;
00138         v[4] = up.z;
00139         v[5] = -up.y;
00140         alListenerfv( AL_ORIENTATION, v );
00141         TestALError();
00142 }
00143 
00144 
00145 /*
00146  * Get the orientation vectors
00147  */
00148 void                                    CListenerAL::getOrientation( NLMISC::CVector& front, NLMISC::CVector& up ) const
00149 {
00150         // Forward then up
00151         ALfloat v[6];
00152         alGetListenerfv( AL_ORIENTATION, v );
00153         TestALError();
00154         // Coordsys conversion
00155         front.set( v[0], -v[2], v[1] );
00156         up.set( v[3], -v[5], v[4] );
00157 }
00158 
00159 
00160 /* Set the gain (volume value inside [0 , 1]). (default: 1)
00161  * 0.0 -> silence
00162  * 0.5 -> -6dB
00163  * 1.0 -> no attenuation
00164  * values > 1 (amplification) not supported by most drivers
00165  */
00166 void                                    CListenerAL::setGain( float gain )
00167 {
00168         alListenerf( AL_GAIN, gain );
00169         TestALError();
00170 }
00171 
00172 
00173 /*
00174  * Get the gain
00175  */
00176 float                                   CListenerAL::getGain() const
00177 {
00178         ALfloat gain;
00179 #ifdef NL_OS_WINDOWS
00180         alGetListenerf( AL_GAIN, &gain );
00181 #else
00182         alGetListenerfv( AL_GAIN, &gain );
00183 #endif
00184         TestALError();
00185         return gain;
00186 }
00187 
00188 
00189 /*
00190  * Set the doppler factor (default: 1) to exaggerate or not the doppler effect
00191  */
00192 void                                    CListenerAL::setDopplerFactor( float f )
00193 {
00194         alDopplerFactor( f );
00195         TestALError();
00196 }
00197 
00198 
00199 /*
00200  * Set the rolloff factor (default: 1) to scale the distance attenuation effect
00201  */
00202 void                                    CListenerAL::setRolloffFactor( float f )
00203 {
00204         nlassert( CSoundDriverAL::instance() != NULL );
00205         CSoundDriverAL::instance()->applyRolloffFactor( f );
00206 }
00207 
00208 
00209 /*
00210  * Set DSPROPERTY_EAXLISTENER_ENVIRONMENT and DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE if EAX available (see EAX listener properties)
00211  */
00212 void                                    CListenerAL::setEnvironment( uint env, float size )
00213 {
00214 #ifdef EAX_AVAILABLE
00215         if ( EAXSetProp != NULL )
00216         {
00217                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, 0, &env, sizeof(unsigned long) );
00218                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, 0, &size, sizeof(float) );
00219         }
00220 #endif
00221 }
00222 
00223 
00224 /*
00225  * Set any EAX listener property if EAX available
00226  */
00227 void                                    CListenerAL::setEAXProperty( uint prop, void *value, uint valuesize )
00228 {
00229 #ifdef EAX_AVAILABLE
00230         if ( EAXSetProp != NULL )
00231         {
00232                 EAXSetProp( &DSPROPSETID_EAX_ListenerProperties, prop, 0, value, valuesize );
00233         }
00234 #endif
00235 }
00236 
00237 
00238 } // NLSOUND