Browse Source

new functionality

Cary Sandvig 25 years ago
parent
commit
4de5776f31

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

@@ -309,7 +309,6 @@ LinuxSamplePlaying::~LinuxSamplePlaying(void) {
 }
 
 AudioTraits::PlayingClass::PlayingStatus LinuxSamplePlaying::status(void) {
-  LinuxSample* s = (LinuxSample*)_sound;
   BufferSet::iterator i = buffers.find(_buff);
   if (i != buffers.end())
     return AudioTraits::PlayingClass::PLAYING;
@@ -344,6 +343,13 @@ void LinuxSamplePlayer::play_sound(AudioTraits::SoundClass*,
   buffers.insert(lplaying->get_data());
 }
 
+void LinuxSamplePlayer::stop_sound(AudioTraits::SoundClass*,
+				   AudioTraits::PlayingClass* playing) {
+  initialize();
+  LinuxSamplePlaying* lplaying = (LinuxSamplePlaying*)playing;
+  buffers.erase(lplaying->get_data());
+}
+
 void LinuxSamplePlayer::set_volume(AudioTraits::PlayingClass*, int) {
 }
 
@@ -364,6 +370,11 @@ void LinuxMusicPlayer::play_sound(AudioTraits::SoundClass*,
   initialize();
 }
 
+void LinuxMusicPlayer::stop_sound(AudioTraits::SoundClass*,
+				  AudioTraits::PlayingClass*) {
+  initialize();
+}
+
 void LinuxMusicPlayer::set_volume(AudioTraits::PlayingClass*, int) {
 }
 

+ 4 - 0
panda/src/audio/audio_linux_traits.h

@@ -122,6 +122,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers
@@ -137,6 +139,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers

+ 28 - 0
panda/src/audio/audio_manager.I

@@ -21,6 +21,7 @@ INLINE void AudioManager::update(void) {
   mutex_lock l(_manager_mutex);
   if (_update_func != (UpdateFunc*)0L)
     (*_update_func)();
+  get_ptr()->ns_update();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -50,6 +51,33 @@ INLINE void AudioManager::set_volume(AudioSound* sound, int v) {
   get_ptr()->ns_set_volume(sound, v);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::stop
+//       Access: Public, Static
+//  Description: stop playing a given sound
+////////////////////////////////////////////////////////////////////
+INLINE void AudioManager::stop(AudioSound* sound) {
+  get_ptr()->ns_stop(sound);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::stop
+//       Access: Public, Static
+//  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);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::get_loop
+//       Access: Public, Static
+//  Description: return the looping state of the given sound
+////////////////////////////////////////////////////////////////////
+INLINE bool AudioManager::get_loop(AudioSound* sound) {
+  return get_ptr()->ns_get_loop(sound);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AudioManager::Constructor
 //       Access: Private

+ 50 - 0
panda/src/audio/audio_manager.cxx

@@ -14,6 +14,7 @@ AudioManager::ShutdownFunc* AudioManager::_shutdown_func =
 mutex AudioManager::_manager_mutex;
 bool* AudioManager::_quit = (bool*)0L;
 thread* AudioManager::_spawned = (thread*)0L;
+AudioManager::LoopSet* AudioManager::_loopset = (AudioManager::LoopSet*)0L;
 
 ////////////////////////////////////////////////////////////////////
 //     Function: AudioManager::destructor
@@ -38,6 +39,19 @@ void AudioManager::set_update_func(AudioManager::UpdateFunc* func) {
   _update_func = func;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::ns_update
+//       Access: Public, Static
+//  Description: do generic update stuff
+////////////////////////////////////////////////////////////////////
+void AudioManager::ns_update(void) {
+  // handle looping
+  if (_loopset != (LoopSet*)0L)
+    for (LoopSet::iterator i=_loopset->begin(); i!=_loopset->end(); ++i)
+      if ((*i)->status() == AudioSound::READY)
+	AudioManager::play(*i);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AudioManager::set_shutdown_func
 //       Access: Public, Static
@@ -74,6 +88,42 @@ void AudioManager::ns_play(AudioSound* sound) {
   sound->get_player()->play_sound(sound->get_sound(), sound->get_state());
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::ns_stop (AudioSound)
+//       Access: Private
+//  Description: get the player off the sound, and stop it playing
+////////////////////////////////////////////////////////////////////
+void AudioManager::ns_stop(AudioSound* sound) {
+  this->ns_set_loop(sound, false);
+  sound->get_player()->stop_sound(sound->get_sound(), sound->get_state());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::ns_set_loop (AudioSound)
+//       Access: Private
+//  Description: set the looping state of the given sound
+////////////////////////////////////////////////////////////////////
+void AudioManager::ns_set_loop(AudioSound* sound, bool state) {
+  if ((_loopset == (LoopSet*)0L) && state)
+    _loopset = new LoopSet;
+  if (state)
+    _loopset->insert(sound);
+  else
+    _loopset->erase(sound);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AudioManager::ns_get_loop (AudioSound)
+//       Access: Private
+//  Description: get the looping state of the given sound
+////////////////////////////////////////////////////////////////////
+bool AudioManager::ns_get_loop(AudioSound* sound) {
+  if (_loopset == (LoopSet*)0L)
+    return false;
+  LoopSet::iterator i = _loopset->find(sound);
+  return (i != _loopset->end());
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AudioManager::spawned_update
 //       Access: static

+ 10 - 0
panda/src/audio/audio_manager.h

@@ -11,27 +11,34 @@
 
 #include <ipc_mutex.h>
 #include <ipc_thread.h>
+#include <set>
 
 class EXPCL_PANDA AudioManager {
 private:
   INLINE AudioManager(void);
 
   void ns_play(AudioSound*);
+  void ns_stop(AudioSound*);
+  void ns_set_loop(AudioSound*, bool);
+  bool ns_get_loop(AudioSound*);
   void ns_set_volume(AudioSound*, int);
   void ns_spawn_update(void);
   void ns_shutdown(void);
+  void ns_update(void);
 
   static AudioManager* get_ptr(void);
   static void* spawned_update(void*);
 
   typedef void UpdateFunc(void);
   typedef void ShutdownFunc(void);
+  typedef set<AudioSound*> LoopSet;
   static AudioManager* _global_ptr;
   static UpdateFunc* _update_func;
   static ShutdownFunc* _shutdown_func;
   static mutex _manager_mutex;
   static bool* _quit;
   static thread* _spawned;
+  static LoopSet* _loopset;
 public:
   virtual ~AudioManager(void);
 
@@ -39,6 +46,9 @@ public:
   static void set_shutdown_func(ShutdownFunc*);
 
   INLINE static void play(AudioSound*);
+  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 update(void);
   INLINE static void spawn_update(void);

+ 15 - 0
panda/src/audio/audio_mikmod_traits.cxx

@@ -324,6 +324,13 @@ void MikModSamplePlayer::play_sound(AudioTraits::SoundClass* sample,
   Voice_SetPanning(mplay->get_voice(), 127);
 }
 
+void MikModSamplePlayer::stop_sound(AudioTraits::SoundClass* sample,
+				    AudioTraits::PlayingClass* playing) {
+  if (!have_initialized)
+    initialize();
+  // stop it
+}
+
 void MikModSamplePlayer::set_volume(AudioTraits::PlayingClass* state, int v) {
   initialize();
   MikModSamplePlaying* mplay = (MikModSamplePlaying*)state;
@@ -351,6 +358,10 @@ void MikModFmsynthPlayer::play_sound(AudioTraits::SoundClass*,
 		     << endl;
 }
 
+void MikModFmsynthPlayer::stop_sound(AudioTraits::SoundClass*,
+				     AudioTraits::PlayingClass*) {
+}
+
 void MikModFmsynthPlayer::set_volume(AudioTraits::PlayingClass*, int) {
   audio_cat->error()
     << "trying to set volume on a sample with a MikModFmsynthPlayer" << endl;
@@ -376,6 +387,10 @@ void MikModMidiPlayer::play_sound(AudioTraits::SoundClass*,
 		     << endl;
 }
 
+void MikModMidiPlayer::stop_sound(AudioTraits::SoundClass*,
+				  AudioTraits::PlayingClass*) {
+}
+
 void MikModMidiPlayer::set_volume(AudioTraits::PlayingClass*, int) {
   audio_cat->error()
     << "trying to set volume on a sample with a MikModMidiPlayer" << endl;

+ 6 - 0
panda/src/audio/audio_mikmod_traits.h

@@ -109,6 +109,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers
@@ -124,6 +126,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers
@@ -139,6 +143,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers

+ 6 - 0
panda/src/audio/audio_null_traits.cxx

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

+ 2 - 0
panda/src/audio/audio_null_traits.h

@@ -42,6 +42,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 };
 

+ 5 - 0
panda/src/audio/audio_trait.cxx

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

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

@@ -45,6 +45,7 @@ public:
     virtual ~PlayerClass(void);
 
     virtual void play_sound(SoundClass*, PlayingClass*) = 0;
+    virtual void stop_sound(SoundClass*, PlayingClass*) = 0;
     virtual void set_volume(PlayingClass*, int) = 0;
   };
 };

+ 22 - 0
panda/src/audio/audio_win_traits.cxx

@@ -810,6 +810,15 @@ void WinSamplePlayer::play_sound(AudioTraits::SoundClass* sample,
     audio_cat->debug() << "out of winsampleplayer play_sound" << endl;
 }
 
+void WinSamplePlayer::stop_sound(AudioTraits::SoundClass*,
+			   AudioTraits::PlayingClass* play) {
+  initialize();
+  WinSamplePlaying* wplay = (WinSamplePlaying*)play;
+  LPDIRECTSOUNDBUFFER chan = wplay->get_channel();
+  if (chan)
+    chan->Stop();
+}
+
 void WinSamplePlayer::set_volume(AudioTraits::PlayingClass*, int) {
   if (audio_cat->is_debug())
     audio_cat->debug() << "winsampleplayer set_volume" << endl;
@@ -871,6 +880,19 @@ void WinMusicPlayer::play_sound(AudioTraits::SoundClass* music,
     audio_cat->debug() << "out of WinMusicPlayer::play_sound()" << endl;
 }
 
+void WinMusicPlayer::stop_sound(AudioTraits::SoundClass* music,
+				AudioTraits::PlayingClass*) {
+  WinMusic* wmusic = (WinMusic*)music;
+  IDirectMusicPerformance* _perf = wmusic->get_performance();
+  IDirectMusicSegment* _msc = wmusic->get_music();
+
+  if (_perf && _msc) {
+    HRESULT result = _perf->Stop(_msc, 0, 0, 0);
+    if (result != S_OK)
+      audio_cat->error() << "music stop failed" << endl;
+  }
+}
+
 void WinMusicPlayer::set_volume(AudioTraits::PlayingClass*, int) {
   if (audio_cat->is_debug())
     audio_cat->debug() << "WinMusicPlayer::set_volume()" << endl;

+ 4 - 0
panda/src/audio/audio_win_traits.h

@@ -98,6 +98,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers
@@ -113,6 +115,8 @@ public:
 
   virtual void play_sound(AudioTraits::SoundClass*,
 			  AudioTraits::PlayingClass*);
+  virtual void stop_sound(AudioTraits::SoundClass*,
+			  AudioTraits::PlayingClass*);
   virtual void set_volume(AudioTraits::PlayingClass*, int);
 public:
   // used by the readers

+ 3 - 2
panda/src/audiotraits/audio_load_mp3.cxx

@@ -374,7 +374,7 @@ static void read_file(Filename filename, unsigned char** buf,
 
   initialize();
   my_buf_head = my_buf_curr = (BufferPart*)0L;
-  if (open_stream((char*)(filename.c_str()), -1)) {
+  if (open_stream((char*)(filename.to_os_specific().c_str()), -1)) {
     long leftFrames, newFrame;
 
     read_frame_init();
@@ -407,7 +407,8 @@ static void read_file(Filename filename, unsigned char** buf,
   if (audio_cat->is_debug())
     audio_cat->debug(false) << endl;
   audio_flush(param.outmode, &ai);
-  free(pcm_sample);
+  if (pcm_sample != (unsigned char*)0L)
+    free(pcm_sample);
   switch (param.outmode) {
   case DECODE_AUDIO:
     audio_close(&ai);