Panda3D
Loading...
Searching...
No Matches
openalAudioManager.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file openalAudioManager.h
10 * @author Ben Buchwald <bb2@alumni.cmu.edu>
11 */
12
13#ifndef __OPENAL_AUDIO_MANAGER_H__
14#define __OPENAL_AUDIO_MANAGER_H__
15
16#include "pandabase.h"
17
18#include "audioManager.h"
19#include "plist.h"
20#include "pmap.h"
21#include "pset.h"
22#include "movieAudioCursor.h"
23#include "reMutex.h"
24
25// OSX uses the OpenAL framework
26#ifdef HAVE_OPENAL_FRAMEWORK
27 #include <OpenAL/al.h>
28 #include <OpenAL/alc.h>
29#else
30 #include <AL/al.h>
31 #include <AL/alc.h>
32#endif
33
35
36extern void al_audio_errcheck(const char *context);
37extern void alc_audio_errcheck(const char *context,ALCdevice* device);
38
39class EXPCL_OPENAL_AUDIO OpenALAudioManager : public AudioManager {
40 class SoundData;
41
42 friend class OpenALAudioSound;
43 friend class OpenALSoundData;
44
45 public:
46 // Constructor and Destructor
48 virtual ~OpenALAudioManager();
49
50 virtual void shutdown();
51
52 virtual bool is_valid();
53
54 virtual PT(AudioSound) get_sound(const Filename &, bool positional = false, int mode=SM_heuristic);
55 virtual PT(AudioSound) get_sound(MovieAudio *sound, bool positional = false, int mode=SM_heuristic);
56
57 virtual void uncache_sound(const Filename &);
58 virtual void clear_cache();
59 virtual void set_cache_limit(unsigned int count);
60 virtual unsigned int get_cache_limit() const;
61
62 virtual void set_volume(PN_stdfloat);
63 virtual PN_stdfloat get_volume() const;
64
65 void set_play_rate(PN_stdfloat play_rate);
66 PN_stdfloat get_play_rate() const;
67
68 virtual void set_active(bool);
69 virtual bool get_active() const;
70
71 // This controls the "set of ears" that listens to 3D spacialized sound px,
72 // py, pz are position coordinates. Can be 0.0f to ignore. vx, vy, vz are
73 // a velocity vector in UNITS PER SECOND. fx, fy and fz are the respective
74 // components of a unit forward-vector ux, uy and uz are the respective
75 // components of a unit up-vector These changes will NOT be invoked until
76 // audio_3d_update() is called.
77 virtual void audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz,
78 PN_stdfloat vx, PN_stdfloat xy, PN_stdfloat xz,
79 PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz,
80 PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz);
81
82 virtual void audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz,
83 PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz,
84 PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz,
85 PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz);
86
87
88 // Control the "relative scale that sets the distance factor" units for 3D
89 // spacialized audio. This is a float in units-per-meter. Default value is
90 // 1.0, which means that Panda units are understood as meters; for e.g.
91 // feet, set 3.28. This factor is applied only to Fmod and OpenAL at the
92 // moment.
93 // OpenAL in fact has no distance factor like Fmod, but works with the speed
94 // of sound instead, so we use this factor to scale the speed of sound.
95 virtual void audio_3d_set_distance_factor(PN_stdfloat factor);
96 virtual PN_stdfloat audio_3d_get_distance_factor() const;
97
98 // Control the presence of the Doppler effect. Default is 1.0 Exaggerated
99 // Doppler, use >1.0 Diminshed Doppler, use <1.0
100 virtual void audio_3d_set_doppler_factor(PN_stdfloat factor);
101 virtual PN_stdfloat audio_3d_get_doppler_factor() const;
102
103 // Exaggerate or diminish the effect of distance on sound. Default is 1.0
104 // Faster drop off, use >1.0 Slower drop off, use <1.0
105 virtual void audio_3d_set_drop_off_factor(PN_stdfloat factor);
106 virtual PN_stdfloat audio_3d_get_drop_off_factor() const;
107
108 virtual void set_concurrent_sound_limit(unsigned int limit = 0);
109 virtual unsigned int get_concurrent_sound_limit() const;
110 virtual void reduce_sounds_playing_to(unsigned int count);
111
112 virtual void stop_all_sounds();
113
114 virtual void update();
115
116private:
117 std::string select_audio_device();
118
119 void make_current() const;
120
121 bool can_use_audio(MovieAudioCursor *source);
122 bool should_load_audio(MovieAudioCursor *source, int mode);
123
124 SoundData *get_sound_data(MovieAudio *source, int mode);
125
126 // Tell the manager that the sound dtor was called.
127 void release_sound(OpenALAudioSound* audioSound);
128 void increment_client_count(SoundData *sd);
129 void decrement_client_count(SoundData *sd);
130 void discard_excess_cache(int limit);
131
132 void delete_buffer(ALuint buffer);
133
134 void starting_sound(OpenALAudioSound* audio);
135 void stopping_sound(OpenALAudioSound* audio);
136
137 void cleanup();
138
139private:
140 // This global lock protects all access to OpenAL library interfaces.
141 static ReMutex _lock;
142
143 // An expiration queue is a list of SoundData that are no longer being used.
144 // They are kept around for a little while, since it is common to stop using
145 // a sound for a brief moment and then quickly resume.
146
148 ExpirationQueue _expiring_samples;
149 ExpirationQueue _expiring_streams;
150
151/*
152 * An AudioSound that uses a SoundData is called a "client" of the SoundData.
153 * The SoundData keeps track of how many clients are using it. When the
154 * number of clients drops to zero, the SoundData is no longer in use. The
155 * expiration queue is a list of all SoundData that aren't in use, in least-
156 * recently-used order. If a SoundData in the expiration queue gains a new
157 * client, it is removed from the expiration queue. When the number of sounds
158 * in the expiration queue exceeds the cache limit, the first sound in the
159 * expiration queue is purged.
160 */
161
162 class SoundData {
163 public:
164 SoundData();
165 ~SoundData();
166 OpenALAudioManager* _manager;
167 PT(MovieAudio) _movie;
168 ALuint _sample;
169 PT(MovieAudioCursor) _stream;
170 double _length;
171 int _rate;
172 int _channels;
173 int _client_count;
174 ExpirationQueue::iterator _expire;
175 };
176
177
178 typedef phash_map<std::string, SoundData *> SampleCache;
179 SampleCache _sample_cache;
180
181 typedef phash_set<PT(OpenALAudioSound)> SoundsPlaying;
182 SoundsPlaying _sounds_playing;
183
184 typedef phash_set<OpenALAudioSound *> AllSounds;
185 AllSounds _all_sounds;
186
187 // State:
188 int _cache_limit;
189 PN_stdfloat _volume;
190 PN_stdfloat _play_rate;
191 bool _active;
192 bool _cleanup_required;
193 // keep a count for startup and shutdown:
194 static int _active_managers;
195 static bool _openal_active;
196 unsigned int _concurrent_sound_limit;
197
198 bool _is_valid;
199
201 static Managers *_managers;
202
203 static ALCdevice* _device;
204 static ALCcontext* _context;
205
206 // cache of openal sources, use only for playing sounds
208 static SourceCache *_al_sources;
209
210 PN_stdfloat _distance_factor;
211 PN_stdfloat _doppler_factor;
212 PN_stdfloat _drop_off_factor;
213
214 ALfloat _position[3];
215 ALfloat _velocity[3];
216 ALfloat _forward_up[6];
217
218 // These are needed for Panda's Pointer System. DO NOT ERASE!
219
220 public:
221 static TypeHandle get_class_type() {
222 return _type_handle;
223 }
224 static void init_type() {
225 AudioManager::init_type();
226 register_type(_type_handle, "OpenALAudioManager", AudioManager::get_class_type());
227 }
228 virtual TypeHandle get_type() const {
229 return get_class_type();
230 }
231 virtual TypeHandle force_init_type() {
232 init_type();
233 return get_class_type();
234 }
235
236 private:
237 static TypeHandle _type_handle;
238
239 // DONE
240
241};
242
243EXPCL_OPENAL_AUDIO AudioManager *Create_OpenALAudioManager();
244
245#endif /* __OPENAL_AUDIO_MANAGER_H__ */
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void shutdown()
Call this at exit time to shut down the audio system.
virtual void update()
Must be called every frame.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
A MovieAudio is actually any source that provides a sequence of audio samples.
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition movieAudio.h:44
A reentrant mutex.
Definition reMutex.h:34
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is our own Panda specialization on the default STL list.
Definition plist.h:35
This is our own Panda specialization on the default STL set.
Definition pset.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EXPCL_OPENAL_AUDIO AudioManager * Create_OpenALAudioManager()
Factory Function.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...