diff --git a/panda/src/audiotraits/milesAudioManager.cxx b/panda/src/audiotraits/milesAudioManager.cxx index f7aa8230be..52d8a4f78b 100644 --- a/panda/src/audiotraits/milesAudioManager.cxx +++ b/panda/src/audiotraits/milesAudioManager.cxx @@ -96,6 +96,7 @@ MilesAudioManager() { _volume = audio_volume; _cache_limit = audio_cache_limit; _is_valid = true; + _bHasMidiSounds = false; if (!_active_managers) { S32 use_digital=(audio_play_wave || audio_play_mp3)?1:0; S32 use_MIDI=(audio_play_midi)?1:0; @@ -315,6 +316,8 @@ get_sound(const string& file_name) { _soundsOnLoan.insert(milesAudioSound); audioSound=milesAudioSound; } + + _bHasMidiSounds |= (file_name.find(".mid")!=string::npos); audio_debug(" returning 0x" << (void*)audioSound); assert(is_valid()); return audioSound; @@ -472,6 +475,33 @@ set_volume(float volume) { } } +void MilesAudioManager:: +stop_all_sounds(void) { + audio_debug("MilesAudioManager::stop_all_sounds()"); + AudioSet::iterator i=_soundsOnLoan.begin(); + for (; i!=_soundsOnLoan.end(); ++i) { + if((**i).status()==AudioSound::PLAYING) + (**i).stop(); + } + + if(_bHasMidiSounds) { + forceMidiReset(); + } +} + +void MilesAudioManager:: +forceMidiReset(void) { + audio_debug("MilesAudioManager::ForceMidiReset"); + + // sometimes Miles seems to leave midi notes hanging, even after stop is called, + // so perform an explicit reset using winMM.dll calls, just to ensure silence. + HMDIDRIVER hMid=NULL; + AIL_quick_handles(0, &hMid, 0); + if ((hMid!=NULL) && (hMid->deviceid != MIDI_NULL_DRIVER) && (hMid->hMidiOut != NULL)) { + midiOutReset(hMid->hMidiOut); + } +} + //////////////////////////////////////////////////////////////////// // Function: MilesAudioManager::get_volume // Access: Public @@ -498,6 +528,10 @@ set_active(bool active) { for (; i!=_soundsOnLoan.end(); ++i) { (**i).set_active(_active); } + + if((!_active) && _bHasMidiSounds) { + forceMidiReset(); + } } } diff --git a/panda/src/audiotraits/milesAudioManager.h b/panda/src/audiotraits/milesAudioManager.h index 585f144e86..640d85d985 100644 --- a/panda/src/audiotraits/milesAudioManager.h +++ b/panda/src/audiotraits/milesAudioManager.h @@ -51,6 +51,8 @@ public: void set_active(bool active); bool get_active(); + void stop_all_sounds(); + void forceMidiReset(); // Optional Downloadable Sound field for software midi: // made public so C atexit fn can access it @@ -60,12 +62,14 @@ private: // The sound cache: typedef pmap SoundMap; SoundMap _sounds; + + typedef pset AudioSet; + // The offspring of this manager: + AudioSet _soundsOnLoan; + // The Least Recently Used mechanism: typedef pdeque LRU; LRU _lru; - // The offspring of this manager: - typedef pset AudioSet; - AudioSet _soundsOnLoan; // State: float _volume; bool _active; @@ -74,6 +78,7 @@ private: static int _active_managers; bool _is_valid; + bool _bHasMidiSounds; HAUDIO load(Filename file_name); // Tell the manager that the sound dtor was called. diff --git a/panda/src/audiotraits/milesAudioSound.cxx b/panda/src/audiotraits/milesAudioSound.cxx index 6aa4f03073..4f06ac7a7a 100644 --- a/panda/src/audiotraits/milesAudioSound.cxx +++ b/panda/src/audiotraits/milesAudioSound.cxx @@ -80,21 +80,26 @@ void MilesAudioSound:: play() { #if 0 if(_file_name.find(".mid")!=string::npos) { - miles_audio_debug("play() midi"); + miles_audio_debug("play() midi"); } #endif - + miles_audio_debug("play()"); if (_active) { + if(_manager->_bExclusive) { + // stop any other sound that parent mgr is playing + _manager->stop_all_sounds(); + } + // Start playing: if (AIL_quick_play(_audio, _loop_count)) { - audio_debug(" started sound"); + audio_debug(" started sound " << _file_name ); } else { - audio_debug(" failed to play sound "<