mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
Cort Stratton's latest updates adding cache limit support
This commit is contained in:
parent
075d6addd6
commit
12de6f6b58
@ -53,8 +53,10 @@ FmodAudioManager() {
|
||||
audio_debug(" audio_volume="<<audio_volume);
|
||||
|
||||
_active = audio_active;
|
||||
_cache_limit = audio_cache_limit;
|
||||
|
||||
// Initialize FMOD, if this is the first manager created.
|
||||
_is_valid = true;
|
||||
if (_active_managers == 0) {
|
||||
do {
|
||||
audio_debug("Initializing FMOD for real.");
|
||||
@ -65,14 +67,15 @@ FmodAudioManager() {
|
||||
_is_valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FSOUND_Init(44100, 32, 0) == 0) {
|
||||
audio_error("Fmod initialization failure.");
|
||||
_is_valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
while(0);
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
// increment regardless of whether an error has occured -- the
|
||||
@ -110,8 +113,22 @@ FmodAudioManager::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool FmodAudioManager::
|
||||
is_valid() {
|
||||
// verify the cache and LRU list here.
|
||||
return true;
|
||||
bool check=true;
|
||||
if (_sounds.size() != _lru.size()) {
|
||||
audio_debug("--sizes--");
|
||||
check=false;
|
||||
} else {
|
||||
LRU::const_iterator i=_lru.begin();
|
||||
for (; i != _lru.end(); ++i) {
|
||||
SoundMap::const_iterator smi=_sounds.find(*i);
|
||||
if (smi == _sounds.end()) {
|
||||
audio_debug("--"<<*i<<"--");
|
||||
check=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _is_valid && check;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -159,6 +176,10 @@ get_sound(const string &file_name) {
|
||||
new_entry.stale = true;
|
||||
|
||||
// Add to the cache
|
||||
while (_sounds.size() >= (unsigned int)_cache_limit) {
|
||||
uncache_a_sound();
|
||||
}
|
||||
|
||||
si = _sounds.insert(SoundMap::value_type(path, new_entry)).first;
|
||||
|
||||
// It's important that we assign entry to the address of the entry
|
||||
@ -193,6 +214,7 @@ get_sound(const string &file_name) {
|
||||
return 0;
|
||||
}
|
||||
inc_refcount(path);
|
||||
most_recently_used(path);
|
||||
|
||||
// determine length of sound
|
||||
float length = (float)FSOUND_Stream_GetLengthMs(stream) * 0.001f;
|
||||
@ -218,8 +240,16 @@ get_sound(const string &file_name) {
|
||||
void FmodAudioManager::
|
||||
uncache_sound(const string& file_name) {
|
||||
audio_debug("FmodAudioManager::uncache_sound(\""<<file_name<<"\")");
|
||||
Filename path = file_name;
|
||||
assert(is_valid());
|
||||
Filename path = file_name;
|
||||
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->resolve_filename(path, get_sound_path());
|
||||
} else {
|
||||
path.resolve_filename(get_sound_path());
|
||||
}
|
||||
audio_debug(" path=\""<<path<<"\"");
|
||||
SoundMap::iterator itor = _sounds.find(path);
|
||||
if (itor == _sounds.end()) {
|
||||
audio_error("FmodAudioManager::uncache_sound: no such entry "<<file_name);
|
||||
@ -227,13 +257,20 @@ uncache_sound(const string& file_name) {
|
||||
}
|
||||
|
||||
// Mark the entry as stale -- when its refcount reaches zero, it will
|
||||
// be removed from the cache. If the refcount is already zero, it can be
|
||||
// purged right now!
|
||||
// be removed from the cache.
|
||||
SoundCacheEntry *entry = &(*itor).second;
|
||||
if (entry->refcount == 0) {
|
||||
// If the refcount is already zero, it can be
|
||||
// purged right now!
|
||||
audio_debug("FmodAudioManager::uncache_sound: purging "<<path
|
||||
<< " from the cache.");
|
||||
delete [] entry->data;
|
||||
|
||||
// Erase the sound from the LRU list as well.
|
||||
assert(_lru.size()>0);
|
||||
LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first);
|
||||
assert(lru_i != _lru.end());
|
||||
_lru.erase(lru_i);
|
||||
_sounds.erase(itor);
|
||||
} else {
|
||||
entry->stale = true;
|
||||
@ -242,6 +279,48 @@ uncache_sound(const string& file_name) {
|
||||
assert(is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FmodAudioManager::uncache_a_sound
|
||||
// Access: Public
|
||||
// Description: Uncaches the least recently used sound.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FmodAudioManager::
|
||||
uncache_a_sound() {
|
||||
audio_debug("FmodAudioManager::uncache_a_sound()");
|
||||
assert(is_valid());
|
||||
// uncache least recently used:
|
||||
assert(_lru.size()>0);
|
||||
LRU::reference path=_lru.front();
|
||||
SoundMap::iterator i = _sounds.find(path);
|
||||
assert(i != _sounds.end());
|
||||
_lru.pop_front();
|
||||
|
||||
if (i != _sounds.end()) {
|
||||
audio_debug(" uncaching \""<<i->first<<"\"");
|
||||
uncache_sound(path);
|
||||
}
|
||||
assert(is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FmodAudioManager::most_recently_used
|
||||
// Access: Public
|
||||
// Description: Indicates that the given sound was the most recently used.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FmodAudioManager::
|
||||
most_recently_used(const string& path) {
|
||||
audio_debug("FmodAudioManager::most_recently_used(path=\""
|
||||
<<path<<"\")");
|
||||
LRU::iterator i=find(_lru.begin(), _lru.end(), path);
|
||||
if (i != _lru.end()) {
|
||||
_lru.erase(i);
|
||||
}
|
||||
// At this point, path should not exist in the _lru:
|
||||
assert(find(_lru.begin(), _lru.end(), path) == _lru.end());
|
||||
_lru.push_back(path);
|
||||
assert(is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FmodAudioManager::clear_cache
|
||||
// Access: Public
|
||||
@ -249,6 +328,7 @@ uncache_sound(const string& file_name) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FmodAudioManager::
|
||||
clear_cache() {
|
||||
audio_debug("FmodAudioManager::clear_cache()");
|
||||
// Mark all cache entries as stale. Delete those which already have
|
||||
// refcounts of zero.
|
||||
|
||||
@ -262,7 +342,14 @@ clear_cache() {
|
||||
audio_debug("FmodAudioManager::clear_cache: purging "<< (*itor).first
|
||||
<< " from the cache.");
|
||||
delete [] entry->data;
|
||||
|
||||
// Erase the sound from the LRU list as well.
|
||||
assert(_lru.size()>0);
|
||||
LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first);
|
||||
assert(lru_i != _lru.end());
|
||||
_lru.erase(lru_i);
|
||||
_sounds.erase(itor);
|
||||
|
||||
itor = _sounds.begin();
|
||||
} else {
|
||||
entry->stale = true;
|
||||
@ -277,8 +364,17 @@ clear_cache() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FmodAudioManager::
|
||||
set_cache_limit(int) {
|
||||
// intentionally blank.
|
||||
set_cache_limit(int count) {
|
||||
audio_debug("FmodAudioManager::set_cache_limit(count="
|
||||
<<count<<")");
|
||||
assert(is_valid());
|
||||
|
||||
while (_lru.size() > (unsigned int) count) {
|
||||
uncache_a_sound();
|
||||
}
|
||||
|
||||
_cache_limit = count;
|
||||
assert(is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -288,8 +384,9 @@ set_cache_limit(int) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int FmodAudioManager::
|
||||
get_cache_limit() {
|
||||
// intentionally blank.
|
||||
return 0;
|
||||
audio_debug("FmodAudioManager::get_cache_limit() returning "
|
||||
<<_cache_limit);
|
||||
return _cache_limit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -377,16 +474,17 @@ stop_all_sounds(void) {
|
||||
void FmodAudioManager::
|
||||
inc_refcount(const string& file_name) {
|
||||
Filename path = file_name;
|
||||
SoundMap::iterator itor = _sounds.find(path.to_os_specific());
|
||||
if (itor != _sounds.end()) {
|
||||
SoundCacheEntry *entry = &(*itor).second;
|
||||
entry->refcount++;
|
||||
entry->stale = false; // definitely not stale!
|
||||
audio_debug("FmodAudioManager: "<<path<<" has a refcount of "
|
||||
<< entry->refcount);
|
||||
} else {
|
||||
SoundMap::iterator itor = _sounds.find(path);
|
||||
if (itor == _sounds.end()) {
|
||||
audio_debug("FmodAudioManager::inc_refcount: no such file "<<path);
|
||||
return;
|
||||
}
|
||||
|
||||
SoundCacheEntry *entry = &(*itor).second;
|
||||
entry->refcount++;
|
||||
entry->stale = false; // definitely not stale!
|
||||
audio_debug("FmodAudioManager: "<<path<<" has a refcount of "
|
||||
<< entry->refcount);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -399,7 +497,7 @@ inc_refcount(const string& file_name) {
|
||||
void FmodAudioManager::
|
||||
dec_refcount(const string& file_name) {
|
||||
Filename path = file_name;
|
||||
SoundMap::iterator itor = _sounds.find(path.to_os_specific());
|
||||
SoundMap::iterator itor = _sounds.find(path);
|
||||
if (itor != _sounds.end()) {
|
||||
SoundCacheEntry *entry = &(*itor).second;
|
||||
entry->refcount--;
|
||||
@ -408,6 +506,12 @@ dec_refcount(const string& file_name) {
|
||||
if (entry->refcount == 0 && entry->stale) {
|
||||
audio_debug("FmodAudioManager::dec_refcount: purging "<<path<< " from the cache.");
|
||||
delete [] entry->data;
|
||||
|
||||
// Erase the sound from the LRU list as well.
|
||||
assert(_lru.size()>0);
|
||||
LRU::iterator lru_i=find(_lru.begin(), _lru.end(), itor->first);
|
||||
assert(lru_i != _lru.end());
|
||||
_lru.erase(lru_i);
|
||||
_sounds.erase(itor);
|
||||
}
|
||||
} else {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "audioManager.h"
|
||||
class FmodAudioSound;
|
||||
#include "filename.h"
|
||||
#include "pdeque.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
|
||||
@ -48,6 +49,12 @@ public:
|
||||
virtual void set_cache_limit(int);
|
||||
virtual int get_cache_limit();
|
||||
|
||||
// Indicates that the given sound was the most recently used.
|
||||
void most_recently_used(const string& path);
|
||||
|
||||
// Uncaches the least recently used sound.
|
||||
void uncache_a_sound();
|
||||
|
||||
virtual void set_volume(float);
|
||||
virtual float get_volume();
|
||||
|
||||
@ -74,8 +81,13 @@ private:
|
||||
// The offspring of this manager:
|
||||
AudioSet _soundsOnLoan;
|
||||
|
||||
// The Least Recently Used mechanism:
|
||||
typedef pdeque<string> LRU;
|
||||
LRU _lru;
|
||||
|
||||
void release_sound(FmodAudioSound *audioSound);
|
||||
|
||||
int _cache_limit;
|
||||
static int _active_managers;
|
||||
bool _is_valid;
|
||||
bool _active;
|
||||
|
Loading…
x
Reference in New Issue
Block a user