From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/env__sound__user_8cpp-source.html | 660 +++++++++++++++++++++ 1 file changed, 660 insertions(+) create mode 100644 docs/doxygen/nel/env__sound__user_8cpp-source.html (limited to 'docs/doxygen/nel/env__sound__user_8cpp-source.html') diff --git a/docs/doxygen/nel/env__sound__user_8cpp-source.html b/docs/doxygen/nel/env__sound__user_8cpp-source.html new file mode 100644 index 00000000..e522e0c7 --- /dev/null +++ b/docs/doxygen/nel/env__sound__user_8cpp-source.html @@ -0,0 +1,660 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

env_sound_user.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 "stdsound.h"
+00027 
+00028 #include "env_sound_user.h"
+00029 #include "sound.h"
+00030 #include "bounding_shape.h"
+00031 #include <stdlib.h>
+00032 
+00033 using namespace std;
+00034 using namespace NLMISC;
+00035 
+00036 
+00037 namespace NLSOUND {
+00038 
+00039 
+00040 /*
+00041  * Constructor
+00042  */
+00043 CEnvSoundUser::CEnvSoundUser() : _Play(false), _Source(NULL), _BoundingShape(NULL), _Transition(false), _Parent(NULL), _Mark(false), _Gain(1.0f)
+00044 {
+00045 }
+00046 
+00047 
+00048 /*
+00049  * Destructor
+00050  */
+00051 CEnvSoundUser::~CEnvSoundUser()
+00052 {
+00053         vector<CEnvSoundUser*>::iterator ipe;
+00054         for ( ipe=_Children.begin(); ipe!=_Children.end(); ++ipe )
+00055         {
+00056                 delete (*ipe);
+00057         }
+00058 
+00059         vector<IPlayable*>::iterator ipp;
+00060         for ( ipp=_SrcBank.begin(); ipp!=_SrcBank.end(); ++ipp )
+00061         {
+00062                 // An IPlayable object can be a CAmbiantSource or a CSourceUser.
+00063                 // A CAmbiantSource removes its source (channels) in destructor, but not a CSourceUser
+00064                 if ( dynamic_cast<CSourceUser*>(*ipp) )
+00065                 {
+00066                         CAudioMixerUser::instance()->removeSource( static_cast<CSourceUser*>(*ipp) );
+00067                 }
+00068                 else
+00069                 {
+00070                         if ( (*ipp) != NULL )
+00071                         {
+00072                                 delete (*ipp);
+00073                         }
+00074                 }
+00075         }
+00076 
+00077         if ( _BoundingShape != NULL )
+00078         {
+00079                 delete _BoundingShape;
+00080         }
+00081 }
+00082 
+00083 
+00084 /*
+00085  * Serialize (recursive)
+00086  */
+00087 void CEnvSoundUser::serial( NLMISC::IStream& s )
+00088 {
+00089         // If you change this, increment the version number in CEnvSoundUser::load() !
+00090 
+00091         s.serial( _Transition );
+00092         s.serialPolyPtr( _BoundingShape );
+00093         s.serialContPolyPtr( _SrcBank ); // serializes sound and looping state only
+00094 
+00095         uint16 srcindex;
+00096 
+00097         if ( s.isReading() )
+00098         {
+00099                 // Select the source in the bank
+00100                 s.serial( srcindex );
+00101                 if ( ! _SrcBank.empty() )
+00102                 {
+00103                         _Source = _SrcBank[srcindex];
+00104                 }
+00105                 else
+00106                 {
+00107                         _Source = NULL;
+00108                 }
+00109 
+00110                 // Set the position which was not serialized
+00111                 if ( (_Source!=NULL) && (_BoundingShape != NULL) )
+00112                 {
+00113                         vector<IPlayable*>::iterator ipp;
+00114                         for ( ipp=_SrcBank.begin(); ipp!=_SrcBank.end(); ++ipp )
+00115                         {
+00116                                 (*ipp)->moveTo( _BoundingShape->getCenter() );
+00117                         }
+00118                 }
+00119 
+00120                 // Init the source (not transition)
+00121                 if ( ! _Transition )
+00122                 {
+00123                         if ( (_Source != NULL) )
+00124                         {
+00125                                 vector<IPlayable*>::iterator ipp;
+00126                                 if ( _BoundingShape != NULL )
+00127                                 {
+00128                                         for ( ipp=_SrcBank.begin(); ipp!=_SrcBank.end(); ++ipp )
+00129                                         {
+00130                                                 (*ipp)->initPos( const_cast<CVector*>(&(_BoundingShape->getCenter())) );
+00131                                         }
+00132                                 }
+00133                                 else
+00134                                 {
+00135                                         // The world envsound will be heard at the listener
+00136                                         for ( ipp=_SrcBank.begin(); ipp!=_SrcBank.end(); ++ipp )
+00137                                         {
+00138                                                 (*ipp)->initPos( &CAudioMixerUser::instance()->getListenPosVector() );
+00139                                         }
+00140                                 }
+00141                         }
+00142                 }
+00143         }
+00144         else
+00145         {
+00146                 uint i;
+00147                 // Find the index of the current source in the bank and serialize it out
+00148                 if ( _SrcBank.size() != 0 )
+00149                 {
+00150                         for ( i=0; i!=_SrcBank.size(); i++ )
+00151                         {
+00152                                 if ( _SrcBank[i] == _Source )
+00153                                 {
+00154                                         break;
+00155                                 }
+00156                         }
+00157                         nlassert( i != _SrcBank.size() );
+00158                         nlassert( i < 0x10000 ); // 16-bit value
+00159                         srcindex = i;
+00160                 }
+00161                 else
+00162                 {
+00163                         srcindex = 0;
+00164                 }
+00165                 s.serial( srcindex );
+00166         }
+00167 
+00168         // Tags
+00169         s.serialCont( _Tags );
+00170 #ifdef NL_DEBUG
+00171         DebugLog->display( "Envsound tags:");
+00172         vector<string>::iterator ist;
+00173         for ( ist=_Tags.begin(); ist!=_Tags.end(); ++ist )
+00174         {
+00175                 DebugLog->displayRaw( (" " + (*ist)).c_str() );
+00176         }
+00177         DebugLog->displayRawNL("");
+00178 #endif
+00179 
+00180         // Children envsounds
+00181         s.serialPtr( _Parent );
+00182         s.serialContPtr( _Children );
+00183 }
+00184 
+00185 
+00186 /*
+00187  * Select current env
+00188  */
+00189 void                    CEnvSoundUser::selectEnv( const char *tag, bool children_too )
+00190 {
+00191         uint i;
+00192         for ( i=0; i!= _Tags.size(); i++ )
+00193         {
+00194                 if ( _Tags[i] == string(tag) )
+00195                 {
+00196                         if ( _Source != NULL )
+00197                         {
+00198                                 _Source->enable( false, 1.0f );
+00199                         }
+00200                         _Source = _SrcBank[i];
+00201                         nldebug( "AM: EnvSound: Environment changed to %s", tag );
+00202                         CAudioMixerUser::instance()->getEnvSounds()->recompute();
+00203                         break;
+00204                 }
+00205         }
+00206         //nldebug( "AM: EnvSound: Environment %s not found", tag );
+00207         // Don't change _Source if not found
+00208 
+00209         // Apply to descendants
+00210         if ( children_too )
+00211         {
+00212                 vector<CEnvSoundUser*>::iterator ipc;
+00213                 for ( ipc=_Children.begin(); ipc!=_Children.end(); ++ipc )
+00214                 {
+00215                         (*ipc)->selectEnv( tag, children_too );
+00216                 }
+00217         }
+00218 }
+00219 
+00220 
+00221 /*
+00222  * Serialize file header
+00223  */
+00224 void    CEnvSoundUser::serialFileHeader( NLMISC::IStream& s )
+00225 {
+00226         // Envsounds file header
+00227         s.serialCheck( (uint32)'SEN' ); // NeL Environment Sounds
+00228         if ( s.serialVersion( 2 ) < 2 )
+00229         {
+00230                 throw EOlderStream(s);
+00231         }
+00232 
+00233         // Check CSound version (and prepare CSound::serial() backward compatibility)
+00234         CSound::FileVersion = s.serialVersion( CSound::CurrentVersion );
+00235         if ( CSound::FileVersion == 0 ) // warning: not multithread-compliant
+00236         {
+00237                 // Not supporting version 0 anymore
+00238                 throw EOlderStream(s);
+00239         }
+00240 }
+00241 
+00242 
+00243 /*
+00244  * Count the envs in the tree (call on the root)
+00245  */
+00246 uint32  CEnvSoundUser::getCount() const
+00247 {
+00248         uint32 cnt=1;
+00249         vector<CEnvSoundUser*>::const_iterator ipe;
+00250         for ( ipe=_Children.begin(); ipe!=_Children.end(); ++ipe )
+00251         {
+00252                 cnt += (*ipe)->getCount();
+00253         }
+00254         return cnt;
+00255 }
+00256 
+00257 
+00258 /*
+00259  * Load several envsounds and return the number of envsounds loaded
+00260  */
+00261 uint32 CEnvSoundUser::load( CEnvSoundUser* &envSoundTreeRoot, NLMISC::IStream& s )
+00262 {
+00263         if ( s.isReading() )
+00264         {
+00265                 serialFileHeader( s );
+00266                 s.serialPtr( envSoundTreeRoot );
+00267                 return envSoundTreeRoot->getCount();
+00268 
+00269                 // Reset CSound version
+00270                 CSound::FileVersion = CSound::CurrentVersion; // warning: not multithread-compliant : do not serialize in different threads !
+00271         }
+00272         else
+00273         {
+00274                 nlstop;
+00275                 return 0;
+00276         }
+00277 }
+00278 
+00279 
+00280 /*
+00281  * Update the stereo mixes (call evenly on the root) (recursive)
+00282  */
+00283 void                    CEnvSoundUser::update()
+00284 {
+00285         if ( _Source != NULL )
+00286         {
+00287                 _Source->update();
+00288         }
+00289         vector<CEnvSoundUser*>::iterator ipe;
+00290         for ( ipe=_Children.begin(); ipe!=_Children.end(); ++ipe )
+00291         {
+00292                 (*ipe)->update();
+00293         }
+00294 }
+00295 
+00296 
+00297 /*
+00298  * Find the area where the listener is located (recursive)
+00299  */
+00300 CEnvSoundUser *CEnvSoundUser::findCurrentEnv( const NLMISC::CVector& listenerpos )
+00301 {
+00302         // Find in children first (check from leaves to root)
+00303         vector<CEnvSoundUser*>::iterator ipe = _Children.begin();
+00304         CEnvSoundUser *found = NULL;
+00305         while ( ! ( (found) || (ipe==_Children.end()) ) )
+00306         {
+00307                 found = (*ipe)->findCurrentEnv( listenerpos );
+00308                 ipe++;
+00309         }
+00310         if ( found )
+00311                 return found;
+00312         else if ( (_BoundingShape == NULL) || (_BoundingShape->include( listenerpos )) )
+00313                 return this;
+00314         else
+00315                 return NULL;
+00316 }
+00317 
+00318 
+00319 /*
+00320  * Return the position
+00321  */
+00322 void CEnvSoundUser::getPos( NLMISC::CVector& pos ) const
+00323 {
+00324         if ( _BoundingShape == NULL )
+00325         {
+00326                 pos = CVector::Null;
+00327         }
+00328         else
+00329         {
+00330                 pos = _BoundingShape->getCenter();
+00331         }
+00332 }
+00333 
+00334 
+00335 /*
+00336  * Moves the envsound (and its transition envsound if it has one)
+00337  */
+00338 void CEnvSoundUser::setPos( const NLMISC::CVector& pos )
+00339 {
+00340         if ( _BoundingShape != NULL )
+00341         {
+00342                 // Get the vector between the pos of this envsound and the pos of its transition envsound
+00343                 CVector newpos;
+00344                 if ( (_Parent != NULL) && ( _Parent->_Transition ) )
+00345                 {
+00346                         newpos = pos + _Parent->_BoundingShape->getCenter() - _BoundingShape->getCenter();
+00347                 }
+00348                 else
+00349                 {
+00350                         newpos = pos;
+00351                 }
+00352 
+00353                 // Set the new pos
+00354                 _BoundingShape->setCenter( pos );
+00355                 if ( (_Parent != NULL) && ( _Parent->_Transition ) )
+00356                 {
+00357                         _Parent->_BoundingShape->setCenter( newpos );
+00358                         if ( _Parent->_Source != NULL )
+00359                         {
+00360                                 _Parent->_Source->moveTo( newpos );
+00361                         }
+00362                 }
+00363 
+00364                 // Recompute the entire tree
+00365                 CAudioMixerUser::instance()->getEnvSounds()->recompute();
+00366         }
+00367 }
+00368 
+00369 
+00370 /*
+00371  * Return the children envsounds
+00372  */
+00373 std::vector<UEnvSound*>& CEnvSoundUser::getChildren()
+00374 {
+00375         return (vector<UEnvSound*>&)(_Children);
+00376 }
+00377 
+00378 
+00379 /*
+00380  * Play or stop the sources (call only on the root env)
+00381  */
+00382 void CEnvSoundUser::recompute()
+00383 {
+00384         nlassert( isRoot() );
+00385 
+00386         // Find the area of the listener
+00387         CVector listenerpos;
+00388         CAudioMixerUser::instance()->getListener()->getPos( listenerpos );
+00389         CEnvSoundUser *current = findCurrentEnv( listenerpos );
+00390 
+00391         // Mark the envs that have to play their source
+00392         if ( current != NULL )
+00393         {
+00394                 current->markSources( listenerpos, 1.0f );
+00395         }
+00396         
+00397         // Enable/disable the sources in the hierarchy, and reset the marks
+00398         applySourcesMarks();
+00399 }
+00400 
+00401 
+00402 /* Prepare the related sources to play (recursive).
+00403  * In each children branch, there must be an env which is not a transition, for the recursion to stop
+00404  */
+00405 void CEnvSoundUser::markSources( const NLMISC::CVector& listenerpos, float gain )
+00406 {
+00407         // Is the listener in a transition area ?
+00408         if ( _Transition )
+00409         {
+00410                 //nldebug( "AM: EnvSound: Marking sources for transition between child and parent" );
+00411 
+00412                 // Compute the listener position to find the ratio between up and down envs
+00413                 nlassert( (_Children.size() == 1) && (_Children[0] != NULL) && (_Parent != NULL) );
+00414                 nlassert( _BoundingShape && _Children[0]->_BoundingShape );
+00415                 float ratio = _BoundingShape->getRatio( listenerpos, _Children[0]->_BoundingShape );
+00416                 nlassert( ratio >= 0.0f && ratio <= 1.0f );
+00417 
+00418                 // The child env plays at gain*ratio
+00419                 // The recursion stops because the child env is not a transition area
+00420                 _Children[0]->markSources( listenerpos, gain * ratio );
+00421 
+00422                 // The parent env (therefore the 3d source of the current env as well) plays at gain*(1-ratio)
+00423                 // The recursion stops because the parent env is not a transition area
+00424                 _Parent->markSources( listenerpos, gain * (1.0f-ratio) );
+00425         }
+00426         else
+00427         {
+00428                 //nldebug( "AM: EnvSound: Marking sources for environnement" );
+00429 
+00430                 // The listener in an environment, containing other environments (e.g. a town) or not (e.g. a room).
+00431                 // The current env plays
+00432                 _Mark = true;
+00433                 _Gain = gain;
+00434 
+00435                 // The children env (next level only) play
+00436                 vector<CEnvSoundUser*>::iterator ipe;
+00437                 for( ipe=_Children.begin(); ipe!=_Children.end(); ++ipe )
+00438                 {
+00439                         (*ipe)->_Mark = true;
+00440                         (*ipe)->_Gain = gain;
+00441                 }
+00442         }
+00443 }
+00444 
+00445 
+00446 /*
+00447  * Enable/disable the source and set general gain if enabled, and reset the source mark (recursive)
+00448  */
+00449 void CEnvSoundUser::applySourcesMarks()
+00450 {
+00451         if ( ! _Play )
+00452         {
+00453                 _Mark = false;
+00454         }
+00455         if ( _Source != NULL )
+00456         {
+00457                 _Source->enable( _Mark, _Gain );
+00458         }
+00459         _Mark = false;
+00460 
+00461         // Apply on children
+00462         vector<CEnvSoundUser*>::iterator ipe;
+00463         for ( ipe=_Children.begin(); ipe!=_Children.end(); ++ipe )
+00464         {
+00465                 (*ipe)->applySourcesMarks();
+00466         }
+00467 }
+00468 
+00469 
+00470 /*
+00471  * Set properties (EDIT)
+00472  */
+00473 void            CEnvSoundUser::setProperties( bool transition, IBoundingShape *bshape )
+00474 {
+00475         _Transition = transition;
+00476         _BoundingShape = bshape;
+00477 }
+00478 
+00479 
+00480 /*
+00481  * Add an environment source/tag (EDIT) (set a NULL source for no source at all)
+00482  * The current source always becomes the first one.
+00483  */
+00484 void            CEnvSoundUser::addEnvTag( IPlayable *source, const std::string& tag )
+00485 {
+00486         _SrcBank.push_back( source );
+00487         _Tags.push_back( tag );
+00488 
+00489         if ( _Source == NULL ) // becomes the first one and stays there
+00490         {
+00491                 _Source = source;
+00492         }
+00493 }
+00494 
+00495 
+00496 /*
+00497  * Save (output stream only) (EDIT)
+00498  */
+00499 void CEnvSoundUser::save( CEnvSoundUser *envSoundTreeRoot, NLMISC::IStream& s )
+00500 {
+00501         nlassert( ! s.isReading() );
+00502         nlassert( envSoundTreeRoot->isRoot() );
+00503 
+00504         serialFileHeader( s );
+00505         s.serialPtr( envSoundTreeRoot );
+00506 }
+00507 
+00508 
+00509 /*
+00510  * Play
+00511  */
+00512 void CEnvSoundUser::play( bool children_too )
+00513 {
+00514         playSub( children_too );
+00515 
+00516         CAudioMixerUser::instance()->getEnvSounds()->recompute();
+00517 }
+00518 
+00519 
+00520 /*
+00521  * Stop playing
+00522  */
+00523 void CEnvSoundUser::stop( bool children_too )
+00524 {
+00525         stopSub( children_too );
+00526         
+00527         CAudioMixerUser::instance()->getEnvSounds()->recompute();
+00528 }
+00529 
+00530 
+00531 /*
+00532  * Play this node, and all descendants if children_too is true, but do not recompute
+00533  */
+00534 void    CEnvSoundUser::playSub( bool children_too )
+00535 {
+00536         _Play = true;
+00537 
+00538         // Start transition as well
+00539         if ( (_Parent != NULL) && ( _Parent->_Transition ) )
+00540         {
+00541                 _Parent->_Play = true;
+00542         }
+00543 
+00544         // Apply to descendants
+00545         if ( children_too )
+00546         {
+00547                 vector<CEnvSoundUser*>::iterator ipc;
+00548                 for ( ipc=_Children.begin(); ipc!=_Children.end(); ++ipc )
+00549                 {
+00550                         (*ipc)->playSub( children_too );
+00551                 }
+00552         }
+00553 }
+00554 
+00555 
+00556 /*
+00557  * Stop playing this node, and all descendants if children_too is true, but do not recompute
+00558  */
+00559 void    CEnvSoundUser::stopSub( bool children_too )
+00560 {
+00561         _Play = false;
+00562 
+00563         // Stop transition as well
+00564         if ( (_Parent != NULL) && ( _Parent->_Transition ) )
+00565         {
+00566                 _Parent->_Play = false;
+00567         }
+00568 
+00569         // Apply to descendants
+00570         if ( children_too )
+00571         {
+00572                 vector<CEnvSoundUser*>::iterator ipc;
+00573                 for ( ipc=_Children.begin(); ipc!=_Children.end(); ++ipc )
+00574                 {
+00575                         (*ipc)->stopSub( children_too );
+00576                 }
+00577         }
+00578 }
+00579 
+00580 
+00581 /*
+00582  * Add a child (EDIT)
+00583  */
+00584 void CEnvSoundUser::addChild( CEnvSoundUser *child ) 
+00585 {
+00586         child->_Parent = this;
+00587         _Children.push_back( child );
+00588 }
+00589 
+00590 
+00591 } // NLSOUND
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1