Panda3D
 All Classes Functions Variables Enumerations
audioManager.cxx
1 // Filename: audioManager.cxx
2 // Created by: skyler (June 6, 2001)
3 // Prior system by: cary
4 //
5 ////////////////////////////////////////////////////////////////////
6 //
7 // PANDA 3D SOFTWARE
8 // Copyright (c) Carnegie Mellon University. All rights reserved.
9 //
10 // All use of this software is subject to the terms of the revised BSD
11 // license. You should have received a copy of this license along
12 // with this source code in a file named "LICENSE."
13 //
14 ////////////////////////////////////////////////////////////////////
15 
16 #include "config_audio.h"
17 #include "audioManager.h"
18 #include "atomicAdjust.h"
19 #include "nullAudioManager.h"
20 #include "windowsRegistry.h"
21 #include "virtualFileSystem.h"
22 #include "config_util.h"
23 #include "load_dso.h"
24 
25 #ifdef WIN32
26 #include <windows.h> // For GetSystemDirectory()
27 #endif
28 
29 
30 TypeHandle AudioManager::_type_handle;
31 
32 
33 namespace {
34  AudioManager *create_NullAudioManager() {
35  audio_debug("create_NullAudioManager()");
36  return new NullAudioManager();
37  }
38 }
39 
40 Create_AudioManager_proc* AudioManager::_create_AudioManager
41  =create_NullAudioManager;
42 
43 void AudioManager::register_AudioManager_creator(Create_AudioManager_proc* proc) {
44  nassertv(_create_AudioManager==create_NullAudioManager);
45  _create_AudioManager=proc;
46 }
47 
48 
49 
50 // Factory method for getting a platform specific AudioManager:
51 PT(AudioManager) AudioManager::create_AudioManager() {
52  audio_debug("create_AudioManager()\n audio_library_name=\""<<audio_library_name<<"\"");
53  static bool lib_load = false;
54  if (!lib_load) {
55  lib_load = true;
56  if (!audio_library_name.empty() && !(audio_library_name == "null")) {
57  Filename dl_name = Filename::dso_filename(
58  "lib"+string(audio_library_name)+".so");
59  dl_name.to_os_specific();
60  audio_debug(" dl_name=\""<<dl_name<<"\"");
61  void *handle = load_dso(get_plugin_path().get_value(), dl_name);
62  if (handle == (void *)NULL) {
63  audio_error(" load_dso(" << dl_name << ") failed, will use NullAudioManager");
64  audio_error(" "<<load_dso_error());
65  nassertr(_create_AudioManager == create_NullAudioManager, NULL);
66  } else {
67  // Get the special function from the dso, which should return
68  // the AudioManager factory function.
69  string lib_name = audio_library_name;
70  if (lib_name.substr(0, 2) == "p3") {
71  lib_name = lib_name.substr(2);
72  }
73  string symbol_name = "get_audio_manager_func_" + lib_name;
74  void *dso_symbol = get_dso_symbol(handle, symbol_name);
75  if (audio_cat.is_debug()) {
76  audio_cat.debug()
77  << "symbol of " << symbol_name << " = " << dso_symbol << "\n";
78  }
79 
80  if (dso_symbol == (void *)NULL) {
81  // Couldn't find the module function.
82  unload_dso(handle);
83  handle = NULL;
84  audio_error(" Audio library did not provide get_audio_manager_func, will use NullAudioManager");
85  } else {
86  typedef Create_AudioManager_proc *FuncType();
87  Create_AudioManager_proc *factory_func = (*(FuncType *)dso_symbol)();
88  AudioManager::register_AudioManager_creator(factory_func);
89  }
90  }
91  }
92  }
93  PT(AudioManager) am = (*_create_AudioManager)();
94  if (!am->is_exact_type(NullAudioManager::get_class_type()) && !am->is_valid()) {
95  audio_error(" " << am->get_type() << " is not valid, will use NullAudioManager");
96  am = create_NullAudioManager();
97  }
98  return am;
99 }
100 
101 ////////////////////////////////////////////////////////////////////
102 // Function: AudioManager::Destructor
103 // Access: Published, Virtual
104 // Description:
105 ////////////////////////////////////////////////////////////////////
106 AudioManager::
107 ~AudioManager() {
108  if (_null_sound != (AudioSound *)NULL) {
109  unref_delete((AudioSound *)_null_sound);
110  }
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function: AudioManager::Constructor
115 // Access: Protected
116 // Description:
117 ////////////////////////////////////////////////////////////////////
118 AudioManager::
119 AudioManager() {
120  _null_sound = NULL;
121 }
122 
123 ////////////////////////////////////////////////////////////////////
124 // Function: AudioManager::shutdown
125 // Access: Published, Virtual
126 // Description: Call this at exit time to shut down the audio system.
127 // This will invalidate all currently-active
128 // AudioManagers and AudioSounds in the system. If you
129 // change your mind and want to play sounds again, you
130 // will have to recreate all of these objects.
131 ////////////////////////////////////////////////////////////////////
132 void AudioManager::
134 }
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: AudioManager::get_null_sound
138 // Access: Public
139 // Description: Returns a special NullAudioSound object that has all
140 // the interface of a normal sound object, but plays no
141 // sound. This same object may also be returned by
142 // get_sound() if it fails.
143 ////////////////////////////////////////////////////////////////////
145 get_null_sound() {
146  if (_null_sound == (AudioSound *)NULL) {
147  AudioSound *new_sound = new NullAudioSound;
148  new_sound->ref();
149  void *result = AtomicAdjust::compare_and_exchange_ptr(_null_sound, (void *)NULL, (void *)new_sound);
150  if (result != NULL) {
151  // Someone else must have assigned the AudioSound first. OK.
152  nassertr(_null_sound != new_sound, NULL);
153  unref_delete(new_sound);
154  }
155  nassertr(_null_sound != NULL, NULL);
156  }
157 
158  return (AudioSound *)_null_sound;
159 }
160 
161 ////////////////////////////////////////////////////////////////////
162 // Function: AudioManager::getSpeakerSetup()
163 // Access: Published
164 // Description:
165 ////////////////////////////////////////////////////////////////////
166 int AudioManager::
167 getSpeakerSetup() {
168  // intentionally blank
169  return 0;
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: AudioManager::setSpeakerSetup()
174 // Access: Published
175 // Description:
176 ////////////////////////////////////////////////////////////////////
177 void AudioManager::
178 setSpeakerSetup(SpeakerModeCategory cat) {
179  // intentionally blank
180 }
181 
182 ////////////////////////////////////////////////////////////////////
183 // Function: AudioManager::configure_filters
184 // Access: Published
185 // Description: Configures the global DSP filter chain.
186 //
187 // There is no guarantee that any given configuration
188 // will be supported by the implementation. The only
189 // way to find out what's supported is to call
190 // configure_filters. If it returns true, the
191 // configuration is supported.
192 ////////////////////////////////////////////////////////////////////
193 bool AudioManager::
195  const FilterProperties::ConfigVector &conf = config->get_config();
196  if (conf.empty()) {
197  return true;
198  } else {
199  return false;
200  }
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: AudioManager::update()
205 // Access: Published, Virtual
206 // Description: Must be called every frame. Failure to call this
207 // every frame could cause problems for some audio
208 // managers.
209 ////////////////////////////////////////////////////////////////////
210 void AudioManager::
212  // Intentionally blank.
213 }
214 
215 ////////////////////////////////////////////////////////////////////
216 // Function: AudioManager::audio_3d_set_listener_attributes
217 // Access: Public
218 // Description:
219 ////////////////////////////////////////////////////////////////////
220 void AudioManager::audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
221  // intentionally blank.
222 }
223 
224 ////////////////////////////////////////////////////////////////////
225 // Function: AudioManager::audio_3d_get_listener_attributes
226 // Access: Public
227 // Description:
228 ////////////////////////////////////////////////////////////////////
229 void AudioManager::audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
230  // intentionally blank.
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: AudioManager::audio_3d_set_distance_factor
235 // Access: Public
236 // Description:
237 ////////////////////////////////////////////////////////////////////
238 void AudioManager::audio_3d_set_distance_factor(PN_stdfloat factor) {
239  // intentionally blank.
240 }
241 
242 ////////////////////////////////////////////////////////////////////
243 // Function: AudioManager::audio_3d_get_distance_factor
244 // Access: Public
245 // Description:
246 ////////////////////////////////////////////////////////////////////
247 PN_stdfloat AudioManager::audio_3d_get_distance_factor() const {
248  // intentionally blank.
249  return 0.0f;
250 }
251 
252 ////////////////////////////////////////////////////////////////////
253 // Function: AudioManager::audio_3d_set_doppler_factor
254 // Access: Public
255 // Description:
256 ////////////////////////////////////////////////////////////////////
257 void AudioManager::audio_3d_set_doppler_factor(PN_stdfloat factor) {
258  // intentionally blank.
259 }
260 
261 ////////////////////////////////////////////////////////////////////
262 // Function: AudioManager::audio_3d_get_doppler_factor
263 // Access: Public
264 // Description:
265 ////////////////////////////////////////////////////////////////////
266 PN_stdfloat AudioManager::audio_3d_get_doppler_factor() const {
267  // intentionally blank.
268  return 0.0f;
269 }
270 
271 ////////////////////////////////////////////////////////////////////
272 // Function: AudioManager::audio_3d_set_drop_off_factor
273 // Access: Public
274 // Description:
275 ////////////////////////////////////////////////////////////////////
276 void AudioManager::audio_3d_set_drop_off_factor(PN_stdfloat factor) {
277  // intentionally blank.
278 }
279 
280 ////////////////////////////////////////////////////////////////////
281 // Function: AudioManager::audio_3d_get_drop_off_factor
282 // Access: Public
283 // Description:
284 ////////////////////////////////////////////////////////////////////
285 PN_stdfloat AudioManager::audio_3d_get_drop_off_factor() const {
286  // intentionally blank.
287  return 0.0f;
288 }
289 
290 ////////////////////////////////////////////////////////////////////
291 // Function: AudioManager::get_dls_pathname
292 // Access: Published, Static
293 // Description: Returns the full pathname to the DLS file, as
294 // specified by the Config.prc file, or the default for
295 // the current OS if appropriate. Returns empty string
296 // if the DLS file is unavailable.
297 ////////////////////////////////////////////////////////////////////
300  Filename dls_filename = audio_dls_file;
301  if (!dls_filename.empty()) {
303  vfs->resolve_filename(dls_filename, get_model_path());
304 
305  return dls_filename;
306  }
307 
308 #ifdef WIN32
309  Filename pathname;
310 
311  // Get the registry key from DirectMusic
312  string os_filename = WindowsRegistry::get_string_value("SOFTWARE\\Microsoft\\DirectMusic", "GMFilePath", "");
313 
314  if (!os_filename.empty()) {
315  pathname = Filename::from_os_specific(os_filename);
316  } else {
317  char sysdir[MAX_PATH+1];
318  GetSystemDirectory(sysdir,MAX_PATH+1);
319  pathname = Filename(Filename::from_os_specific(sysdir), Filename("drivers/gm.dls"));
320  }
321  pathname.make_true_case();
322  return pathname;
323 
324 #elif defined(IS_OSX)
325  // This appears to be the standard place for this file on OSX 10.4.
326  return Filename("/System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls");
327 
328 #else
329  return Filename();
330 #endif
331 }
332 
333 ////////////////////////////////////////////////////////////////////
334 // Function: AudioManager::output
335 // Access: Published, Virtual
336 // Description:
337 ////////////////////////////////////////////////////////////////////
338 void AudioManager::
339 output(ostream &out) const {
340  out << get_type();
341 }
342 
343 ////////////////////////////////////////////////////////////////////
344 // Function: AudioManager::write
345 // Access: Published, Virtual
346 // Description:
347 ////////////////////////////////////////////////////////////////////
348 void AudioManager::
349 write(ostream &out) const {
350  out << (*this) << "\n";
351 }
352 
353 ////////////////////////////////////////////////////////////////////
354 // Function: AudioManager::set_speaker_configuration
355 // Access: Published
356 // Description: For use only with Miles.
357 ////////////////////////////////////////////////////////////////////
358 void AudioManager::
359 set_speaker_configuration(LVecBase3 *speaker1, LVecBase3 *speaker2, LVecBase3 *speaker3, LVecBase3 *speaker4, LVecBase3 *speaker5, LVecBase3 *speaker6, LVecBase3 *speaker7, LVecBase3 *speaker8, LVecBase3 *speaker9) {
360  // intentionally blank
361 }
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
virtual bool configure_filters(FilterProperties *config)
Configures the global DSP filter chain.
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS&#39;s file system.
static Filename get_dls_pathname()
Returns the full pathname to the DLS file, as specified by the Config.prc file, or the default for th...
Stores a configuration for a set of audio DSP filters.
bool make_true_case()
On a case-insensitive operating system (e.g.
Definition: filename.cxx:1120
const ConfigVector & get_config()
Intended for use by AudioManager and AudioSound implementations: allows access to the config vector...
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
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const string &default_extension=string()) const
Searches the given search path for the filename.
string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
Definition: filename.cxx:1196
virtual void shutdown()
Call this at exit time to shut down the audio system.
void ref() const
Explicitly increments the reference count.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual void set_speaker_configuration(LVecBase3 *speaker1, LVecBase3 *speaker2=NULL, LVecBase3 *speaker3=NULL, LVecBase3 *speaker4=NULL, LVecBase3 *speaker5=NULL, LVecBase3 *speaker6=NULL, LVecBase3 *speaker7=NULL, LVecBase3 *speaker8=NULL, LVecBase3 *speaker9=NULL)
For use only with Miles.
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).
Definition: filename.cxx:332