Panda3D
 All Classes Functions Variables Enumerations
audioManager.cxx
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 }
 All Classes Functions Variables Enumerations