Skip to content

Commit

Permalink
LASTEXPRESS: Replace shared sound buffer by per-entry buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Templier committed Jun 29, 2011
1 parent b0ee7bb commit 9cc5d40
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 91 deletions.
21 changes: 17 additions & 4 deletions engines/lastexpress/sound/entry.cpp
Expand Up @@ -38,14 +38,16 @@

namespace LastExpress {

#define SOUNDCACHE_ENTRY_SIZE 92160

//////////////////////////////////////////////////////////////////////////
// SoundEntry
//////////////////////////////////////////////////////////////////////////
SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
_type = kSoundTypeNone;

_currentDataPtr = 0;
_soundData = NULL;
_soundBuffer = NULL;

_blockCount = 0;
_time = 0;
Expand All @@ -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;
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 5 additions & 5 deletions engines/lastexpress/sound/entry.h
Expand Up @@ -152,10 +152,7 @@ class SoundEntry : Common::Serializable {
// 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;
Expand Down Expand Up @@ -184,8 +181,11 @@ class SoundEntry : Common::Serializable {
// 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();
};

//////////////////////////////////////////////////////////////////////////
Expand Down
76 changes: 2 additions & 74 deletions engines/lastexpress/sound/queue.cpp
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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]);
}
}

Expand Down
8 changes: 0 additions & 8 deletions engines/lastexpress/sound/queue.h
Expand Up @@ -78,9 +78,6 @@ class SoundQueue : Common::Serializable {
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }

// Cache
bool setupCache(SoundEntry *entry);

// Serializable
void saveLoadWithSerializer(Common::Serializer &ser);
uint32 count();
Expand Down Expand Up @@ -109,18 +106,13 @@ class SoundQueue : Common::Serializable {

// Entries
Common::List<SoundEntry *> _soundList; ///< List of all sound entries
Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
void *_soundCacheData;

// Subtitles
int _subtitlesFlag;
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;
Expand Down

0 comments on commit 9cc5d40

Please sign in to comment.