Parcourir la source

fix volume, and disable on initialize failure

Cary Sandvig il y a 25 ans
Parent
commit
23a4ae9a0d

+ 12 - 3
panda/src/audio/audio_linux_traits.cxx

@@ -139,6 +139,8 @@ static void mix_buffer(byte* buf) {
 static void update_linux(void) {
   if (buffers.empty())
     return;
+  if (!audio_is_active)
+    return;
   switch (want_buffers) {
   case 0:
     // all buffers are full right now.  This is a good state.
@@ -162,32 +164,37 @@ static void update_linux(void) {
 static void* internal_update(void*) {
   if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) {
     audio_cat->error() << "could not open '" << audio_device << "'" << endl;
+    audio_is_active = false;
     return (void*)0L;
   }
   // this one I don't know about
   int fragsize = 0x0004000c;
   if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
     audio_cat->error() << "faied to set fragment size" << endl;
+    audio_is_active = false;
     return (void*)0L;
   }
   // for now signed, 16-bit, little endian
   int format = AFMT_S16_LE;
   if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
     audio_cat->error() << "failed to set format on the dsp" << endl;
+    audio_is_active = false;
     return (void*)0L;
   }
   // set stereo
   int stereo = 1;
   if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
     audio_cat->error() << "failed to set stereo on the dsp" << endl;
+    audio_is_active = false;
     return (void*)0L;
   }
   // set the frequency
   if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
     audio_cat->error() << "failed to set frequency on the dsp" << endl;
+    audio_is_active = false;
     return (void*)0L;
   }
-  while (!stop_mixing) {
+  while (!stop_mixing && !audio_is_active) {
     if (have_buffers == 0) {
       ipc_traits::sleep(0, audio_auto_update_delay);
     } else {
@@ -219,6 +226,8 @@ static void shutdown_linux(void) {
 static void initialize(void) {
   if (have_initialized)
     return;
+  if (!audio_is_active)
+    return;
 
   buffer1 = new byte[audio_buffer_size];
   buffer2 = new byte[audio_buffer_size];
@@ -350,7 +359,7 @@ void LinuxSamplePlayer::stop_sound(AudioTraits::SoundClass*,
   buffers.erase(lplaying->get_data());
 }
 
-void LinuxSamplePlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void LinuxSamplePlayer::set_volume(AudioTraits::PlayingClass*, float) {
 }
 
 LinuxSamplePlayer* LinuxSamplePlayer::get_instance(void) {
@@ -375,7 +384,7 @@ void LinuxMusicPlayer::stop_sound(AudioTraits::SoundClass*,
   initialize();
 }
 
-void LinuxMusicPlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void LinuxMusicPlayer::set_volume(AudioTraits::PlayingClass*, float) {
 }
 
 LinuxMusicPlayer* LinuxMusicPlayer::get_instance(void) {

+ 2 - 2
panda/src/audio/audio_linux_traits.h

@@ -124,7 +124,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static LinuxSamplePlayer* get_instance(void);
@@ -141,7 +141,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static LinuxMusicPlayer* get_instance(void);

+ 13 - 6
panda/src/audio/audio_manager.I

@@ -9,7 +9,8 @@
 //  Description: Play some audio
 ////////////////////////////////////////////////////////////////////
 INLINE void AudioManager::play(AudioSound* sound) {
-  get_ptr()->ns_play(sound);
+  if (audio_is_active)
+    get_ptr()->ns_play(sound);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -18,6 +19,8 @@ INLINE void AudioManager::play(AudioSound* sound) {
 //  Description: make sure buffers are full
 ////////////////////////////////////////////////////////////////////
 INLINE void AudioManager::update(void) {
+  if (!audio_is_active)
+    return;
   mutex_lock l(_manager_mutex);
   if (_update_func != (UpdateFunc*)0L)
     (*_update_func)();
@@ -30,7 +33,8 @@ INLINE void AudioManager::update(void) {
 //  Description: spawn a thread to call update
 ////////////////////////////////////////////////////////////////////
 INLINE void AudioManager::spawn_update(void) {
-  get_ptr()->ns_spawn_update();
+  if (audio_is_active)
+    get_ptr()->ns_spawn_update();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -47,8 +51,9 @@ INLINE void AudioManager::shutdown(void) {
 //       Access: Public, Static
 //  Description: set the volume on a sound instance
 ////////////////////////////////////////////////////////////////////
-INLINE void AudioManager::set_volume(AudioSound* sound, int v) {
-  get_ptr()->ns_set_volume(sound, v);
+INLINE void AudioManager::set_volume(AudioSound* sound, float v) {
+  if (audio_is_active)
+    get_ptr()->ns_set_volume(sound, v);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -57,7 +62,8 @@ INLINE void AudioManager::set_volume(AudioSound* sound, int v) {
 //  Description: stop playing a given sound
 ////////////////////////////////////////////////////////////////////
 INLINE void AudioManager::stop(AudioSound* sound) {
-  get_ptr()->ns_stop(sound);
+  if (audio_is_active)
+    get_ptr()->ns_stop(sound);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -66,7 +72,8 @@ INLINE void AudioManager::stop(AudioSound* sound) {
 //  Description: set the looping state of the given sound
 ////////////////////////////////////////////////////////////////////
 INLINE void AudioManager::set_loop(AudioSound* sound, bool state) {
-  get_ptr()->ns_set_loop(sound, state);
+  if (audio_is_active)
+    get_ptr()->ns_set_loop(sound, state);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/audio/audio_manager.cxx

@@ -145,7 +145,7 @@ void* AudioManager::spawned_update(void* data) {
 //       Access: Private
 //  Description: get the player off the sound, and set volume on it
 ////////////////////////////////////////////////////////////////////
-void AudioManager::ns_set_volume(AudioSound* sound, int v) {
+void AudioManager::ns_set_volume(AudioSound* sound, float v) {
   sound->get_player()->set_volume(sound->get_state(), v);
 }
 

+ 3 - 2
panda/src/audio/audio_manager.h

@@ -8,6 +8,7 @@
 
 #include "audio_trait.h"
 #include "audio_sound.h"
+#include "config_audio.h"
 
 #include <ipc_mutex.h>
 #include <ipc_thread.h>
@@ -21,7 +22,7 @@ private:
   void ns_stop(AudioSound*);
   void ns_set_loop(AudioSound*, bool);
   bool ns_get_loop(AudioSound*);
-  void ns_set_volume(AudioSound*, int);
+  void ns_set_volume(AudioSound*, float);
   void ns_spawn_update(void);
   void ns_shutdown(void);
   void ns_update(void);
@@ -50,7 +51,7 @@ PUBLISHED:
   INLINE static void stop(AudioSound*);
   INLINE static void set_loop(AudioSound*, bool);
   INLINE static bool get_loop(AudioSound*);
-  INLINE static void set_volume(AudioSound*, int);
+  INLINE static void set_volume(AudioSound*, float);
   INLINE static void update(void);
   INLINE static void spawn_update(void);
   INLINE static void shutdown(void);

+ 4 - 3
panda/src/audio/audio_mikmod_traits.cxx

@@ -331,7 +331,8 @@ void MikModSamplePlayer::stop_sound(AudioTraits::SoundClass* sample,
   // stop it
 }
 
-void MikModSamplePlayer::set_volume(AudioTraits::PlayingClass* state, int v) {
+void MikModSamplePlayer::set_volume(AudioTraits::PlayingClass* state,
+				    float v) {
   initialize();
   MikModSamplePlaying* mplay = (MikModSamplePlaying*)state;
   Voice_SetVolume(mplay->get_voice(), v);
@@ -362,7 +363,7 @@ void MikModFmsynthPlayer::stop_sound(AudioTraits::SoundClass*,
 				     AudioTraits::PlayingClass*) {
 }
 
-void MikModFmsynthPlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void MikModFmsynthPlayer::set_volume(AudioTraits::PlayingClass*, float) {
   audio_cat->error()
     << "trying to set volume on a sample with a MikModFmsynthPlayer" << endl;
 }
@@ -391,7 +392,7 @@ void MikModMidiPlayer::stop_sound(AudioTraits::SoundClass*,
 				  AudioTraits::PlayingClass*) {
 }
 
-void MikModMidiPlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void MikModMidiPlayer::set_volume(AudioTraits::PlayingClass*, float) {
   audio_cat->error()
     << "trying to set volume on a sample with a MikModMidiPlayer" << endl;
 }

+ 3 - 3
panda/src/audio/audio_mikmod_traits.h

@@ -111,7 +111,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static MikModSamplePlayer* get_instance(void);
@@ -128,7 +128,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static MikModFmsynthPlayer* get_instance(void);
@@ -145,7 +145,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static MikModMidiPlayer* get_instance(void);

+ 1 - 1
panda/src/audio/audio_null_traits.cxx

@@ -81,7 +81,7 @@ void NullPlayer::stop_sound(AudioTraits::SoundClass*,
     audio_cat->debug() << "in stop sound in Null audio driver" << endl;
 }
 
-void NullPlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void NullPlayer::set_volume(AudioTraits::PlayingClass*, float) {
   if (audio_cat->is_debug())
     audio_cat->debug() << "in set volume in Null audio driver"
 		       << endl;

+ 1 - 1
panda/src/audio/audio_null_traits.h

@@ -44,7 +44,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 };
 
 #include "audio_null_traits.I"

+ 3 - 1
panda/src/audio/audio_pool.I

@@ -37,7 +37,9 @@ INLINE bool AudioPool::verify_sound(const string& filename) {
 //               file cannot be found, returns NULL.
 ////////////////////////////////////////////////////////////////////
 INLINE AudioSound* AudioPool::load_sound(const string& filename) {
-  return get_ptr()->ns_load_sound(filename);
+  if (audio_is_active)
+    return get_ptr()->ns_load_sound(filename);
+  return (AudioSound*)0L;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/audio/audio_pool.cxx

@@ -30,6 +30,7 @@ static void check_sound_loaders(void) {
 AudioPool* AudioPool::get_ptr(void) {
   if (_global_ptr == (AudioPool*)0L)
     _global_ptr = new AudioPool;
+  audio_load_loaders();
   return _global_ptr;
 }
 

+ 1 - 0
panda/src/audio/audio_pool.h

@@ -8,6 +8,7 @@
 
 #include "audio_sound.h"
 #include "audio_trait.h"
+#include "config_audio.h"
 #include <map>
 #include <pandabase.h>
 #include <filename.h>

+ 1 - 1
panda/src/audio/audio_trait.cxx

@@ -58,6 +58,6 @@ void AudioTraits::PlayerClass::stop_sound(AudioTraits::SoundClass*,
   audio_cat->error() << "In abstract PlayerClass::stop_sound!" << endl;
 }
 
-void AudioTraits::PlayerClass::set_volume(AudioTraits::PlayingClass*, int) {
+void AudioTraits::PlayerClass::set_volume(AudioTraits::PlayingClass*, float) {
   audio_cat->error() << "In abstract PlayerClass::set_volume!" << endl;
 }

+ 1 - 1
panda/src/audio/audio_trait.h

@@ -46,7 +46,7 @@ public:
 
     virtual void play_sound(SoundClass*, PlayingClass*) = 0;
     virtual void stop_sound(SoundClass*, PlayingClass*) = 0;
-    virtual void set_volume(PlayingClass*, int) = 0;
+    virtual void set_volume(PlayingClass*, float) = 0;
   };
 };
 

+ 5 - 0
panda/src/audio/audio_win_traits.I

@@ -25,6 +25,11 @@ INLINE LPDIRECTSOUNDBUFFER WinSamplePlaying::get_channel(void) {
   return _channel;
 }
 
+INLINE IDirectMusicPerformance* WinMusic::get_performance(void) const {
+  WinMusic* wmusic = (WinMusic*)_sound;
+  return wmusic->get_performance();
+}
+
 INLINE WinSamplePlayer::WinSamplePlayer(void) : AudioTraits::PlayerClass() {
 }
 

+ 18 - 2
panda/src/audio/audio_win_traits.cxx

@@ -28,6 +28,7 @@ static IDirectSound* musicDirectSound = NULL;
   if (FAILED(_result)) { \
     audio_cat->error() << _msg << " at " << __FILE__ << ":" << __LINE__ \
                        << endl; \
+    audio_is_active = false; \
     return; \
   }
 
@@ -40,6 +41,8 @@ static void update_win(void) {
 static void initialize(void) {
   if (have_initialized)
     return;
+  if (!audio_is_active)
+    return;
 
   if (audio_cat->is_debug())
     audio_cat->debug() << "in winAudio initialize" << endl;
@@ -821,9 +824,16 @@ void WinSamplePlayer::stop_sound(AudioTraits::SoundClass*,
     chan->Stop();
 }
 
-void WinSamplePlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void WinSamplePlayer::set_volume(AudioTraits::PlayingClass* play, float v) {
   if (audio_cat->is_debug())
     audio_cat->debug() << "winsampleplayer set_volume" << endl;
+  initialize();
+  WinSamplePlaying* wplay = (WinSamplePlaying*)play;
+  LPDIRECTSOUNDBUFFER chan = wplay->get_channel();
+  if (chan) {
+    LONG v2 = (v * (DSBVOLUME_MAX - DSBVOLUME_MIN)) + DSBVOLUME_MIN;
+    chan->SetVolume(v2);
+  }
 }
 
 WinSamplePlayer* WinSamplePlayer::get_instance(void) {
@@ -895,9 +905,15 @@ void WinMusicPlayer::stop_sound(AudioTraits::SoundClass* music,
   }
 }
 
-void WinMusicPlayer::set_volume(AudioTraits::PlayingClass*, int) {
+void WinMusicPlayer::set_volume(AudioTraits::PlayingClass* play, float v) {
   if (audio_cat->is_debug())
     audio_cat->debug() << "WinMusicPlayer::set_volume()" << endl;
+  WinMusicPlaying* wplay = (WinMusicPlaying*)play;
+  IDirectMusicPerformance* perf = wplay->get_performance();
+  if (perf) {
+    LONG v2 = (v * (DSBVOLUME_MAX - DSBVOLUME_MIN)) + DSBVOLUME_MIN;
+    perf->SetGlobalParam(GUID_PerfMasterVolume, &v2, sizeof(LONG));
+  }
 }
 
 WinMusicPlayer* WinMusicPlayer::get_instance(void) {

+ 3 - 2
panda/src/audio/audio_win_traits.h

@@ -89,6 +89,7 @@ public:
 
   virtual AudioTraits::PlayingClass::PlayingStatus status(void);
   static void destroy(AudioTraits::PlayingClass*);
+  INLINE IDirectMusicPerformance* get_performance(void) const;
 };
 
 class EXPCL_PANDA WinSamplePlayer : public AudioTraits::PlayerClass {
@@ -100,7 +101,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static WinSamplePlayer* get_instance(void);
@@ -117,7 +118,7 @@ public:
 			  AudioTraits::PlayingClass*);
   virtual void stop_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
-  virtual void set_volume(AudioTraits::PlayingClass*, int);
+  virtual void set_volume(AudioTraits::PlayingClass*, float);
 public:
   // used by the readers
   static WinMusicPlayer* get_instance(void);

+ 7 - 2
panda/src/audio/config_audio.cxx

@@ -21,6 +21,7 @@ int audio_buffer_size = config_audio.GetInt("audio-buffer-size", 4096);
 string* audio_device;
 int audio_auto_update_delay = config_audio.GetInt("audio-auto-update-delay",
 						  100000);
+bool audio_is_active = config_audio.GetBool("audio-is-active", true);
 
 ConfigureFn(config_audio) {
   AudioSound::init_type();
@@ -43,6 +44,12 @@ ConfigureFn(config_audio) {
     *audio_driver_params += (*i).Val();
   }
 
+  audio_device = new string(config_audio.GetString("audio-device",
+						   "/dev/dsp"));
+}
+
+void audio_load_loaders(void) {
+  Config::ConfigTable::Symbol::iterator i;
   Config::ConfigTable::Symbol loaders;
   config_audio.GetAll("audio-loader", loaders);
   for (i=loaders.begin(); i!=loaders.end(); ++i) {
@@ -53,6 +60,4 @@ ConfigureFn(config_audio) {
     if (tmp == (void*)0L)
       audio_cat->info() << "unable to load: " << load_dso_error() << endl;
   }
-  audio_device = new string(config_audio.GetString("audio-device",
-						   "/dev/dsp"));
 }

+ 3 - 0
panda/src/audio/config_audio.h

@@ -19,5 +19,8 @@ extern EXPCL_PANDA string* audio_driver_params;
 extern EXPCL_PANDA int audio_buffer_size;
 extern EXPCL_PANDA string* audio_device;
 extern EXPCL_PANDA int audio_auto_update_delay;
+extern EXPCL_PANDA bool audio_is_active;
+
+extern EXPCL_PANDA void audio_load_loaders(void);
 
 #endif /* __CONFIG_AUDIO_H__ */