Panda3D

openalAudioManager.h

00001 // Filename: openalAudioManager.h
00002 // Created by:  Ben Buchwald <bb2@alumni.cmu.edu>
00003 //
00004 //
00005 ////////////////////////////////////////////////////////////////////
00006 //
00007 // PANDA 3D SOFTWARE
00008 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00009 //
00010 // All use of this software is subject to the terms of the revised BSD
00011 // license.  You should have received a copy of this license along
00012 // with this source code in a file named "LICENSE."
00013 //
00014 ////////////////////////////////////////////////////////////////////
00015 
00016 
00017 #ifndef __OPENAL_AUDIO_MANAGER_H__
00018 #define __OPENAL_AUDIO_MANAGER_H__
00019 
00020 #include "pandabase.h"
00021 #ifdef HAVE_OPENAL //[
00022 
00023 #include "audioManager.h"
00024 #include "plist.h"
00025 #include "pmap.h"
00026 #include "pset.h"
00027 #include "movieAudioCursor.h"
00028 
00029 // OSX uses the OpenAL framework
00030 #ifdef IS_OSX
00031   #include <OpenAL/al.h>
00032   #include <OpenAL/alc.h>
00033 #else
00034   #include <AL/al.h>
00035   #include <AL/alc.h>
00036 #endif
00037 
00038 class OpenALAudioSound;
00039 
00040 extern void al_audio_errcheck(const char *context);
00041 extern void alc_audio_errcheck(const char *context,ALCdevice* device);
00042 
00043 class EXPCL_OPENAL_AUDIO OpenALAudioManager : public AudioManager {
00044   class SoundData;
00045   
00046   friend class OpenALAudioSound;
00047   friend class OpenALSoundData;
00048  public:
00049 
00050   //Constructor and Destructor
00051   OpenALAudioManager();
00052   virtual ~OpenALAudioManager();
00053 
00054   virtual void shutdown();
00055 
00056   virtual bool is_valid();
00057           
00058   virtual PT(AudioSound) get_sound(const string&,     bool positional = false, int mode=SM_heuristic);
00059   virtual PT(AudioSound) get_sound(MovieAudio *sound, bool positional = false, int mode=SM_heuristic);
00060   
00061   virtual void uncache_sound(const string&);
00062   virtual void clear_cache();
00063   virtual void set_cache_limit(unsigned int count);
00064   virtual unsigned int get_cache_limit() const;
00065     
00066   virtual void set_volume(float);
00067   virtual float get_volume() const;
00068           
00069   void set_play_rate(float play_rate);
00070   float get_play_rate() const;
00071 
00072   virtual void set_active(bool);
00073   virtual bool get_active() const;
00074 
00075   // This controls the "set of ears" that listens to 3D spacialized sound
00076   // px, py, pz are position coordinates. Can be 0.0f to ignore.
00077   // vx, vy, vz are a velocity vector in UNITS PER SECOND.
00078   // fx, fy and fz are the respective components of a unit forward-vector
00079   // ux, uy and uz are the respective components of a unit up-vector
00080   // These changes will NOT be invoked until audio_3d_update() is called.
00081   virtual void audio_3d_set_listener_attributes(float px, float py, float pz,
00082                                                 float vx, float xy, float xz, 
00083                                                 float fx, float fy, float fz,
00084                                                 float ux, float uy, float uz);
00085 
00086   virtual void audio_3d_get_listener_attributes(float *px, float *py, float *pz,
00087                                                 float *vx, float *vy, float *vz,
00088                                                 float *fx, float *fy, float *fz,
00089                                                 float *ux, float *uy, float *uz);
00090           
00091   // Control the "relative distance factor" for 3D spacialized audio in units-per-foot. Default is 1.0
00092   // OpenAL has no distance factor but we use this as a scale
00093   // on the min/max distances of sounds to preserve FMOD compatibility.
00094   // Also, adjusts the speed of sound to compensate for unit difference.
00095   virtual void audio_3d_set_distance_factor(float factor);
00096   virtual float audio_3d_get_distance_factor() const;
00097 
00098   // Control the presence of the Doppler effect. Default is 1.0
00099   // Exaggerated Doppler, use >1.0
00100   // Diminshed Doppler, use <1.0
00101   virtual void audio_3d_set_doppler_factor(float factor);
00102   virtual float audio_3d_get_doppler_factor() const;
00103 
00104   // Exaggerate or diminish the effect of distance on sound. Default is 1.0
00105   // Faster drop off, use >1.0
00106   // Slower drop off, use <1.0
00107   virtual void audio_3d_set_drop_off_factor(float factor);
00108   virtual float audio_3d_get_drop_off_factor() const;
00109 
00110   virtual void set_concurrent_sound_limit(unsigned int limit = 0);
00111   virtual unsigned int get_concurrent_sound_limit() const;
00112   virtual void reduce_sounds_playing_to(unsigned int count);
00113 
00114   virtual void stop_all_sounds();
00115 
00116   virtual void update();
00117 
00118 private:
00119   void make_current() const;
00120 
00121   bool can_use_audio(MovieAudioCursor *source);
00122   bool should_load_audio(MovieAudioCursor *source, int mode);
00123   
00124   SoundData *get_sound_data(MovieAudio *source, int mode);
00125 
00126   // Tell the manager that the sound dtor was called.
00127   void release_sound(OpenALAudioSound* audioSound);
00128   void increment_client_count(SoundData *sd);
00129   void decrement_client_count(SoundData *sd);
00130   void discard_excess_cache(int limit);
00131   
00132   void starting_sound(OpenALAudioSound* audio);
00133   void stopping_sound(OpenALAudioSound* audio);
00134   
00135   void cleanup();
00136   
00137 private:
00138 
00139   // An expiration queue is a list of SoundData
00140   // that are no longer being used.  They are kept
00141   // around for a little while, since it is common to
00142   // stop using a sound for a brief moment and then
00143   // quickly resume.
00144   
00145   typedef plist<void *> ExpirationQueue;
00146   ExpirationQueue _expiring_samples;
00147   ExpirationQueue _expiring_streams;
00148 
00149   // An AudioSound that uses a SoundData is called a "client"
00150   // of the SoundData.  The SoundData keeps track of how
00151   // many clients are using it.  When the number of clients
00152   // drops to zero, the SoundData is no longer in use.  The
00153   // expiration queue is a list of all SoundData that aren't
00154   // in use, in least-recently-used order.  If a SoundData
00155   // in the expiration queue gains a new client, it is removed
00156   // from the expiration queue.  When the number of sounds
00157   // in the expiration queue exceeds the cache limit, the
00158   // first sound in the expiration queue is purged.
00159 
00160   class SoundData {
00161   public:
00162     SoundData();
00163     ~SoundData();
00164     OpenALAudioManager*  _manager;
00165     PT(MovieAudio)       _movie;
00166     ALuint               _sample;
00167     PT(MovieAudioCursor) _stream;
00168     double               _length;
00169     int                  _rate;
00170     int                  _channels;
00171     int                  _client_count;
00172     ExpirationQueue::iterator _expire;
00173   };
00174 
00175   
00176   typedef phash_map<string, SoundData *> SampleCache;
00177   SampleCache _sample_cache;
00178   
00179   typedef phash_set<PT(OpenALAudioSound)> SoundsPlaying;
00180   SoundsPlaying _sounds_playing;
00181 
00182   typedef phash_set<OpenALAudioSound *> AllSounds;
00183   AllSounds _all_sounds;
00184   
00185   // State:
00186   int _cache_limit;
00187   float _volume;
00188   float _play_rate;
00189   bool _active;
00190   bool _cleanup_required;
00191   // keep a count for startup and shutdown:
00192   static int _active_managers;
00193   static bool _openal_active;
00194   unsigned int _concurrent_sound_limit;
00195   
00196   bool _is_valid;
00197   
00198   typedef pset<OpenALAudioManager *> Managers;
00199   static Managers *_managers;
00200 
00201   static ALCdevice* _device; 
00202   static ALCcontext* _context;
00203 
00204   // cache of openal sources, use only for playing sounds
00205   typedef pset<ALuint > SourceCache;
00206   static SourceCache *_al_sources;
00207 
00208   float _distance_factor;
00209   float _doppler_factor;
00210   float _drop_off_factor;
00211 
00212   ALfloat _position[3];
00213   ALfloat _velocity[3];
00214   ALfloat _forward_up[6];
00215 
00216   ////////////////////////////////////////////////////////////
00217   //These are needed for Panda's Pointer System. DO NOT ERASE!
00218   ////////////////////////////////////////////////////////////
00219 
00220  public:
00221   static TypeHandle get_class_type() {
00222     return _type_handle;
00223   }
00224   static void init_type() {
00225     AudioManager::init_type();
00226     register_type(_type_handle, "OpenALAudioManager", AudioManager::get_class_type());
00227   }
00228   virtual TypeHandle get_type() const {
00229     return get_class_type();
00230   }
00231   virtual TypeHandle force_init_type() {
00232     init_type(); 
00233     return get_class_type();
00234   }
00235 
00236  private:
00237   static TypeHandle _type_handle;
00238 
00239   ////////////////////////////////////////////////////////////
00240   //DONE
00241   ////////////////////////////////////////////////////////////
00242 
00243 };
00244 
00245 EXPCL_OPENAL_AUDIO AudioManager *Create_OpenALAudioManager();
00246 
00247 
00248 #endif //]
00249 
00250 #endif /* __OPENAL_AUDIO_MANAGER_H__ */
 All Classes Functions Variables Enumerations