# 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  

source_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 "source_al.h"
00029 
00030 using namespace NLMISC;
00031 
00032 
00033 namespace NLSOUND {
00034 
00035 
00036 // Currently, the OpenAL headers are different between Windows and Linux versions !
00037 #ifdef NL_OS_UNIX
00038 #define alGetSourcei alGetSourceiv
00039 #define alGetSourcef alGetSourcefv
00040 #endif
00041 
00042 
00043 /*
00044  * Constructor
00045  */
00046 CSourceAL::CSourceAL( ALuint sourcename ) : ISource(), _SourceName(sourcename)
00047 {}
00048 
00049 
00050 /*
00051  * Destructor
00052  */
00053 CSourceAL::~CSourceAL()
00054 {
00055         CSoundDriverAL *sdal = CSoundDriverAL::instance();
00056         sdal->removeSource( this );
00057 }
00058 
00059 
00060 /* Set the buffer that will be played (no streaming)
00061  * If the buffer is stereo, the source mode becomes stereo and the source relative mode is on,
00062  * otherwise the source is considered as a 3D source.
00063  */
00064 void                                    CSourceAL::setStaticBuffer( IBuffer *buffer )
00065 {
00066         ISource::setStaticBuffer( buffer );
00067 
00068         // Stop source
00069         alSourceStop( _SourceName );
00070         TestALError();
00071 
00072         // Set buffer
00073         if ( buffer == NULL )
00074         {
00075                 alSourcei( _SourceName, AL_BUFFER, AL_NONE );
00076                 TestALError();
00077         }
00078         else
00079         {
00080                 CBufferAL *bufferAL = dynamic_cast<CBufferAL*>(buffer);
00081                 alSourcei( _SourceName, AL_BUFFER, bufferAL->bufferName() );
00082                 TestALError();
00083 
00084                 // Set relative mode if the buffer is stereo
00085                 setSourceRelativeMode( bufferAL->isStereo() );
00086         }
00087 }
00088 
00089 
00090 /*
00091  * Set looping on/off for future playbacks (default: off)
00092  */
00093 void                                    CSourceAL::setLooping( bool l )
00094 {
00095         alSourcei( _SourceName, AL_LOOPING, l?AL_TRUE:AL_FALSE );
00096         TestALError();
00097 }
00098 
00099 
00100 /*
00101  * Return the looping state
00102  */
00103 bool                                    CSourceAL::getLooping() const
00104 {
00105         ALint b;
00106         alGetSourcei( _SourceName, AL_LOOPING, &b );
00107         TestALError();
00108         return ( b == AL_TRUE );
00109 }
00110 
00111 
00112 /*
00113  * Play the static buffer (or stream in and play)
00114  */
00115 bool            CSourceAL::play()
00116 {
00117         if ( _Buffer != NULL )
00118         {
00119                 // Static playing mode
00120                 alSourcePlay( _SourceName );
00121                 TestALError();
00122         }
00123         else
00124         {
00125                 // Streaming mode
00126                 nlwarning( "AM: Cannot play null buffer; streaming not implemented" );
00127                 nlstop;
00128         }
00129 
00130         // TODO : return a correct value, depending on alSourcePlay result.
00131         return true;
00132 }
00133 
00134 
00135 /*
00136  * Stop playing
00137  */
00138 void                                    CSourceAL::stop()
00139 {
00140         if ( _Buffer != NULL )
00141         {
00142                 // Static playing mode
00143                 alSourceStop( _SourceName );
00144                 TestALError();
00145         }
00146         else
00147         {
00148                 // Streaming mode
00149                 nlwarning( "AM: Cannot stop null buffer; streaming not implemented" );
00150                 //nlstop;
00151         }
00152 }
00153 
00154 
00155 /*
00156  * Pause. Call play() to resume.
00157  */
00158 void                                    CSourceAL::pause()
00159 {
00160         if ( _Buffer != NULL )
00161         {
00162                 // Static playing mode
00163                 alSourcePause( _SourceName );
00164                 TestALError();
00165         }
00166         else
00167         {
00168                 // Streaming mode
00169                 nlwarning( "AM: Cannot pause null buffer; streaming not implemented" );
00170                 nlstop;
00171         }
00172 }
00173 
00174 
00175 /*
00176  * Return the playing state
00177  */
00178 bool                                    CSourceAL::isPlaying() const
00179 {
00180         ALint srcstate;
00181         alGetSourcei( _SourceName, AL_SOURCE_STATE, &srcstate );
00182         TestALError();
00183         return (srcstate == AL_PLAYING);
00184 }
00185 
00186 
00187 /*
00188  * Return true if playing is finished or stop() has been called.
00189  */
00190 bool                                    CSourceAL::isStopped() const
00191 {
00192         ALint srcstate;
00193         alGetSourcei( _SourceName, AL_SOURCE_STATE, &srcstate );
00194         TestALError();
00195         return (srcstate == AL_STOPPED);
00196 }
00197 
00198 
00199 /*
00200  * Update the source (e.g. continue to stream the data in)
00201  */
00202 void                                    CSourceAL::update()
00203 {
00204         // Streaming not implemented
00205 }
00206 
00207 
00208 
00209 /* Set the position vector.
00210  * 3D mode -> 3D position
00211  * st mode -> x is the pan value (from left (-1) to right (1)), set y and z to 0
00212  */
00213 void                                    CSourceAL::setPos( const NLMISC::CVector& pos )
00214 {
00215         _Pos = pos;
00216         // Coordinate system: conversion from NeL to OpenAL/GL:
00217         alSource3f( _SourceName, AL_POSITION, pos.x, pos.z, -pos.y );
00218         TestALError();
00219 }
00220 
00221 
00222 /* Get the position vector.
00223  * See setPos() for details.
00224  */
00225 const NLMISC::CVector &CSourceAL::getPos() const
00226 {
00227         return _Pos;
00228 /*
00229         ALfloat v[3];
00230         alGetSourcefv( _SourceName, AL_POSITION, v );
00231         TestALError();
00232         // Coordsys conversion
00233         pos.set( v[0], -v[2], v[1] );
00234 */
00235 }
00236 
00237 
00238 /*
00239  * Set the velocity vector (3D mode only)
00240  */
00241 void                                    CSourceAL::setVelocity( const NLMISC::CVector& vel, bool deferred )
00242 {
00243         // Coordsys conversion
00244         alSource3f( _SourceName, AL_VELOCITY, vel.x, vel.z, -vel.y );
00245         TestALError();
00246 }
00247 
00248 
00249 /*
00250  * Get the velocity vector
00251  */
00252 void                                    CSourceAL::getVelocity( NLMISC::CVector& vel ) const
00253 {
00254         ALfloat v[3];
00255         alGetSourcefv( _SourceName, AL_VELOCITY, v );
00256         TestALError();
00257         // Coordsys conversion
00258         vel.set( v[0], -v[2], v[1] );
00259 }
00260 
00261 
00262 /*
00263  * Set the direction vector (3D mode only)
00264  */
00265 void                                    CSourceAL::setDirection( const NLMISC::CVector& dir )
00266 {
00267         // Coordsys conversion
00268         alSource3f( _SourceName, AL_DIRECTION, dir.x, dir.z, -dir.y );
00269         TestALError();
00270 }
00271 
00272 
00273 /*
00274  * Get the direction vector
00275  */
00276 void                                    CSourceAL::getDirection( NLMISC::CVector& dir ) const
00277 {
00278         ALfloat v[3];
00279         alGetSourcefv( _SourceName, AL_DIRECTION, v );
00280         TestALError();
00281         // Coordsys conversion
00282         dir.set( v[0], -v[2], v[1] );
00283 }
00284 
00285 
00286 /* Set the gain (volume value inside [0 , 1]).
00287  * 0.0 -> silence
00288  * 0.5 -> -6dB
00289  * 1.0 -> no attenuation
00290  * values > 1 (amplification) not supported by most drivers
00291  */
00292 void                                    CSourceAL::setGain( float gain )
00293 {
00294         nlassert( (gain >= 0.0f) && (gain <= 1.0f ) );
00295         alSourcef( _SourceName, AL_GAIN, gain );
00296         TestALError();
00297 }
00298 
00299 
00300 /*
00301  * Get the gain
00302  */
00303 float                                   CSourceAL::getGain() const
00304 {
00305         ALfloat gain;
00306         alGetSourcef( _SourceName, AL_GAIN, &gain );
00307         TestALError();
00308         return gain;
00309 }
00310 
00311 
00312 /* Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
00313  * of one octave. 0 is not a legal value.
00314  */
00315 void                                    CSourceAL::setPitch( float pitch )
00316 {
00317         nlassert( (pitch > 0) && (pitch <= 1.0f ) );
00318         alSourcef( _SourceName, AL_PITCH, pitch );
00319         TestALError();
00320 }
00321 
00322 
00323 /*
00324  * Get the pitch
00325  */
00326 float                                   CSourceAL::getPitch() const
00327 {
00328         ALfloat pitch;
00329         alGetSourcef( _SourceName, AL_PITCH, &pitch );
00330         TestALError();
00331         return pitch;
00332 }
00333 
00334 
00335 /*
00336  * Set the source relative mode. If true, positions are interpreted relative to the listener position.
00337  */
00338 void                                    CSourceAL::setSourceRelativeMode( bool mode )
00339 {
00340         alSourcei( _SourceName, AL_SOURCE_RELATIVE, mode?AL_TRUE:AL_FALSE );
00341         TestALError();
00342 }
00343 
00344 
00345 /*
00346  * Get the source relative mode (3D mode only)
00347  */
00348 bool                                    CSourceAL::getSourceRelativeMode() const
00349 {
00350         ALint b;
00351         alGetSourcei( _SourceName, AL_SOURCE_RELATIVE, &b );
00352         TestALError();
00353         return (b==AL_TRUE);
00354 }
00355 
00356 
00357 /*
00358  * Set the min and max distances (3D mode only)
00359  */
00360 void                                    CSourceAL::setMinMaxDistances( float mindist, float maxdist, bool deferred )
00361 {
00362         nlassert( (mindist >= 0.0f) && (maxdist >= 0.0f) );
00363         alSourcef( _SourceName, AL_REFERENCE_DISTANCE, mindist );
00364         alSourcef( _SourceName, AL_MAX_DISTANCE, maxdist );
00365         TestALError();
00366 }
00367 
00368 
00369 /*
00370  * Get the min and max distances
00371  */
00372 void                                    CSourceAL::getMinMaxDistances( float& mindist, float& maxdist ) const
00373 {
00374         alGetSourcef( _SourceName, AL_REFERENCE_DISTANCE, &mindist );
00375         alGetSourcef( _SourceName, AL_MAX_DISTANCE, &maxdist );
00376         TestALError();
00377 }
00378 
00379 
00380 /*
00381  * Set the cone angles (in radian) and gain (in [0 , 1]) (3D mode only)
00382  */
00383 void                                    CSourceAL::setCone( float innerAngle, float outerAngle, float outerGain )
00384 {
00385         nlassert( (outerGain >= 0.0f) && (outerGain <= 1.0f ) );
00386         alSourcef( _SourceName, AL_CONE_INNER_ANGLE, radToDeg(innerAngle) );
00387         alSourcef( _SourceName, AL_CONE_OUTER_ANGLE, radToDeg(outerAngle) );
00388         alSourcef( _SourceName, AL_CONE_OUTER_GAIN, outerGain );
00389         TestALError();
00390 }
00391 
00392 
00393 /*
00394  * Get the cone angles (in radian)
00395  */
00396 void                                    CSourceAL::getCone( float& innerAngle, float& outerAngle, float& outerGain ) const
00397 {
00398         float ina, outa;
00399         alGetSourcef( _SourceName, AL_CONE_INNER_ANGLE, &ina );
00400         innerAngle = degToRad(ina);
00401         alGetSourcef( _SourceName, AL_CONE_OUTER_ANGLE, &outa );
00402         outerAngle = degToRad(outa);
00403         alGetSourcef( _SourceName, AL_CONE_OUTER_GAIN, &outerGain );
00404         TestALError();
00405 }
00406 
00407 
00408 /*
00409  * Set any EAX source property if EAX available
00410  */
00411 void                                    CSourceAL::setEAXProperty( uint prop, void *value, uint valuesize )
00412 {
00413 #ifdef EAX_AVAILABLE
00414         if ( EAXSetProp != NULL )
00415         {
00416                 EAXSetProp( &DSPROPSETID_EAX_SourceProperties, prop, _SourceName, value, valuesize );
00417         }
00418 #endif
00419 }
00420 
00421 
00422 } // NLSOUND