diff --git a/panda/src/audio/audio_linux_traits.cxx b/panda/src/audio/audio_linux_traits.cxx index bab922b918..e273b30f30 100644 --- a/panda/src/audio/audio_linux_traits.cxx +++ b/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) { } diff --git a/panda/src/audio/audio_linux_traits.h b/panda/src/audio/audio_linux_traits.h index 372888748e..2a7c06a142 100644 --- a/panda/src/audio/audio_linux_traits.h +++ b/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 diff --git a/panda/src/audio/audio_manager.I b/panda/src/audio/audio_manager.I index 4536f7f0a2..9b92da612e 100644 --- a/panda/src/audio/audio_manager.I +++ b/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 diff --git a/panda/src/audio/audio_manager.cxx b/panda/src/audio/audio_manager.cxx index c6470a1233..166e20b9a0 100644 --- a/panda/src/audio/audio_manager.cxx +++ b/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 diff --git a/panda/src/audio/audio_manager.h b/panda/src/audio/audio_manager.h index 38723e9e63..ba2a7a2732 100644 --- a/panda/src/audio/audio_manager.h +++ b/panda/src/audio/audio_manager.h @@ -11,27 +11,34 @@ #include #include +#include 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 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); diff --git a/panda/src/audio/audio_mikmod_traits.cxx b/panda/src/audio/audio_mikmod_traits.cxx index a0605b8d8a..3a74e5345f 100644 --- a/panda/src/audio/audio_mikmod_traits.cxx +++ b/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; diff --git a/panda/src/audio/audio_mikmod_traits.h b/panda/src/audio/audio_mikmod_traits.h index f369b78475..a1aeca3ed1 100644 --- a/panda/src/audio/audio_mikmod_traits.h +++ b/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 diff --git a/panda/src/audio/audio_null_traits.cxx b/panda/src/audio/audio_null_traits.cxx index 6c5c7155c5..93eff93bad 100644 --- a/panda/src/audio/audio_null_traits.cxx +++ b/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" diff --git a/panda/src/audio/audio_null_traits.h b/panda/src/audio/audio_null_traits.h index 0609ad6dc7..6b301288b4 100644 --- a/panda/src/audio/audio_null_traits.h +++ b/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); }; diff --git a/panda/src/audio/audio_trait.cxx b/panda/src/audio/audio_trait.cxx index 163dc55830..513da49831 100644 --- a/panda/src/audio/audio_trait.cxx +++ b/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; } diff --git a/panda/src/audio/audio_trait.h b/panda/src/audio/audio_trait.h index 6a385b3770..a121eb6c2b 100644 --- a/panda/src/audio/audio_trait.h +++ b/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; }; }; diff --git a/panda/src/audio/audio_win_traits.cxx b/panda/src/audio/audio_win_traits.cxx index 6b7d898a1b..6951c1b183 100644 --- a/panda/src/audio/audio_win_traits.cxx +++ b/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; diff --git a/panda/src/audio/audio_win_traits.h b/panda/src/audio/audio_win_traits.h index 28f398733c..c642aa4e6e 100644 --- a/panda/src/audio/audio_win_traits.h +++ b/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 diff --git a/panda/src/audiotraits/audio_load_mp3.cxx b/panda/src/audiotraits/audio_load_mp3.cxx index ab30817c42..cdad0fe1eb 100644 --- a/panda/src/audiotraits/audio_load_mp3.cxx +++ b/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);