LASTEXPRESS: Replace shared sound buffer by per-entry buffer

This commit is contained in:
Littleboy 2011-06-29 06:19:19 -04:00
parent b0ee7bbb7e
commit 9cc5d404c7
4 changed files with 24 additions and 91 deletions

View File

@ -38,6 +38,8 @@
namespace LastExpress {
#define SOUNDCACHE_ENTRY_SIZE 92160
//////////////////////////////////////////////////////////////////////////
// SoundEntry
//////////////////////////////////////////////////////////////////////////
@ -45,7 +47,7 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
_type = kSoundTypeNone;
_currentDataPtr = 0;
_soundData = NULL;
_soundBuffer = NULL;
_blockCount = 0;
_time = 0;
@ -66,12 +68,13 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
}
SoundEntry::~SoundEntry() {
// Entries that have been queued would have their streamed disposed automatically
// Entries that have been queued will have their streamed disposed automatically
if (!_soundStream)
SAFE_DELETE(_stream);
delete _soundStream;
free(_soundBuffer);
// Zero passed pointers
_engine = NULL;
}
@ -85,7 +88,7 @@ void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
getSoundQueue()->addToQueue(this);
// Add entry to cache and load sound data
getSoundQueue()->setupCache(this);
setupCache();
loadSoundData(name);
}
@ -197,6 +200,16 @@ void SoundEntry::setStatus(SoundFlag flag) {
_status.status = (statusFlag | kSoundStatusClear4);
}
void SoundEntry::setupCache() {
if (_soundBuffer)
return;
// Original has a priority-based shared buffer (of 6 entries)
// We simply allocate a new buffer for each sound entry that needs it
_soundBuffer = (byte *)malloc(SOUNDCACHE_ENTRY_SIZE);
memset(_soundBuffer, 0, SOUNDCACHE_ENTRY_SIZE);
}
void SoundEntry::setInCache() {
_status.status |= kSoundStatusClear2;
}

View File

@ -152,10 +152,7 @@ public:
// Streams
Common::SeekableReadStream *getStream() { return _stream; }
StreamedSound *getStreamedSound() { return _soundStream; }
public:
// TODO replace by on-the-fly allocated buffer
void *_soundData;
byte *getSoundBuffer() { return _soundBuffer; }
private:
LastExpressEngine *_engine;
@ -184,8 +181,11 @@ private:
// original has pointer to the next structure in the list (not used)
SubtitleEntry *_subtitle;
// Sound stream
// Sound buffer & stream
byte *_soundBuffer;
StreamedSound *_soundStream;
void setupCache();
};
//////////////////////////////////////////////////////////////////////////

View File

@ -32,18 +32,11 @@
namespace LastExpress {
#define SOUNDCACHE_ENTRY_SIZE 92160
#define SOUNDCACHE_MAX_SIZE 6
SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) {
_state = 0;
_currentType = kSoundType16;
_flag = 0;
// Cache and filter buffers
memset(&_buffer, 0, sizeof(_buffer));
_soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
_subtitlesFlag = 0;
_currentSubtitle = NULL;
}
@ -53,17 +46,12 @@ SoundQueue::~SoundQueue() {
SAFE_DELETE(*i);
_soundList.clear();
// Entries in the cache are just pointers to sound list entries
_soundCache.clear();
for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
SAFE_DELETE(*i);
_subtitles.clear();
_currentSubtitle = NULL;
free(_soundCacheData);
// Zero passed pointers
_engine = NULL;
}
@ -333,66 +321,6 @@ void SoundQueue::updateSubtitles() {
}
}
//////////////////////////////////////////////////////////////////////////
// Cache
//////////////////////////////////////////////////////////////////////////
bool SoundQueue::setupCache(SoundEntry *entry) {
if (entry->_soundData)
return true;
if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
SoundEntry *cacheEntry = NULL;
uint32 size = 1000;
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
if (!((*i)->getStatus().status & kSoundStatus_180)) {
uint32 newSize = (*i)->getPriority() + ((*i)->getStatus().status & kSoundStatusClear1);
if (newSize < size) {
cacheEntry = (*i);
size = newSize;
}
}
}
if (entry->getPriority() <= size)
return false;
if (!cacheEntry)
error("[SoundManager::setupCache] Cannot find a valid entry");
cacheEntry->setInCache();
// TODO: Wait until the cache entry is ready to be removed
while (!(cacheEntry->getStatus().status1 & 1))
;
if (cacheEntry->_soundData)
removeFromCache(cacheEntry);
_soundCache.push_back(entry);
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
} else {
_soundCache.push_back(entry);
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
}
return true;
}
void SoundQueue::removeFromCache(SoundEntry *entry) {
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
if ((*i) == entry) {
// Remove sound buffer
entry->_soundData = NULL;
// Remove entry from sound cache
i = _soundCache.reverse_erase(i);
}
}
}
//////////////////////////////////////////////////////////////////////////
// Savegame
//////////////////////////////////////////////////////////////////////////
@ -746,12 +674,12 @@ static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15,
static void soundFilter(byte *data, int16 *buffer, int p1, int p2);
void SoundQueue::applyFilter(SoundEntry *entry, int16 *buffer) {
if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
if ((((byte *)entry->getSoundBuffer())[1] << 6) > 0x1600) {
entry->setStatus(entry->getStatus().status | kSoundStatus_20000000);
} else {
int variant = entry->getStatus().status & 0x1f;
soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
soundFilter((byte *)entry->getSoundBuffer(), buffer, p1s[variant], p2s[variant]);
}
}

View File

@ -78,9 +78,6 @@ public:
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
// Cache
bool setupCache(SoundEntry *entry);
// Serializable
void saveLoadWithSerializer(Common::Serializer &ser);
uint32 count();
@ -109,7 +106,6 @@ private:
// Entries
Common::List<SoundEntry *> _soundList; ///< List of all sound entries
Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
void *_soundCacheData;
// Subtitles
@ -117,10 +113,6 @@ private:
Common::List<SubtitleEntry *> _subtitles;
SubtitleEntry *_currentSubtitle;
// Filters
int32 _buffer[2940]; ///< Static sound buffer
void removeFromCache(SoundEntry *entry);
void applyFilter(SoundEntry *entry, int16 *buffer);
friend class Debugger;