Panda3D
|
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__ */