Panda3D
|
00001 // Filename: audioManager.cxx 00002 // Created by: skyler (June 6, 2001) 00003 // Prior system by: cary 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 #include "config_audio.h" 00017 #include "audioManager.h" 00018 #include "atomicAdjust.h" 00019 #include "nullAudioManager.h" 00020 #include "windowsRegistry.h" 00021 #include "virtualFileSystem.h" 00022 #include "config_util.h" 00023 #include "load_dso.h" 00024 00025 #ifdef WIN32 00026 #include <windows.h> // For GetSystemDirectory() 00027 #endif 00028 00029 00030 TypeHandle AudioManager::_type_handle; 00031 00032 00033 namespace { 00034 AudioManager *create_NullAudioManager() { 00035 audio_debug("create_NullAudioManager()"); 00036 return new NullAudioManager(); 00037 } 00038 } 00039 00040 Create_AudioManager_proc* AudioManager::_create_AudioManager 00041 =create_NullAudioManager; 00042 00043 void AudioManager::register_AudioManager_creator(Create_AudioManager_proc* proc) { 00044 nassertv(_create_AudioManager==create_NullAudioManager); 00045 _create_AudioManager=proc; 00046 } 00047 00048 00049 00050 // Factory method for getting a platform specific AudioManager: 00051 PT(AudioManager) AudioManager::create_AudioManager() { 00052 audio_debug("create_AudioManager()\n audio_library_name=\""<<audio_library_name<<"\""); 00053 static bool lib_load = false; 00054 if (!lib_load) { 00055 lib_load = true; 00056 if (!audio_library_name.empty() && !(audio_library_name == "null")) { 00057 Filename dl_name = Filename::dso_filename( 00058 "lib"+string(audio_library_name)+".so"); 00059 dl_name.to_os_specific(); 00060 audio_debug(" dl_name=\""<<dl_name<<"\""); 00061 void *handle = load_dso(get_plugin_path().get_value(), dl_name); 00062 if (handle == (void *)NULL) { 00063 audio_error(" load_dso(" << dl_name << ") failed, will use NullAudioManager"); 00064 audio_error(" "<<load_dso_error()); 00065 nassertr(_create_AudioManager == create_NullAudioManager, NULL); 00066 } else { 00067 // Get the special function from the dso, which should return 00068 // the AudioManager factory function. 00069 string lib_name = audio_library_name; 00070 if (lib_name.substr(0, 2) == "p3") { 00071 lib_name = lib_name.substr(2); 00072 } 00073 string symbol_name = "get_audio_manager_func_" + lib_name; 00074 void *dso_symbol = get_dso_symbol(handle, symbol_name); 00075 if (audio_cat.is_debug()) { 00076 audio_cat.debug() 00077 << "symbol of " << symbol_name << " = " << dso_symbol << "\n"; 00078 } 00079 00080 if (dso_symbol == (void *)NULL) { 00081 // Couldn't find the module function. 00082 unload_dso(handle); 00083 handle = NULL; 00084 audio_error(" Audio library did not provide get_audio_manager_func, will use NullAudioManager"); 00085 } else { 00086 typedef Create_AudioManager_proc *FuncType(); 00087 Create_AudioManager_proc *factory_func = (*(FuncType *)dso_symbol)(); 00088 AudioManager::register_AudioManager_creator(factory_func); 00089 } 00090 } 00091 } 00092 } 00093 PT(AudioManager) am = (*_create_AudioManager)(); 00094 if (!am->is_exact_type(NullAudioManager::get_class_type()) && !am->is_valid()) { 00095 audio_error(" " << am->get_type() << " is not valid, will use NullAudioManager"); 00096 am = create_NullAudioManager(); 00097 } 00098 return am; 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: AudioManager::Destructor 00103 // Access: Published, Virtual 00104 // Description: 00105 //////////////////////////////////////////////////////////////////// 00106 AudioManager:: 00107 ~AudioManager() { 00108 if (_null_sound != (AudioSound *)NULL) { 00109 unref_delete((AudioSound *)_null_sound); 00110 } 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: AudioManager::Constructor 00115 // Access: Protected 00116 // Description: 00117 //////////////////////////////////////////////////////////////////// 00118 AudioManager:: 00119 AudioManager() { 00120 _null_sound = NULL; 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: AudioManager::shutdown 00125 // Access: Published, Virtual 00126 // Description: Call this at exit time to shut down the audio system. 00127 // This will invalidate all currently-active 00128 // AudioManagers and AudioSounds in the system. If you 00129 // change your mind and want to play sounds again, you 00130 // will have to recreate all of these objects. 00131 //////////////////////////////////////////////////////////////////// 00132 void AudioManager:: 00133 shutdown() { 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: AudioManager::get_null_sound 00138 // Access: Public 00139 // Description: Returns a special NullAudioSound object that has all 00140 // the interface of a normal sound object, but plays no 00141 // sound. This same object may also be returned by 00142 // get_sound() if it fails. 00143 //////////////////////////////////////////////////////////////////// 00144 PT(AudioSound) AudioManager:: 00145 get_null_sound() { 00146 if (_null_sound == (AudioSound *)NULL) { 00147 AudioSound *new_sound = new NullAudioSound; 00148 new_sound->ref(); 00149 void *result = AtomicAdjust::compare_and_exchange_ptr(_null_sound, (void *)NULL, (void *)new_sound); 00150 if (result != NULL) { 00151 // Someone else must have assigned the AudioSound first. OK. 00152 nassertr(_null_sound != new_sound, NULL); 00153 unref_delete(new_sound); 00154 } 00155 nassertr(_null_sound != NULL, NULL); 00156 } 00157 00158 return (AudioSound *)_null_sound; 00159 } 00160 00161 //////////////////////////////////////////////////////////////////// 00162 // Function: AudioManager::getSpeakerSetup() 00163 // Access: Published 00164 // Description: 00165 //////////////////////////////////////////////////////////////////// 00166 int AudioManager:: 00167 getSpeakerSetup() { 00168 // intentionally blank 00169 return 0; 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function: AudioManager::setSpeakerSetup() 00174 // Access: Published 00175 // Description: 00176 //////////////////////////////////////////////////////////////////// 00177 void AudioManager:: 00178 setSpeakerSetup(SpeakerModeCategory cat) { 00179 // intentionally blank 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: AudioManager::configure_filters 00184 // Access: Published 00185 // Description: Configures the global DSP filter chain. 00186 // 00187 // There is no guarantee that any given configuration 00188 // will be supported by the implementation. The only 00189 // way to find out what's supported is to call 00190 // configure_filters. If it returns true, the 00191 // configuration is supported. 00192 //////////////////////////////////////////////////////////////////// 00193 bool AudioManager:: 00194 configure_filters(FilterProperties *config) { 00195 const FilterProperties::ConfigVector &conf = config->get_config(); 00196 if (conf.empty()) { 00197 return true; 00198 } else { 00199 return false; 00200 } 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: AudioManager::update() 00205 // Access: Published, Virtual 00206 // Description: Must be called every frame. Failure to call this 00207 // every frame could cause problems for some audio 00208 // managers. 00209 //////////////////////////////////////////////////////////////////// 00210 void AudioManager:: 00211 update() { 00212 // Intentionally blank. 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: AudioManager::audio_3d_set_listener_attributes 00217 // Access: Public 00218 // Description: 00219 //////////////////////////////////////////////////////////////////// 00220 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) { 00221 // intentionally blank. 00222 } 00223 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: AudioManager::audio_3d_get_listener_attributes 00226 // Access: Public 00227 // Description: 00228 //////////////////////////////////////////////////////////////////// 00229 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) { 00230 // intentionally blank. 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: AudioManager::audio_3d_set_distance_factor 00235 // Access: Public 00236 // Description: 00237 //////////////////////////////////////////////////////////////////// 00238 void AudioManager::audio_3d_set_distance_factor(PN_stdfloat factor) { 00239 // intentionally blank. 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: AudioManager::audio_3d_get_distance_factor 00244 // Access: Public 00245 // Description: 00246 //////////////////////////////////////////////////////////////////// 00247 PN_stdfloat AudioManager::audio_3d_get_distance_factor() const { 00248 // intentionally blank. 00249 return 0.0f; 00250 } 00251 00252 //////////////////////////////////////////////////////////////////// 00253 // Function: AudioManager::audio_3d_set_doppler_factor 00254 // Access: Public 00255 // Description: 00256 //////////////////////////////////////////////////////////////////// 00257 void AudioManager::audio_3d_set_doppler_factor(PN_stdfloat factor) { 00258 // intentionally blank. 00259 } 00260 00261 //////////////////////////////////////////////////////////////////// 00262 // Function: AudioManager::audio_3d_get_doppler_factor 00263 // Access: Public 00264 // Description: 00265 //////////////////////////////////////////////////////////////////// 00266 PN_stdfloat AudioManager::audio_3d_get_doppler_factor() const { 00267 // intentionally blank. 00268 return 0.0f; 00269 } 00270 00271 //////////////////////////////////////////////////////////////////// 00272 // Function: AudioManager::audio_3d_set_drop_off_factor 00273 // Access: Public 00274 // Description: 00275 //////////////////////////////////////////////////////////////////// 00276 void AudioManager::audio_3d_set_drop_off_factor(PN_stdfloat factor) { 00277 // intentionally blank. 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: AudioManager::audio_3d_get_drop_off_factor 00282 // Access: Public 00283 // Description: 00284 //////////////////////////////////////////////////////////////////// 00285 PN_stdfloat AudioManager::audio_3d_get_drop_off_factor() const { 00286 // intentionally blank. 00287 return 0.0f; 00288 } 00289 00290 //////////////////////////////////////////////////////////////////// 00291 // Function: AudioManager::get_dls_pathname 00292 // Access: Published, Static 00293 // Description: Returns the full pathname to the DLS file, as 00294 // specified by the Config.prc file, or the default for 00295 // the current OS if appropriate. Returns empty string 00296 // if the DLS file is unavailable. 00297 //////////////////////////////////////////////////////////////////// 00298 Filename AudioManager:: 00299 get_dls_pathname() { 00300 Filename dls_filename = audio_dls_file; 00301 if (!dls_filename.empty()) { 00302 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); 00303 vfs->resolve_filename(dls_filename, get_model_path()); 00304 00305 return dls_filename; 00306 } 00307 00308 #ifdef WIN32 00309 Filename pathname; 00310 00311 // Get the registry key from DirectMusic 00312 string os_filename = WindowsRegistry::get_string_value("SOFTWARE\\Microsoft\\DirectMusic", "GMFilePath", ""); 00313 00314 if (!os_filename.empty()) { 00315 pathname = Filename::from_os_specific(os_filename); 00316 } else { 00317 char sysdir[MAX_PATH+1]; 00318 GetSystemDirectory(sysdir,MAX_PATH+1); 00319 pathname = Filename(Filename::from_os_specific(sysdir), Filename("drivers/gm.dls")); 00320 } 00321 pathname.make_true_case(); 00322 return pathname; 00323 00324 #elif defined(IS_OSX) 00325 // This appears to be the standard place for this file on OSX 10.4. 00326 return Filename("/System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls"); 00327 00328 #else 00329 return Filename(); 00330 #endif 00331 } 00332 00333 //////////////////////////////////////////////////////////////////// 00334 // Function: AudioManager::output 00335 // Access: Published, Virtual 00336 // Description: 00337 //////////////////////////////////////////////////////////////////// 00338 void AudioManager:: 00339 output(ostream &out) const { 00340 out << get_type(); 00341 } 00342 00343 //////////////////////////////////////////////////////////////////// 00344 // Function: AudioManager::write 00345 // Access: Published, Virtual 00346 // Description: 00347 //////////////////////////////////////////////////////////////////// 00348 void AudioManager:: 00349 write(ostream &out) const { 00350 out << (*this) << "\n"; 00351 } 00352 00353 //////////////////////////////////////////////////////////////////// 00354 // Function: AudioManager::set_speaker_configuration 00355 // Access: Published 00356 // Description: For use only with Miles. 00357 //////////////////////////////////////////////////////////////////// 00358 void AudioManager:: 00359 set_speaker_configuration(LVecBase3 *speaker1, LVecBase3 *speaker2, LVecBase3 *speaker3, LVecBase3 *speaker4, LVecBase3 *speaker5, LVecBase3 *speaker6, LVecBase3 *speaker7, LVecBase3 *speaker8, LVecBase3 *speaker9) { 00360 // intentionally blank 00361 }