mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
cleanup miles better at program exit
This commit is contained in:
parent
3a4f540867
commit
b905967e2d
@ -282,6 +282,12 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
the desktop and keyboard functionality, etc.
|
the desktop and keyboard functionality, etc.
|
||||||
"""
|
"""
|
||||||
self.graphicsEngine.removeAllWindows()
|
self.graphicsEngine.removeAllWindows()
|
||||||
|
|
||||||
|
if self.musicManager:
|
||||||
|
# Temporary condition for old Pandas.
|
||||||
|
if hasattr(self.musicManager, 'shutdown'):
|
||||||
|
self.musicManager.shutdown()
|
||||||
|
|
||||||
del self.win
|
del self.win
|
||||||
del self.winList
|
del self.winList
|
||||||
del self.pipe
|
del self.pipe
|
||||||
|
@ -86,6 +86,28 @@ create_AudioManager() {
|
|||||||
return am;
|
return am;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AudioManager::Destructor
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
AudioManager::
|
||||||
|
~AudioManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AudioManager::shutdown
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Call this at exit time to shut down the audio system.
|
||||||
|
// This will invalidate all currently-active
|
||||||
|
// AudioManagers and AudioSounds in the system. If you
|
||||||
|
// change your mind and want to play sounds again, you
|
||||||
|
// will have to recreate all of these objects.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AudioManager::
|
||||||
|
shutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AudioManager::get_null_sound
|
// Function: AudioManager::get_null_sound
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -37,7 +37,9 @@ PUBLISHED:
|
|||||||
// my_music = MyMusicManager.get_sound("introTheme.mid");
|
// my_music = MyMusicManager.get_sound("introTheme.mid");
|
||||||
|
|
||||||
static PT(AudioManager) create_AudioManager();
|
static PT(AudioManager) create_AudioManager();
|
||||||
virtual ~AudioManager() {}
|
virtual ~AudioManager();
|
||||||
|
|
||||||
|
virtual void shutdown();
|
||||||
|
|
||||||
// If you're interested in knowing whether this audio manager
|
// If you're interested in knowing whether this audio manager
|
||||||
// is valid, here's the call to do it. It is not necessary
|
// is valid, here's the call to do it. It is not necessary
|
||||||
|
@ -34,56 +34,19 @@
|
|||||||
TypeHandle MilesAudioManager::_type_handle;
|
TypeHandle MilesAudioManager::_type_handle;
|
||||||
|
|
||||||
int MilesAudioManager::_active_managers = 0;
|
int MilesAudioManager::_active_managers = 0;
|
||||||
|
bool MilesAudioManager::_miles_active = false;
|
||||||
HDLSFILEID MilesAudioManager::_dls_field = NULL;
|
HDLSFILEID MilesAudioManager::_dls_field = NULL;
|
||||||
|
|
||||||
namespace {
|
// This is the list of all MilesAudioManager objects in the world. It
|
||||||
bool miles_shutdown_called = false;
|
// must be a pointer rather than a concrete object, so it won't be
|
||||||
}
|
// destructed at exit time before we're done removing things from it.
|
||||||
|
MilesAudioManager::Managers *MilesAudioManager::_managers;
|
||||||
|
|
||||||
PT(AudioManager) Create_AudioManager() {
|
PT(AudioManager) Create_AudioManager() {
|
||||||
audio_debug("Create_AudioManager() Miles.");
|
audio_debug("Create_AudioManager() Miles.");
|
||||||
return new MilesAudioManager();
|
return new MilesAudioManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMilesShutdown() {
|
|
||||||
if (miles_shutdown_called) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
miles_shutdown_called = true;
|
|
||||||
|
|
||||||
if (MilesAudioManager::_dls_field!=NULL) {
|
|
||||||
HDLSDEVICE dls= NULL;
|
|
||||||
AIL_quick_handles(0, 0, &dls);
|
|
||||||
if (dls!=NULL) {
|
|
||||||
AIL_DLS_unload(dls,MilesAudioManager::_dls_field);
|
|
||||||
}
|
|
||||||
#ifndef NDEBUG //[
|
|
||||||
// Clear _dls_field in debug version (for assert in ctor):
|
|
||||||
MilesAudioManager::_dls_field = NULL;
|
|
||||||
#endif //]
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SHUTDOWN_HACK
|
|
||||||
// if python crashes, the midi notes are left on,
|
|
||||||
// so we need to turn them off. Unfortunately
|
|
||||||
// in Miles 6.5, AIL_quick_shutdown() crashes
|
|
||||||
// when it's called from atexit after a python crash, probably
|
|
||||||
// because mss32.dll has already been unloaded
|
|
||||||
// workaround: use these internal values in the miles struct
|
|
||||||
// to reset the win32 midi ourselves
|
|
||||||
#ifdef SHUTDOWN_HACK
|
|
||||||
HMDIDRIVER hMid=NULL;
|
|
||||||
AIL_quick_handles(0, &hMid, 0);
|
|
||||||
if ((hMid!=NULL) && (hMid->deviceid != MIDI_NULL_DRIVER) && (hMid->hMidiOut != NULL)) {
|
|
||||||
midiOutReset(hMid->hMidiOut);
|
|
||||||
midiOutClose(hMid->hMidiOut);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
audio_debug(" AIL_quick_shutdown()");
|
|
||||||
AIL_quick_shutdown();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MilesAudioManager::MilesAudioManager
|
// Function: MilesAudioManager::MilesAudioManager
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -94,16 +57,23 @@ void CustomMilesShutdown() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
MilesAudioManager::
|
MilesAudioManager::
|
||||||
MilesAudioManager() {
|
MilesAudioManager() {
|
||||||
audio_debug("MilesAudioManager::MilesAudioManager()");
|
audio_debug("MilesAudioManager::MilesAudioManager(), this = "
|
||||||
|
<< (void *)this);
|
||||||
|
if (_managers == (Managers *)NULL) {
|
||||||
|
_managers = new Managers;
|
||||||
|
}
|
||||||
|
_managers->insert(this);
|
||||||
|
|
||||||
audio_debug(" audio_active="<<audio_active);
|
audio_debug(" audio_active="<<audio_active);
|
||||||
audio_debug(" audio_volume="<<audio_volume);
|
audio_debug(" audio_volume="<<audio_volume);
|
||||||
|
_cleanup_required = true;
|
||||||
_active = audio_active;
|
_active = audio_active;
|
||||||
_volume = audio_volume;
|
_volume = audio_volume;
|
||||||
_cache_limit = audio_cache_limit;
|
_cache_limit = audio_cache_limit;
|
||||||
_concurrent_sound_limit = 0;
|
_concurrent_sound_limit = 0;
|
||||||
_is_valid = true;
|
_is_valid = true;
|
||||||
_hasMidiSounds = false;
|
_hasMidiSounds = false;
|
||||||
if (_active_managers==0) {
|
if (_active_managers==0 || !_miles_active) {
|
||||||
S32 use_digital=(audio_play_wave || audio_play_mp3)?1:0;
|
S32 use_digital=(audio_play_wave || audio_play_mp3)?1:0;
|
||||||
S32 use_MIDI=(audio_play_midi)?1:0;
|
S32 use_MIDI=(audio_play_midi)?1:0;
|
||||||
if (audio_play_midi && audio_software_midi) {
|
if (audio_play_midi && audio_software_midi) {
|
||||||
@ -123,33 +93,38 @@ MilesAudioManager() {
|
|||||||
if (AIL_quick_startup(use_digital,
|
if (AIL_quick_startup(use_digital,
|
||||||
use_MIDI, audio_output_rate,
|
use_MIDI, audio_output_rate,
|
||||||
audio_output_bits, audio_output_channels)) {
|
audio_output_bits, audio_output_channels)) {
|
||||||
|
_miles_active = true;
|
||||||
if (audio_software_midi) {
|
if (audio_software_midi) {
|
||||||
// Load the downloadable sounds file:
|
// Load the downloadable sounds file:
|
||||||
|
|
||||||
HDLSDEVICE dls;
|
if (_dls_field == NULL) {
|
||||||
AIL_quick_handles(0, 0, &dls);
|
HDLSDEVICE dls;
|
||||||
nassertv(!_dls_field);
|
AIL_quick_handles(0, 0, &dls);
|
||||||
string dls_file = Filename(audio_dls_file).to_os_specific();
|
nassertv(dls != NULL);
|
||||||
if (dls_file.empty()) {
|
string dls_file = Filename(audio_dls_file).to_os_specific();
|
||||||
get_gm_file_path(dls_file);
|
if (dls_file.empty()) {
|
||||||
// we need more dbg info in logs, so bumping the msgs from 'debug' status to 'info' status
|
get_gm_file_path(dls_file);
|
||||||
audio_info(" using default dls_file: "<< dls_file );
|
// we need more dbg info in logs, so bumping the msgs from 'debug' status to 'info' status
|
||||||
}
|
audio_info(" using default dls_file: "<< dls_file );
|
||||||
|
}
|
||||||
audio_debug(" dls_file=\""<<dls_file<<"\"");
|
|
||||||
|
audio_debug(" dls_file=\""<<dls_file<<"\"");
|
||||||
// note: if AIL_DLS_load_file is not done, midi fails to play on some machines.
|
|
||||||
_dls_field=AIL_DLS_load_file(dls, dls_file.c_str(), 0);
|
// note: if AIL_DLS_load_file is not done, midi fails to play on some machines.
|
||||||
if (!_dls_field) {
|
nassertv(_dls_field == NULL);
|
||||||
audio_error(" AIL_DLS_load_file() failed, \""<<AIL_last_error() <<"\" Switching to hardware midi");
|
audio_debug(" AIL_DLS_load_file(dls, " << dls_file << ", 0)");
|
||||||
AIL_quick_shutdown();
|
_dls_field = AIL_DLS_load_file(dls, dls_file.c_str(), 0);
|
||||||
if (!AIL_quick_startup(use_digital, 1, audio_output_rate,
|
if (!_dls_field) {
|
||||||
audio_output_bits, audio_output_channels)) {
|
audio_error(" AIL_DLS_load_file() failed, \""<<AIL_last_error() <<"\" Switching to hardware midi");
|
||||||
audio_error(" midi hardware startup failed, "<<AIL_last_error());
|
AIL_quick_shutdown();
|
||||||
_is_valid = false;
|
if (!AIL_quick_startup(use_digital, 1, audio_output_rate,
|
||||||
|
audio_output_bits, audio_output_channels)) {
|
||||||
|
audio_error(" midi hardware startup failed, "<<AIL_last_error());
|
||||||
|
_is_valid = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
audio_info(" using Miles software midi");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
audio_info(" using Miles software midi");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
audio_info(" using Miles hardware midi");
|
audio_info(" using Miles hardware midi");
|
||||||
@ -166,15 +141,17 @@ MilesAudioManager() {
|
|||||||
audio_debug(" _active_managers="<<_active_managers);
|
audio_debug(" _active_managers="<<_active_managers);
|
||||||
nassertv(_active_managers>0);
|
nassertv(_active_managers>0);
|
||||||
|
|
||||||
if (_is_valid) {
|
// We used to hang a call to a force-shutdown function on atexit(),
|
||||||
assert(is_valid());
|
// so that any running sounds (particularly MIDI sounds) would be
|
||||||
|
// silenced on exit, especially a sudden exit triggered by a Python
|
||||||
|
// exception. But that causes problems because Miles itself also
|
||||||
|
// hangs a force-shutdown function on atexit(), and you can't call
|
||||||
|
// AIL_cleanup() twice--that results in a crash.
|
||||||
|
|
||||||
static bool atexit_registered = false;
|
// Nowadays, we provide the AudioManager::shutdown() method instead,
|
||||||
if(!atexit_registered) {
|
// which allows the app to force all sounds to stop cleanly before
|
||||||
atexit_registered = true;
|
// we get to the atexit() stack. In Python, we guarantee that this
|
||||||
atexit(CustomMilesShutdown);
|
// method will be called in the sys.exitfunc chain.
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -187,27 +164,38 @@ MilesAudioManager() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
MilesAudioManager::
|
MilesAudioManager::
|
||||||
~MilesAudioManager() {
|
~MilesAudioManager() {
|
||||||
audio_debug("MilesAudioManager::~MilesAudioManager()");
|
audio_debug("MilesAudioManager::~MilesAudioManager(), this = "
|
||||||
// Be sure to delete associated sounds before deleting the manager:
|
<< (void *)this);
|
||||||
nassertv(_sounds_on_loan.empty());
|
nassertv(_managers != (Managers *)NULL);
|
||||||
clear_cache();
|
Managers::iterator mi = _managers->find(this);
|
||||||
nassertv(_active_managers>0);
|
nassertv(mi != _managers->end());
|
||||||
--_active_managers;
|
_managers->erase(mi);
|
||||||
audio_debug(" _active_managers="<<_active_managers);
|
|
||||||
if (_active_managers==0) {
|
cleanup();
|
||||||
if (audio_software_midi) {
|
audio_debug("MilesAudioManager::~MilesAudioManager() finished");
|
||||||
HDLSDEVICE dls;
|
}
|
||||||
AIL_quick_handles(0, 0, &dls);
|
|
||||||
AIL_DLS_unload(dls, _dls_field);
|
////////////////////////////////////////////////////////////////////
|
||||||
#ifndef NDEBUG //[
|
// Function: MilesAudioManager::shutdown
|
||||||
// Clear _dls_field in debug version (for assert in ctor):
|
// Access: Published, Virtual
|
||||||
_dls_field=0;
|
// Description: Call this at exit time to shut down the audio system.
|
||||||
#endif //]
|
// This will invalidate all currently-active
|
||||||
|
// AudioManagers and AudioSounds in the system. If you
|
||||||
|
// change your mind and want to play sounds again, you
|
||||||
|
// will have to recreate all of these objects.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MilesAudioManager::
|
||||||
|
shutdown() {
|
||||||
|
audio_debug("shutdown(), _miles_active = " << _miles_active);
|
||||||
|
if (_managers != (Managers *)NULL) {
|
||||||
|
Managers::iterator mi;
|
||||||
|
for (mi = _managers->begin(); mi != _managers->end(); ++mi) {
|
||||||
|
(*mi)->cleanup();
|
||||||
}
|
}
|
||||||
audio_debug(" AIL_quick_shutdown()");
|
|
||||||
AIL_quick_shutdown();
|
|
||||||
miles_shutdown_called = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nassertv(_active_managers == 0);
|
||||||
|
audio_debug("shutdown() finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -305,7 +293,7 @@ load(Filename file_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sd->_audio = AIL_quick_load_mem(sd->_raw_data.data(), sd->_raw_data.size());
|
sd->_audio = AIL_quick_load_mem(sd->_raw_data.data(), sd->_raw_data.size());
|
||||||
|
|
||||||
if (!sd->_audio) {
|
if (!sd->_audio) {
|
||||||
audio_error(" MilesAudioManager::load failed "<< AIL_last_error());
|
audio_error(" MilesAudioManager::load failed "<< AIL_last_error());
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -376,7 +364,8 @@ get_sound(const string& file_name, bool) {
|
|||||||
=new MilesAudioSound(this, sd, (*si).first);
|
=new MilesAudioSound(this, sd, (*si).first);
|
||||||
nassertr(milesAudioSound, 0);
|
nassertr(milesAudioSound, 0);
|
||||||
milesAudioSound->set_active(_active);
|
milesAudioSound->set_active(_active);
|
||||||
_sounds_on_loan.insert(milesAudioSound);
|
bool inserted = _sounds_on_loan.insert(milesAudioSound).second;
|
||||||
|
nassertr(inserted, milesAudioSound.p());
|
||||||
audioSound=milesAudioSound;
|
audioSound=milesAudioSound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,8 +494,12 @@ get_cache_limit() const {
|
|||||||
void MilesAudioManager::
|
void MilesAudioManager::
|
||||||
release_sound(MilesAudioSound* audioSound) {
|
release_sound(MilesAudioSound* audioSound) {
|
||||||
audio_debug("MilesAudioManager::release_sound(audioSound=\""
|
audio_debug("MilesAudioManager::release_sound(audioSound=\""
|
||||||
<<audioSound->get_name()<<"\")");
|
<<audioSound->get_name()<<"\"), this = " << (void *)this);
|
||||||
_sounds_on_loan.erase(audioSound);
|
AudioSet::iterator ai = _sounds_on_loan.find(audioSound);
|
||||||
|
nassertv(ai != _sounds_on_loan.end());
|
||||||
|
_sounds_on_loan.erase(ai);
|
||||||
|
|
||||||
|
audio_debug("MilesAudioManager::release_sound() finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -527,29 +520,6 @@ set_volume(float volume) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MilesAudioManager::force_midi_reset
|
|
||||||
// Access: Public
|
|
||||||
// Description: ?????.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void MilesAudioManager::
|
|
||||||
force_midi_reset() {
|
|
||||||
if (!miles_audio_force_midi_reset) {
|
|
||||||
audio_debug("MilesAudioManager::skipping force_midi_reset");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
audio_debug("MilesAudioManager::force_midi_reset");
|
|
||||||
|
|
||||||
// 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)) {
|
|
||||||
audio_debug("MilesAudioManager::calling midiOutReset");
|
|
||||||
midiOutReset(hMid->hMidiOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MilesAudioManager::get_volume
|
// Function: MilesAudioManager::get_volume
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -732,6 +702,76 @@ get_gm_file_path(string& result) {
|
|||||||
audio_debug("MilesAudioManager::get_gm_file_path() result out=\""<<result<<"\"");
|
audio_debug("MilesAudioManager::get_gm_file_path() result out=\""<<result<<"\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MilesAudioManager::force_midi_reset
|
||||||
|
// Access: Private
|
||||||
|
// Description: ?????.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MilesAudioManager::
|
||||||
|
force_midi_reset() {
|
||||||
|
if (!miles_audio_force_midi_reset) {
|
||||||
|
audio_debug("MilesAudioManager::skipping force_midi_reset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audio_debug("MilesAudioManager::force_midi_reset");
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
audio_debug("MilesAudioManager::calling midiOutReset");
|
||||||
|
midiOutReset(hMid->hMidiOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MilesAudioManager::cleanup
|
||||||
|
// Access: Private
|
||||||
|
// Description: Shuts down the audio manager and releases any
|
||||||
|
// resources associated with it. Also cleans up all
|
||||||
|
// AudioSounds created via the manager.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MilesAudioManager::
|
||||||
|
cleanup() {
|
||||||
|
audio_debug("MilesAudioManager::cleanup(), this = " << (void *)this
|
||||||
|
<< ", _cleanup_required = " << _cleanup_required);
|
||||||
|
if (!_cleanup_required) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Be sure to cleanup associated sounds before cleaning up the manager:
|
||||||
|
AudioSet::iterator ai;
|
||||||
|
for (ai = _sounds_on_loan.begin(); ai != _sounds_on_loan.end(); ++ai) {
|
||||||
|
(*ai)->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_cache();
|
||||||
|
nassertv(_active_managers > 0);
|
||||||
|
--_active_managers;
|
||||||
|
audio_debug(" _active_managers="<<_active_managers);
|
||||||
|
|
||||||
|
if (_active_managers == 0) {
|
||||||
|
if (_dls_field != NULL) {
|
||||||
|
HDLSDEVICE dls;
|
||||||
|
AIL_quick_handles(0, 0, &dls);
|
||||||
|
audio_debug(" AIL_DLS_unload()");
|
||||||
|
AIL_DLS_unload(dls, _dls_field);
|
||||||
|
_dls_field = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_miles_active) {
|
||||||
|
audio_debug(" AIL_quick_shutdown()");
|
||||||
|
AIL_quick_shutdown();
|
||||||
|
_miles_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_cleanup_required = false;
|
||||||
|
audio_debug("MilesAudioManager::cleanup() finished");
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MilesAudioManager::SoundData::Constructor
|
// Function: MilesAudioManager::SoundData::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -752,7 +792,10 @@ SoundData() :
|
|||||||
MilesAudioManager::SoundData::
|
MilesAudioManager::SoundData::
|
||||||
~SoundData() {
|
~SoundData() {
|
||||||
if (_audio != 0) {
|
if (_audio != 0) {
|
||||||
AIL_quick_unload(_audio);
|
if (_miles_active) {
|
||||||
|
AIL_quick_unload(_audio);
|
||||||
|
}
|
||||||
|
_audio = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@ public:
|
|||||||
MilesAudioManager();
|
MilesAudioManager();
|
||||||
~MilesAudioManager();
|
~MilesAudioManager();
|
||||||
|
|
||||||
|
virtual void shutdown();
|
||||||
|
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
|
|
||||||
virtual PT(AudioSound) get_sound(const string& file_name, bool positional = false);
|
virtual PT(AudioSound) get_sound(const string& file_name, bool positional = false);
|
||||||
@ -59,10 +61,6 @@ public:
|
|||||||
|
|
||||||
void stop_all_sounds();
|
void stop_all_sounds();
|
||||||
|
|
||||||
// Optional Downloadable Sound field for software midi:
|
|
||||||
// made public so C atexit fn can access it
|
|
||||||
static HDLSFILEID _dls_field;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The sound cache:
|
// The sound cache:
|
||||||
class SoundData : public ReferenceCount {
|
class SoundData : public ReferenceCount {
|
||||||
@ -96,12 +94,20 @@ private:
|
|||||||
float _volume;
|
float _volume;
|
||||||
bool _active;
|
bool _active;
|
||||||
int _cache_limit;
|
int _cache_limit;
|
||||||
|
bool _cleanup_required;
|
||||||
// keep a count for startup and shutdown:
|
// keep a count for startup and shutdown:
|
||||||
static int _active_managers;
|
static int _active_managers;
|
||||||
|
static bool _miles_active;
|
||||||
unsigned int _concurrent_sound_limit;
|
unsigned int _concurrent_sound_limit;
|
||||||
|
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
bool _hasMidiSounds;
|
bool _hasMidiSounds;
|
||||||
|
|
||||||
|
// Optional Downloadable Sound field for software midi
|
||||||
|
static HDLSFILEID _dls_field;
|
||||||
|
|
||||||
|
typedef pset<MilesAudioManager *> Managers;
|
||||||
|
static Managers *_managers;
|
||||||
|
|
||||||
PT(SoundData) load(Filename file_name);
|
PT(SoundData) load(Filename file_name);
|
||||||
// Tell the manager that the sound dtor was called.
|
// Tell the manager that the sound dtor was called.
|
||||||
@ -122,6 +128,7 @@ private:
|
|||||||
void get_gm_file_path(string& result);
|
void get_gm_file_path(string& result);
|
||||||
|
|
||||||
void force_midi_reset();
|
void force_midi_reset();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
friend class MilesAudioSound;
|
friend class MilesAudioSound;
|
||||||
|
|
||||||
|
@ -181,9 +181,9 @@ MilesAudioSound(MilesAudioManager* manager,
|
|||||||
MilesAudioSound::
|
MilesAudioSound::
|
||||||
~MilesAudioSound() {
|
~MilesAudioSound() {
|
||||||
miles_audio_debug("~MilesAudioSound()");
|
miles_audio_debug("~MilesAudioSound()");
|
||||||
stop();
|
cleanup();
|
||||||
_manager->release_sound(this);
|
_manager->release_sound(this);
|
||||||
AIL_quick_unload(_audio);
|
miles_audio_debug("~MilesAudioSound() done");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -204,6 +204,7 @@ play() {
|
|||||||
if (status() == AudioSound::PLAYING) {
|
if (status() == AudioSound::PLAYING) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
nassertv(_audio);
|
||||||
_manager->starting_sound(this);
|
_manager->starting_sound(this);
|
||||||
// Start playing:
|
// Start playing:
|
||||||
if (AIL_quick_play(_audio, _loop_count)) {
|
if (AIL_quick_play(_audio, _loop_count)) {
|
||||||
@ -235,6 +236,7 @@ stop() {
|
|||||||
// make this symmetrical with play(). set_active() is the 'owner' of
|
// make this symmetrical with play(). set_active() is the 'owner' of
|
||||||
// _paused. play() accesses _paused to help in the situation where
|
// _paused. play() accesses _paused to help in the situation where
|
||||||
// someone calls play on an inactive sound().
|
// someone calls play on an inactive sound().
|
||||||
|
nassertv(_audio);
|
||||||
AIL_quick_halt(_audio);
|
AIL_quick_halt(_audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +321,7 @@ void MilesAudioSound::
|
|||||||
set_time(float time) {
|
set_time(float time) {
|
||||||
miles_audio_debug("set_time(time="<<time<<")");
|
miles_audio_debug("set_time(time="<<time<<")");
|
||||||
|
|
||||||
|
nassertv(_audio);
|
||||||
// Ensure we don't inadvertently run off the end of the sound.
|
// Ensure we don't inadvertently run off the end of the sound.
|
||||||
float max_time = length();
|
float max_time = length();
|
||||||
if (time > max_time) {
|
if (time > max_time) {
|
||||||
@ -339,6 +342,7 @@ set_time(float time) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float MilesAudioSound::
|
float MilesAudioSound::
|
||||||
get_time() const {
|
get_time() const {
|
||||||
|
nassertr(_audio, 0.0f);
|
||||||
S32 millisecond_time=AIL_quick_ms_position(_audio);
|
S32 millisecond_time=AIL_quick_ms_position(_audio);
|
||||||
float time=float(millisecond_time*.001);
|
float time=float(millisecond_time*.001);
|
||||||
miles_audio_debug("get_time() returning "<<time);
|
miles_audio_debug("get_time() returning "<<time);
|
||||||
@ -353,6 +357,7 @@ get_time() const {
|
|||||||
void MilesAudioSound::
|
void MilesAudioSound::
|
||||||
set_volume(float volume) {
|
set_volume(float volume) {
|
||||||
miles_audio_debug("set_volume(volume="<<volume<<")");
|
miles_audio_debug("set_volume(volume="<<volume<<")");
|
||||||
|
nassertv(_audio);
|
||||||
// *Set the volume even if our volume is not changing, because the
|
// *Set the volume even if our volume is not changing, because the
|
||||||
// MilesAudioManager will call set_volume when *its* volume changes.
|
// MilesAudioManager will call set_volume when *its* volume changes.
|
||||||
// Set the volume:
|
// Set the volume:
|
||||||
@ -539,5 +544,22 @@ status() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MilesAudioSound::cleanup
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called to release any resources associated with the
|
||||||
|
// sound.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MilesAudioSound::
|
||||||
|
cleanup() {
|
||||||
|
if (_audio) {
|
||||||
|
stop();
|
||||||
|
if (MilesAudioManager::_miles_active) {
|
||||||
|
AIL_quick_unload(_audio);
|
||||||
|
}
|
||||||
|
_audio = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //]
|
#endif //]
|
||||||
|
@ -142,8 +142,9 @@ private:
|
|||||||
// itwas set inactive.
|
// itwas set inactive.
|
||||||
bool _paused;
|
bool _paused;
|
||||||
|
|
||||||
MilesAudioSound(MilesAudioManager* manager,
|
MilesAudioSound(MilesAudioManager* manager, MilesAudioManager::SoundData *sd,
|
||||||
MilesAudioManager::SoundData *sd, string file_name, float length=0.0f);
|
string file_name, float length=0.0f);
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
friend class MilesAudioManager;
|
friend class MilesAudioManager;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user