[Scummvm-cvs-logs] scummvm master -> 04933a1937ef0de703a932e1392578aea4d38d64

Littleboy littleboy22 at gmail.com
Wed Jun 29 05:20:48 CEST 2011


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
d1341387e3 LASTEXPRESS: Move more entry-related functions to Entry class
6eace0ca75 LASTEXPRESS: Move sound queue related functions to a separate class
90dc4f9a8c LASTEXPRESS: Move Sound class to the sound folder
b4ac4988cc LASTEXPRESS: Cleanup comments
04933a1937 LASTEXPRESS: Make SoundEntry members private


Commit: d1341387e3c396aa6b48b39379afc9e201448048
    https://github.com/scummvm/scummvm/commit/d1341387e3c396aa6b48b39379afc9e201448048
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-28T17:09:56-07:00

Commit Message:
LASTEXPRESS: Move more entry-related functions to Entry class

Changed paths:
    engines/lastexpress/game/sound.cpp
    engines/lastexpress/game/sound.h
    engines/lastexpress/sound/entry.cpp
    engines/lastexpress/sound/entry.h



diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
index c95ef85..3fb3f88 100644
--- a/engines/lastexpress/game/sound.cpp
+++ b/engines/lastexpress/game/sound.cpp
@@ -161,15 +161,15 @@ void SoundManager::handleTimer() {
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
 		SoundEntry *entry = (*i);
-		if (entry->stream == NULL) {
+		if (entry->_stream == NULL) {
 			SAFE_DELETE(*i);
 			i = _soundList.reverse_erase(i);
 			continue;
-		} else if (!entry->soundStream) {
-			entry->soundStream = new StreamedSound();
+		} else if (!entry->_soundStream) {
+			entry->_soundStream = new StreamedSound();
 
 			// TODO: stream any sound in the queue after filtering
-			entry->soundStream->load(entry->stream);
+			entry->_soundStream->load(entry->_stream);
 		}
 	}
 }
@@ -189,7 +189,7 @@ void SoundManager::resetQueue(SoundType type1, SoundType type2) {
 	Common::StackLock locker(_mutex);
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->type != type1 && (*i)->type != type2)
+		if ((*i)->getType() != type1 && (*i)->getType() != type2)
 			(*i)->reset();
 	}
 }
@@ -226,7 +226,7 @@ void SoundManager::clearQueue() {
 		SoundEntry *entry = (*i);
 
 		// Delete entry
-		removeEntry(entry);
+		entry->close();
 		SAFE_DELETE(entry);
 
 		i = _soundList.reverse_erase(i);
@@ -247,7 +247,7 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
 	SoundEntry *entry = getEntry(filename);
 
 	if (testForEntity)
-		return entry != NULL && !entry->entity;
+		return entry != NULL && entry->getEntity() != kEntityPlayer;
 
 	return (entry != NULL);
 }
@@ -255,96 +255,8 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
 //////////////////////////////////////////////////////////////////////////
 // Entry
 //////////////////////////////////////////////////////////////////////////
-void SoundManager::setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority) {
-	if (!entry)
-		error("SoundManager::setupEntry: Invalid entry!");
-
-	entry->priority = priority;
-	setEntryType(entry, flag);
-	entry->setStatus(flag);
-
-	// Add entry to sound list
-	_soundList.push_back(entry);
-
-	// TODO Add entry to cache and load sound data
-	//setupCache(entry);
-	loadSoundData(entry, name);
-}
-
-void SoundManager::setEntryType(SoundEntry *entry, SoundFlag flag) {
-	switch (flag & kFlagType9) {
-	default:
-	case kFlagNone:
-		entry->type = _currentType;
-		_currentType = (SoundType)(_currentType + 1);
-		break;
-
-	case kFlagType1_2: {
-		SoundEntry *previous2 = getEntry(kSoundType2);
-		if (previous2)
-			previous2->update(0);
-
-		SoundEntry *previous = getEntry(kSoundType1);
-		if (previous) {
-			previous->type = kSoundType2;
-			previous->update(0);
-		}
-
-		entry->type = kSoundType1;
-		}
-		break;
-
-	case kFlagType3: {
-		SoundEntry *previous = getEntry(kSoundType3);
-		if (previous) {
-			previous->type = kSoundType4;
-			previous->update(0);
-		}
-
-		entry->type = kSoundType11;
-		}
-		break;
-
-	case kFlagType7: {
-		SoundEntry *previous = getEntry(kSoundType7);
-		if (previous)
-			previous->type = kSoundType8;
-
-		entry->type = kSoundType7;
-		}
-		break;
-
-	case kFlagType9: {
-		SoundEntry *previous = getEntry(kSoundType9);
-		if (previous)
-			previous->type = kSoundType10;
-
-		entry->type = kSoundType9;
-		}
-		break;
-
-	case kFlagType11: {
-		SoundEntry *previous = getEntry(kSoundType11);
-		if (previous)
-			previous->type = kSoundType14;
-
-		entry->type = kSoundType11;
-		}
-		break;
-
-	case kFlagType13: {
-		SoundEntry *previous = getEntry(kSoundType13);
-		if (previous)
-			previous->type = kSoundType14;
-
-		entry->type = kSoundType13;
-		}
-		break;
-	}
-}
-
 bool SoundManager::setupCache(SoundEntry *entry) {
-	if (entry->soundData)
+	if (entry->_soundData)
 		return true;
 
 	if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
@@ -353,8 +265,8 @@ bool SoundManager::setupCache(SoundEntry *entry) {
 		uint32 size = 1000;
 
 		for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
-			if (!((*i)->status.status & kSoundStatus_180)) {
-				uint32 newSize = (*i)->priority + ((*i)->status.status & kSoundStatusClear1);
+			if (!((*i)->_status.status & kSoundStatus_180)) {
+				uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1);
 
 				if (newSize < size) {
 					cacheEntry = (*i);
@@ -363,7 +275,7 @@ bool SoundManager::setupCache(SoundEntry *entry) {
 			}
 		}
 
-		if (entry->priority <= size)
+		if (entry->_priority <= size)
 			return false;
 
 		if (!cacheEntry)
@@ -372,17 +284,17 @@ bool SoundManager::setupCache(SoundEntry *entry) {
 		cacheEntry->setInCache();
 
 		// TODO: Wait until the cache entry is ready to be removed
-		while (!(cacheEntry->status.status1 & 1))
+		while (!(cacheEntry->_status.status1 & 1))
 			;
 
-		if (cacheEntry->soundData)
+		if (cacheEntry->_soundData)
 			removeFromCache(cacheEntry);
 
 		_soundCache.push_back(entry);
-		entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
+		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);
+		entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
 	}
 
 	return true;
@@ -392,7 +304,7 @@ void SoundManager::removeFromCache(SoundEntry *entry) {
 	for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
 		if ((*i) == entry) {
 			// Remove sound buffer
-			entry->soundData = NULL;
+			entry->_soundData = NULL;
 
 			// Remove entry from sound cache
 			i = _soundCache.reverse_erase(i);
@@ -404,48 +316,7 @@ void SoundManager::clearStatus() {
 	Common::StackLock locker(_mutex);
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->status.status |= kSoundStatusClear3;
-}
-
-void SoundManager::loadSoundData(SoundEntry *entry, Common::String name) {
-	entry->name2 = name;
-
-	// Load sound data
-	entry->stream = getArchive(name);
-
-	if (!entry->stream)
-		entry->stream = getArchive("DEFAULT.SND");
-
-	if (entry->stream) {
-		warning("Sound::loadSoundData: not implemented!");
-	} else {
-		entry->status.status = kSoundStatusRemoved;
-	}
-}
-
-void SoundManager::removeEntry(SoundEntry *entry) {
-	entry->status.status |= kSoundStatusRemoved;
-
-	// Loop until ready
-	while (!(entry->status.status1 & 4) && !(_flag & 8) && (_flag & 1))
-		;	// empty loop body
-
-	// The original game remove the entry from the cache here,
-	// but since we are called from within an iterator loop
-	// we will remove the entry there
-	// removeFromCache(entry);
-
-	if (entry->subtitle) {
-		entry->subtitle->draw();
-		SAFE_DELETE(entry->subtitle);
-	}
-
-	if (entry->entity) {
-		if (entry->entity == kEntitySteam)
-			playLoopingSound(2);
-		else if (entry->entity != kEntityTrain)
-			getSavePoints()->push(kEntityPlayer, entry->entity, kActionEndSound);
-	}
+		(*i)->_status.status |= kSoundStatusClear3;
 }
 
 void SoundManager::processEntry(EntityIndex entity) {
@@ -454,7 +325,7 @@ void SoundManager::processEntry(EntityIndex entity) {
 	SoundEntry *entry = getEntry(entity);
 	if (entry) {
 		entry->update(0);
-		entry->entity = kEntityPlayer;
+		entry->setEntity(kEntityPlayer);
 	}
 }
 
@@ -471,7 +342,7 @@ void SoundManager::setupEntry(SoundType type, EntityIndex index) {
 
 	SoundEntry *entry = getEntry(type);
 	if (entry)
-		entry->entity = index;
+		entry->setEntity(index);
 }
 
 void SoundManager::processEntry(Common::String filename) {
@@ -480,7 +351,7 @@ void SoundManager::processEntry(Common::String filename) {
 	SoundEntry *entry = getEntry(filename);
 	if (entry) {
 		entry->update(0);
-		entry->entity = kEntityPlayer;
+		entry->setEntity(kEntityPlayer);
 	}
 }
 
@@ -496,7 +367,7 @@ uint32 SoundManager::getEntryTime(EntityIndex index) {
 
 	SoundEntry *entry = getEntry(index);
 	if (entry)
-		return entry->time;
+		return entry->_time;
 
 	return 0;
 }
@@ -515,7 +386,7 @@ void SoundManager::unknownFunction4() {
 //////////////////////////////////////////////////////////////////////////
 SoundEntry *SoundManager::getEntry(EntityIndex index) {
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->entity == index)
+		if ((*i)->getEntity() == index)
 			return *i;
 	}
 
@@ -527,7 +398,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) {
 		name += ".SND";
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->name2 == name)
+		if ((*i)->_name2 == name)
 			return *i;
 	}
 
@@ -536,7 +407,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) {
 
 SoundEntry *SoundManager::getEntry(SoundType type) {
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->type == type)
+		if ((*i)->getType() == type)
 			return *i;
 	}
 
@@ -547,6 +418,8 @@ SoundEntry *SoundManager::getEntry(SoundType type) {
 // Savegame
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
+	Common::StackLock locker(_mutex);
+
 	s.syncAsUint32LE(_state);
 	s.syncAsUint32LE(_currentType);
 
@@ -554,39 +427,12 @@ void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
 	uint32 numEntries = count();
 	s.syncAsUint32LE(numEntries);
 
-	Common::StackLock locker(_mutex);
-
 	// Save or load each entry data
 	if (s.isSaving()) {
-		for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-			SoundEntry *entry = *i;
-			if (entry->name2.matchString("NISSND?") && (entry->status.status & kFlagType7) != kFlag3) {
-				s.syncAsUint32LE(entry->status.status); // status;
-				s.syncAsUint32LE(entry->type); // type;
-				s.syncAsUint32LE(entry->blockCount); // field_8;
-				s.syncAsUint32LE(entry->time); // time;
-				s.syncAsUint32LE(entry->field_34); // field_10;
-				s.syncAsUint32LE(entry->field_38); // field_14;
-				s.syncAsUint32LE(entry->entity); // entity;
-
-				uint32 blockCount = (uint32)entry->field_48 - _data2;
-				if (blockCount > kFlag8)
-					blockCount = 0;
-				s.syncAsUint32LE(blockCount); // blockCount;
-
-				s.syncAsUint32LE(entry->priority); // field_20;
-
-				char name1[16];
-				strcpy((char *)&name1, entry->name1.c_str());
-				s.syncBytes((byte *)&name1, 16);
-
-				char name2[16];
-				strcpy((char *)&name2, entry->name2.c_str());
-				s.syncBytes((byte *)&name2, 16);
-			}
-		}
+		for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+			(*i)->saveLoadWithSerializer(s);
 	} else {
-		warning("Sound::saveLoadWithSerializer: not implemented!");
+		warning("Sound::saveLoadWithSerializer: loading not implemented");
 		s.skip(numEntries * 64);
 	}
 }
@@ -600,7 +446,7 @@ uint32 SoundManager::count() {
 
 	uint32 numEntries = 0;
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		if ((*i)->name2.matchString("NISSND?"))
+		if ((*i)->_name2.matchString("NISSND?"))
 			++numEntries;
 
 	return numEntries;
@@ -629,12 +475,12 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
 
 	Common::StackLock locker(_mutex);
 
-	setupEntry(entry, filename, flag, 30);
-	entry->entity = entity;
+	entry->open(filename, flag, 30);
+	entry->_entity = entity;
 
 	if (a4) {
-		entry->field_48 = _data2 + 2 * a4;
-		entry->status.status |= kSoundStatus_8000;
+		entry->_field_48 = _data2 + 2 * a4;
+		entry->_status.status |= kSoundStatus_8000;
 	} else {
 		// Get subtitles name
 		while (filename.size() > 4)
@@ -644,7 +490,7 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
 		entry->updateState();
 	}
 
-	return (entry->type != kSoundTypeNone);
+	return (entry->getType() != kSoundTypeNone);
 }
 
 void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
@@ -1763,16 +1609,16 @@ void SoundManager::updateSubtitles() {
 	for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
 		uint32 current_index = 0;
 		SoundEntry *soundEntry = (*i)->getSoundEntry();
-		SoundStatus status = (SoundStatus)soundEntry->status.status;
+		SoundStatus status = (SoundStatus)soundEntry->_status.status;
 
 		if (!(status & kSoundStatus_40)
-		 || status & 0x180
-		 || soundEntry->time == 0
-		 || (status & 0x1F) < 6
-		 || ((getFlags()->nis & 0x8000) && soundEntry->priority < 90)) {
+		 || status & kSoundStatus_180
+		 || soundEntry->_time == 0
+		 || (status & kSoundStatusClear1) < 6
+		 || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) {
 			 current_index = 0;
 		} else {
-			current_index = soundEntry->priority + (status & 0x1F);
+			current_index = soundEntry->_priority + (status & kSoundStatusClear1);
 
 			if (_currentSubtitle == (*i))
 				current_index += 4;
@@ -1808,15 +1654,15 @@ void SoundManager::playLoopingSound(int param) {
 	char tmp[80];
 
 	for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
-		if ((*snd)->type == kSoundType1)
+		if ((*snd)->getType() == kSoundType1)
 			break;
 	}
 
 	byte numLoops[8];
 	static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
-												 kPosition_6470, kPosition_5790,
-												 kPosition_4840, kPosition_4070,
-												 kPosition_3050, kPosition_2740 };
+	                                             kPosition_6470, kPosition_5790,
+	                                             kPosition_4840, kPosition_4070,
+	                                             kPosition_3050, kPosition_2740 };
 
 	numLoops[1] = 4;
 	numLoops[2] = 2;
@@ -1889,7 +1735,7 @@ void SoundManager::playLoopingSound(int param) {
 		if (getFlags()->flag_3)
 			fnameLen = 5;
 
-		if (!*snd || scumm_strnicmp((*snd)->name2.c_str(), tmp, fnameLen)) {
+		if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) {
 			_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
 
 			if (partNumber != 99) {
@@ -1899,7 +1745,7 @@ void SoundManager::playLoopingSound(int param) {
 					(*snd)->update(0);
 
 				for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
-					if ((*snd)->type == kSoundType1) {
+					if ((*snd)->getType() == kSoundType1) {
 						(*snd)->update(7);
 						break;
 					}
@@ -1913,7 +1759,7 @@ void SoundManager::stopAllSound() {
 	Common::StackLock locker(_mutex);
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->soundStream->stop();
+		(*i)->_soundStream->stop();
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -2232,12 +2078,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 SoundManager::applyFilter(SoundEntry *entry, int16 *buffer) {
-	if ((((byte *)entry->soundData)[1] << 6) > 0x1600) {
-    entry->status.status |= 0x20000000;
+	if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
+    entry->_status.status |= 0x20000000;
   } else {
-	  int variant = entry->status.status & 0x1f;
+	  int variant = entry->_status.status & 0x1f;
 
-	  soundFilter((byte *)entry->soundData, buffer, p1s[variant], p2s[variant]);
+	  soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
   }
 }
 
diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h
index e7b0660..414fb0d 100644
--- a/engines/lastexpress/game/sound.h
+++ b/engines/lastexpress/game/sound.h
@@ -84,6 +84,8 @@ public:
 	void playLocomotiveSound();
 	void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
 
+	void playLoopingSound(int param);
+
 	// Dialog & Letters
 	void readText(int id);
 	const char *getDialogName(EntityIndex entity) const;
@@ -109,6 +111,9 @@ public:
 	uint32 getFlag() { return _flag; }
 	int getSubtitleFlag() { return _subtitlesFlag; }
 	void setSubtitleFlag(int flag) { _subtitlesFlag = flag; }
+	SoundType getCurrentType() { return _currentType; }
+	void setCurrentType(SoundType type) { _currentType = type; }
+	uint32 getData2() { return _data2; }
 
 	// Subtitles
 	void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); }
@@ -116,6 +121,12 @@ public:
 	void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
 	SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
 
+	// Queue
+	bool setupCache(SoundEntry *entry);
+	void addToQueue(SoundEntry *entry) { _soundList.push_back(entry); }
+
+	SoundEntry *getEntry(SoundType type);
+
 private:
 	typedef int32 *SoundBuffer;
 
@@ -149,7 +160,6 @@ private:
 	uint32 _lastWarning[12];
 
 	// Looping sound
-	void playLoopingSound(int param);
 	int _loopingSoundDuration;
 
 	// Sound entries
@@ -159,14 +169,8 @@ private:
 
 	SoundEntry *getEntry(EntityIndex index);
 	SoundEntry *getEntry(Common::String name);
-	SoundEntry *getEntry(SoundType type);
 
-	void setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority);
-	void setEntryType(SoundEntry *entry, SoundFlag flag);
-	bool setupCache(SoundEntry *entry);
 	void removeFromCache(SoundEntry *entry);
-	void loadSoundData(SoundEntry *entry, Common::String name);
-	void removeEntry(SoundEntry *entry);
 
 	// Subtitles
 	int _subtitlesFlag;
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 67549cb..304d524 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -22,7 +22,10 @@
 
 #include "lastexpress/sound/entry.h"
 
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
@@ -37,114 +40,267 @@ namespace LastExpress {
 // SoundEntry
 //////////////////////////////////////////////////////////////////////////
 SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
-	type = kSoundTypeNone;
+	_type = kSoundTypeNone;
 
-	currentDataPtr = 0;
-	soundData = NULL;
+	_currentDataPtr = 0;
+	_soundData = NULL;
 
-	blockCount = 0;
-	time = 0;
+	_blockCount = 0;
+	_time = 0;
 
-	stream = NULL;
+	_stream = NULL;
 
-	field_34 = 0;
-	field_38 = 0;
-	field_3C = 0;
-	field_40 = 0;
-	entity = kEntityPlayer;
-	field_48 = 0;
-	priority = 0;
+	_field_34 = 0;
+	_field_38 = 0;
+	_field_3C = 0;
+	_field_40 = 0;
+	_entity = kEntityPlayer;
+	_field_48 = 0;
+	_priority = 0;
 
-	subtitle = NULL;
+	_subtitle = NULL;
 
-	soundStream = NULL;
+	_soundStream = NULL;
 }
 
 SoundEntry::~SoundEntry() {
 	// Entries that have been queued would have their streamed disposed automatically
-	if (!soundStream)
-		SAFE_DELETE(stream);
+	if (!_soundStream)
+		SAFE_DELETE(_stream);
 
-	delete soundStream;
+	delete _soundStream;
 
 	_engine = NULL;
 }
 
+void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
+	_priority = priority;
+	setType(flag);
+	setStatus(flag);
+
+	// Add entry to sound list
+	getSound()->addToQueue(this);
+
+	// Add entry to cache and load sound data
+	getSound()->setupCache(this);
+	loadSoundData(name);
+}
+
+void SoundEntry::close() {
+	_status.status |= kSoundStatusRemoved;
+
+	// Loop until ready
+	while (!(_status.status1 & 4) && !(getSound()->getFlag() & 8) && (getSound()->getFlag() & 1))
+		;	// empty loop body
+
+	// The original game remove the entry from the cache here,
+	// but since we are called from within an iterator loop
+	// we will remove the entry there
+	// removeFromCache(entry);
+
+	if (_subtitle) {
+		_subtitle->draw();
+		SAFE_DELETE(_subtitle);
+	}
+
+	if (_entity) {
+		if (_entity == kEntitySteam)
+			getSound()->playLoopingSound(2);
+		else if (_entity != kEntityTrain)
+			getSavePoints()->push(kEntityPlayer, _entity, kActionEndSound);
+	}
+}
+
+void SoundEntry::setType(SoundFlag flag) {
+	switch (flag & kFlagType9) {
+	default:
+	case kFlagNone:
+		_type = getSound()->getCurrentType();
+		getSound()->setCurrentType((SoundType)(_type + 1));
+		break;
+
+	case kFlagType1_2: {
+		SoundEntry *previous2 = getSound()->getEntry(kSoundType2);
+		if (previous2)
+			previous2->update(0);
+
+		SoundEntry *previous = getSound()->getEntry(kSoundType1);
+		if (previous) {
+			previous->setType(kSoundType2);
+			previous->update(0);
+		}
+
+		_type = kSoundType1;
+		}
+		break;
+
+	case kFlagType3: {
+		SoundEntry *previous = getSound()->getEntry(kSoundType3);
+		if (previous) {
+			previous->setType(kSoundType4);
+			previous->update(0);
+		}
+
+		_type = kSoundType11;
+		}
+		break;
+
+	case kFlagType7: {
+		SoundEntry *previous = getSound()->getEntry(kSoundType7);
+		if (previous)
+			previous->setType(kSoundType8);
+
+		_type = kSoundType7;
+		}
+		break;
+
+	case kFlagType9: {
+		SoundEntry *previous = getSound()->getEntry(kSoundType9);
+		if (previous)
+			previous->setType(kSoundType10);
+
+		_type = kSoundType9;
+		}
+		break;
+
+	case kFlagType11: {
+		SoundEntry *previous = getSound()->getEntry(kSoundType11);
+		if (previous)
+			previous->setType(kSoundType14);
+
+		_type = kSoundType11;
+		}
+		break;
+
+	case kFlagType13: {
+		SoundEntry *previous = getSound()->getEntry(kSoundType13);
+		if (previous)
+			previous->setType(kSoundType14);
+
+		_type = kSoundType13;
+		}
+		break;
+	}
+}
+
 void SoundEntry::setStatus(SoundFlag flag) {
 	SoundStatus statusFlag = (SoundStatus)flag;
 	if (!((statusFlag & 0xFF) & kSoundStatusClear1))
 		statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2);
 
 	if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0)
-		status.status = (uint32)statusFlag;
+		_status.status = (uint32)statusFlag;
 	else
-		status.status = (statusFlag | kSoundStatusClear4);
+		_status.status = (statusFlag | kSoundStatusClear4);
 }
 
 void SoundEntry::setInCache() {
-	status.status |= kSoundStatusClear2;
+	_status.status |= kSoundStatusClear2;
+}
+
+void SoundEntry::loadSoundData(Common::String name) {
+	_name2 = name;
+
+	// Load sound data
+	_stream = getArchive(name);
+
+	if (!_stream)
+		_stream = getArchive("DEFAULT.SND");
+
+	if (_stream) {
+		warning("Sound::loadSoundData: not implemented!");
+	} else {
+		_status.status = kSoundStatusRemoved;
+	}
 }
 
 void SoundEntry::update(uint val) {
-	if (!(status.status3 & 64)) {
+	if (!(_status.status3 & 64)) {
 		int value2 = val;
 
-		status.status |= kSoundStatus_100000;
+		_status.status |= kSoundStatus_100000;
 
 		if (val) {
 			if (getSound()->getFlag() & 32) {
-				field_40 = val;
+				_field_40 = val;
 				value2 = val * 2 + 1;
 			}
 
-			field_3C = value2;
+			_field_3C = value2;
 		} else {
-			field_3C = 0;
-			status.status |= kSoundStatus_40000000;
+			_field_3C = 0;
+			_status.status |= kSoundStatus_40000000;
 		}
 	}
 }
 
 void SoundEntry::updateState() {
 	if (getSound()->getFlag() & 32) {
-		if (type != kSoundType9 && type != kSoundType7 && type != kSoundType5) {
-			uint32 newStatus = status.status & kSoundStatusClear1;
+		if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
+			uint32 newStatus = _status.status & kSoundStatusClear1;
 
-			status.status &= kSoundStatusClearAll;
+			_status.status &= kSoundStatusClearAll;
 
-			field_40 = newStatus;
-			status.status |= newStatus * 2 + 1;
+			_field_40 = newStatus;
+			_status.status |= newStatus * 2 + 1;
 		}
 	}
 
-	status.status |= kSoundStatus_20;
+	_status.status |= kSoundStatus_20;
 }
 
 void SoundEntry::reset() {
-	status.status |= kSoundStatusRemoved;
-	entity = kEntityPlayer;
+	_status.status |= kSoundStatusRemoved;
+	_entity = kEntityPlayer;
 
-	if (stream) {
-		if (!soundStream) {
-			SAFE_DELETE(stream);
+	if (_stream) {
+		if (!_soundStream) {
+			SAFE_DELETE(_stream);
 		} else {
-			soundStream->stop();
-			SAFE_DELETE(soundStream);
+			_soundStream->stop();
+			SAFE_DELETE(_soundStream);
 		}
 
-		stream = NULL;
+		_stream = NULL;
 	}
 }
 
 void SoundEntry::showSubtitle(Common::String filename) {
-	subtitle = new SubtitleEntry(_engine);
-	subtitle->load(filename, this);
+	_subtitle = new SubtitleEntry(_engine);
+	_subtitle->load(filename, this);
 
-	if (subtitle->getStatus().status2 & 4) {
-		subtitle->draw();
-		SAFE_DELETE(subtitle);
+	if (_subtitle->getStatus().status2 & 4) {
+		_subtitle->draw();
+		SAFE_DELETE(_subtitle);
 	} else {
-		status.status |= kSoundStatus_20000;
+		_status.status |= kSoundStatus_20000;
+	}
+}
+
+void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
+	if (_name2.matchString("NISSND?") && (_status.status & kFlagType7) != kFlag3) {
+		s.syncAsUint32LE(_status.status);
+		s.syncAsUint32LE(_type);
+		s.syncAsUint32LE(_blockCount); // field_8;
+		s.syncAsUint32LE(_time);
+		s.syncAsUint32LE(_field_34); // field_10;
+		s.syncAsUint32LE(_field_38); // field_14;
+		s.syncAsUint32LE(_entity);
+
+		uint32 delta = (uint32)_field_48 - getSound()->getData2();
+		if (delta > kFlag8)
+			delta = 0;
+		s.syncAsUint32LE(delta);
+
+		s.syncAsUint32LE(_priority);
+
+		char name1[16];
+		strcpy((char *)&name1, _name1.c_str());
+		s.syncBytes((byte *)&name1, 16);
+
+		char name2[16];
+		strcpy((char *)&name2, _name2.c_str());
+		s.syncBytes((byte *)&name2, 16);
 	}
 }
 
@@ -193,10 +349,10 @@ void SubtitleEntry::setupAndDraw() {
 		_data->load(getArchive(_filename));
 	}
 
-	if (_data->getMaxTime() > _sound->time) {
+	if (_data->getMaxTime() > _sound->_time) {
 		_status.status = kSoundStatus_400;
 	} else {
-		_data->setTime((uint16)_sound->time);
+		_data->setTime((uint16)_sound->_time);
 
 		if (getSound()->getSubtitleFlag() & 1)
 			drawOnScreen();
diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h
index 84a2342..929d346 100644
--- a/engines/lastexpress/sound/entry.h
+++ b/engines/lastexpress/sound/entry.h
@@ -24,30 +24,30 @@
 #define LASTEXPRESS_SOUND_ENTRY_H
 
 /*
-	Sound entry: 68 bytes (this is what appears in the savegames)
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
+	Sound entry: 68 bytes (this is what appears in savegames)
+	    uint32 {4}      - status
+	    uint32 {4}      - type
+	    uint32 {4}      - blockCount
+	    uint32 {4}      - time
 	    uint32 {4}      - ??
 	    uint32 {4}      - ??
 	    uint32 {4}      - entity
 	    uint32 {4}      - ??
-	    uint32 {4}      - ??
+	    uint32 {4}      - priority
 	    char {16}       - name 1
 	    char {16}       - name 2
 
 	Sound queue entry: 120 bytes
 	    uint16 {2}      - status
+	    byte {1}        - type
 	    byte {1}        - ??
-	    byte {1}        - ??
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
-	    uint32 {4}      - file data pointer
-	    uint32 {4}      - ??
-	    uint32 {4}      - ??
 	    uint32 {4}      - ??
+	    uint32 {4}      - currentDataPtr
+	    uint32 {4}      - soundData
+	    uint32 {4}      - currentBufferPtr
+	    uint32 {4}      - blockCount
+	    uint32 {4}      - time
+	    uint32 {4}      - size
 	    uint32 {4}      - ??
 	    uint32 {4}      - archive structure pointer
 	    uint32 {4}      - ??
@@ -57,7 +57,7 @@
 	    uint32 {4}      - ??
 	    uint32 {4}      - entity
 	    uint32 {4}      - ??
-	    uint32 {4}      - ??
+	    uint32 {4}      - priority
 	    char {16}       - name 1
 	    char {16}       - name 2
 	    uint32 {4}      - pointer to next entry in the queue
@@ -69,6 +69,8 @@
 
 #include "lastexpress/shared.h"
 
+#include "common/serializer.h"
+
 namespace LastExpress {
 
 class LastExpressEngine;
@@ -109,13 +111,18 @@ union SoundStatusUnion {
 //////////////////////////////////////////////////////////////////////////
 // SoundEntry
 //////////////////////////////////////////////////////////////////////////
-class SoundEntry {
+class SoundEntry : Common::Serializable {
 public:
 	SoundEntry(LastExpressEngine *engine);
 	~SoundEntry();
 
+	void open(Common::String name, SoundFlag flag, int priority);
+	void close();
+
 	void setStatus(SoundFlag flag);
+	void setType(SoundFlag flag);
 	void setInCache();
+	void loadSoundData(Common::String name);
 	void update(uint val);
 	void updateState();
 	void reset();
@@ -123,37 +130,47 @@ public:
 	// Subtitles
 	void showSubtitle(Common::String filename);
 
+	// Serializable
+	void saveLoadWithSerializer(Common::Serializer &ser);
+
+	// Accessors
+	void setType(SoundType type) { _type = type; }
+	SoundType getType() { return _type; }
+
+	void setEntity(EntityIndex entity) { _entity = entity; }
+	EntityIndex getEntity() { return _entity; }
+
 private:
 	LastExpressEngine *_engine;
 
 public:
-	SoundStatusUnion status;
-	SoundType type;    // int
-	//int data;
-	//int endOffset;
-	int currentDataPtr;
-	void *soundData;
-	//int currentBufferPtr;
-	int blockCount;
-	uint32 time;
-	//int size;
-	//int field_28;
-	Common::SeekableReadStream *stream;	// int
-	//int field_30;
-	int field_34;
-	int field_38;
-	int field_3C;
-	int field_40;
-	EntityIndex entity;
-	int field_48;
-	uint32 priority;
-	Common::String name1; //char[16];
-	Common::String name2; //char[16];
-	//int next; // offset to the next structure in the list (not used)
-	SubtitleEntry *subtitle;
+	SoundStatusUnion _status;
+	SoundType _type;    // int
+	//int _data;
+	//int _endOffset;
+	int _currentDataPtr;
+	void *_soundData;
+	//int _currentBufferPtr;
+	int _blockCount;
+	uint32 _time;
+	//int _size;
+	//int _field_28;
+	Common::SeekableReadStream *_stream;    // int
+	//int _field_30;
+	int _field_34;
+	int _field_38;
+	int _field_3C;
+	int _field_40;
+	EntityIndex _entity;
+	int _field_48;
+	uint32 _priority;
+	Common::String _name1;    //char[16];
+	Common::String _name2;    //char[16];
+	// original has pointer to the next structure in the list (not used)
+	SubtitleEntry *_subtitle;
 
 	// Sound stream
-	StreamedSound *soundStream;
+	StreamedSound *_soundStream;
 };
 
 //////////////////////////////////////////////////////////////////////////


Commit: 6eace0ca759bc62b6b0b6cf69a4341b4d1bb43e4
    https://github.com/scummvm/scummvm/commit/6eace0ca759bc62b6b0b6cf69a4341b4d1bb43e4
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-28T19:13:40-07:00

Commit Message:
LASTEXPRESS: Move sound queue related functions to a separate class

 - Implement missing queue reset function
 - Cleanup SoundManager::playLoopingSound()

Changed paths:
  A engines/lastexpress/sound/queue.cpp
  A engines/lastexpress/sound/queue.h
    engines/lastexpress/debug.cpp
    engines/lastexpress/entities/abbot.cpp
    engines/lastexpress/entities/anna.cpp
    engines/lastexpress/entities/august.cpp
    engines/lastexpress/entities/boutarel.cpp
    engines/lastexpress/entities/chapters.cpp
    engines/lastexpress/entities/cooks.cpp
    engines/lastexpress/entities/coudert.cpp
    engines/lastexpress/entities/francois.cpp
    engines/lastexpress/entities/kahina.cpp
    engines/lastexpress/entities/kronos.cpp
    engines/lastexpress/entities/mahmud.cpp
    engines/lastexpress/entities/max.cpp
    engines/lastexpress/entities/mertens.cpp
    engines/lastexpress/entities/milos.cpp
    engines/lastexpress/entities/mmeboutarel.cpp
    engines/lastexpress/entities/pascale.cpp
    engines/lastexpress/entities/rebecca.cpp
    engines/lastexpress/entities/salko.cpp
    engines/lastexpress/entities/tables.cpp
    engines/lastexpress/entities/tatiana.cpp
    engines/lastexpress/entities/train.cpp
    engines/lastexpress/entities/vassili.cpp
    engines/lastexpress/entities/verges.cpp
    engines/lastexpress/fight/fight.cpp
    engines/lastexpress/fight/fighter_anna.cpp
    engines/lastexpress/fight/fighter_ivo.cpp
    engines/lastexpress/fight/fighter_milos.cpp
    engines/lastexpress/fight/fighter_salko.cpp
    engines/lastexpress/fight/fighter_vesna.cpp
    engines/lastexpress/game/action.cpp
    engines/lastexpress/game/entities.cpp
    engines/lastexpress/game/inventory.cpp
    engines/lastexpress/game/logic.cpp
    engines/lastexpress/game/savegame.cpp
    engines/lastexpress/game/scenes.cpp
    engines/lastexpress/game/sound.cpp
    engines/lastexpress/game/sound.h
    engines/lastexpress/helpers.h
    engines/lastexpress/lastexpress.cpp
    engines/lastexpress/menu/menu.cpp
    engines/lastexpress/module.mk
    engines/lastexpress/shared.h
    engines/lastexpress/sound/entry.cpp



diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index d5c7df0..2d22630 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -44,6 +44,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -793,7 +795,7 @@ bool Debugger::cmdFight(int argc, const char **argv) {
 			restoreArchive();
 
 			// Stop audio and restore scene
-			getSound()->stopAllSound();
+			getSoundQueue()->stopAllSound();
 
 			clearBg(GraphicsManager::kBackgroundAll);
 
@@ -925,7 +927,7 @@ bool Debugger::cmdBeetle(int argc, const char **argv) {
 			restoreArchive();
 
 			// Stop audio and restore scene
-			getSound()->stopAllSound();
+			getSoundQueue()->stopAllSound();
 
 			clearBg(GraphicsManager::kBackgroundAll);
 
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 112edec..6fcadcf 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -34,6 +34,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -1409,7 +1411,7 @@ IMPLEMENT_FUNCTION(43, Abbot, function43)
 				setup_playSound("Abb4002");
 				break;
 			} else {
-				if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSound()->isBuffered(kEntityBoutarel) || !params->param4)
+				if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSoundQueue()->isBuffered(kEntityBoutarel) || !params->param4)
 					params->param4 = (uint)getState()->time + 450;
 
 				if (params->param4 < getState()->time) {
@@ -1754,7 +1756,7 @@ IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
 		break;
 
 	case kActionKnock:
-		if (!getSound()->isBuffered("LIB012", true))
+		if (!getSoundQueue()->isBuffered("LIB012", true))
 			getSound()->playSound(kEntityPlayer, "LIB012");
 		break;
 
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index d794cc8..2eb3a9e 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -34,6 +34,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -312,7 +314,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
 			params->param4 = 0;
 			params->param5 = 0;
 		} else {
-			getSound()->removeFromQueue(kEntityAnna);
+			getSoundQueue()->removeFromQueue(kEntityAnna);
 
 			getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
 			getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal);
@@ -323,7 +325,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
 		break;
 
 	case kActionOpenDoor:
-		getSound()->removeFromQueue(kEntityAnna);
+		getSoundQueue()->removeFromQueue(kEntityAnna);
 		setCallback(3);
 		setup_playSound("LIB013");
 		break;
@@ -339,8 +341,8 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
 
 		getEntities()->drawSequenceLeft(kEntityAnna, "418C");
 
-		if (getSound()->isBuffered(kEntityAnna))
-			getSound()->processEntry(kEntityAnna);
+		if (getSoundQueue()->isBuffered(kEntityAnna))
+			getSoundQueue()->processEntry(kEntityAnna);
 
 		getSound()->playSound(kEntityAnna, "ANN2135A");
 		break;
@@ -379,7 +381,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12)
 			break;
 
 		case 3:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(4);
 				setup_playSound("MAX1120");
 				break;
@@ -503,7 +505,7 @@ IMPLEMENT_FUNCTION_IS(15, Anna, function15, TimeValue)
 			break;
 
 		case 1:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(2);
 				setup_playSound("MAX1120");
 				break;
@@ -1456,7 +1458,7 @@ label_callback_1:
 
 		case 2:
 		case 3:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(4);
 				setup_playSound("MAX1120");
 				break;
@@ -1521,8 +1523,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
 
 	case kActionKnock:
 	case kActionOpenDoor:
-		if (getSound()->isBuffered(kEntityAnna))
-			getSound()->processEntry(kEntityAnna);
+		if (getSoundQueue()->isBuffered(kEntityAnna))
+			getSoundQueue()->processEntry(kEntityAnna);
 
 		if (savepoint.action == kActionKnock)
 			getSound()->playSound(kEntityPlayer, "LIB012");
@@ -1564,8 +1566,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
 		break;
 
 	case kAction226031488:
-		if (getSound()->isBuffered(kEntityAnna))
-			getSound()->processEntry(kEntityAnna);
+		if (getSoundQueue()->isBuffered(kEntityAnna))
+			getSoundQueue()->processEntry(kEntityAnna);
 
 		getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
 		break;
@@ -1844,7 +1846,7 @@ IMPLEMENT_FUNCTION(41, Anna, function41)
 
 		case 1:
 		case 2:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(3);
 				setup_playSound("MAX1120");
 				break;
@@ -2090,7 +2092,7 @@ IMPLEMENT_FUNCTION(48, Anna, function48)
 			break;
 
 		if (params->param3 != kTimeInvalid && getState()->time > kTime1969200) {
-			UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSound()->isBuffered(kEntityBoutarel)), params->param3, 150)
+			UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSoundQueue()->isBuffered(kEntityBoutarel)), params->param3, 150)
 				setCallback(3);
 				setup_playSound("Aug3007A");
 				break;
@@ -2481,7 +2483,7 @@ IMPLEMENT_FUNCTION(53, Anna, function53)
 			break;
 
 		case 1:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(2);
 				setup_playSound("MAX1120");
 				break;
@@ -2620,7 +2622,7 @@ IMPLEMENT_FUNCTION(54, Anna, function54)
 			break;
 
 		case 1:
-			if (!getSound()->isBuffered(kEntityMax)) {
+			if (!getSoundQueue()->isBuffered(kEntityMax)) {
 				setCallback(2);
 				setup_playSound("MAX1120");
 				break;
@@ -2789,7 +2791,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
 			break;
 
 		case 4:
-			if (getSound()->isBuffered(kEntityAugust)) {
+			if (getSoundQueue()->isBuffered(kEntityAugust)) {
 				setCallback(4);
 				setup_updateFromTime(75);
 			} else {
@@ -2817,7 +2819,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
 	case kAction123712592:
 		getEntities()->drawSequenceLeft(kEntityAnna, "628Af");
 
-		if (getSound()->isBuffered(kEntityAugust)) {
+		if (getSoundQueue()->isBuffered(kEntityAugust)) {
 			setCallback(4);
 			setup_updateFromTime(75);
 		} else {
@@ -3158,8 +3160,8 @@ IMPLEMENT_FUNCTION(63, Anna, function63)
 
 	// Anna will get killed...
 	case kAction272177921:
-		if (getSound()->isBuffered("MUS012"))
-			getSound()->processEntry("MUS012");
+		if (getSoundQueue()->isBuffered("MUS012"))
+			getSoundQueue()->processEntry("MUS012");
 
 		setCallback(1);
 		setup_savegame(kSavegameTypeEvent, kEventAnnaKilled);
@@ -3935,8 +3937,8 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
 			break;
 
 		case 1:
-			if (getSound()->isBuffered(kEntityAnna))
-				getSound()->processEntry(kEntityAnna);
+			if (getSoundQueue()->isBuffered(kEntityAnna))
+				getSoundQueue()->processEntry(kEntityAnna);
 
 			getAction()->playAnimation(kEventKronosBringFirebird);
 			getScenes()->loadSceneFromItem(kItemFirebird);
@@ -3951,8 +3953,8 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
 		case 3:
 			getProgress().isEggOpen = true;
 
-			if (getSound()->isBuffered(kEntityAnna))
-				getSound()->processEntry(kEntityAnna);
+			if (getSoundQueue()->isBuffered(kEntityAnna))
+				getSoundQueue()->processEntry(kEntityAnna);
 
 			getAction()->playAnimation(kEventKronosOpenFirebird);
 			getScenes()->loadSceneFromPosition(kCarRestaurant, 3);
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index fbd50d6..44dd3eb 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -36,6 +36,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -1427,7 +1429,7 @@ IMPLEMENT_FUNCTION(29, August, function29)
 		if (getState()->time < kTime1134000) {
 
 			if (!getEntities()->isInRestaurant(kEntityPlayer)
-			 || getSound()->isBuffered("MRB1076") || getSound()->isBuffered("MRB1078") || getSound()->isBuffered("MRB1078A"))
+			 || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A"))
 				params->param3 = (uint)getState()->time + 225;
 
 			if (params->param3 > getState()->time)
@@ -1762,7 +1764,7 @@ IMPLEMENT_FUNCTION(34, August, function34)
 		break;
 
 	case kActionNone:
-		if (!getSound()->isBuffered(kEntityAugust) && getProgress().field_18 != 4)
+		if (!getSoundQueue()->isBuffered(kEntityAugust) && getProgress().field_18 != 4)
 			getSound()->playSound(kEntityAugust, "AUG1057");    // August snoring
 		break;
 
@@ -2183,7 +2185,7 @@ IMPLEMENT_FUNCTION_III(42, August, function42, CarIndex, EntityPosition, bool)
 		break;
 
 	case kActionExcuseMe:
-		if (!getSound()->isBuffered(kEntityAugust))
+		if (!getSoundQueue()->isBuffered(kEntityAugust))
 			getSound()->excuseMe(kEntityAugust);
 		break;
 
@@ -3343,7 +3345,7 @@ IMPLEMENT_FUNCTION(65, August, function65)
 
 		getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 
-		if (!getSound()->isBuffered(kEntityAugust))
+		if (!getSoundQueue()->isBuffered(kEntityAugust))
 			getSound()->playSound(kEntityAugust, "AUG1057");   // August snoring
 		break;
 	}
@@ -3504,9 +3506,9 @@ IMPLEMENT_FUNCTION(69, August, unhookCars)
 		break;
 
 	case kActionDefault:
-		getSound()->processEntries();
-		if (getSound()->isBuffered("ARRIVE"))
-			getSound()->removeFromQueue("ARRIVE");
+		getSoundQueue()->processEntries();
+		if (getSoundQueue()->isBuffered("ARRIVE"))
+			getSoundQueue()->removeFromQueue("ARRIVE");
 
 		setCallback(1);
 		setup_savegame(kSavegameTypeEvent, kEventAugustUnhookCarsBetrayal);
@@ -3516,7 +3518,7 @@ IMPLEMENT_FUNCTION(69, August, unhookCars)
 		if (getCallback() == 1) {
 			getAction()->playAnimation(getProgress().field_C ? kEventAugustUnhookCarsBetrayal : kEventAugustUnhookCars);
 			getEntities()->clearSequences(kEntityAugust);
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			getSound()->playSound(kEntityPlayer, "MUS050");
 			getScenes()->loadSceneFromPosition(kCarRestaurant, 85, 1);
 			getSavePoints()->pushAll(kEntityAugust, kActionProceedChapter5);
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
index db77617..cf5d286 100644
--- a/engines/lastexpress/entities/boutarel.cpp
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -941,7 +943,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
 
 		if (getEntities()->isInRestaurant(kEntityAnna)
 		 && getEntities()->isInRestaurant(kEntityAugust)
-		 && !getSound()->isBuffered(kEntityBoutarel)
+		 && !getSoundQueue()->isBuffered(kEntityBoutarel)
 		 && params->param3 != kTimeInvalid) {
 
 			if (getState()->time <= kTime1998000)
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index d4425ad..53d89e9 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -65,6 +65,8 @@
 
 #include "lastexpress/menu/menu.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -164,16 +166,16 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
 		break;
 
 	case kActionKnock:
-		if (!getSound()->isBuffered("LIB012", true))
+		if (!getSoundQueue()->isBuffered("LIB012", true))
 			getSound()->playSound(kEntityPlayer, "LIB012");
 		break;
 
 	case kActionOpenDoor:
 		if (params->param1) {
 			getEntities()->clearSequences(kEntityChapters);
-			getSound()->processEntry(kEntityChapters);
+			getSoundQueue()->processEntry(kEntityChapters);
 			getSound()->playSound(kEntityPlayer, "LIB014");
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 
 			ENTITY_PARAM(0, 4) = 7;
 
@@ -194,7 +196,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
 			getSound()->playSound(kEntityPlayer, "LIB014");
 			getSound()->playSound(kEntityPlayer, "LIB015", kFlagDefault, 15);
 
-			if (!getSound()->isBuffered(kEntityChapters))
+			if (!getSoundQueue()->isBuffered(kEntityChapters))
 				getSound()->playSound(kEntityChapters, "MUS009", kFlagDefault);
 
 			getScenes()->loadSceneFromPosition(kCarLocomotive, 38);
@@ -241,42 +243,42 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
 		RESET_ENTITY_STATE(kEntityHadija, Alouan, setup_function12);
 
 		if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-			getSound()->removeFromQueue(kEntityChapters);
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 
 			ENTITY_PARAM(0, 2) = 0;
 			ENTITY_PARAM(0, 3) = 0;
 		}
 
-		getSound()->processEntries();
+		getSoundQueue()->processEntries();
 
-		if (getSound()->isBuffered("CON1505"))
-			getSound()->processEntry("CON1505");
+		if (getSoundQueue()->isBuffered("CON1505"))
+			getSoundQueue()->processEntry("CON1505");
 
-		if (getSound()->isBuffered("AUG1057"))
-			getSound()->processEntry("AUG1057");
+		if (getSoundQueue()->isBuffered("AUG1057"))
+			getSoundQueue()->processEntry("AUG1057");
 
-		if (getSound()->isBuffered("ZFX1005"))
-			getSound()->processEntry("ZFX1005");
+		if (getSoundQueue()->isBuffered("ZFX1005"))
+			getSoundQueue()->processEntry("ZFX1005");
 
-		if (getSound()->isBuffered("ZFX1006"))
-			getSound()->processEntry("ZFX1006");
+		if (getSoundQueue()->isBuffered("ZFX1006"))
+			getSoundQueue()->processEntry("ZFX1006");
 
-		if (getSound()->isBuffered("ZFX1007"))
-			getSound()->processEntry("ZFX1007");
+		if (getSoundQueue()->isBuffered("ZFX1007"))
+			getSoundQueue()->processEntry("ZFX1007");
 
-		if (getSound()->isBuffered("ZFX1007A"))
-			getSound()->processEntry("ZFX1007A");
+		if (getSoundQueue()->isBuffered("ZFX1007A"))
+			getSoundQueue()->processEntry("ZFX1007A");
 
-		if (getSound()->isBuffered("ZFX1007B"))
-			getSound()->processEntry("ZFX1007B");
+		if (getSoundQueue()->isBuffered("ZFX1007B"))
+			getSoundQueue()->processEntry("ZFX1007B");
 
 
 		getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
 		getInventory()->unselectItem();
 
 		// FIXME add event pump ?
-		while (getSound()->isBuffered("MUS008"))
-			getSound()->updateQueue();
+		while (getSoundQueue()->isBuffered("MUS008"))
+			getSoundQueue()->updateQueue();
 
 		getProgress().field_84 = true;
 
@@ -301,7 +303,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
 
 		if (params->param2 >= 3) {
 
-			if (!getSound()->isBuffered("LIB031", true))
+			if (!getSoundQueue()->isBuffered("LIB031", true))
 				getSound()->playSound(kEntityPlayer, "LIB031");
 
 			if (params->param2 == 3) {
@@ -319,7 +321,7 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
 		return;
 
 	getProgress().chapter = kChapter1;
-	getSound()->resetState();
+	getSoundQueue()->resetState();
 
 	getState()->time = kTimeChapter1;
 	getState()->timeDelta = 0;
@@ -385,7 +387,7 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 #define PLAY_STEAM() { \
-	getSound()->resetState(); \
+	getSoundQueue()->resetState(); \
 	getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4)); \
 	ENTITY_PARAM(0, 2) = 0; \
 	}
@@ -563,7 +565,7 @@ label_chapter1_next:
 		}
 
 		if (ENTITY_PARAM(0, 3)) {
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			ENTITY_PARAM(0, 3) = 0;
 
 			if (params->param4) {
@@ -694,7 +696,7 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next)
 	if (savepoint.action == kActionDefault) {
 		// Reset sound cache
 		if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-			getSound()->removeFromQueue(kEntityChapters);
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 			ENTITY_PARAM(0, 2) = 0;
 			ENTITY_PARAM(0, 3) = 0;
 		}
@@ -702,8 +704,8 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next)
 		getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
 		getInventory()->unselectItem();
 
-		while (getSound()->isBuffered("MUS008"))
-			getSound()->updateQueue();
+		while (getSoundQueue()->isBuffered("MUS008"))
+			getSoundQueue()->updateQueue();
 
 		setup_chapter2();
 	}
@@ -790,7 +792,7 @@ IMPLEMENT_FUNCTION(11, Chapters, chapter2Init)
 
 	// Reset sound cache
 	if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-		getSound()->removeFromQueue(kEntityChapters);
+		getSoundQueue()->removeFromQueue(kEntityChapters);
 		ENTITY_PARAM(0, 2) = 0;
 		ENTITY_PARAM(0, 3) = 0;
 	}
@@ -874,7 +876,7 @@ IMPLEMENT_FUNCTION(14, Chapters, chapter3Init)
 		getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
 
 		if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-			getSound()->removeFromQueue(kEntityChapters);
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 			ENTITY_PARAM(0, 2) = 0;
 			ENTITY_PARAM(0, 3) = 0;
 		}
@@ -987,7 +989,7 @@ label_callback_8:
 				}
 			}
 
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4));
 
 			ENTITY_PARAM(0, 2) = 0;
@@ -998,7 +1000,7 @@ label_callback_8:
 		}
 
 		if (ENTITY_PARAM(0, 3)) {
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			ENTITY_PARAM(0, 3) = 0;
 		}
 		break;
@@ -1150,8 +1152,8 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
 	if (savepoint.action != kActionDefault)
 		return;
 
-	getSound()->processEntries();
-	getSound()->resetState();
+	getSoundQueue()->processEntries();
+	getSoundQueue()->resetState();
 
 	getProgress().isTrainRunning = true;
 
@@ -1177,7 +1179,7 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
 	getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
 
 	if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-		getSound()->removeFromQueue(kEntityChapters);
+		getSoundQueue()->removeFromQueue(kEntityChapters);
 		ENTITY_PARAM(0, 2) = 0;
 		ENTITY_PARAM(0, 3) = 0;
 	}
@@ -1319,7 +1321,7 @@ label_callback_4:
 		}
 
 		if (ENTITY_PARAM(0, 3)) {
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			ENTITY_PARAM(0, 3) = 0;
 		} else if (!params->param2 && !params->param3) {
 			getSound()->playSound(kEntityChapters, "ZFX1001");
@@ -1356,17 +1358,17 @@ label_callback_4:
 			goto label_callback_4;
 
 		case 5:
-			if (getSound()->isBuffered(kEntityChapters))
-				getSound()->removeFromQueue(kEntityChapters);
+			if (getSoundQueue()->isBuffered(kEntityChapters))
+				getSoundQueue()->removeFromQueue(kEntityChapters);
 
 			getAction()->playAnimation(kEventTrainExplosionBridge);
 			getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true);
 			break;
 
 		case 6:
-			getSound()->processEntries();
+			getSoundQueue()->processEntries();
 			getAction()->playAnimation(kEventTylerCastleDream);
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 
 			getProgress().field_18 = 1;
 
@@ -1465,7 +1467,7 @@ label_callback_4:
 		params->param1 = 1;
 
 		if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-			getSound()->removeFromQueue(kEntityChapters);
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 
 			ENTITY_PARAM(0, 2) = 0;
 			ENTITY_PARAM(0, 3) = 0;
@@ -1474,8 +1476,8 @@ label_callback_4:
 		getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
 		getInventory()->unselectItem();
 
-		while (getSound()->isBuffered("MUS008"))
-			getSound()->updateQueue();
+		while (getSoundQueue()->isBuffered("MUS008"))
+			getSoundQueue()->updateQueue();
 
 		if (getInventory()->hasItem(kItemBomb)) {
 			RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function47);
@@ -1522,8 +1524,8 @@ label_callback_4:
 	case kAction191001984:
 		getState()->time = kTime2520000;
 
-		if (getSound()->isBuffered(kEntityChapters))
-			getSound()->removeFromQueue(kEntityChapters);
+		if (getSoundQueue()->isBuffered(kEntityChapters))
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 
 		getEntities()->clearSequences(kEntityChapters);
 		getInventory()->removeItem(kItemTelegram);
@@ -1535,8 +1537,8 @@ label_callback_4:
 		break;
 
 	case kAction201959744:
-		if (getSound()->isBuffered(kEntityChapters))
-			getSound()->removeFromQueue(kEntityChapters);
+		if (getSoundQueue()->isBuffered(kEntityChapters))
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 
 		getSound()->playSound(kEntityTrain, "ZFX4001", kFlagDefault);
 
@@ -1644,7 +1646,7 @@ IMPLEMENT_FUNCTION(21, Chapters, chapter5Init)
 		getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation2);
 
 		if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
-			getSound()->removeFromQueue(kEntityChapters);
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 			ENTITY_PARAM(0, 2) = 0;
 			ENTITY_PARAM(0, 3) = 0;
 		}
@@ -1675,7 +1677,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
 
 			if (!getProgress().isNightTime) {
 				getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8);
-				getSound()->processEntries();
+				getSoundQueue()->processEntries();
 			}
 		}
 
@@ -1684,7 +1686,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
 
 			if (!getEvent(kEventLocomotiveMilosDay) && !getEvent(kEventLocomotiveMilosNight)) {
 				getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8);
-				getSound()->processEntries();
+				getSoundQueue()->processEntries();
 			}
 		}
 		break;
@@ -1713,8 +1715,8 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
 		getProgress().isNightTime = true;
 		getState()->time = kTime2916000;
 
-		if (getSound()->isBuffered(kEntityChapters))
-			getSound()->removeFromQueue(kEntityChapters);
+		if (getSoundQueue()->isBuffered(kEntityChapters))
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 		break;
 	}
 IMPLEMENT_FUNCTION_END
@@ -1730,7 +1732,7 @@ void Chapters::enterExitStation(const SavePoint &savepoint, bool isEnteringStati
 			return;
 		}
 
-		getSound()->removeFromQueue(kEntityChapters);
+		getSoundQueue()->removeFromQueue(kEntityChapters);
 
 		if (!ENTITY_PARAM(0, 2)) {
 			if (ENTITY_PARAM(0, 3))
@@ -1798,7 +1800,7 @@ void Chapters::enterExitHelper(bool isEnteringStation) {
 	EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
 
 	getSound()->playSound(kEntityChapters, isEnteringStation ? "ARRIVE" : "DEPART", kFlag8);
-	getSound()->processEntries();
+	getSoundQueue()->processEntries();
 
 	getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
 	getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand);
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
index 336f911..cd8fbfd 100644
--- a/engines/lastexpress/entities/cooks.cpp
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -29,6 +29,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -101,7 +103,7 @@ IMPLEMENT_FUNCTION(3, Cooks, function3)
 		if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) {
 			getEntities()->drawSequenceLeft(kEntityCooks, "308D");
 
-			if (!getSound()->isBuffered(kEntityCooks)) {
+			if (!getSoundQueue()->isBuffered(kEntityCooks)) {
 				if (params->param1) {
 					if (!getEntities()->hasValidFrame(kEntityCooks)) {
 						getSound()->playSound(kEntityCooks, "LIB015");
@@ -187,7 +189,7 @@ IMPLEMENT_FUNCTION(4, Cooks, function4)
 		if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
 			getEntities()->drawSequenceLeft(kEntityCooks, "308D");
 
-			if (!getSound()->isBuffered(kEntityCooks)) {
+			if (!getSoundQueue()->isBuffered(kEntityCooks)) {
 				if (params->param1) {
 					if (!getEntities()->hasValidFrame(kEntityCooks)) {
 						getSound()->playSound(kEntityCooks, "LIB015");
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index 0733a4c..fea08f4 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -314,7 +316,7 @@ IMPLEMENT_FUNCTION_II(9, Coudert, updateEntity, CarIndex, EntityPosition)
 	case kActionExcuseMeCath:
 		if (getData()->clothes == kClothes1)
 			getSound()->playSound(kEntityPlayer, "ZFX1003", getSound()->getSoundFlag(kEntityCoudert));
-		else if (!getSound()->isBuffered(kEntityCoudert))
+		else if (!getSoundQueue()->isBuffered(kEntityCoudert))
 			getSound()->playSound(kEntityPlayer, "JAC1112", getSound()->getSoundFlag(kEntityCoudert));
 		break;
 
@@ -409,7 +411,7 @@ IMPLEMENT_FUNCTION_I(12, Coudert, excuseMe, EntityIndex)
 	if (savepoint.action != kActionDefault)
 		return;
 
-	if (getSound()->isBuffered(kEntityCoudert)) {
+	if (getSoundQueue()->isBuffered(kEntityCoudert)) {
 		CALLBACK_ACTION();
 		return;
 	}
@@ -823,7 +825,7 @@ IMPLEMENT_FUNCTION(18, Coudert, function18)
 		getScenes()->loadSceneFromItemPosition(kItem5);
 
 		if (getEntities()->isPlayerPosition(kCarRedSleeping, 68)) {
-			if (!getSound()->isBuffered(kEntityCoudert))
+			if (!getSoundQueue()->isBuffered(kEntityCoudert))
 				getSound()->playSound(kEntityCoudert, "JAC1111");
 
 			getScenes()->loadSceneFromPosition(kCarRedSleeping, 25);
@@ -1642,7 +1644,7 @@ IMPLEMENT_FUNCTION_I(31, Coudert, function31, uint32)
 			break;
 
 		case 1:
-			if (getSound()->isBuffered(kEntityCoudert)) {
+			if (getSoundQueue()->isBuffered(kEntityCoudert)) {
 				getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
 			} else {
 				setCallback(2);
@@ -1929,7 +1931,7 @@ IMPLEMENT_FUNCTION_I(35, Coudert, function35, bool)
 			break;
 
 		case 1:
-			if (!getSound()->isBuffered(kEntityCoudert))
+			if (!getSoundQueue()->isBuffered(kEntityCoudert))
 				getSound()->playSound(kEntityCoudert, "Ann3124");
 
 			if (params->param1)
@@ -2008,8 +2010,8 @@ IMPLEMENT_FUNCTION(37, Coudert, function37)
 		break;
 
 	case kActionDefault:
-		if (getSound()->isBuffered(kEntityCoudert))
-			getSound()->processEntry(kEntityCoudert);
+		if (getSoundQueue()->isBuffered(kEntityCoudert))
+			getSoundQueue()->processEntry(kEntityCoudert);
 
 		if (ENTITY_PARAM(0, 7)) {
 			getData()->entityPosition = kPosition_8200;
@@ -2268,7 +2270,7 @@ label_callback_8:
 		}
 
 label_callback_9:
-		if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityCoudert))
+		if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityCoudert))
 			getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A");
 
 		if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) {
@@ -3019,7 +3021,7 @@ IMPLEMENT_FUNCTION(46, Coudert, function46)
 			// Fallback to next case
 
 		case 7:
-			if (getSound()->isBuffered(kEntityCoudert)) {
+			if (getSoundQueue()->isBuffered(kEntityCoudert)) {
 				setCallback(7);
 				setup_updateFromTime(75);
 			} else {
@@ -3088,7 +3090,7 @@ IMPLEMENT_FUNCTION_I(47, Coudert, function47, bool)
 			// Fallback to next case
 
 		case 4:
-			if (getSound()->isBuffered(kEntityCoudert)) {
+			if (getSoundQueue()->isBuffered(kEntityCoudert)) {
 				setCallback(4);
 				setup_updateFromTime(225);
 			} else {
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index 86b6820..6bbe740 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -30,6 +30,8 @@
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
@@ -275,7 +277,7 @@ IMPLEMENT_FUNCTION_I(11, Francois, function11, TimeValue)
 		break;
 
 	case kActionNone:
-		if (!getSound()->isBuffered(kEntityFrancois)) {
+		if (!getSoundQueue()->isBuffered(kEntityFrancois)) {
 
 			UPDATE_PARAM_PROC(CURRENT_PARAM(1, 1), getState()->timeTicks, params->param6)
 				switch (rnd(7)) {
@@ -370,8 +372,8 @@ label_callback:
 			getData()->field_4A3 = 30;
 			getData()->inventoryItem = kItemNone;
 
-			if (getSound()->isBuffered(kEntityFrancois))
-				getSound()->processEntry(kEntityFrancois);
+			if (getSoundQueue()->isBuffered(kEntityFrancois))
+				getSoundQueue()->processEntry(kEntityFrancois);
 
 			setCallback(4);
 			setup_updateEntity(kCarRedSleeping, kPosition_5790);
@@ -381,8 +383,8 @@ label_callback:
 	case kAction1:
 		getData()->inventoryItem = kItemNone;
 
-		if (getSound()->isBuffered(kEntityFrancois))
-			getSound()->processEntry(kEntityFrancois);
+		if (getSoundQueue()->isBuffered(kEntityFrancois))
+			getSoundQueue()->processEntry(kEntityFrancois);
 
 		setCallback(6);
 		setup_savegame(kSavegameTypeEvent, kEventFrancoisWhistle);
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index db71981..6c73784 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -607,8 +609,8 @@ label_callback_3:
 			break;
 
 		if (getEvent(kEventKahinaAskSpeakFirebird)) {
-			if (getSound()->isBuffered(kEntityKahina))
-				getSound()->processEntry(kEntityKahina);
+			if (getSoundQueue()->isBuffered(kEntityKahina))
+				getSoundQueue()->processEntry(kEntityKahina);
 
 			if (savepoint.action == kActionKnock)
 				getSound()->playSound(kEntityPlayer, "LIB012");
@@ -1163,8 +1165,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24)
 		case 1:
 			if (ENTITY_PARAM(0, 2)) {
 				getEntities()->clearSequences(kEntityKahina);
-				if (getSound()->isBuffered(kEntityKahina))
-					getSound()->processEntry(kEntityKahina);
+				if (getSoundQueue()->isBuffered(kEntityKahina))
+					getSoundQueue()->processEntry(kEntityKahina);
 
 				getProgress().field_44 = 0;
 
@@ -1198,8 +1200,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24)
 
 	case kAction137503360:
 		getEntities()->clearSequences(kEntityKahina);
-		if (getSound()->isBuffered(kEntityKahina))
-			getSound()->processEntry(kEntityKahina);
+		if (getSoundQueue()->isBuffered(kEntityKahina))
+			getSoundQueue()->processEntry(kEntityKahina);
 
 		getProgress().field_44 = 0;
 
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 5afc52f..06ebd54 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -39,6 +39,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -216,7 +218,7 @@ IMPLEMENT_FUNCTION(11, Kronos, function11)
 	case kActionDefault:
 		getData()->entityPosition = kPosition_7000;
 
-		if (!getSound()->isBuffered(kEntityKronos))
+		if (!getSoundQueue()->isBuffered(kEntityKronos))
 			getSound()->playSound(kEntityKronos, "KRO1001");
 		break;
 	}
@@ -457,7 +459,7 @@ IMPLEMENT_FUNCTION(19, Kronos, function19)
 
 		case 2:
 			getAction()->playAnimation(kEventConcertStart);
-			getSound()->setupEntry(kSoundType7, kEntityKronos);
+			getSoundQueue()->setupEntry(kSoundType7, kEntityKronos);
 			getScenes()->loadSceneFromPosition(kCarKronos, 83);
 
 			RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function39);
@@ -480,7 +482,7 @@ IMPLEMENT_FUNCTION(20, Kronos, function20)
 		break;
 
 	case kActionNone:
-		params->param5 = getSound()->getEntryTime(kEntityKronos)* 2;
+		params->param5 = getSoundQueue()->getEntryTime(kEntityKronos)* 2;
 
 		if (params->param6 < ARRAYSIZE(concertData) && params->param5 > concertData[params->param6].time) {
 
@@ -560,8 +562,8 @@ IMPLEMENT_FUNCTION(20, Kronos, function20)
 			case 3:
 				getAction()->playAnimation(kEventCathFallingAsleep);
 
-				while (getSound()->isBuffered("1919.LNK"))
-					getSound()->updateQueue();
+				while (getSoundQueue()->isBuffered("1919.LNK"))
+					getSoundQueue()->updateQueue();
 
 				getAction()->playAnimation(kEventCathWakingUp);
 				getScenes()->processScene();
@@ -746,7 +748,7 @@ IMPLEMENT_FUNCTION(22, Kronos, function22)
 
 	case kActionKnock:
 	case kActionOpenDoor:
-		if (!getSound()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true))
+		if (!getSoundQueue()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true))
 			getSound()->playSound(kEntityPlayer, savepoint.action == kActionKnock ? "LIB012" : "LIB013");
 
 		if (getEvent(kEventConcertLeaveWithBriefcase))
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
index f9ae741..cb78285 100644
--- a/engines/lastexpress/entities/mahmud.cpp
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -34,6 +34,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -157,7 +159,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
 
 	case kActionEndSound:
 	case kActionDrawScene:
-		if (!getSound()->isBuffered(kEntityMahmud)) {
+		if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
 			EntityPosition position = getEntityData(kEntityPlayer)->entityPosition;
 			if (position < kPosition_1500 || position >= kPosition_5790 || (position > kPosition_4455 && params->param5 != 5)) {
 				getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
@@ -173,12 +175,12 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
 
 	case kActionKnock:
 	case kActionOpenDoor:
-		if (!getSound()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true))
+		if (!getSoundQueue()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true))
 			getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
 
 		params->param5 = savepoint.param.intValue;
 
-		if (!getSound()->isBuffered(kEntityMahmud)) {
+		if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
 			params->param3++;
 
 			switch(params->param3) {
@@ -282,7 +284,7 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11)
 	case kActionOpenDoor: {
 		getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock ? "LIB012" : "LIB013"));
 
-		if (!getSound()->isBuffered(kEntityMahmud)) {
+		if (!getSoundQueue()->isBuffered(kEntityMahmud)) {
 			params->param1++;
 
 			getSound()->playSound(kEntityMahmud, (params->param1 == 1 ? "MAH1170E" : (params->param1 == 2 ? "MAH1173B" : "MAH1174")));
@@ -396,8 +398,8 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11)
 		break;
 
 	case kAction123852928:
-		if (getSound()->isBuffered(kEntityMahmud))
-			getSound()->processEntry(kEntityMahmud);
+		if (getSoundQueue()->isBuffered(kEntityMahmud))
+			getSoundQueue()->processEntry(kEntityMahmud);
 
 		getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand);
@@ -560,7 +562,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
 
 			TIME_CHECK_CALLBACK(kTime1098000, params->param6, 1, setup_function13);
 
-			if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+			if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
 				params->param7 = 1;
 
 				setCallback(2);
@@ -636,7 +638,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
 			params->param4 = 0;
 			params->param5 = 0;
 
-			if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
+			if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) {
 				params->param7 = 1;
 				setCallback(2);
 				setup_function12();
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
index 12123ed..924f8f7 100644
--- a/engines/lastexpress/entities/max.cpp
+++ b/engines/lastexpress/entities/max.cpp
@@ -31,6 +31,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -91,7 +93,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler)
 	case kActionNone:
 		UPDATE_PARAM(params->param2, getState()->time, params->param1);
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
 		params->param1 = 255 * (4 * rnd(20) + 40);
@@ -108,7 +110,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler)
 		break;
 
 	case kAction158007856:
-		if (!getSound()->isBuffered(kEntityMax)) {
+		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
 			params->param1 = 255 * (4 * rnd(20) + 40);
 		}
@@ -125,7 +127,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
 	case kActionNone:
 		UPDATE_PARAM(params->param2, getState()->time, params->param1)
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
 		params->param1 = 255 * (4 * rnd(20) + 40);
@@ -137,8 +139,8 @@ IMPLEMENT_FUNCTION(7, Max, function7)
 		getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
 		getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal);
 
-		if (getSound()->isBuffered(kEntityMax))
-			getSound()->processEntry(kEntityMax);
+		if (getSoundQueue()->isBuffered(kEntityMax))
+			getSoundQueue()->processEntry(kEntityMax);
 
 		setCallback((savepoint.action == kActionKnock) ? 1 : 2);
 		setup_playSound((savepoint.action == kActionKnock) ? "LIB012" : "LIB013");
@@ -156,7 +158,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
 		break;
 
 	case kActionDrawScene:
-		if (!getSound()->isBuffered(kEntityMax)) {
+		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78))
 				getSound()->playSound(kEntityMax, "Max1120");
 		}
@@ -197,7 +199,7 @@ IMPLEMENT_FUNCTION(7, Max, function7)
 		break;
 
 	case kAction158007856:
-		if (!getSound()->isBuffered(kEntityMax)) {
+		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
 			params->param1 = 255 * (4 * rnd(20) + 40);
 		}
@@ -214,7 +216,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
 	case kActionNone:
 		UPDATE_PARAM(params->param3, getState()->time, params->param2);
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max3101");
 
 		params->param2 = 255 * (4 * rnd(20) + 40);
@@ -228,8 +230,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
 			break;
 		}
 
-		if (getSound()->isBuffered(kEntityMax))
-			getSound()->processEntry(kEntityMax);
+		if (getSoundQueue()->isBuffered(kEntityMax))
+			getSoundQueue()->processEntry(kEntityMax);
 
 		getAction()->playAnimation(kEventCathMaxLickHand);
 		getScenes()->processScene();
@@ -247,7 +249,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
 		getData()->location = kLocationInsideCompartment;
 		getData()->car = kCarBaggage;
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max3101");
 		break;
 
@@ -255,8 +257,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler)
 		if (getCallback() != 1)
 			break;
 
-		if (getSound()->isBuffered(kEntityMax))
-			getSound()->processEntry(kEntityMax);
+		if (getSoundQueue()->isBuffered(kEntityMax))
+			getSoundQueue()->processEntry(kEntityMax);
 
 		getSound()->playSound(kEntityPlayer, "LIB026");
 		getAction()->playAnimation(kEventCathMaxFree);
@@ -392,7 +394,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
 
 		UPDATE_PARAM(params->param3, getState()->time, params->param1);
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
 		params->param1 = 255 * (4 * rnd(20) + 40);
@@ -424,7 +426,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
 		if (params->param2)
 			break;
 
-		if (!getSound()->isBuffered(kEntityMax)) {
+		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
 			params->param1 = 255 * (4 * rnd(20) + 40);
 		}
@@ -464,7 +466,7 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage)
 		getData()->location = kLocationInsideCompartment;
 		getData()->car = kCarBaggage;
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 		break;
 
@@ -476,17 +478,17 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage)
 			break;
 
 		case 1:
-			if (getSound()->isBuffered(kEntityMax))
-				getSound()->removeFromQueue(kEntityMax);
+			if (getSoundQueue()->isBuffered(kEntityMax))
+				getSoundQueue()->removeFromQueue(kEntityMax);
 
 			getAction()->playAnimation(kEventCathMaxCage);
-			getSound()->setupEntry(kSoundType7, kEntityMax);
+			getSoundQueue()->setupEntry(kSoundType7, kEntityMax);
 			getScenes()->processScene();
 			break;
 
 		case 2:
-			if (getSound()->isBuffered(kEntityMax))
-				getSound()->processEntry(kEntityMax);
+			if (getSoundQueue()->isBuffered(kEntityMax))
+				getSoundQueue()->processEntry(kEntityMax);
 
 			getSound()->playSound(kEntityPlayer, "LIB026");
 			getAction()->playAnimation(kEventCathMaxFree);
@@ -523,7 +525,7 @@ IMPLEMENT_FUNCTION(15, Max, function15)
 		getData()->location = kLocationOutsideCompartment;
 		getData()->car = kCarRedSleeping;
 
-		if (!getSound()->isBuffered(kEntityMax))
+		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max3010");
 
 		setCallback(1);
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index b99e344..464cc34 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/state.h"
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -503,7 +505,7 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
 	if (savepoint.action == kActionDefault)
 		return;
 
-	if (getSound()->isBuffered(kEntityMertens)) {
+	if (getSoundQueue()->isBuffered(kEntityMertens)) {
 		CALLBACK_ACTION();
 		return;
 	}
@@ -589,7 +591,7 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
 		if (params->param2)
 			params->param3 = 1;
 
-		if (!getSound()->isBuffered(kEntityMertens)) {
+		if (!getSoundQueue()->isBuffered(kEntityMertens)) {
 
 		}
 
@@ -1188,7 +1190,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
 			break;
 
 		case 5:
-			if (!getSound()->isBuffered(kEntityMertens))
+			if (!getSoundQueue()->isBuffered(kEntityMertens))
 				getSound()->playSound(kEntityMertens, "MAH1170I");
 
 			setCallback(6);
@@ -1198,7 +1200,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
 		case 6:
 			getData()->location = kLocationInsideCompartment;
 			getEntities()->clearSequences(kEntityMertens);
-			if (!getSound()->isBuffered(kEntityMertens))
+			if (!getSoundQueue()->isBuffered(kEntityMertens))
 				getSound()->playSound(kEntityMertens, "MAH1172", kFlagInvalid, 225);
 
 			setCallback(7);
@@ -2300,7 +2302,7 @@ IMPLEMENT_FUNCTION_I(31, Mertens, function31, MertensActionType)
 			break;
 
 		case 1:
-			if (getSound()->isBuffered(kEntityMertens)) {
+			if (getSoundQueue()->isBuffered(kEntityMertens)) {
 				getEntities()->drawSequenceLeft(kEntityMertens, "601J");
 			} else {
 				setCallback(2);
@@ -3017,7 +3019,7 @@ IMPLEMENT_FUNCTION(42, Mertens, function42)
 
 				if (getState()->time <= kTime1188000) {
 					if ((!getEntities()->isPlayerInCar(kCarGreenSleeping) && !getEntities()->isPlayerInCar(kCarRedSleeping))
-					  || getSound()->isBuffered("REB1205")
+					  || getSoundQueue()->isBuffered("REB1205")
 					  || !getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790)
 					  || !params->param4) {
 						params->param4 = (uint)getState()->time;
@@ -3138,7 +3140,7 @@ label_callback_18:
 		}
 
 label_callback_19:
-		if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityMertens)) {
+		if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityMertens)) {
 			if (getProgress().field_18 != 4)
 				getSound()->playSound(kEntityMertens, "CON1505");
 		}
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 68030b3..1526c28 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -36,6 +36,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -1577,8 +1579,8 @@ IMPLEMENT_FUNCTION(29, Milos, chapter4Handler)
 		break;
 
 	case kAction221683008:
-		if (getSound()->isBuffered(kEntityMilos))
-			getSound()->processEntry(kEntityMilos);
+		if (getSoundQueue()->isBuffered(kEntityMilos))
+			getSoundQueue()->processEntry(kEntityMilos);
 
 		params->param1 = 1;
 		getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction123199584);
@@ -1720,15 +1722,15 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 			break;
 
 		case 2:
-			if (getSound()->isBuffered("MUS050"))
-				getSound()->processEntry("MUS050");
+			if (getSoundQueue()->isBuffered("MUS050"))
+				getSoundQueue()->processEntry("MUS050");
 
-			if (getSound()->isBuffered("ARRIVE"))
-				getSound()->removeFromQueue("ARRIVE");
+			if (getSoundQueue()->isBuffered("ARRIVE"))
+				getSoundQueue()->removeFromQueue("ARRIVE");
 
-			getSound()->processEntries();
+			getSoundQueue()->processEntries();
 			getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay);
-			getSound()->setupEntry(kSoundType7, kEntityMilos);
+			getSoundQueue()->setupEntry(kSoundType7, kEntityMilos);
 			getScenes()->loadSceneFromPosition(kCarCoalTender, 1);
 			break;
 
@@ -1740,7 +1742,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 		case 4:
 			getAction()->playAnimation(kEventLocomotiveRestartTrain);
 			getAction()->playAnimation(kEventLocomotiveOldBridge);
-			getSound()->resetState();
+			getSoundQueue()->resetState();
 			getState()->time = kTime2983500;
 
 			setCallback(5);
@@ -1783,7 +1785,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 			setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain);
 		}
 
-		getSound()->processEntry(kEntityMilos);
+		getSoundQueue()->processEntry(kEntityMilos);
 		if (getState()->time < kTimeTrainStopped2)
 			getState()->time = kTimeTrainStopped2;
 
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
index 78f2d2f..1d4c52c 100644
--- a/engines/lastexpress/entities/mmeboutarel.cpp
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -31,6 +31,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -399,7 +401,7 @@ IMPLEMENT_FUNCTION(13, MmeBoutarel, function13)
 		break;
 
 	case kActionNone:
-		if (!getSound()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) {
+		if (!getSoundQueue()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) {
 			UPDATE_PARAM_PROC_TIME(params->param1, !getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 2000), params->param6, 0)
 				getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
 				getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
@@ -883,8 +885,8 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
 			if (getState()->time <= kTime2038500) {
 				if (!getEntities()->isPlayerInCar(kCarRedSleeping)
 				 || !params->param1
-				 || getSound()->isBuffered("FRA2012")
-				 || getSound()->isBuffered("FRA2010")
+				 || getSoundQueue()->isBuffered("FRA2012")
+				 || getSoundQueue()->isBuffered("FRA2010")
 				 ||!params->param2)
 					params->param2 = (uint)getState()->time;
 
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
index d4a7359..8bbcf64 100644
--- a/engines/lastexpress/entities/pascale.cpp
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -30,6 +30,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -201,7 +203,7 @@ IMPLEMENT_FUNCTION(10, Pascale, welcomeCath)
 		break;
 
 	case kActionNone:
-		if (params->param1 && !getSound()->isBuffered(kEntityPascale))
+		if (params->param1 && !getSoundQueue()->isBuffered(kEntityPascale))
 			getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 64);
 		break;
 
@@ -462,10 +464,10 @@ IMPLEMENT_FUNCTION(16, Pascale, serveTatianaVassili)
 			getEntities()->drawSequenceLeft(kEntityPascale, "014B");
 			getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 67);
 
-			if (getSound()->isBuffered("TAT1069A"))
-				getSound()->processEntry("TAT1069A");
-			else if (getSound()->isBuffered("TAT1069B"))
-				getSound()->processEntry("TAT1069B");
+			if (getSoundQueue()->isBuffered("TAT1069A"))
+				getSoundQueue()->processEntry("TAT1069A");
+			else if (getSoundQueue()->isBuffered("TAT1069B"))
+				getSoundQueue()->processEntry("TAT1069B");
 
 			setCallback(2);
 			setup_playSound("TAT1066");
@@ -1213,7 +1215,7 @@ label_callback1:
 		break;
 
 	case kAction169750080:
-		if (getSound()->isBuffered(kEntityPascale)) {
+		if (getSoundQueue()->isBuffered(kEntityPascale)) {
 			params->param4 = 1;
 		} else {
 			setCallback(7);
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index 68a37b3..6d1c524 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -30,6 +30,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -511,7 +513,7 @@ IMPLEMENT_FUNCTION_I(20, Rebecca, function20, TimeValue)
 		if (getProgress().chapter == kChapter1 && !ENTITY_PARAM(0, 3)) {
 			if (params->param7 != kTimeInvalid && getState()->time > kTime1174500) {
 				if (getState()->time <= kTime1183500) {
-					if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSound()->isBuffered("CON1210") || !params->param7)
+					if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSoundQueue()->isBuffered("CON1210") || !params->param7)
 						params->param7 = (uint)(getState()->time);
 
 					if (params->param7 >= getState()->time)
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
index bbaff5f..6dcab71 100644
--- a/engines/lastexpress/entities/salko.cpp
+++ b/engines/lastexpress/entities/salko.cpp
@@ -33,6 +33,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -596,8 +598,8 @@ IMPLEMENT_FUNCTION(24, Salko, chapter5Handler)
 			break;
 
 		case 1:
-			if (getSound()->isBuffered("MUS050"))
-				getSound()->processEntry("MUS050");
+			if (getSoundQueue()->isBuffered("MUS050"))
+				getSoundQueue()->processEntry("MUS050");
 
 			getAction()->playAnimation(kEventCathSalkoTrainTopFight);
 
diff --git a/engines/lastexpress/entities/tables.cpp b/engines/lastexpress/entities/tables.cpp
index da053c5..702b636 100644
--- a/engines/lastexpress/entities/tables.cpp
+++ b/engines/lastexpress/entities/tables.cpp
@@ -29,6 +29,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -88,8 +90,8 @@ IMPLEMENT_FUNCTION_END
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(5, Tables, chapter5)
 	if (savepoint.action == kActionDefault) {
-		if (_id == kEntityTables2 && getSound()->isBuffered(kEntityTables2))
-			getSound()->processEntry(kEntityTables2);
+		if (_id == kEntityTables2 && getSoundQueue()->isBuffered(kEntityTables2))
+			getSoundQueue()->processEntry(kEntityTables2);
 
 		setup_draw();
 	}
@@ -113,21 +115,21 @@ IMPLEMENT_FUNCTION(6, Tables, draw)
 		case kChapter1:
 			if (getState()->time > kTime1165500 && !params->param1) {
 				params->param1 = 1;
-				getSound()->processEntry(kEntityTables2);
+				getSoundQueue()->processEntry(kEntityTables2);
 			}
 			break;
 
 		case kChapter3:
 			if (getState()->time > kTime2052000 && !params->param2) {
 				params->param2 = 1;
-				getSound()->processEntry(kEntityTables2);
+				getSoundQueue()->processEntry(kEntityTables2);
 			}
 			break;
 
 		case kChapter4:
 			if (getState()->time > kTime2488500 && !params->param3) {
 				params->param3 = 1;
-				getSound()->processEntry(kEntityTables2);
+				getSoundQueue()->processEntry(kEntityTables2);
 			}
 			break;
 
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index db5c413..2f60b44 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -35,6 +35,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -420,7 +422,7 @@ IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
 		break;
 
 	case kActionNone:
-		if (getSound()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSound()->isBuffered("TAT1066"))
+		if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSoundQueue()->isBuffered("TAT1066"))
 			goto label_tatiana_chapter1_2;
 
 		UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, 450)
@@ -568,7 +570,7 @@ IMPLEMENT_FUNCTION(21, Tatiana, function21)
 			// Fallback to next case
 
 		case 3:
-			if (getSound()->isBuffered(kEntityTatiana)) {
+			if (getSoundQueue()->isBuffered(kEntityTatiana)) {
 				setCallback(3);
 				setup_updateFromTime(75);
 			} else {
@@ -1858,7 +1860,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, function46)
 			parameters->param3 = 1;
 
 			if (parameters->param2) {
-				getSound()->removeFromQueue(kEntityTatiana);
+				getSoundQueue()->removeFromQueue(kEntityTatiana);
 				getSavePoints()->call(kEntityTatiana, kEntityTatiana, kActionEndSound);
 			}
 		} else {
@@ -1947,7 +1949,7 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48)
 			params->param1 = 0;
 		}
 
-		if (!params->param1 || getSound()->isBuffered(kEntityTatiana))
+		if (!params->param1 || getSoundQueue()->isBuffered(kEntityTatiana))
 			goto label_end;
 
 		UPDATE_PARAM_GOTO(params->param2, getState()->timeTicks, 5 * (3 * rnd(5) + 30), label_end);
@@ -2086,7 +2088,7 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50)
 		break;
 
 	case kActionKnock:
-		if (!getSound()->isBuffered("LIB012", true))
+		if (!getSoundQueue()->isBuffered("LIB012", true))
 			getSound()->playSound(kEntityPlayer, "LIB012");
 		break;
 
@@ -2107,14 +2109,14 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50)
 		getObjects()->update(kObject48, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObjectCompartmentA, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 
-		if (!getSound()->isBuffered(kEntityTatiana))
+		if (!getSoundQueue()->isBuffered(kEntityTatiana))
 			getSound()->playSound(kEntityTatiana, "Tat4166");
 		break;
 
 	case kActionCallback:
 		if (getCallback() == 1) {
-			if (getSound()->isBuffered("MUS013"))
-				getSound()->processEntry("MUS013");
+			if (getSoundQueue()->isBuffered("MUS013"))
+				getSoundQueue()->processEntry("MUS013");
 
 			getAction()->playAnimation(kEventVassiliDeadAlexei);
 			getSavePoints()->push(kEntityTatiana, kEntityAbbot, kAction104060776);
@@ -2223,11 +2225,11 @@ IMPLEMENT_FUNCTION(54, Tatiana, function54)
 
 	case kActionCallback:
 		if (getCallback() == 1) {
-			if (getSound()->isBuffered("MUS050"))
-				getSound()->processEntry("MUS050");
+			if (getSoundQueue()->isBuffered("MUS050"))
+				getSoundQueue()->processEntry("MUS050");
 
-			if (getSound()->isBuffered(kEntityTatiana))
-				getSound()->processEntry(kEntityTatiana);
+			if (getSoundQueue()->isBuffered(kEntityTatiana))
+				getSoundQueue()->processEntry(kEntityTatiana);
 
 			getAction()->playAnimation(isNight() ? kEventTatianaVassiliTalkNight : kEventTatianaVassiliTalk);
 			getScenes()->processScene();
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index 1a5c6f4..74eed63 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/state.h"
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -300,13 +302,13 @@ label_process:
 		}
 
 		// Update object
-		if (ENTITY_PARAM(0, 8) && !getSound()->isBuffered(kEntityTables5)) {
+		if (ENTITY_PARAM(0, 8) && !getSoundQueue()->isBuffered(kEntityTables5)) {
 			getObjects()->update((ObjectIndex)ENTITY_PARAM(0, 8), getObjects()->get((ObjectIndex)ENTITY_PARAM(0, 8)).entity, kObjectLocation3, kCursorHandKnock, kCursorHand);
 			ENTITY_PARAM(0, 8) = 0;
 		}
 
 		// Play clock sound
-		if (params->param6 && !getSound()->isBuffered("ZFX1001", true))
+		if (params->param6 && !getSoundQueue()->isBuffered("ZFX1001", true))
 			getSound()->playSound(kEntityPlayer, "ZFX1001");
 
 		break;
@@ -339,12 +341,12 @@ label_process:
 		// Play clock sound
 		if (getEntities()->isPlayerPosition(kCarRestaurant, 81)) {
 			params->param6 = 1;
-			if (!getSound()->isBuffered("ZFX1001"))
+			if (!getSoundQueue()->isBuffered("ZFX1001"))
 				getSound()->playSound(kEntityPlayer, "ZFX1001");
 		} else {
 			params->param6 = 0;
-			if (getSound()->isBuffered("ZFX1001", true))
-				getSound()->removeFromQueue("ZFX1001");
+			if (getSoundQueue()->isBuffered("ZFX1001", true))
+				getSoundQueue()->removeFromQueue("ZFX1001");
 		}
 
 		// Draw moving background behind windows
@@ -562,8 +564,8 @@ void Train::resetParam8() {
 	 && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param2)
 	 && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param3)) {
 
-		if (getSound()->isBuffered((const char *)&params1->seq))
-			getSound()->processEntry((const char *)&params1->seq);
+		if (getSoundQueue()->isBuffered((const char *)&params1->seq))
+			getSoundQueue()->processEntry((const char *)&params1->seq);
 
 		params->param8 = 0;
 	}
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index a1daf3e..a7fbc7c 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -35,6 +35,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -295,7 +297,7 @@ IMPLEMENT_FUNCTION(9, Vassili, function9)
 		|| getEntities()->isPlayerPosition(kCarRedSleeping, 41)) {
 
 			if (savepoint.action == kActionDrawScene)
-				getSound()->processEntry(kEntityVassili);
+				getSoundQueue()->processEntry(kEntityVassili);
 
 			setup_seizure();
 		} else {
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index c0a00b8..c18137c 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -32,6 +32,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
@@ -139,7 +141,7 @@ IMPLEMENT_FUNCTION_END
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION_II(8, Verges, updateEntity, CarIndex, EntityPosition)
 	if (savepoint.action == kActionExcuseMeCath) {
-		if (!getSound()->isBuffered(kEntityVerges))
+		if (!getSoundQueue()->isBuffered(kEntityVerges))
 			getSound()->playSound(kEntityPlayer, "TRA1113", getSound()->getSoundFlag(kEntityVerges));
 
 		return;
@@ -187,7 +189,7 @@ switch (savepoint.action) {
 			break;
 
 		case 2:
-			if (!getSound()->isBuffered(kEntityVerges))
+			if (!getSoundQueue()->isBuffered(kEntityVerges))
 				getSound()->playSound(kEntityVerges, (char *)&params->seq1);
 
 			getEntities()->drawSequenceRight(kEntityVerges, "813DS");
@@ -232,7 +234,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition)
 
 	case kActionNone:
 		if (!params->param7) {
-			if (!getSound()->isBuffered(kEntityVerges)) {
+			if (!getSoundQueue()->isBuffered(kEntityVerges)) {
 				getSound()->playSound(kEntityVerges, (char *)&params->seq);
 				params->param7 = 1;
 			}
@@ -258,7 +260,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition)
 		break;
 
 	case kActionDefault:
-		if (!getSound()->isBuffered(kEntityVerges)) {
+		if (!getSoundQueue()->isBuffered(kEntityVerges)) {
 			getSound()->playSound(kEntityVerges, (char *)&params->seq);
 			params->param7 = 1;
 		}
@@ -704,7 +706,7 @@ IMPLEMENT_FUNCTION(24, Verges, policeGettingOffTrain)
 
 	case kActionCallback:
 		if (getCallback() == 1) {
-			getSound()->processEntry(kEntityVerges);
+			getSoundQueue()->processEntry(kEntityVerges);
 			getAction()->playAnimation(kEventGendarmesArrestation);
 			getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true);
 		}
@@ -1314,7 +1316,7 @@ IMPLEMENT_FUNCTION(32, Verges, function32)
 			break;
 
 		case 2:
-			if (!getSound()->isBuffered(kEntityVerges))
+			if (!getSoundQueue()->isBuffered(kEntityVerges))
 				getSound()->playSound(kEntityVerges, "TRA3004");
 
 			getEntities()->drawSequenceRight(kEntityVerges, "813DS");
@@ -1752,16 +1754,16 @@ IMPLEMENT_FUNCTION(40, Verges, chapter5Handler)
 		break;
 
 	case kActionNone:
-		if (getEntities()->isInSalon(kEntityPlayer) && !getSound()->isBuffered(kEntityVerges))
+		if (getEntities()->isInSalon(kEntityPlayer) && !getSoundQueue()->isBuffered(kEntityVerges))
 			getSound()->playSound(kEntityVerges, "WAT5000");
 		break;
 
 	case kActionOpenDoor:
-		if (getSound()->isBuffered(kEntityVerges))
-			getSound()->processEntry(kEntityVerges);
+		if (getSoundQueue()->isBuffered(kEntityVerges))
+			getSoundQueue()->processEntry(kEntityVerges);
 
-		if (getSound()->isBuffered("MUS050"))
-			getSound()->processEntry("MUS050");
+		if (getSoundQueue()->isBuffered("MUS050"))
+			getSoundQueue()->processEntry("MUS050");
 
 		getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
 
@@ -1811,7 +1813,7 @@ IMPLEMENT_FUNCTION(41, Verges, function41)
 			// Fallback to next case
 
 		case 2:
-			if (getSound()->isBuffered(kEntityVerges)) {
+			if (getSoundQueue()->isBuffered(kEntityVerges)) {
 				setCallback(2);
 				setup_updateFromTime(225);
 			} else {
diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp
index 685b3b0..38a93cf 100644
--- a/engines/lastexpress/fight/fight.cpp
+++ b/engines/lastexpress/fight/fight.cpp
@@ -37,6 +37,8 @@
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -86,7 +88,7 @@ void Fight::eventMouse(const Common::Event &ev) {
 
 		// Handle right button click
 		if (ev.type == Common::EVENT_RBUTTONUP) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			setStopped();
 
 			getGlobalTimer() ? _state = 0 : ++_state;
@@ -133,15 +135,15 @@ void Fight::eventMouse(const Common::Event &ev) {
 		// Stop fight if clicked
 		if (ev.type == Common::EVENT_LBUTTONUP) {
 			_handleTimer = false;
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			bailout(kFightEndExit);
 		}
 
 		// Reset timer on right click
 		if (ev.type == Common::EVENT_RBUTTONUP) {
 			if (getGlobalTimer()) {
-				if (getSound()->isBuffered("TIMER"))
-					getSound()->removeFromQueue("TIMER");
+				if (getSoundQueue()->isBuffered("TIMER"))
+					getSoundQueue()->removeFromQueue("TIMER");
 
 				setGlobalTimer(900);
 			}
@@ -277,7 +279,7 @@ Fight::FightEndType Fight::setup(FightType type) {
 		if (_engine->handleEvents())
 			continue;
 
-		getSound()->updateQueue();
+		getSoundQueue()->updateQueue();
 	}
 
 	// Cleanup after fight is over
diff --git a/engines/lastexpress/fight/fighter_anna.cpp b/engines/lastexpress/fight/fighter_anna.cpp
index 3c0132e..feb3551 100644
--- a/engines/lastexpress/fight/fighter_anna.cpp
+++ b/engines/lastexpress/fight/fighter_anna.cpp
@@ -26,6 +26,8 @@
 
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -107,7 +109,7 @@ void FighterPlayerAnna::handleAction(FightAction action) {
 	}
 
 	if (_field_34 > 4) {
-		getSound()->removeFromQueue(kEntityTables0);
+		getSoundQueue()->removeFromQueue(kEntityTables0);
 		_fight->bailout(Fight::kFightEndWin);
 	}
 }
@@ -175,7 +177,7 @@ void FighterOpponentAnna::update() {
 			_opponent->handleAction((FightAction)_sequenceIndex);
 
 		if (_opponent->getCountdown() <= 0) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			handleAction(kFightActionLost);
 		}
 	}
diff --git a/engines/lastexpress/fight/fighter_ivo.cpp b/engines/lastexpress/fight/fighter_ivo.cpp
index 60d6c1a..9988fca 100644
--- a/engines/lastexpress/fight/fighter_ivo.cpp
+++ b/engines/lastexpress/fight/fighter_ivo.cpp
@@ -26,6 +26,8 @@
 
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -110,7 +112,7 @@ void FighterPlayerIvo::update() {
 		if (_opponent->getCountdown() <= 0) {
 			setSequenceAndDraw(9, kFightSequenceType1);
 			_opponent->setSequenceAndDraw(8, kFightSequenceType1);
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 
 			handleAction(kFightActionWin);
 			return;
@@ -227,7 +229,7 @@ void FighterOpponentIvo::update() {
 		if (_opponent->getCountdown() <= 0) {
 			setSequenceAndDraw(7, kFightSequenceType1);
 			_opponent->setSequenceAndDraw(8, kFightSequenceType1);
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 
 			_opponent->handleAction(kFightActionWin);
 
diff --git a/engines/lastexpress/fight/fighter_milos.cpp b/engines/lastexpress/fight/fighter_milos.cpp
index 972c448..82c965c 100644
--- a/engines/lastexpress/fight/fighter_milos.cpp
+++ b/engines/lastexpress/fight/fighter_milos.cpp
@@ -27,6 +27,8 @@
 
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -107,7 +109,7 @@ void FighterPlayerMilos::update() {
 			setSequenceAndDraw(5, kFightSequenceType1);
 			_opponent->setSequenceAndDraw(6, kFightSequenceType1);
 
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			getSound()->playSound(kEntityTrain, "MUS029", kFlagDefault);
 
 			handleAction(kFightActionWin);
@@ -210,7 +212,7 @@ void FighterOpponentMilos::update() {
 			_opponent->handleAction((FightAction)_sequenceIndex);
 
 		if (_opponent->getCountdown() <= 0) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			handleAction(kFightActionLost);
 		}
 	}
diff --git a/engines/lastexpress/fight/fighter_salko.cpp b/engines/lastexpress/fight/fighter_salko.cpp
index 6f71a6d..166f7c3 100644
--- a/engines/lastexpress/fight/fighter_salko.cpp
+++ b/engines/lastexpress/fight/fighter_salko.cpp
@@ -27,6 +27,8 @@
 
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -95,7 +97,7 @@ void FighterPlayerSalko::update() {
 	if (_frame && checkFrame(2)) {
 
 		if (_opponent->getCountdown() <= 0) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			_fight->bailout(Fight::kFightEndWin);
 
 			return;
@@ -184,7 +186,7 @@ void FighterOpponentSalko::update() {
 
 	if (_frame && checkFrame(2)) {
 		if (_opponent->getCountdown() <= 0) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			_fight->bailout(Fight::kFightEndLost);
 
 			// Stop processing
diff --git a/engines/lastexpress/fight/fighter_vesna.cpp b/engines/lastexpress/fight/fighter_vesna.cpp
index c92d041..075f158 100644
--- a/engines/lastexpress/fight/fighter_vesna.cpp
+++ b/engines/lastexpress/fight/fighter_vesna.cpp
@@ -27,6 +27,8 @@
 
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -103,7 +105,7 @@ void FighterPlayerVesna::update() {
 			_opponent->handleAction(kFightAction3);
 
 		if (_opponent->getCountdown() <= 0) {
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 			_fight->bailout(Fight::kFightEndWin);
 			return;
 		}
@@ -251,7 +253,7 @@ void FighterOpponentVesna::update() {
 			_opponent->update();
 			Fighter::update();
 
-			getSound()->removeFromQueue(kEntityTables0);
+			getSoundQueue()->removeFromQueue(kEntityTables0);
 
 			// Stop processing
 			return;
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index 54bb875..f195825 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -42,6 +42,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
@@ -453,7 +455,7 @@ IMPLEMENT_ACTION(savePoint)
 IMPLEMENT_ACTION(playSound)
 
 	// Check that the file is not already buffered
-	if (hotspot.param2 || !getSound()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true))
+	if (hotspot.param2 || !getSoundQueue()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true))
 		getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2);
 
 	return kSceneInvalid;
@@ -465,7 +467,7 @@ IMPLEMENT_ACTION(playMusic)
 	// Check that the file is not already buffered
 	Common::String filename = Common::String::format("MUS%03d", hotspot.param1);
 
-	if (!getSound()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5))
+	if (!getSoundQueue()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5))
 		getSound()->playSound(kEntityPlayer, filename, kFlagDefault, hotspot.param2);
 
 	return kSceneInvalid;
@@ -481,7 +483,7 @@ IMPLEMENT_ACTION(knock)
 	if (getObjects()->get(object).entity) {
 		getSavePoints()->push(kEntityPlayer, getObjects()->get(object).entity, kActionKnock, object);
 	} else {
-		if (!getSound()->isBuffered("LIB012", true))
+		if (!getSoundQueue()->isBuffered("LIB012", true))
 			getSound()->playSoundEvent(kEntityPlayer, 12);
 	}
 
@@ -516,7 +518,7 @@ IMPLEMENT_ACTION(compartment)
 		 && (compartment != kObjectCompartment1
 		  || !getInventory()->hasItem(kItemKey)
 		  || (getInventory()->getSelectedItem() != kItemFirebird && getInventory()->getSelectedItem() != kItemBriefcase)))) {
-			if (!getSound()->isBuffered("LIB13"))
+			if (!getSoundQueue()->isBuffered("LIB13"))
 				getSound()->playSoundEvent(kEntityPlayer, 13);
 
 			// Stop processing further
@@ -621,7 +623,7 @@ IMPLEMENT_ACTION(updateObjetLocation2)
 
 	getObjects()->updateLocation2(object, location);
 
-	if (object != kObject112 || getSound()->isBuffered("LIB096")) {
+	if (object != kObject112 || getSoundQueue()->isBuffered("LIB096")) {
 		if (object == 1)
 			getSound()->playSoundEvent(kEntityPlayer, 73);
 	} else {
@@ -805,7 +807,7 @@ IMPLEMENT_ACTION(enterCompartment)
 		getSound()->playSoundEvent(kEntityPlayer, 14);
 		getSound()->playSoundEvent(kEntityPlayer, 15, 22);
 
-		if (getProgress().field_78 && !getSound()->isBuffered("MUS003")) {
+		if (getProgress().field_78 && !getSoundQueue()->isBuffered("MUS003")) {
 			getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
 			getProgress().field_78 = 0;
 		}
@@ -1083,7 +1085,7 @@ IMPLEMENT_ACTION(25)
 		break;
 
 	case 2:
-		if (!getSound()->isBuffered("MUS021"))
+		if (!getSoundQueue()->isBuffered("MUS021"))
 			getSound()->playSound(kEntityPlayer, "MUS021", kFlagDefault);
 		break;
 
@@ -1134,7 +1136,7 @@ IMPLEMENT_ACTION(26)
 //////////////////////////////////////////////////////////////////////////
 // Action 27
 IMPLEMENT_ACTION(27)
-	if (!getSound()->isBuffered("LIB031", true))
+	if (!getSoundQueue()->isBuffered("LIB031", true))
 		getSound()->playSoundEvent(kEntityPlayer, 31);
 
 	switch (getEntityData(kEntityPlayer)->car) {
@@ -1182,7 +1184,7 @@ IMPLEMENT_ACTION(29)
 	getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2);
 
 	Common::String filename = Common::String::format("MUS%03d", hotspot.param3);
-	if (!getSound()->isBuffered(filename))
+	if (!getSoundQueue()->isBuffered(filename))
 		getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
 
 	return kSceneInvalid;
@@ -1354,7 +1356,7 @@ IMPLEMENT_ACTION(dialog)
 // Action 38
 IMPLEMENT_ACTION(eggBox)
 	getSound()->playSoundEvent(kEntityPlayer, 43);
-	if (getProgress().field_7C && !getSound()->isBuffered("MUS003")) {
+	if (getProgress().field_7C && !getSoundQueue()->isBuffered("MUS003")) {
 		getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
 		getProgress().field_7C = 0;
 	}
@@ -1366,7 +1368,7 @@ IMPLEMENT_ACTION(eggBox)
 // Action 39
 IMPLEMENT_ACTION(39)
 	getSound()->playSoundEvent(kEntityPlayer, 24);
-	if (getProgress().field_80 && !getSound()->isBuffered("MUS003")) {
+	if (getProgress().field_80 && !getSoundQueue()->isBuffered("MUS003")) {
 		getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault);
 		getProgress().field_80 = 0;
 	}
@@ -1408,7 +1410,7 @@ IMPLEMENT_ACTION(playMusicChapter)
 	if (id) {
 		Common::String filename = Common::String::format("MUS%03d", id);
 
-		if (!getSound()->isBuffered(filename))
+		if (!getSoundQueue()->isBuffered(filename))
 			getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
 	}
 
@@ -1440,7 +1442,7 @@ IMPLEMENT_ACTION(playMusicChapterSetupTrain)
 
 	Common::String filename = Common::String::format("MUS%03d", hotspot.param1);
 
-	if (!getSound()->isBuffered(filename) && hotspot.param3 & id) {
+	if (!getSoundQueue()->isBuffered(filename) && hotspot.param3 & id) {
 		getSound()->playSound(kEntityPlayer, filename, kFlagDefault);
 
 		getSavePoints()->call(kEntityPlayer, kEntityTrain, kAction203863200, filename.c_str());
@@ -1612,7 +1614,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 				if (doPlaySound)
 					playCompartmentSoundEvents(object);
 
-				if (!getSound()->isBuffered(kEntityMertens))
+				if (!getSoundQueue()->isBuffered(kEntityMertens))
 					getSound()->playWarningCompartment(kEntityMertens, object);
 
 				getSavePoints()->push(kEntityPlayer, kEntityMertens, kAction305159806);
@@ -1628,7 +1630,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 				if (doPlaySound)
 					playCompartmentSoundEvents(object);
 
-				if (!getSound()->isBuffered(kEntityMertens))
+				if (!getSoundQueue()->isBuffered(kEntityMertens))
 					getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A");
 
 				if (doLoadScene)
@@ -1640,7 +1642,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 				if (doPlaySound)
 					playCompartmentSoundEvents(object);
 
-				if (!getSound()->isBuffered(kEntityMertens))
+				if (!getSoundQueue()->isBuffered(kEntityMertens))
 					getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A");
 
 				if (doLoadScene)
@@ -1667,7 +1669,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 			if (doPlaySound)
 				playCompartmentSoundEvents(object);
 
-			if (!getSound()->isBuffered(kEntityCoudert))
+			if (!getSoundQueue()->isBuffered(kEntityCoudert))
 				getSound()->playWarningCompartment(kEntityCoudert, object);
 
 			getSavePoints()->push(kEntityPlayer, kEntityCoudert, kAction305159806);
@@ -1684,7 +1686,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 			if (doPlaySound)
 				playCompartmentSoundEvents(object);
 
-			if (!getSound()->isBuffered(kEntityCoudert))
+			if (!getSoundQueue()->isBuffered(kEntityCoudert))
 				getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A");
 
 			if (doLoadScene)
@@ -1699,7 +1701,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
 			if (doPlaySound)
 				playCompartmentSoundEvents(object);
 
-			if (!getSound()->isBuffered(kEntityCoudert))
+			if (!getSoundQueue()->isBuffered(kEntityCoudert))
 				getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A");
 
 			if (doLoadScene)
@@ -1930,8 +1932,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const {
 	if (!getFlags()->mouseRightClick) {
 
 		if (getGlobalTimer()) {
-			if (getSound()->isBuffered("TIMER")) {
-				getSound()->processEntry("TIMER");
+			if (getSoundQueue()->isBuffered("TIMER")) {
+				getSoundQueue()->processEntry("TIMER");
 				setGlobalTimer(105);
 			}
 		}
@@ -1948,8 +1950,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const {
 		if (animation.load(getArchive(Common::String(_animationList[index].filename) + ".nis") , processSound ? Animation::kFlagDefault : Animation::kFlagProcess))
 			animation.play();
 
-		if (getSound()->isBuffered("TIMER"))
-			getSound()->removeFromQueue("TIMER");
+		if (getSoundQueue()->isBuffered("TIMER"))
+			getSoundQueue()->removeFromQueue("TIMER");
 	}
 
 	// Show cursor
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index 0fa3af3..8dd2c26 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -71,6 +71,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -299,7 +301,7 @@ void Entities::setupChapter(ChapterIndex chapter) {
 		memset(&_compartments1, 0, sizeof(_compartments1));
 		memset(&_positions, 0, sizeof(_positions));
 
-		getSound()->resetQueue(kSoundType13);
+		getSoundQueue()->resetQueue(kSoundType13);
 	}
 
 	// we skip the header when doing entity setup
@@ -369,8 +371,8 @@ void Entities::resetState(EntityIndex entityIndex) {
 	getData(entityIndex)->currentCall = 0;
 	getData(entityIndex)->inventoryItem = kItemNone;
 
-	if (getSound()->isBuffered(entityIndex))
-		getSound()->removeFromQueue(entityIndex);
+	if (getSoundQueue()->isBuffered(entityIndex))
+		getSoundQueue()->removeFromQueue(entityIndex);
 
 	clearSequences(entityIndex);
 
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index 4d75fca..c3a1022 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -33,6 +33,8 @@
 
 #include "lastexpress/menu/menu.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -162,8 +164,8 @@ void Inventory::handleMouseEvent(const Common::Event &ev) {
 
 		} else if (ev.type == Common::EVENT_RBUTTONDOWN) {
 			if (getGlobalTimer()) {
-				if (getSound()->isBuffered("TIMER"))
-					getSound()->removeFromQueue("TIMER");
+				if (getSoundQueue()->isBuffered("TIMER"))
+					getSoundQueue()->removeFromQueue("TIMER");
 
 				setGlobalTimer(900);
 			}
@@ -630,7 +632,7 @@ void Inventory::drawBlinkingEgg() {
 	//	if (getGlobalTimer() + ticks >= 90)
 	//		getSound()->playSoundWithSubtitles("TIMER.SND", 50331664, kEntityPlayer);
 
-	//	if (getSound()->isBuffered("TIMER"))
+	//	if (getSoundQueue()->isBuffered("TIMER"))
 	//		setGlobalTimer(0);
 	//}
 
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index c1237ee..cdde2a0 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -47,6 +47,8 @@
 
 #include "lastexpress/menu/menu.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -152,7 +154,7 @@ void Logic::eventMouse(const Common::Event &ev) {
 		_engine->getCursor()->setStyle(getInventory()->get(kItemWhistle)->cursor);
 
 		// Check if clicked
-		if (ev.type == Common::EVENT_LBUTTONUP && !getSound()->isBuffered("LIB045")) {
+		if (ev.type == Common::EVENT_LBUTTONUP && !getSoundQueue()->isBuffered("LIB045")) {
 
 			getSound()->playSoundEvent(kEntityPlayer, 45);
 
@@ -424,7 +426,7 @@ void Logic::resetState() {
  */
 void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, bool showScene) const {
 
-	getSound()->processEntries();
+	getSoundQueue()->processEntries();
 	getEntities()->reset();
 	getFlags()->isGameRunning = false;
 	getSavePoints()->reset();
@@ -432,16 +434,16 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo
 
 	if (showScene) {
 
-		getSound()->processEntry(kSoundType11);
+		getSoundQueue()->processEntry(kSoundType11);
 
 		if (sceneIndex && !getFlags()->mouseRightClick) {
 			getScenes()->loadScene(sceneIndex);
 
-			while (getSound()->isBuffered(kEntityTables4)) {
+			while (getSoundQueue()->isBuffered(kEntityTables4)) {
 				if (getFlags()->mouseRightClick)
 					break;
 
-				getSound()->updateQueue();
+				getSoundQueue()->updateQueue();
 			}
 		}
 	}
@@ -451,7 +453,7 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo
 }
 
 void Logic::switchChapter() const {
-	getSound()->clearStatus();
+	getSoundQueue()->clearStatus();
 
 	switch(getState()->progress.chapter) {
 	default:
@@ -491,7 +493,7 @@ void Logic::switchChapter() const {
 }
 
 void Logic::playFinalSequence() const {
-	getSound()->processEntries();
+	getSoundQueue()->processEntries();
 
 	_action->playAnimation(kEventFinalSequence);
 	showCredits();
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 594cd12..8dfc214 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -30,6 +30,8 @@
 
 #include "lastexpress/menu/menu.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/debug.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
@@ -125,7 +127,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
 		while (_savegame->pos() < _savegame->size() && !_savegame->eos() && !_savegame->err()) {
 
 			// Update sound queue while we go through the savegame
-			getSound()->updateQueue();
+			getSoundQueue()->updateQueue();
 
 			SavegameEntryHeader *entry = new SavegameEntryHeader();
 			entry->saveLoadWithSerializer(ser);
@@ -217,7 +219,7 @@ void SaveLoad::loadGame(GameId id) {
 	_gameTicksLastSavegame = getState()->timeTicks;
 
 	if (header.keepIndex) {
-		getSound()->clearQueue();
+		getSoundQueue()->clearQueue();
 
 		readEntry(&type, &entity, &val, false);
 	}
@@ -377,7 +379,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
 	WRITE_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
 	WRITE_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
 	WRITE_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
-	WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 3 * 4 + getSound()->count() * 64);
+	WRITE_ENTRY("sound", getSoundQueue()->saveLoadWithSerializer(ser), 3 * 4 + getSoundQueue()->count() * 64);
 	WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 128 * 16 + 4 + getSavePoints()->count() * 16);
 
 	header.offset = (uint32)_savegame->pos() - (originalPosition + 32);
@@ -452,7 +454,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 	LOAD_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
 	LOAD_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
 	LOAD_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
-	LOAD_ENTRY_ONLY("sound", getSound()->saveLoadWithSerializer(ser));
+	LOAD_ENTRY_ONLY("sound", getSoundQueue()->saveLoadWithSerializer(ser));
 	LOAD_ENTRY_ONLY("savepoints", getSavePoints()->saveLoadWithSerializer(ser));
 
 	// Update chapter
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index b346c9d..408f480 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -34,6 +34,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -1057,9 +1059,9 @@ void SceneManager::preProcessScene(SceneIndex *index) {
 
 	// Sound processing
 	Scene *newScene = getScenes()->get(*index);
-	if (getSound()->isBuffered(kEntityTables4)) {
+	if (getSoundQueue()->isBuffered(kEntityTables4)) {
 		if (newScene->type != Scene::kTypeReadText || newScene->param1)
-			getSound()->processEntry(kEntityTables4);
+			getSoundQueue()->processEntry(kEntityTables4);
 	}
 
 	// Cleanup beetle sequences
@@ -1089,8 +1091,8 @@ void SceneManager::postProcessScene() {
 				if (getFlags()->mouseRightClick)
 					break;
 
-				getSound()->updateQueue();
-				getSound()->updateSubtitles();
+				getSoundQueue()->updateQueue();
+				getSoundQueue()->updateSubtitles();
 			}
 		}
 
@@ -1157,7 +1159,7 @@ void SceneManager::postProcessScene() {
 		if (getState()->time >= kTimeCityGalanta || getProgress().field_18 == 4)
 			break;
 
-		getSound()->processEntry(kSoundType7);
+		getSoundQueue()->processEntry(kSoundType7);
 		getSound()->playSound(kEntityTrain, "LIB050", kFlagDefault);
 
 		switch (getProgress().chapter) {
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
index 3fb3f88..bc4f71e 100644
--- a/engines/lastexpress/game/sound.cpp
+++ b/engines/lastexpress/game/sound.cpp
@@ -31,6 +31,7 @@
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/entry.h"
+#include "lastexpress/sound/queue.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/graphics.h"
@@ -39,9 +40,6 @@
 
 namespace LastExpress {
 
-#define SOUNDCACHE_ENTRY_SIZE 92160
-#define SOUNDCACHE_MAX_SIZE   6
-
 // Letters & messages
 static const char *const messages[24] = {
 	"",
@@ -115,349 +113,32 @@ static const SoundFlag soundFlags[32] = {
 	kFlag3,  kFlag3, kFlag3, kFlag3, kFlag3
 };
 
-SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state(0), _currentType(kSoundType16), _flag(0) {
+SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) {
+	_loopingSoundDuration = 0;
+
+	_queue = new SoundQueue(engine);
+
+	memset(&_lastWarning, 0, sizeof(_lastWarning));
+
 	// Initialize unknown data
 	_data0 = 0;
 	_data1 = 0;
 	_data2 = 0;
-
-	memset(&_buffer, 0, sizeof(_buffer));
-	memset(&_lastWarning, 0, sizeof(_lastWarning));
-
-	// Sound cache
-	_soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
-
-	_subtitlesFlag = 0;
-	_currentSubtitle = NULL;
-
-	_loopingSoundDuration = 0;
 }
 
 SoundManager::~SoundManager() {
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		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);
+	SAFE_DELETE(_queue);
 
 	// Zero passed pointers
 	_engine = NULL;
 }
 
 //////////////////////////////////////////////////////////////////////////
-// Timer
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::handleTimer() {
-	Common::StackLock locker(_mutex);
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		SoundEntry *entry = (*i);
-		if (entry->_stream == NULL) {
-			SAFE_DELETE(*i);
-			i = _soundList.reverse_erase(i);
-			continue;
-		} else if (!entry->_soundStream) {
-			entry->_soundStream = new StreamedSound();
-
-			// TODO: stream any sound in the queue after filtering
-			entry->_soundStream->load(entry->_stream);
-		}
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound queue management
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateQueue() {
-	// TODO add mutex lock!
-	warning("Sound::updateQueue: not implemented!");
-}
-
-void SoundManager::resetQueue(SoundType type1, SoundType type2) {
-	if (!type2)
-		type2 = type1;
-
-	Common::StackLock locker(_mutex);
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->getType() != type1 && (*i)->getType() != type2)
-			(*i)->reset();
-	}
-}
-
-void SoundManager::removeFromQueue(EntityIndex entity) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(entity);
-	if (entry)
-		entry->reset();
-}
-
-void SoundManager::removeFromQueue(Common::String filename) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(filename);
-	if (entry)
-		entry->reset();
-}
-
-void SoundManager::clearQueue() {
-	_flag |= 4;
-
-	// FIXME: Wait a while for a flag to be set
-	//for (int i = 0; i < 3000000; i++)
-	//	if (_flag & 8)
-	//		break;
-
-	_flag |= 8;
-
-	Common::StackLock locker(_mutex);
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		SoundEntry *entry = (*i);
-
-		// Delete entry
-		entry->close();
-		SAFE_DELETE(entry);
-
-		i = _soundList.reverse_erase(i);
-	}
-
-	updateSubtitles();
-}
-
-bool SoundManager::isBuffered(EntityIndex entity) {
-	Common::StackLock locker(_mutex);
-
-	return (getEntry(entity) != NULL);
-}
-
-bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(filename);
-
-	if (testForEntity)
-		return entry != NULL && entry->getEntity() != kEntityPlayer;
-
-	return (entry != NULL);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry
-//////////////////////////////////////////////////////////////////////////
-bool SoundManager::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)->_status.status & kSoundStatus_180)) {
-				uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1);
-
-				if (newSize < size) {
-					cacheEntry = (*i);
-					size = newSize;
-				}
-			}
-		}
-
-		if (entry->_priority <= 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->_status.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 SoundManager::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);
-		}
-	}
-}
-
-void SoundManager::clearStatus() {
-	Common::StackLock locker(_mutex);
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->_status.status |= kSoundStatusClear3;
-}
-
-void SoundManager::processEntry(EntityIndex entity) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(entity);
-	if (entry) {
-		entry->update(0);
-		entry->setEntity(kEntityPlayer);
-	}
-}
-
-void SoundManager::processEntry(SoundType type) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(type);
-	if (entry)
-		entry->update(0);
-}
-
-void SoundManager::setupEntry(SoundType type, EntityIndex index) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(type);
-	if (entry)
-		entry->setEntity(index);
-}
-
-void SoundManager::processEntry(Common::String filename) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(filename);
-	if (entry) {
-		entry->update(0);
-		entry->setEntity(kEntityPlayer);
-	}
-}
-
-void SoundManager::processEntries() {
-	_state = 0;
-
-	processEntry(kSoundType1);
-	processEntry(kSoundType2);
-}
-
-uint32 SoundManager::getEntryTime(EntityIndex index) {
-	Common::StackLock locker(_mutex);
-
-	SoundEntry *entry = getEntry(index);
-	if (entry)
-		return entry->_time;
-
-	return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-
-void SoundManager::unknownFunction4() {
-	// TODO: Add mutex ?
-	warning("Sound::unknownFunction4: not implemented!");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Entry search
-//////////////////////////////////////////////////////////////////////////
-SoundEntry *SoundManager::getEntry(EntityIndex index) {
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->getEntity() == index)
-			return *i;
-	}
-
-	return NULL;
-}
-
-SoundEntry *SoundManager::getEntry(Common::String name) {
-	if (!name.contains('.'))
-		name += ".SND";
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->_name2 == name)
-			return *i;
-	}
-
-	return NULL;
-}
-
-SoundEntry *SoundManager::getEntry(SoundType type) {
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->getType() == type)
-			return *i;
-	}
-
-	return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Savegame
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
-	Common::StackLock locker(_mutex);
-
-	s.syncAsUint32LE(_state);
-	s.syncAsUint32LE(_currentType);
-
-	// Compute the number of entries to save
-	uint32 numEntries = count();
-	s.syncAsUint32LE(numEntries);
-
-	// Save or load each entry data
-	if (s.isSaving()) {
-		for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-			(*i)->saveLoadWithSerializer(s);
-	} else {
-		warning("Sound::saveLoadWithSerializer: loading not implemented");
-		s.skip(numEntries * 64);
-	}
-}
-
-
-// FIXME: We probably need another mutex here to protect during the whole savegame process
-// as we could have removed an entry between the time we check the count and the time we
-// save the entries
-uint32 SoundManager::count() {
-	Common::StackLock locker(_mutex);
-
-	uint32 numEntries = 0;
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		if ((*i)->_name2.matchString("NISSND?"))
-			++numEntries;
-
-	return numEntries;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Game-related functions
+// Sound-related functions
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
-	if (isBuffered(entity) && entity)
-		removeFromQueue(entity);
+	if (_queue->isBuffered(entity) && entity)
+		_queue->removeFromQueue(entity);
 
 	SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
 
@@ -473,8 +154,6 @@ void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundF
 bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) {
 	SoundEntry *entry = new SoundEntry(_engine);
 
-	Common::StackLock locker(_mutex);
-
 	entry->open(filename, flag, 30);
 	entry->_entity = entity;
 
@@ -623,13 +302,13 @@ void SoundManager::playSteam(CityIndex index) {
 	if (index >= ARRAYSIZE(cities))
 		error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
 
-	_state |= kSoundState2;
+	_queue->resetState(kSoundState2);
 
-	if (!getEntry(kSoundType1))
+	if (!_queue->getEntry(kSoundType1))
 		playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam);
 
 	// Get the new sound entry and show subtitles
-	SoundEntry *entry = getEntry(kSoundType1);
+	SoundEntry *entry = _queue->getEntry(kSoundType1);
 	if (entry)
 		entry->showSubtitle(cities[index]);
 }
@@ -679,8 +358,8 @@ void SoundManager::playFightSound(byte action, byte a4) {
 }
 
 void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) {
-	if (isBuffered(getDialogName(entityDialog)))
-		removeFromQueue(getDialogName(entityDialog));
+	if (_queue->isBuffered(getDialogName(entityDialog)))
+		_queue->removeFromQueue(getDialogName(entityDialog));
 
 	playSound(entity, getDialogName(entityDialog), flag, a4);
 }
@@ -993,7 +672,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
 // Letters & Messages
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::readText(int id){
-	if (!isBuffered(kEntityTables4))
+	if (!_queue->isBuffered(kEntityTables4))
 		return;
 
 	if (id < 0 || (id > 8 && id < 50) || id > 64)
@@ -1004,8 +683,8 @@ void SoundManager::readText(int id){
 
 	// Check if file is in cache for id [1;8]
 	if (id <= 8)
-		if (isBuffered(text))
-			removeFromQueue(text);
+		if (_queue->isBuffered(text))
+			_queue->removeFromQueue(text);
 
 	playSound(kEntityTables4, text, kFlagDefault);
 }
@@ -1193,7 +872,7 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
 }
 
 void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) {
-	if (isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
+	if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
 		return;
 
 	if (entity2 == kEntityFrancois || entity2 == kEntityMax)
@@ -1598,72 +1277,17 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
 }
 
 //////////////////////////////////////////////////////////////////////////
-// Subtitles
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::updateSubtitles() {
-	Common::StackLock locker(_mutex);
-
-	uint32 index = 0;
-	SubtitleEntry *subtitle = NULL;
-
-	for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
-		uint32 current_index = 0;
-		SoundEntry *soundEntry = (*i)->getSoundEntry();
-		SoundStatus status = (SoundStatus)soundEntry->_status.status;
-
-		if (!(status & kSoundStatus_40)
-		 || status & kSoundStatus_180
-		 || soundEntry->_time == 0
-		 || (status & kSoundStatusClear1) < 6
-		 || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) {
-			 current_index = 0;
-		} else {
-			current_index = soundEntry->_priority + (status & kSoundStatusClear1);
-
-			if (_currentSubtitle == (*i))
-				current_index += 4;
-		}
-
-		if (index < current_index) {
-			index = current_index;
-			subtitle = (*i);
-		}
-	}
-
-	if (_currentSubtitle == subtitle) {
-		if (subtitle)
-			subtitle->setupAndDraw();
-
-		return;
-	}
-
-	if (_subtitlesFlag & 1)
-		subtitle->drawOnScreen();
-
-	if (subtitle) {
-		subtitle->loadData();
-		subtitle->setupAndDraw();
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
 // Misc
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::playLoopingSound(int param) {
-	Common::List<SoundEntry *>::iterator snd;
-	char tmp[80];
+	SoundEntry *entry = _queue->getEntry(kSoundType1);
 
-	for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
-		if ((*snd)->getType() == kSoundType1)
-			break;
-	}
-
-	byte numLoops[8];
 	static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
 	                                             kPosition_6470, kPosition_5790,
 	                                             kPosition_4840, kPosition_4070,
 	                                             kPosition_3050, kPosition_2740 };
 
+	byte numLoops[8];
 	numLoops[1] = 4;
 	numLoops[2] = 2;
 	numLoops[3] = 2;
@@ -1671,13 +1295,14 @@ void SoundManager::playLoopingSound(int param) {
 	numLoops[5] = 2;
 	numLoops[6] = 2;
 
+	char tmp[80];
 	tmp[0] = 0;
 
 	int partNumber = 1;
 	int fnameLen = 6;
 
-	if (_state & 1 && param >= 0x45 && param <= 0x46) {
-		if (_state & 2) {
+	if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) {
+		if (_queue->getSoundState() & 2) {
 			strcpy(tmp, "STEAM.SND");
 
 			_loopingSoundDuration = 32767;
@@ -1727,390 +1352,28 @@ void SoundManager::playLoopingSound(int param) {
 				}
 			}
 
-			if (partNumber != 99) {
+			if (partNumber != 99)
 				sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A');
-			}
 		}
 
 		if (getFlags()->flag_3)
 			fnameLen = 5;
 
-		if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) {
+		if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) {
 			_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
 
 			if (partNumber != 99) {
 				playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam);
 
-				if (*snd)
-					(*snd)->update(0);
+				if (entry)
+					entry->update(0);
 
-				for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
-					if ((*snd)->getType() == kSoundType1) {
-						(*snd)->update(7);
-						break;
-					}
-				}
+				SoundEntry *entry1 = _queue->getEntry(kSoundType1);
+				if (entry1)
+					entry1->update(7);
 			}
 		}
 	}
 }
 
-void SoundManager::stopAllSound() {
-	Common::StackLock locker(_mutex);
-
-	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->_soundStream->stop();
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound filter
-//////////////////////////////////////////////////////////////////////////
-
-static const int filterData[1424] = {
-	0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256,
-	384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0,
-	192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640,
-	64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128,
-	320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576,
-	704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192,
-	192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448,
-	576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832,
-	320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320,
-	320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704,
-	832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448,
-	448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448,
-	640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960,
-	1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576,
-	576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576,
-	576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832,
-	960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088,
-	1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704,
-	704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768,
-	768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960,
-	1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280,
-	1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896,
-	896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896,
-	896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152,
-	1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408,
-	1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600,
-	1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088,
-	1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088,
-	1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152,
-	1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152,
-	1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408,
-	1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536,
-	1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728,
-	1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856,
-	1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344,
-	1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408,
-	1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408,
-	1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472,
-	1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664,
-	1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856,
-	1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984,
-	2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176,
-	1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664,
-	1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664,
-	1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728,
-	1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728,
-	1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984,
-	2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112,
-	2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304,
-	2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432,
-	1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920,
-	1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984,
-	1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984,
-	1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048,
-	2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240,
-	2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432,
-	2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560,
-	2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752,
-	2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240,
-	2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240,
-	2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304,
-	2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304,
-	2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560,
-	2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688,
-	2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880,
-	3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008,
-	2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496,
-	2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560,
-	2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560,
-	2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624,
-	2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816,
-	2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008,
-	3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136,
-	3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328,
-	2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816,
-	2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816,
-	2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880,
-	2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880,
-	3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136,
-	3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264,
-	3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456,
-	3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584,
-	3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072,
-	3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136,
-	3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136,
-	3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200,
-	3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392,
-	3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584,
-	3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712,
-	3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904,
-	3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392,
-	3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392,
-	3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456,
-	3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456,
-	3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712,
-	3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840,
-	3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032,
-	4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160,
-	3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648,
-	3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712,
-	3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712,
-	3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776,
-	3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968,
-	4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160,
-	4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288,
-	4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480,
-	3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968,
-	3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968,
-	3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032,
-	4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032,
-	4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288,
-	4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416,
-	4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608,
-	4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736,
-	4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224,
-	4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288,
-	4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288,
-	4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352,
-	4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544,
-	4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736,
-	4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864,
-	4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056,
-	4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544,
-	4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544,
-	4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608,
-	4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608,
-	4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864,
-	4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992,
-	5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184,
-	5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312,
-	4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800,
-	4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864,
-	4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864,
-	4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928,
-	5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120,
-	5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312,
-	5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440,
-	5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632,
-	5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120,
-	5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120,
-	5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184,
-	5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184,
-	5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440,
-	5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568,
-	5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632,
-	5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632,
-	5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376,
-	5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440,
-	5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440,
-	5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504,
-	5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632,
-	5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632,
-	5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632,
-	5632
-};
-
-static const int filterData2[1424] = {
-	0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11,
-	-13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9,
-	-11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5,
-	-7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18,
-	-1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12,
-	15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4,
-	7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19,
-	-22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14,
-	-17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5,
-	-8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26,
-	30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10,
-	14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27,
-	-31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16,
-	-21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2,
-	-7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25,
-	31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3,
-	9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34,
-	-40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17,
-	-24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50,
-	58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21,
-	29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55,
-	-63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32,
-	-41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5,
-	-15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50,
-	61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6,
-	18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56,
-	-68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20,
-	-34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82,
-	97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8,
-	24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74,
-	-90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9,
-	-27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70,
-	90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130,
-	-150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55,
-	-77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133,
-	157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
-	13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93,
-	-120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191,
-	221, -14, -44, -73, -103, -132, -162, -191, -221, 16,
-	48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113,
-	-146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232,
-	268, -17, -53, -89, -125, -160, -196, -232, -268, 19,
-	58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137,
-	-176, -215, -255, -294, 21, 64, 108, 151, 194, 237,
-	281, 324, -21, -64, -108, -151, -194, -237, -281, -324,
-	23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118,
-	-166, -213, -261, -308, -356, 26, 78, 130, 182, 235,
-	287, 339, 391, -26, -78, -130, -182, -235, -287, -339,
-	-391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86,
-	-143, -201, -258, -316, -373, -431, 31, 94, 158, 221,
-	284, 347, 411, 474, -31, -94, -158, -221, -284, -347,
-	-411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34,
-	-104, -174, -244, -313, -383, -453, -523, 38, 115, 191,
-	268, 345, 422, 498, 575, -38, -115, -191, -268, -345,
-	-422, -498, -575, 42, 126, 210, 294, 379, 463, 547,
-	631, -42, -126, -210, -294, -379, -463, -547, -631,
-	46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231,
-	-324, -417, -510, -602, -695, 51, 153, 255, 357, 459,
-	561, 663, 765, -51, -153, -255, -357, -459, -561, -663,
-	-765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168,
-	-280, -392, -505, -617, -729, -841, 61, 185, 308, 432,
-	555, 679, 802, 926, -61, -185, -308, -432, -555, -679,
-	-802, -926, 68, 204, 340, 476, 612, 748, 884, 1020,
-	-68, -204, -340, -476, -612, -748, -884, -1020, 74,
-	224, 373, 523, 672, 822, 971, 1121, -74, -224, -373,
-	-523, -672, -822, -971, -1121, 82, 246, 411, 575, 740,
-	904, 1069, 1233, -82, -246, -411, -575, -740, -904,
-	-1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357,
-	-90, -271, -452, -633, -814, -995, -1176, -1357, 99,
-	298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497,
-	-696, -895, -1094, -1293, -1492, 109, 328, 547, 766,
-	985, 1204, 1423, 1642, -109, -328, -547, -766, -985,
-	-1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324,
-	1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564,
-	-1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132,
-	-397, -662, -927, -1192, -1457, -1722, -1987, 145, 437,
-	728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728,
-	-1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121,
-	1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442,
-	-1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940,
-	2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292,
-	-2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910,
-	-194, -582, -970, -1358, -1746, -2134, -2522, -2910,
-	213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213,
-	-640, -1066, -1493, -1920, -2347, -2773, -3200, 234,
-	704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704,
-	-1173, -1643, -2112, -2582, -3051, -3521, 258, 774,
-	1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291,
-	-1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988,
-	2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556,
-	-3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436,
-	4060, 4685, -312, -937, -1561, -2186, -2811, -3436,
-	-4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467,
-	5154, -343, -1030, -1718, -2405, -3092, -3779, -4467,
-	-5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670,
-	-378, -1134, -1890, -2646, -3402, -4158, -4914, -5670,
-	415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415,
-	-1247, -2079, -2911, -3742, -4574, -5406, -6238, 457,
-	1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372,
-	-2287, -3202, -4117, -5032, -5947, -6862, 503, 1509,
-	2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516,
-	-3522, -4529, -5535, -6542, -7548, 553, 1660, 2767,
-	3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874,
-	-4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479,
-	6697, 7915, 9133, -608, -1826, -3044, -4262, -5479,
-	-6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367,
-	8706, 10046, -669, -2009, -3348, -4688, -6027, -7367,
-	-8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577,
-	11051, -736, -2210, -3683, -5157, -6630, -8104, -9577,
-	-11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157,
-	-810, -2431, -4052, -5673, -7294, -8915, -10536, -12157,
-	891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891,
-	-2674, -4457, -6240, -8023, -9806, -11589, -13372, 980,
-	2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941,
-	-4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236,
-	5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236,
-	-5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559,
-	5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559,
-	-5933, -8306, -10679, -13052, -15426, -17799, 1305,
-	3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305,
-	-3915, -6526, -9136, -11747, -14357, -16968, -19578,
-	1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538,
-	-1435, -4307, -7179, -10051, -12922, -15794, -18666,
-	-21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531,
-	23690, -1579, -4738, -7896, -11055, -14214, -17373,
-	-20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111,
-	22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111,
-	-22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022,
-	24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022,
-	-24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124,
-	27329, 31533, -2102, -6306, -10511, -14715, -18920,
-	-23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812,
-	25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812,
-	-25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893,
-	27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893,
-	-27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183,
-	30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183,
-	-30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700,
-	32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700,
-	-32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471,
-	32767, 32767, 32767, -3385, -10157, -16928, -23700,
-	-30471, -32767, -32767, -32767, 3724, 11172, 18621,
-	26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621,
-	-26069, -32767, -32767, -32767, -32767, 4095, 12287,
-	20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287,
-	-20479, -28671, -32767, -32767, -32767, -32767
-};
-
-static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4,  2, 4,  3, 4,  0 };
-static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 };
-
-static void soundFilter(byte *data, int16 *buffer, int p1, int p2);
-
-void SoundManager::applyFilter(SoundEntry *entry, int16 *buffer) {
-	if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
-    entry->_status.status |= 0x20000000;
-  } else {
-	  int variant = entry->_status.status & 0x1f;
-
-	  soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
-  }
-}
-
-
-static void soundFilter(byte *data, int16 *buffer, int p1, int p2) {
-	int data1, data2, data1p, data2p;
-	byte idx;
-
-	data2 = data[0];
-	data1 = data[1] << 6;
-
-	data += 2;
-
-	for (int count = 0; count < 735; count++) {
-		idx = data[count] >> 4;
-		data1p = filterData[idx + data1];
-		data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767);
-
-		buffer[2 * count] = (p2 * data2p) >> p1;
-
-		idx = data[count] & 0xF;
-
-		data1 = filterData[idx + data1p];
-		data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767);
-		buffer[2 * count + 1] = (p2 * data2) >> p1;
-	}
-}
-
-
 } // End of namespace LastExpress
diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h
index 414fb0d..797e526 100644
--- a/engines/lastexpress/game/sound.h
+++ b/engines/lastexpress/game/sound.h
@@ -25,55 +25,18 @@
 
 #include "lastexpress/shared.h"
 
-#include "lastexpress/helpers.h"
-
-#include "common/list.h"
-#include "common/mutex.h"
-#include "common/system.h"
-#include "common/serializer.h"
+#include "common/str.h"
 
 namespace LastExpress {
 
 class LastExpressEngine;
-class SubtitleManager;
-class SoundEntry;
-class SubtitleEntry;
+class SoundQueue;
 
-class SoundManager : Common::Serializable {
+class SoundManager {
 public:
 	SoundManager(LastExpressEngine *engine);
 	~SoundManager();
 
-	// Timer
-	void handleTimer();
-
-	// State
-	void resetState() { _state |= kSoundType1; }
-
-	// Sound queue
-	void updateQueue();
-	void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone);
-	void clearQueue();
-
-	// Subtitles
-	void updateSubtitles();
-
-	// Entry
-	bool isBuffered(Common::String filename, bool testForEntity = false);
-	bool isBuffered(EntityIndex entity);
-	void setupEntry(SoundType type, EntityIndex index);
-	void processEntry(EntityIndex entity);
-	void processEntry(SoundType type);
-	void processEntry(Common::String filename);
-	void processEntries();
-	void removeFromQueue(Common::String filename);
-	void removeFromQueue(EntityIndex entity);
-	uint32 getEntryTime(EntityIndex index);
-
-	// Misc
-	void unknownFunction4();
-	void clearStatus();
-
 	// Sound playing
 	void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0);
 	bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0);
@@ -83,7 +46,6 @@ public:
 	void playFightSound(byte action, byte a4);
 	void playLocomotiveSound();
 	void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
-
 	void playLoopingSound(int param);
 
 	// Dialog & Letters
@@ -97,64 +59,16 @@ public:
 	const char *wrongDoorCath() const;
 	const char *justAMinuteCath() const;
 
-	// FLags
+	// Flags
 	SoundFlag getSoundFlag(EntityIndex index) const;
 
-	// Debug
-	void stopAllSound();
-
-	// Serializable
-	void saveLoadWithSerializer(Common::Serializer &ser);
-	uint32 count();
-
 	// Accessors
-	uint32 getFlag() { return _flag; }
-	int getSubtitleFlag() { return _subtitlesFlag; }
-	void setSubtitleFlag(int flag) { _subtitlesFlag = flag; }
-	SoundType getCurrentType() { return _currentType; }
-	void setCurrentType(SoundType type) { _currentType = type; }
+	SoundQueue *getQueue() { return _queue; }
 	uint32 getData2() { return _data2; }
 
-	// Subtitles
-	void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); }
-	void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); }
-	void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
-	SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
-
-	// Queue
-	bool setupCache(SoundEntry *entry);
-	void addToQueue(SoundEntry *entry) { _soundList.push_back(entry); }
-
-	SoundEntry *getEntry(SoundType type);
-
 private:
-	typedef int32 *SoundBuffer;
-
-	enum SoundState {
-		kSoundState0 = 0,
-		kSoundState1 = 1,
-		kSoundState2 = 2
-	};
-
-	// Engine
 	LastExpressEngine *_engine;
-
-	// State flag
-	int _state;
-	SoundType _currentType;
-
-	Common::Mutex _mutex;
-
-	// Unknown data
-	uint32 _data0;
-	uint32 _data1;
-	uint32 _data2;
-
-	// TODO: this seems to be a synchronization flag for the sound timer
-	uint32 _flag;
-
-	// Filters
-	int32 _buffer[2940];    ///< Static sound buffer
+	SoundQueue *_queue;
 
 	// Compartment warnings by Mertens or Coudert
 	uint32 _lastWarning[12];
@@ -162,23 +76,10 @@ private:
 	// Looping sound
 	int _loopingSoundDuration;
 
-	// Sound entries
-	Common::List<SoundEntry *> _soundList;    ///< List of all sound entries
-	Common::List<SoundEntry *> _soundCache;   ///< List of entries with a data buffer
-	void *_soundCacheData;
-
-	SoundEntry *getEntry(EntityIndex index);
-	SoundEntry *getEntry(Common::String name);
-
-	void removeFromCache(SoundEntry *entry);
-
-	// Subtitles
-	int _subtitlesFlag;
-	Common::List<SubtitleEntry *> _subtitles;
-	SubtitleEntry *_currentSubtitle;
-
-	// Sound filter
-	void applyFilter(SoundEntry *entry, int16 *buffer);
+	// Unknown data
+	uint32 _data0;
+	uint32 _data1;
+	uint32 _data2;
 };
 
 } // End of namespace LastExpress
diff --git a/engines/lastexpress/helpers.h b/engines/lastexpress/helpers.h
index 594c8b0..7f3f1e2 100644
--- a/engines/lastexpress/helpers.h
+++ b/engines/lastexpress/helpers.h
@@ -63,6 +63,7 @@
 
 // Sound
 #define getSound() _engine->getSoundManager()
+#define getSoundQueue() _engine->getSoundManager()->getQueue()
 
 // Others
 #define getEntityData(entity) getEntities()->getData(entity)
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 73893c9..2829f60 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -32,6 +32,8 @@
 
 #include "lastexpress/menu/menu.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/resource.h"
@@ -151,8 +153,8 @@ Common::Error LastExpressEngine::run() {
 	_menu->show(false, kSavegameTypeIndex, 0);
 
 	while (!shouldQuit()) {
-		_soundMan->updateQueue();
-		_soundMan->updateSubtitles();
+		_soundMan->getQueue()->updateQueue();
+		_soundMan->getQueue()->updateSubtitles();
 
 		if (handleEvents())
 			continue;
@@ -280,7 +282,7 @@ void LastExpressEngine::soundTimer(void *refCon) {
 void LastExpressEngine::handleSoundTimer() {
 	if (_frameCounter & 1)
 		if (_soundMan)
-			_soundMan->handleTimer();
+			_soundMan->getQueue()->handleTimer();
 
 	_frameCounter++;
 }
diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp
index 74a2c77..288e53f 100644
--- a/engines/lastexpress/menu/menu.cpp
+++ b/engines/lastexpress/menu/menu.cpp
@@ -41,6 +41,8 @@
 #include "lastexpress/menu/clock.h"
 #include "lastexpress/menu/trainline.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -336,7 +338,7 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
 					if (getFlags()->mouseRightClick)
 						break;
 
-					getSound()->updateQueue();
+					getSoundQueue()->updateQueue();
 				}
 			}
 		}
@@ -348,10 +350,10 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
 	init(doSavegame, type, value);
 
 	// Setup sound
-	getSound()->unknownFunction4();
-	getSound()->resetQueue(kSoundType11, kSoundType13);
-	if (getSound()->isBuffered("TIMER"))
-		getSound()->removeFromQueue("TIMER");
+	getSoundQueue()->resetQueue();
+	getSoundQueue()->resetQueue(kSoundType11, kSoundType13);
+	if (getSoundQueue()->isBuffered("TIMER"))
+		getSoundQueue()->removeFromQueue("TIMER");
 
 	// Init flags & misc
 	_isShowingCredits = false;
@@ -411,13 +413,13 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 		if (clicked) {
 			showFrame(kOverlayButtons, kButtonQuitPushed, true);
 
-			getSound()->clearStatus();
-			getSound()->updateQueue();
+			getSoundQueue()->clearStatus();
+			getSoundQueue()->updateQueue();
 			getSound()->playSound(kEntityPlayer, "LIB046");
 
 			// FIXME uncomment when sound queue is properly implemented
-			/*while (getSound()->isBuffered("LIB046"))
-				getSound()->updateQueue();*/
+			/*while (getSoundQueue()->isBuffered("LIB046"))
+				getSoundQueue()->updateQueue();*/
 
 			getFlags()->shouldRedraw = false;
 
@@ -484,7 +486,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 		setLogicEventHandlers();
 
 		if (_index) {
-			getSound()->processEntry(kSoundType11);
+			getSoundQueue()->processEntry(kSoundType11);
 		} else {
 			if (!getFlags()->mouseRightClick) {
 				getScenes()->loadScene((SceneIndex)(5 * _gameId + 3));
@@ -496,7 +498,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 						getScenes()->loadScene((SceneIndex)(5 * _gameId + 5));
 
 						if (!getFlags()->mouseRightClick) {
-							getSound()->processEntry(kSoundType11);
+							getSoundQueue()->processEntry(kSoundType11);
 
 							// Show intro
 							Animation animation;
@@ -512,7 +514,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 			if (!getEvent(kEventIntro))	{
 				getEvent(kEventIntro) = 1;
 
-				getSound()->processEntry(kSoundType11);
+				getSoundQueue()->processEntry(kSoundType11);
 			}
 		}
 
@@ -707,7 +709,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 			while (nextFrameCount > getFrameCount()) {
 				_engine->pollEvents();
 
-				getSound()->updateQueue();
+				getSoundQueue()->updateQueue();
 			}
 		} else {
 			showFrame(kOverlayButtons, kButtonVolumeDown, true);
@@ -742,7 +744,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
 			while (nextFrameCount > getFrameCount()) {
 				_engine->pollEvents();
 
-				getSound()->updateQueue();
+				getSoundQueue()->updateQueue();
 			}
 		} else {
 			showFrame(kOverlayButtons, kButtonVolumeUp, true);
@@ -1117,8 +1119,8 @@ void Menu::updateTime(uint32 time) {
 	_currentTime = time;
 
 	if (_time != time) {
-		if (getSound()->isBuffered(kEntityChapters))
-			getSound()->removeFromQueue(kEntityChapters);
+		if (getSoundQueue()->isBuffered(kEntityChapters))
+			getSoundQueue()->removeFromQueue(kEntityChapters);
 
 		getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", kFlagMenuClock, kEntityChapters);
 		adjustIndex(_currentTime, _time, false);
@@ -1249,8 +1251,8 @@ void Menu::adjustTime() {
 			_time = _currentTime;
 	}
 
-	if (_currentTime == _time && getSound()->isBuffered(kEntityChapters))
-		getSound()->removeFromQueue(kEntityChapters);
+	if (_currentTime == _time && getSoundQueue()->isBuffered(kEntityChapters))
+		getSoundQueue()->removeFromQueue(kEntityChapters);
 
 	_clock->draw(_time);
 	_trainLine->draw(_time);
diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk
index eff68ef..355ecba 100644
--- a/engines/lastexpress/module.mk
+++ b/engines/lastexpress/module.mk
@@ -67,6 +67,7 @@ MODULE_OBJS := \
 	menu/menu.o \
 	menu/trainline.o \
 	sound/entry.o \
+	sound/queue.o \
 	debug.o \
 	detection.o \
 	graphics.o \
diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h
index d1730ee..69816a3 100644
--- a/engines/lastexpress/shared.h
+++ b/engines/lastexpress/shared.h
@@ -83,6 +83,12 @@ enum SoundFlag {
 	kFlagType9       = 0x7000000
 };
 
+enum SoundState {
+	kSoundState0 = 0,
+	kSoundState1 = 1,
+	kSoundState2 = 2
+};
+
 //////////////////////////////////////////////////////////////////////////
 // Time values
 //////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 304d524..8174161 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -27,6 +27,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -70,6 +72,7 @@ SoundEntry::~SoundEntry() {
 
 	delete _soundStream;
 
+	// Zero passed pointers
 	_engine = NULL;
 }
 
@@ -79,10 +82,10 @@ void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
 	setStatus(flag);
 
 	// Add entry to sound list
-	getSound()->addToQueue(this);
+	getSoundQueue()->addToQueue(this);
 
 	// Add entry to cache and load sound data
-	getSound()->setupCache(this);
+	getSoundQueue()->setupCache(this);
 	loadSoundData(name);
 }
 
@@ -90,7 +93,7 @@ void SoundEntry::close() {
 	_status.status |= kSoundStatusRemoved;
 
 	// Loop until ready
-	while (!(_status.status1 & 4) && !(getSound()->getFlag() & 8) && (getSound()->getFlag() & 1))
+	while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
 		;	// empty loop body
 
 	// The original game remove the entry from the cache here,
@@ -115,16 +118,16 @@ void SoundEntry::setType(SoundFlag flag) {
 	switch (flag & kFlagType9) {
 	default:
 	case kFlagNone:
-		_type = getSound()->getCurrentType();
-		getSound()->setCurrentType((SoundType)(_type + 1));
+		_type = getSoundQueue()->getCurrentType();
+		getSoundQueue()->setCurrentType((SoundType)(_type + 1));
 		break;
 
 	case kFlagType1_2: {
-		SoundEntry *previous2 = getSound()->getEntry(kSoundType2);
+		SoundEntry *previous2 = getSoundQueue()->getEntry(kSoundType2);
 		if (previous2)
 			previous2->update(0);
 
-		SoundEntry *previous = getSound()->getEntry(kSoundType1);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType1);
 		if (previous) {
 			previous->setType(kSoundType2);
 			previous->update(0);
@@ -135,7 +138,7 @@ void SoundEntry::setType(SoundFlag flag) {
 		break;
 
 	case kFlagType3: {
-		SoundEntry *previous = getSound()->getEntry(kSoundType3);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType3);
 		if (previous) {
 			previous->setType(kSoundType4);
 			previous->update(0);
@@ -146,7 +149,7 @@ void SoundEntry::setType(SoundFlag flag) {
 		break;
 
 	case kFlagType7: {
-		SoundEntry *previous = getSound()->getEntry(kSoundType7);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType7);
 		if (previous)
 			previous->setType(kSoundType8);
 
@@ -155,7 +158,7 @@ void SoundEntry::setType(SoundFlag flag) {
 		break;
 
 	case kFlagType9: {
-		SoundEntry *previous = getSound()->getEntry(kSoundType9);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType9);
 		if (previous)
 			previous->setType(kSoundType10);
 
@@ -164,7 +167,7 @@ void SoundEntry::setType(SoundFlag flag) {
 		break;
 
 	case kFlagType11: {
-		SoundEntry *previous = getSound()->getEntry(kSoundType11);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType11);
 		if (previous)
 			previous->setType(kSoundType14);
 
@@ -173,7 +176,7 @@ void SoundEntry::setType(SoundFlag flag) {
 		break;
 
 	case kFlagType13: {
-		SoundEntry *previous = getSound()->getEntry(kSoundType13);
+		SoundEntry *previous = getSoundQueue()->getEntry(kSoundType13);
 		if (previous)
 			previous->setType(kSoundType14);
 
@@ -221,7 +224,7 @@ void SoundEntry::update(uint val) {
 		_status.status |= kSoundStatus_100000;
 
 		if (val) {
-			if (getSound()->getFlag() & 32) {
+			if (getSoundQueue()->getFlag() & 32) {
 				_field_40 = val;
 				value2 = val * 2 + 1;
 			}
@@ -235,7 +238,7 @@ void SoundEntry::update(uint val) {
 }
 
 void SoundEntry::updateState() {
-	if (getSound()->getFlag() & 32) {
+	if (getSoundQueue()->getFlag() & 32) {
 		if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
 			uint32 newStatus = _status.status & kSoundStatusClear1;
 
@@ -318,7 +321,7 @@ SubtitleEntry::~SubtitleEntry() {
 
 void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) {
 	// Add ourselves to the list of active subtitles
-	getSound()->addSubtitle(this);
+	getSoundQueue()->addSubtitle(this);
 
 	// Set sound entry and filename
 	_filename = filename + ".SBE";
@@ -326,7 +329,7 @@ void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) {
 
 	// Load subtitle data
 	if (_engine->getResourceManager()->hasFile(filename)) {
-		if (getSound()->getSubtitleFlag() & 2)
+		if (getSoundQueue()->getSubtitleFlag() & 2)
 			return;
 
 		loadData();
@@ -339,8 +342,8 @@ void SubtitleEntry::loadData() {
 	_data = new SubtitleManager(_engine->getFont());
 	_data->load(getArchive(_filename));
 
-	getSound()->setSubtitleFlag(getSound()->getSubtitleFlag() | 2);
-	getSound()->setCurrentSubtitle(this);
+	getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() | 2);
+	getSoundQueue()->setCurrentSubtitle(this);
 }
 
 void SubtitleEntry::setupAndDraw() {
@@ -354,32 +357,32 @@ void SubtitleEntry::setupAndDraw() {
 	} else {
 		_data->setTime((uint16)_sound->_time);
 
-		if (getSound()->getSubtitleFlag() & 1)
+		if (getSoundQueue()->getSubtitleFlag() & 1)
 			drawOnScreen();
 	}
 
-	getSound()->setCurrentSubtitle(this);
+	getSoundQueue()->setCurrentSubtitle(this);
 }
 
 void SubtitleEntry::draw() {
 	// Remove ourselves from the queue
-	getSound()->removeSubtitle(this);
+	getSoundQueue()->removeSubtitle(this);
 
-	if (this == getSound()->getCurrentSubtitle()) {
+	if (this == getSoundQueue()->getCurrentSubtitle()) {
 		drawOnScreen();
 
-		getSound()->setCurrentSubtitle(NULL);
-		getSound()->setSubtitleFlag(0);
+		getSoundQueue()->setCurrentSubtitle(NULL);
+		getSoundQueue()->setSubtitleFlag(0);
 	}
 }
 
 void SubtitleEntry::drawOnScreen() {
-	getSound()->setSubtitleFlag(getSound()->getSubtitleFlag() & -1);
+	getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() & -1);
 
 	if (_data == NULL)
 		return;
 
-	if (getSound()->getSubtitleFlag() & 1)
+	if (getSoundQueue()->getSubtitleFlag() & 1)
 		_engine->getGraphicsManager()->draw(_data, GraphicsManager::kBackgroundOverlay);
 }
 
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
new file mode 100644
index 0000000..9126f57
--- /dev/null
+++ b/engines/lastexpress/sound/queue.cpp
@@ -0,0 +1,795 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/sound/queue.h"
+
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/sound/entry.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+
+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;
+}
+
+SoundQueue::~SoundQueue() {
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+		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;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Timer
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::handleTimer() {
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		SoundEntry *entry = (*i);
+		if (entry->_stream == NULL) {
+			SAFE_DELETE(*i);
+			i = _soundList.reverse_erase(i);
+			continue;
+		} else if (!entry->_soundStream) {
+			entry->_soundStream = new StreamedSound();
+
+			// TODO: stream any sound in the queue after filtering
+			entry->_soundStream->load(entry->_stream);
+		}
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound queue management
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::addToQueue(SoundEntry *entry) {
+	_soundList.push_back(entry);
+}
+
+void SoundQueue::removeFromQueue(EntityIndex entity) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(entity);
+	if (entry)
+		entry->reset();
+}
+
+void SoundQueue::removeFromQueue(Common::String filename) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(filename);
+	if (entry)
+		entry->reset();
+}
+
+void SoundQueue::updateQueue() {
+	Common::StackLock locker(_mutex);
+
+	warning("Sound::updateQueue: not implemented!");
+}
+
+void SoundQueue::resetQueue() {
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->getType() == kSoundType1) {
+			(*i)->reset();
+			break;
+		}
+	}
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->getType() == kSoundType2) {
+			(*i)->reset();
+			break;
+		}
+	}
+}
+
+void SoundQueue::resetQueue(SoundType type1, SoundType type2) {
+	if (!type2)
+		type2 = type1;
+
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->getType() != type1 && (*i)->getType() != type2)
+			(*i)->reset();
+	}
+}
+
+void SoundQueue::clearQueue() {
+	_flag |= 4;
+
+	// FIXME: Wait a while for a flag to be set
+	//for (int i = 0; i < 3000000; i++)
+	//	if (_flag & 8)
+	//		break;
+
+	_flag |= 8;
+
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		SoundEntry *entry = (*i);
+
+		// Delete entry
+		entry->close();
+		SAFE_DELETE(entry);
+
+		i = _soundList.reverse_erase(i);
+	}
+
+	updateSubtitles();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// State
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::clearStatus() {
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+		(*i)->_status.status |= kSoundStatusClear3;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Entry management
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::setupEntry(SoundType type, EntityIndex index) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(type);
+	if (entry)
+		entry->setEntity(index);
+}
+
+void SoundQueue::processEntry(EntityIndex entity) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(entity);
+	if (entry) {
+		entry->update(0);
+		entry->setEntity(kEntityPlayer);
+	}
+}
+
+void SoundQueue::processEntry(SoundType type) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(type);
+	if (entry)
+		entry->update(0);
+}
+
+void SoundQueue::processEntry(Common::String filename) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(filename);
+	if (entry) {
+		entry->update(0);
+		entry->setEntity(kEntityPlayer);
+	}
+}
+
+void SoundQueue::processEntries() {
+	_state = 0;
+
+	processEntry(kSoundType1);
+	processEntry(kSoundType2);
+}
+
+SoundEntry *SoundQueue::getEntry(EntityIndex index) {
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->getEntity() == index)
+			return *i;
+	}
+
+	return NULL;
+}
+
+SoundEntry *SoundQueue::getEntry(Common::String name) {
+	if (!name.contains('.'))
+		name += ".SND";
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->_name2 == name)
+			return *i;
+	}
+
+	return NULL;
+}
+
+SoundEntry *SoundQueue::getEntry(SoundType type) {
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
+		if ((*i)->getType() == type)
+			return *i;
+	}
+
+	return NULL;
+}
+
+uint32 SoundQueue::getEntryTime(EntityIndex index) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(index);
+	if (entry)
+		return entry->_time;
+
+	return 0;
+}
+
+bool SoundQueue::isBuffered(EntityIndex entity) {
+	Common::StackLock locker(_mutex);
+
+	return (getEntry(entity) != NULL);
+}
+
+bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) {
+	Common::StackLock locker(_mutex);
+
+	SoundEntry *entry = getEntry(filename);
+
+	if (testForEntity)
+		return entry != NULL && entry->getEntity() != kEntityPlayer;
+
+	return (entry != NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Subtitles
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::updateSubtitles() {
+	Common::StackLock locker(_mutex);
+
+	uint32 index = 0;
+	SubtitleEntry *subtitle = NULL;
+
+	for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
+		uint32 current_index = 0;
+		SoundEntry *soundEntry = (*i)->getSoundEntry();
+		SoundStatus status = (SoundStatus)soundEntry->_status.status;
+
+		if (!(status & kSoundStatus_40)
+		 || status & kSoundStatus_180
+		 || soundEntry->_time == 0
+		 || (status & kSoundStatusClear1) < 6
+		 || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) {
+			 current_index = 0;
+		} else {
+			current_index = soundEntry->_priority + (status & kSoundStatusClear1);
+
+			if (_currentSubtitle == (*i))
+				current_index += 4;
+		}
+
+		if (index < current_index) {
+			index = current_index;
+			subtitle = (*i);
+		}
+	}
+
+	if (_currentSubtitle == subtitle) {
+		if (subtitle)
+			subtitle->setupAndDraw();
+
+		return;
+	}
+
+	if (_subtitlesFlag & 1)
+		subtitle->drawOnScreen();
+
+	if (subtitle) {
+		subtitle->loadData();
+		subtitle->setupAndDraw();
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 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)->_status.status & kSoundStatus_180)) {
+				uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1);
+
+				if (newSize < size) {
+					cacheEntry = (*i);
+					size = newSize;
+				}
+			}
+		}
+
+		if (entry->_priority <= 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->_status.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
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
+	Common::StackLock locker(_mutex);
+
+	s.syncAsUint32LE(_state);
+	s.syncAsUint32LE(_currentType);
+
+	// Compute the number of entries to save
+	uint32 numEntries = count();
+	s.syncAsUint32LE(numEntries);
+
+	// Save or load each entry data
+	if (s.isSaving()) {
+		for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+			(*i)->saveLoadWithSerializer(s);
+	} else {
+		warning("Sound::saveLoadWithSerializer: loading not implemented");
+		s.skip(numEntries * 64);
+	}
+}
+
+
+// FIXME: We probably need another mutex here to protect during the whole savegame process
+// as we could have removed an entry between the time we check the count and the time we
+// save the entries
+uint32 SoundQueue::count() {
+	Common::StackLock locker(_mutex);
+
+	uint32 numEntries = 0;
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+		if ((*i)->_name2.matchString("NISSND?"))
+			++numEntries;
+
+	return numEntries;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound filters
+//////////////////////////////////////////////////////////////////////////
+static const int filterData[1424] = {
+	0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256,
+	384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0,
+	192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640,
+	64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128,
+	320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576,
+	704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192,
+	192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448,
+	576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832,
+	320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320,
+	320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704,
+	832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448,
+	448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448,
+	640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960,
+	1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576,
+	576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576,
+	576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832,
+	960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088,
+	1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704,
+	704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768,
+	768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960,
+	1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280,
+	1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896,
+	896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896,
+	896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152,
+	1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408,
+	1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600,
+	1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088,
+	1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088,
+	1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152,
+	1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152,
+	1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408,
+	1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536,
+	1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728,
+	1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856,
+	1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344,
+	1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408,
+	1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408,
+	1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472,
+	1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664,
+	1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856,
+	1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984,
+	2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176,
+	1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664,
+	1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664,
+	1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728,
+	1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728,
+	1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984,
+	2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112,
+	2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304,
+	2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432,
+	1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920,
+	1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984,
+	1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984,
+	1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048,
+	2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240,
+	2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432,
+	2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560,
+	2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752,
+	2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240,
+	2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240,
+	2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304,
+	2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304,
+	2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560,
+	2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688,
+	2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880,
+	3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008,
+	2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496,
+	2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560,
+	2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560,
+	2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624,
+	2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816,
+	2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008,
+	3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136,
+	3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328,
+	2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816,
+	2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816,
+	2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880,
+	2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880,
+	3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136,
+	3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264,
+	3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456,
+	3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584,
+	3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072,
+	3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136,
+	3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136,
+	3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200,
+	3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392,
+	3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584,
+	3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712,
+	3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904,
+	3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392,
+	3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392,
+	3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456,
+	3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456,
+	3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712,
+	3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840,
+	3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032,
+	4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160,
+	3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648,
+	3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712,
+	3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712,
+	3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776,
+	3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968,
+	4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160,
+	4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288,
+	4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480,
+	3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968,
+	3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968,
+	3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032,
+	4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032,
+	4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288,
+	4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416,
+	4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608,
+	4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736,
+	4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224,
+	4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288,
+	4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288,
+	4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352,
+	4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544,
+	4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736,
+	4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864,
+	4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056,
+	4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544,
+	4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544,
+	4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608,
+	4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608,
+	4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864,
+	4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992,
+	5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184,
+	5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312,
+	4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800,
+	4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864,
+	4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864,
+	4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928,
+	5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120,
+	5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312,
+	5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440,
+	5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632,
+	5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120,
+	5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120,
+	5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184,
+	5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184,
+	5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440,
+	5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568,
+	5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632,
+	5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632,
+	5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376,
+	5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440,
+	5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440,
+	5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504,
+	5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632,
+	5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632,
+	5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632,
+	5632
+};
+
+static const int filterData2[1424] = {
+	0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11,
+	-13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9,
+	-11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5,
+	-7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18,
+	-1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12,
+	15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4,
+	7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19,
+	-22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14,
+	-17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5,
+	-8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26,
+	30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10,
+	14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27,
+	-31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16,
+	-21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2,
+	-7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25,
+	31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3,
+	9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34,
+	-40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17,
+	-24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50,
+	58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21,
+	29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55,
+	-63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32,
+	-41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5,
+	-15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50,
+	61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6,
+	18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56,
+	-68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20,
+	-34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82,
+	97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8,
+	24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74,
+	-90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9,
+	-27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70,
+	90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130,
+	-150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55,
+	-77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133,
+	157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
+	13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93,
+	-120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191,
+	221, -14, -44, -73, -103, -132, -162, -191, -221, 16,
+	48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113,
+	-146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232,
+	268, -17, -53, -89, -125, -160, -196, -232, -268, 19,
+	58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137,
+	-176, -215, -255, -294, 21, 64, 108, 151, 194, 237,
+	281, 324, -21, -64, -108, -151, -194, -237, -281, -324,
+	23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118,
+	-166, -213, -261, -308, -356, 26, 78, 130, 182, 235,
+	287, 339, 391, -26, -78, -130, -182, -235, -287, -339,
+	-391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86,
+	-143, -201, -258, -316, -373, -431, 31, 94, 158, 221,
+	284, 347, 411, 474, -31, -94, -158, -221, -284, -347,
+	-411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34,
+	-104, -174, -244, -313, -383, -453, -523, 38, 115, 191,
+	268, 345, 422, 498, 575, -38, -115, -191, -268, -345,
+	-422, -498, -575, 42, 126, 210, 294, 379, 463, 547,
+	631, -42, -126, -210, -294, -379, -463, -547, -631,
+	46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231,
+	-324, -417, -510, -602, -695, 51, 153, 255, 357, 459,
+	561, 663, 765, -51, -153, -255, -357, -459, -561, -663,
+	-765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168,
+	-280, -392, -505, -617, -729, -841, 61, 185, 308, 432,
+	555, 679, 802, 926, -61, -185, -308, -432, -555, -679,
+	-802, -926, 68, 204, 340, 476, 612, 748, 884, 1020,
+	-68, -204, -340, -476, -612, -748, -884, -1020, 74,
+	224, 373, 523, 672, 822, 971, 1121, -74, -224, -373,
+	-523, -672, -822, -971, -1121, 82, 246, 411, 575, 740,
+	904, 1069, 1233, -82, -246, -411, -575, -740, -904,
+	-1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357,
+	-90, -271, -452, -633, -814, -995, -1176, -1357, 99,
+	298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497,
+	-696, -895, -1094, -1293, -1492, 109, 328, 547, 766,
+	985, 1204, 1423, 1642, -109, -328, -547, -766, -985,
+	-1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324,
+	1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564,
+	-1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132,
+	-397, -662, -927, -1192, -1457, -1722, -1987, 145, 437,
+	728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728,
+	-1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121,
+	1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442,
+	-1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940,
+	2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292,
+	-2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910,
+	-194, -582, -970, -1358, -1746, -2134, -2522, -2910,
+	213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213,
+	-640, -1066, -1493, -1920, -2347, -2773, -3200, 234,
+	704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704,
+	-1173, -1643, -2112, -2582, -3051, -3521, 258, 774,
+	1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291,
+	-1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988,
+	2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556,
+	-3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436,
+	4060, 4685, -312, -937, -1561, -2186, -2811, -3436,
+	-4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467,
+	5154, -343, -1030, -1718, -2405, -3092, -3779, -4467,
+	-5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670,
+	-378, -1134, -1890, -2646, -3402, -4158, -4914, -5670,
+	415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415,
+	-1247, -2079, -2911, -3742, -4574, -5406, -6238, 457,
+	1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372,
+	-2287, -3202, -4117, -5032, -5947, -6862, 503, 1509,
+	2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516,
+	-3522, -4529, -5535, -6542, -7548, 553, 1660, 2767,
+	3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874,
+	-4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479,
+	6697, 7915, 9133, -608, -1826, -3044, -4262, -5479,
+	-6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367,
+	8706, 10046, -669, -2009, -3348, -4688, -6027, -7367,
+	-8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577,
+	11051, -736, -2210, -3683, -5157, -6630, -8104, -9577,
+	-11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157,
+	-810, -2431, -4052, -5673, -7294, -8915, -10536, -12157,
+	891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891,
+	-2674, -4457, -6240, -8023, -9806, -11589, -13372, 980,
+	2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941,
+	-4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236,
+	5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236,
+	-5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559,
+	5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559,
+	-5933, -8306, -10679, -13052, -15426, -17799, 1305,
+	3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305,
+	-3915, -6526, -9136, -11747, -14357, -16968, -19578,
+	1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538,
+	-1435, -4307, -7179, -10051, -12922, -15794, -18666,
+	-21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531,
+	23690, -1579, -4738, -7896, -11055, -14214, -17373,
+	-20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111,
+	22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111,
+	-22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022,
+	24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022,
+	-24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124,
+	27329, 31533, -2102, -6306, -10511, -14715, -18920,
+	-23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812,
+	25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812,
+	-25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893,
+	27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893,
+	-27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183,
+	30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183,
+	-30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700,
+	32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700,
+	-32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471,
+	32767, 32767, 32767, -3385, -10157, -16928, -23700,
+	-30471, -32767, -32767, -32767, 3724, 11172, 18621,
+	26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621,
+	-26069, -32767, -32767, -32767, -32767, 4095, 12287,
+	20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287,
+	-20479, -28671, -32767, -32767, -32767, -32767
+};
+
+static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4,  2, 4,  3, 4,  0 };
+static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 };
+
+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) {
+		entry->_status.status |= 0x20000000;
+	} else {
+		int variant = entry->_status.status & 0x1f;
+
+		soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
+	}
+}
+
+
+static void soundFilter(byte *data, int16 *buffer, int p1, int p2) {
+	int data1, data2, data1p, data2p;
+	byte idx;
+
+	data2 = data[0];
+	data1 = data[1] << 6;
+
+	data += 2;
+
+	for (int count = 0; count < 735; count++) {
+		idx = data[count] >> 4;
+		data1p = filterData[idx + data1];
+		data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767);
+
+		buffer[2 * count] = (p2 * data2p) >> p1;
+
+		idx = data[count] & 0xF;
+
+		data1 = filterData[idx + data1p];
+		data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767);
+		buffer[2 * count + 1] = (p2 * data2) >> p1;
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Debug
+//////////////////////////////////////////////////////////////////////////
+void SoundQueue::stopAllSound() {
+	Common::StackLock locker(_mutex);
+
+	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
+		(*i)->_soundStream->stop();
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/queue.h b/engines/lastexpress/sound/queue.h
new file mode 100644
index 0000000..3748a26
--- /dev/null
+++ b/engines/lastexpress/sound/queue.h
@@ -0,0 +1,131 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_SOUND_QUEUE_H
+#define LASTEXPRESS_SOUND_QUEUE_H
+
+#include "lastexpress/shared.h"
+
+#include "common/array.h"
+#include "common/mutex.h"
+#include "common/serializer.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SoundEntry;
+class SubtitleEntry;
+
+class SoundQueue : Common::Serializable {
+public:
+	SoundQueue(LastExpressEngine *engine);
+	~SoundQueue();
+
+	// Timer
+	void handleTimer();
+
+	// Queue
+	void addToQueue(SoundEntry *entry);
+	void removeFromQueue(Common::String filename);
+	void removeFromQueue(EntityIndex entity);
+	void updateQueue();
+	void resetQueue();
+	void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone);
+	void clearQueue();
+
+	// State
+	void clearStatus();
+	int getSoundState() { return _state; }
+	void resetState() { resetState(kSoundState1); }
+	void resetState(SoundState state) { _state |= state; }
+
+	// Entries
+	void setupEntry(SoundType type, EntityIndex index);
+	void processEntry(EntityIndex entity);
+	void processEntry(SoundType type);
+	void processEntry(Common::String filename);
+	void processEntries();
+	SoundEntry *getEntry(SoundType type);
+	SoundEntry *getEntry(EntityIndex index);
+	SoundEntry *getEntry(Common::String name);
+	uint32 getEntryTime(EntityIndex index);
+	bool isBuffered(Common::String filename, bool testForEntity = false);
+	bool isBuffered(EntityIndex entity);
+
+	// Subtitles
+	void updateSubtitles();
+	void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); }
+	void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); }
+	void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
+	SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
+
+	// Cache
+	bool setupCache(SoundEntry *entry);
+
+	// Serializable
+	void saveLoadWithSerializer(Common::Serializer &ser);
+	uint32 count();
+
+	// Accessors
+	uint32 getFlag() { return _flag; }
+	int getSubtitleFlag() { return _subtitlesFlag; }
+	void setSubtitleFlag(int flag) { _subtitlesFlag = flag; }
+	SoundType getCurrentType() { return _currentType; }
+	void setCurrentType(SoundType type) { _currentType = type; }
+
+protected:
+	// Debug
+	void stopAllSound();
+
+private:
+	LastExpressEngine *_engine;
+
+	Common::Mutex _mutex;
+
+	// State & shared data
+	int _state;
+	SoundType _currentType;
+	// TODO: this seems to be a synchronization flag for the sound timer
+	uint32 _flag;
+
+	// 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;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOUND_QUEUE_H


Commit: 90dc4f9a8c3f77b15c7c6d49651338dbc40c40fa
    https://github.com/scummvm/scummvm/commit/90dc4f9a8c3f77b15c7c6d49651338dbc40c40fa
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-28T19:30:24-07:00

Commit Message:
LASTEXPRESS: Move Sound class to the sound folder

Changed paths:
  A engines/lastexpress/sound/sound.cpp
  A engines/lastexpress/sound/sound.h
  R engines/lastexpress/game/sound.cpp
  R engines/lastexpress/game/sound.h
    engines/lastexpress/debug.cpp
    engines/lastexpress/entities/abbot.cpp
    engines/lastexpress/entities/alexei.cpp
    engines/lastexpress/entities/alouan.cpp
    engines/lastexpress/entities/anna.cpp
    engines/lastexpress/entities/august.cpp
    engines/lastexpress/entities/boutarel.cpp
    engines/lastexpress/entities/chapters.cpp
    engines/lastexpress/entities/cooks.cpp
    engines/lastexpress/entities/coudert.cpp
    engines/lastexpress/entities/entity.cpp
    engines/lastexpress/entities/entity.h
    engines/lastexpress/entities/gendarmes.h
    engines/lastexpress/entities/hadija.cpp
    engines/lastexpress/entities/ivo.cpp
    engines/lastexpress/entities/kahina.cpp
    engines/lastexpress/entities/kronos.cpp
    engines/lastexpress/entities/mahmud.cpp
    engines/lastexpress/entities/max.cpp
    engines/lastexpress/entities/mertens.cpp
    engines/lastexpress/entities/milos.cpp
    engines/lastexpress/entities/mmeboutarel.cpp
    engines/lastexpress/entities/pascale.cpp
    engines/lastexpress/entities/rebecca.cpp
    engines/lastexpress/entities/salko.cpp
    engines/lastexpress/entities/servers0.cpp
    engines/lastexpress/entities/servers1.cpp
    engines/lastexpress/entities/sophie.cpp
    engines/lastexpress/entities/tables.cpp
    engines/lastexpress/entities/tatiana.cpp
    engines/lastexpress/entities/train.cpp
    engines/lastexpress/entities/vassili.cpp
    engines/lastexpress/entities/verges.cpp
    engines/lastexpress/entities/vesna.cpp
    engines/lastexpress/entities/yasmin.cpp
    engines/lastexpress/fight/fighter.cpp
    engines/lastexpress/fight/fighter_anna.cpp
    engines/lastexpress/fight/fighter_ivo.cpp
    engines/lastexpress/fight/fighter_milos.cpp
    engines/lastexpress/fight/fighter_salko.cpp
    engines/lastexpress/fight/fighter_vesna.cpp
    engines/lastexpress/game/action.cpp
    engines/lastexpress/game/entities.cpp
    engines/lastexpress/game/inventory.cpp
    engines/lastexpress/game/logic.cpp
    engines/lastexpress/game/scenes.cpp
    engines/lastexpress/lastexpress.cpp
    engines/lastexpress/menu/menu.cpp
    engines/lastexpress/module.mk
    engines/lastexpress/sound/entry.cpp



diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index 2d22630..dc2807d 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -41,10 +41,10 @@
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 6fcadcf..c5c6f2a 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -31,10 +31,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index d723a56..073ca3f 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -29,9 +29,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
index 715622a..cd79870 100644
--- a/engines/lastexpress/entities/alouan.cpp
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -26,9 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index 2eb3a9e..b13aa21 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -31,10 +31,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index 44dd3eb..eb3b09a 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -33,10 +33,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
index cf5d286..315b12a 100644
--- a/engines/lastexpress/entities/boutarel.cpp
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -29,10 +29,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index 53d89e9..96e08ba 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -60,10 +60,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/menu/menu.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/sound/queue.h"
 
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
index cd8fbfd..42e888c 100644
--- a/engines/lastexpress/entities/cooks.cpp
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -26,10 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index fea08f4..c3e7e37 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -29,10 +29,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index f6d24d6..60efd70 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -33,9 +33,10 @@
 #include "lastexpress/game/state.h"
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 1988aef..6a4f416 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -25,7 +25,7 @@
 
 #include "lastexpress/shared.h"
 
-#include "lastexpress/game/sound.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/gendarmes.h b/engines/lastexpress/entities/gendarmes.h
index 5c3ff1d..d999cfc 100644
--- a/engines/lastexpress/entities/gendarmes.h
+++ b/engines/lastexpress/entities/gendarmes.h
@@ -26,7 +26,7 @@
 #include "lastexpress/entities/entity.h"
 #include "lastexpress/entities/entity_intern.h"
 
-#include "lastexpress/game/sound.h"
+#include "lastexpress/sound/sound.h"
 
 namespace LastExpress {
 
diff --git a/engines/lastexpress/entities/hadija.cpp b/engines/lastexpress/entities/hadija.cpp
index ce2c971..8ec972b 100644
--- a/engines/lastexpress/entities/hadija.cpp
+++ b/engines/lastexpress/entities/hadija.cpp
@@ -26,9 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/ivo.cpp b/engines/lastexpress/entities/ivo.cpp
index 861c3cf..f2261b4 100644
--- a/engines/lastexpress/entities/ivo.cpp
+++ b/engines/lastexpress/entities/ivo.cpp
@@ -30,9 +30,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index 6c73784..2918b1e 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -29,10 +29,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 06ebd54..134dce9 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -36,10 +36,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
index cb78285..0e67b45 100644
--- a/engines/lastexpress/entities/mahmud.cpp
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -31,10 +31,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
index 924f8f7..eacc38b 100644
--- a/engines/lastexpress/entities/max.cpp
+++ b/engines/lastexpress/entities/max.cpp
@@ -28,10 +28,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index 464cc34..e222af4 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -30,9 +30,9 @@
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 1526c28..ff3d2b6 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -33,10 +33,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
index 1d4c52c..9ca10ca 100644
--- a/engines/lastexpress/entities/mmeboutarel.cpp
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -28,10 +28,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
index 8bbcf64..a191273 100644
--- a/engines/lastexpress/entities/pascale.cpp
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -27,10 +27,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index 6d1c524..b1a176b 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -27,10 +27,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
index 6dcab71..63d995d 100644
--- a/engines/lastexpress/entities/salko.cpp
+++ b/engines/lastexpress/entities/salko.cpp
@@ -30,10 +30,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/servers0.cpp b/engines/lastexpress/entities/servers0.cpp
index 1fec775..989bddd 100644
--- a/engines/lastexpress/entities/servers0.cpp
+++ b/engines/lastexpress/entities/servers0.cpp
@@ -26,9 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/servers1.cpp b/engines/lastexpress/entities/servers1.cpp
index cd0a162..995fbbc 100644
--- a/engines/lastexpress/entities/servers1.cpp
+++ b/engines/lastexpress/entities/servers1.cpp
@@ -26,9 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/sophie.cpp b/engines/lastexpress/entities/sophie.cpp
index e0c63f7..57bd491 100644
--- a/engines/lastexpress/entities/sophie.cpp
+++ b/engines/lastexpress/entities/sophie.cpp
@@ -25,9 +25,10 @@
 #include "lastexpress/game/entities.h"
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 
diff --git a/engines/lastexpress/entities/tables.cpp b/engines/lastexpress/entities/tables.cpp
index 702b636..06ea4c5 100644
--- a/engines/lastexpress/entities/tables.cpp
+++ b/engines/lastexpress/entities/tables.cpp
@@ -26,10 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index 2f60b44..c8901b3 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -32,10 +32,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index 74eed63..7d90ea5 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -30,9 +30,9 @@
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index a7fbc7c..22f41af 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -32,10 +32,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index c18137c..8246f85 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -29,10 +29,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
index 74bc0d3..7a1f1d3 100644
--- a/engines/lastexpress/entities/vesna.cpp
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -30,9 +30,10 @@
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
index 7e8b2f7..45e5e11 100644
--- a/engines/lastexpress/entities/yasmin.cpp
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -26,9 +26,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/sound.h"
+
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
 
diff --git a/engines/lastexpress/fight/fighter.cpp b/engines/lastexpress/fight/fighter.cpp
index fcd6918..bae7728 100644
--- a/engines/lastexpress/fight/fighter.cpp
+++ b/engines/lastexpress/fight/fighter.cpp
@@ -25,7 +25,8 @@
 #include "lastexpress/data/sequence.h"
 
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
+
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/fight/fighter_anna.cpp b/engines/lastexpress/fight/fighter_anna.cpp
index feb3551..c7660ca 100644
--- a/engines/lastexpress/fight/fighter_anna.cpp
+++ b/engines/lastexpress/fight/fighter_anna.cpp
@@ -24,9 +24,8 @@
 
 #include "lastexpress/data/sequence.h"
 
-#include "lastexpress/game/sound.h"
-
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/fight/fighter_ivo.cpp b/engines/lastexpress/fight/fighter_ivo.cpp
index 9988fca..87a52c6 100644
--- a/engines/lastexpress/fight/fighter_ivo.cpp
+++ b/engines/lastexpress/fight/fighter_ivo.cpp
@@ -24,9 +24,8 @@
 
 #include "lastexpress/data/sequence.h"
 
-#include "lastexpress/game/sound.h"
-
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/fight/fighter_milos.cpp b/engines/lastexpress/fight/fighter_milos.cpp
index 82c965c..9f8e726 100644
--- a/engines/lastexpress/fight/fighter_milos.cpp
+++ b/engines/lastexpress/fight/fighter_milos.cpp
@@ -25,9 +25,8 @@
 #include "lastexpress/data/cursor.h"
 #include "lastexpress/data/sequence.h"
 
-#include "lastexpress/game/sound.h"
-
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/fight/fighter_salko.cpp b/engines/lastexpress/fight/fighter_salko.cpp
index 166f7c3..1082674 100644
--- a/engines/lastexpress/fight/fighter_salko.cpp
+++ b/engines/lastexpress/fight/fighter_salko.cpp
@@ -25,9 +25,8 @@
 #include "lastexpress/data/cursor.h"
 #include "lastexpress/data/sequence.h"
 
-#include "lastexpress/game/sound.h"
-
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/fight/fighter_vesna.cpp b/engines/lastexpress/fight/fighter_vesna.cpp
index 075f158..02aaa1c 100644
--- a/engines/lastexpress/fight/fighter_vesna.cpp
+++ b/engines/lastexpress/fight/fighter_vesna.cpp
@@ -25,9 +25,8 @@
 #include "lastexpress/data/cursor.h"
 #include "lastexpress/data/sequence.h"
 
-#include "lastexpress/game/sound.h"
-
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index f195825..2c7b5b3 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -39,10 +39,10 @@
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index 8dd2c26..a565318 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -68,10 +68,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index c3a1022..d902c88 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -28,12 +28,12 @@
 
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/menu/menu.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index cdde2a0..2b7b1cf 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -42,12 +42,12 @@
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/menu/menu.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index 408f480..65efc80 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -31,10 +31,10 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
deleted file mode 100644
index bc4f71e..0000000
--- a/engines/lastexpress/game/sound.cpp
+++ /dev/null
@@ -1,1379 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "lastexpress/game/sound.h"
-
-#include "lastexpress/game/action.h"
-#include "lastexpress/game/entities.h"
-#include "lastexpress/game/inventory.h"
-#include "lastexpress/game/logic.h"
-#include "lastexpress/game/object.h"
-#include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/state.h"
-
-#include "lastexpress/sound/entry.h"
-#include "lastexpress/sound/queue.h"
-
-#include "lastexpress/helpers.h"
-#include "lastexpress/graphics.h"
-#include "lastexpress/lastexpress.h"
-#include "lastexpress/resource.h"
-
-namespace LastExpress {
-
-// Letters & messages
-static const char *const messages[24] = {
-	"",
-	"TXT1001",  // 1
-	"TXT1001A", // 2
-	"TXT1011",  // 3
-	"TXT1012",  // 4
-	"TXT1013",  // 5
-	"TXT1014",  // 6
-	"TXT1020",  // 7
-	"TXT1030",  // 8
-	"END1009B", // 50
-	"END1046",  // 51
-	"END1047",  // 52
-	"END1112",  // 53
-	"END1112A", // 54
-	"END1503",  // 55
-	"END1505A", // 56
-	"END1505B", // 57
-	"END1610",  // 58
-	"END1612A", // 59
-	"END1612C", // 61
-	"END1612D", // 62
-	"ENDALRM1", // 63
-	"ENDALRM2", // 64
-	"ENDALRM3"  // 65
-};
-
-static const char *const cities[17] = {
-	"EPERNAY",
-	"CHALONS",
-	"BARLEDUC",
-	"NANCY",
-	"LUNEVILL",
-	"AVRICOUR",
-	"DEUTSCHA",
-	"STRASBOU",
-	"BADENOOS",
-	"SALZBURG",
-	"ATTNANG",
-	"WELS",
-	"LINZ",
-	"VIENNA",
-	"POZSONY",
-	"GALANTA",
-	"POLICE"
-};
-
-static const char *const locomotiveSounds[5] = {
-	"ZFX1005",
-	"ZFX1006",
-	"ZFX1007",
-	"ZFX1007A",
-	"ZFX1007B"
-};
-
-static const SoundFlag soundFlags[32] = {
-	kFlagDefault,
-	kFlag15,
-	kFlag14,
-	kFlag13,
-	kFlag12,
-	kFlag11, kFlag11,
-	kFlag10, kFlag10,
-	kFlag9,  kFlag9,
-	kFlag8,  kFlag8,
-	kFlag7,  kFlag7, kFlag7,
-	kFlag6,  kFlag6, kFlag6,
-	kFlag5,  kFlag5, kFlag5, kFlag5,
-	kFlag4,  kFlag4, kFlag4, kFlag4,
-	kFlag3,  kFlag3, kFlag3, kFlag3, kFlag3
-};
-
-SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) {
-	_loopingSoundDuration = 0;
-
-	_queue = new SoundQueue(engine);
-
-	memset(&_lastWarning, 0, sizeof(_lastWarning));
-
-	// Initialize unknown data
-	_data0 = 0;
-	_data1 = 0;
-	_data2 = 0;
-}
-
-SoundManager::~SoundManager() {
-	SAFE_DELETE(_queue);
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound-related functions
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
-	if (_queue->isBuffered(entity) && entity)
-		_queue->removeFromQueue(entity);
-
-	SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
-
-	// Add .SND at the end of the filename if needed
-	if (!filename.contains('.'))
-		filename += ".SND";
-
-	if (!playSoundWithSubtitles(filename, currentFlag, entity, a4))
-		if (entity)
-			getSavePoints()->push(kEntityPlayer, entity, kActionEndSound);
-}
-
-bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) {
-	SoundEntry *entry = new SoundEntry(_engine);
-
-	entry->open(filename, flag, 30);
-	entry->_entity = entity;
-
-	if (a4) {
-		entry->_field_48 = _data2 + 2 * a4;
-		entry->_status.status |= kSoundStatus_8000;
-	} else {
-		// Get subtitles name
-		while (filename.size() > 4)
-			filename.deleteLastChar();
-
-		entry->showSubtitle(filename);
-		entry->updateState();
-	}
-
-	return (entry->getType() != kSoundTypeNone);
-}
-
-void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
-	int values[5];
-
-	if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
-		return;
-
-	if (getEntities()->isInSalon(entity) != getEntities()->isInSalon(kEntityPlayer))
-		return;
-
-	int _action = (int)action;
-	SoundFlag flag = getSoundFlag(entity);
-
-	switch (action) {
-	case 36: {
-		int _param3 = (flag <= 9) ? flag + 7 : 16;
-
-		if (_param3 > 7) {
-			_data0 = (uint)_param3;
-			_data1 = _data2 + 2 * a3;
-		}
-		break;
-		}
-
-	case 37:
-		_data0 = 7;
-		_data1 = _data2 + 2 * a3;
-		break;
-
-	case 150:
-	case 156:
-	case 162:
-	case 168:
-	case 188:
-	case 198:
-		_action += 1 + (int)rnd(5);
-		break;
-
-	case 174:
-	case 184:
-	case 194:
-		_action += 1 + (int)rnd(3);
-		break;
-
-	case 180:
-		_action += 1 + (int)rnd(4);
-		break;
-
-	case 246:
-		values[0] = 0;
-		values[1] = 104;
-		values[2] = 105;
-		values[3] = 106;
-		values[4] = 116;
-		_action = values[rnd(5)];
-		break;
-
-	case 247:
-		values[0] = 11;
-		values[1] = 123;
-		values[2] = 124;
-		_action = values[rnd(3)];
-		break;
-
-	case 248:
-		values[0] = 0;
-		values[1] = 103;
-		values[2] = 108;
-		values[3] = 109;
-		_action = values[rnd(4)];
-		break;
-
-	case 249:
-		values[0] = 0;
-		values[1] = 56;
-		values[2] = 112;
-		values[3] = 113;
-		_action = values[rnd(4)];
-		break;
-
-	case 250:
-		values[0] = 0;
-		values[1] = 107;
-		values[2] = 115;
-		values[3] = 117;
-		_action = values[rnd(4)];
-		break;
-
-	case 251:
-		values[0] = 0;
-		values[1] = 11;
-		values[2] = 56;
-		values[3] = 113;
-		_action = values[rnd(4)];
-		break;
-
-	case 252:
-		values[0] = 0;
-		values[1] = 6;
-		values[2] = 109;
-		values[3] = 121;
-		_action = values[rnd(4)];
-		break;
-
-	case 254:
-		values[0] = 0;
-		values[1] = 104;
-		values[2] = 120;
-		values[3] = 121;
-		_action = values[rnd(4)];
-		break;
-
-	case 255:
-		values[0] = 0;
-		values[1] = 106;
-		values[2] = 115;
-		_action = values[rnd(3)];
-		break;
-
-	default:
-		break;
-	}
-
-	if (_action && flag)
-		playSoundWithSubtitles(Common::String::format("LIB%03d.SND", _action), flag, kEntityPlayer, a3);
-}
-
-void SoundManager::playSteam(CityIndex index) {
-	if (index >= ARRAYSIZE(cities))
-		error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
-
-	_queue->resetState(kSoundState2);
-
-	if (!_queue->getEntry(kSoundType1))
-		playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam);
-
-	// Get the new sound entry and show subtitles
-	SoundEntry *entry = _queue->getEntry(kSoundType1);
-	if (entry)
-		entry->showSubtitle(cities[index]);
-}
-
-void SoundManager::playFightSound(byte action, byte a4) {
-	int _action = (int)action;
-	int values[5];
-
-	switch (action) {
-	default:
-		break;
-
-	case 174:
-	case 184:
-	case 194:
-		values[0] = action + 1;
-		values[1] = action + 2;
-		values[2] = action + 3;
-		_action = values[rnd(3)];
-		break;
-
-	case 180:
-		values[0] = action + 1;
-		values[1] = action + 2;
-		values[2] = action + 3;
-		values[3] = action + 4;
-		_action = values[rnd(4)];
-		break;
-
-	case 150:
-	case 156:
-	case 162:
-	case 168:
-	case 188:
-	case 198:
-		values[0] = action + 1;
-		values[1] = action + 2;
-		values[2] = action + 3;
-		values[3] = action + 4;
-		values[4] = action + 5;
-		_action = values[rnd(5)];
-		break;
-	}
-
-	if (_action)
-		playSound(kEntityTrain, Common::String::format("LIB%03d.SND", _action), kFlagDefault, a4);
-}
-
-void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) {
-	if (_queue->isBuffered(getDialogName(entityDialog)))
-		_queue->removeFromQueue(getDialogName(entityDialog));
-
-	playSound(entity, getDialogName(entityDialog), flag, a4);
-}
-
-void SoundManager::playLocomotiveSound() {
-	playSound(kEntityPlayer, locomotiveSounds[rnd(5)], (SoundFlag)(rnd(15) + 2));
-}
-
-const char *SoundManager::getDialogName(EntityIndex entity) const {
-	switch (entity) {
-	case kEntityAnna:
-		if (getEvent(kEventAnnaDialogGoToJerusalem))
-			return "XANN12";
-
-		if (getEvent(kEventLocomotiveRestartTrain))
-			return "XANN11";
-
-		if (getEvent(kEventAnnaBaggageTies) || getEvent(kEventAnnaBaggageTies2) || getEvent(kEventAnnaBaggageTies3) || getEvent(kEventAnnaBaggageTies4))
-			return "XANN10";
-
-		if (getEvent(kEventAnnaTired) || getEvent(kEventAnnaTiredKiss))
-			return "XANN9";
-
-		if (getEvent(kEventAnnaBaggageArgument))
-			return "XANN8";
-
-		if (getEvent(kEventKronosVisit))
-			return "XANN7";
-
-		if (getEvent(kEventAbbotIntroduction))
-			return "XANN6A";
-
-		if (getEvent(kEventVassiliSeizure))
-			return "XANN6";
-
-		if (getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction))
-			return "XANN5";
-
-		if (getProgress().field_60)
-			return "XANN4";
-
-		if (getEvent(kEventAnnaGiveScarf) || getEvent(kEventAnnaGiveScarfDiner) || getEvent(kEventAnnaGiveScarfSalon)
-		 || getEvent(kEventAnnaGiveScarfMonogram) || getEvent(kEventAnnaGiveScarfDinerMonogram) || getEvent(kEventAnnaGiveScarfSalonMonogram))
-			return "XANN3";
-
-		if (getEvent(kEventDinerMindJoin))
-			return "XANN2";
-
-		if (getEvent(kEventGotALight) || getEvent(kEventGotALightD))
-			return "XANN1";
-
-		break;
-
-	case kEntityAugust:
-		if (getEvent(kEventAugustTalkCigar))
-			return "XAUG6";
-
-		if (getEvent(kEventAugustBringBriefcase))
-			return "XAUG5";
-
-		// Getting closer to Vienna...
-		if (getState()->time > kTime2200500 && !getEvent(kEventAugustMerchandise))
-			return "XAUG4A";
-
-		if (getEvent(kEventAugustMerchandise))
-			return "XAUG4";
-
-		if (getEvent(kEventDinerAugust) || getEvent(kEventDinerAugustAlexeiBackground) || getEvent(kEventMeetAugustTylerCompartment)
-		 || getEvent(kEventMeetAugustTylerCompartmentBed) || getEvent(kEventMeetAugustHisCompartment) || getEvent(kEventMeetAugustHisCompartmentBed))
-			return "XAUG3";
-
-		if (getEvent(kEventAugustPresentAnnaFirstIntroduction))
-			return "XAUG2";
-
-		if (getProgress().eventMertensAugustWaiting)
-			return "XAUG1";
-
-		break;
-
-	case kEntityTatiana:
-		if (getEvent(kEventTatianaTylerCompartment))
-			return "XTAT6";
-
-		if (getEvent(kEventTatianaCompartmentStealEgg))
-			return "XTAT5";
-
-		if (getEvent(kEventTatianaGivePoem))
-			return "XTAT3";
-
-		if (getProgress().field_64)
-			return "XTAT1";
-
-		break;
-
-	case kEntityVassili:
-		if (getEvent(kEventCathFreePassengers))
-			return "XVAS4";
-
-		if (getEvent(kEventVassiliCompartmentStealEgg))
-			return "XVAS3";
-
-		if (getEvent(kEventAbbotIntroduction))
-			return "XVAS2";
-
-		if (getEvent(kEventVassiliSeizure))
-			return "XVAS1A";
-
-		if (getProgress().field_64)
-			return "XVAS1";
-
-		break;
-
-	case kEntityAlexei:
-		if (getProgress().field_88)
-			return "XALX6";
-
-		if (getProgress().field_8C)
-			return "XALX5";
-
-		if (getProgress().field_90)
-			return "XALX4A";
-
-		if (getProgress().field_68)
-			return "XALX4";
-
-		if (getEvent(kEventAlexeiSalonPoem))
-			return "XALX3";
-
-		if (getEvent(kEventAlexeiSalonVassili))
-			return "XALX2";
-
-		if (getEvent(kEventAlexeiDiner) || getEvent(kEventAlexeiDinerOriginalJacket))
-			return "XALX1";
-
-		break;
-
-	case kEntityAbbot:
-		if (getEvent(kEventAbbotDrinkDefuse))
-			return "XABB4";
-
-		if (getEvent(kEventAbbotInvitationDrink) || getEvent(kEventDefuseBomb))
-			return "XABB3";
-
-		if (getEvent(kEventAbbotWrongCompartment) || getEvent(kEventAbbotWrongCompartmentBed))
-			return "XABB2";
-
-		if (getEvent(kEventAbbotIntroduction))
-			return "XABB1";
-
-		break;
-
-	case kEntityMilos:
-		if (getEvent(kEventLocomotiveMilosDay) || getEvent(kEventLocomotiveMilosNight))
-			return "XMIL5";
-
-		if (getEvent(kEventMilosCompartmentVisitTyler) && (getProgress().chapter == kChapter3 || getProgress().chapter == kChapter4))
-			return "XMIL4";
-
-		if (getEvent(kEventMilosCorridorThanks) || getProgress().chapter == kChapter5)
-			return "XMIL3";
-
-		if (getEvent(kEventMilosCompartmentVisitAugust))
-			return "XMIL2";
-
-		if (getEvent(kEventMilosTylerCompartmentDefeat))
-			return "XMIL1";
-
-		break;
-
-	case kEntityVesna:
-		if (getProgress().field_94)
-			return "XVES2";
-
-		if (getProgress().field_98)
-			return "XVES1";
-
-		break;
-
-	case kEntityKronos:
-		if (getEvent(kEventKronosReturnBriefcase))
-			return "XKRO6";
-
-		if (getEvent(kEventKronosBringEggCeiling) || getEvent(kEventKronosBringEgg))
-			return "XKRO5";
-
-		if (getEvent(kEventKronosConversation) || getEvent(kEventKronosConversationFirebird)) {
-			ObjectLocation location = getInventory()->get(kItemFirebird)->location;
-			if (location != kObjectLocation6 && location != kObjectLocation5 && location != kObjectLocation2 && location != kObjectLocation1)
-				return "XKRO4A";
-		}
-
-		if (getEvent(kEventKronosConversationFirebird))
-			return "XKRO4";
-
-		if (getEvent(kEventKronosConversation)) {
-			if (!getEvent(kEventMilosCompartmentVisitAugust))
-				return "XKRO3";
-			else
-				return "XKRO2";
-		}
-
-		if (getProgress().eventMertensKronosInvitation)
-			return "XKRO1";
-
-		break;
-
-	case kEntityFrancois:
-		if (getProgress().field_9C)
-			return "XFRA3";
-
-		if (getProgress().field_A0
-		 || getEvent(kEventFrancoisWhistle) || getEvent(kEventFrancoisWhistleD)
-		 || getEvent(kEventFrancoisWhistleNight) || getEvent(kEventFrancoisWhistleNightD))
-			return "XFRA2";
-
-		if (getState()->time > kTimeParisEpernay) // Between Paris and Epernay
-			return "XFRA1";
-
-		break;
-
-	case kEntityMmeBoutarel:
-		if (getProgress().field_A4)
-			return "XMME4";
-
-		if (getProgress().field_A8)
-			return "XMME3";
-
-		if (getProgress().field_A0)
-			return "XMME2";
-
-		if (getProgress().field_AC)
-			return "XMME1";
-
-		break;
-
-	case kEntityBoutarel:
-		if (getProgress().eventMetBoutarel)
-			return "XMRB1";
-
-		break;
-
-	case kEntityRebecca:
-		if (getProgress().field_B4)
-			return "XREB1A";
-
-		if (getProgress().field_B8)
-			return "XREB1";
-
-		break;
-
-	case kEntitySophie:
-		if (getProgress().field_B0)
-			return "XSOP2";
-
-		if (getProgress().field_BC)
-			return "XSOP1B";
-
-		if (getProgress().field_B4)
-			return "XSOP1A";
-
-		if (getProgress().field_B8)
-			return "XSOP1";
-
-		break;
-
-	case kEntityMahmud:
-		if (getProgress().field_C4)
-			return "XMAH1";
-
-		break;
-
-	case kEntityYasmin:
-		if (getProgress().eventMetYasmin)
-			return "XHAR2";
-
-		break;
-
-	case kEntityHadija:
-		if (getProgress().eventMetHadija)
-			return "XHAR1";
-
-		break;
-
-	case kEntityAlouan:
-		if (getProgress().field_DC)
-			return "XHAR3";
-
-		break;
-
-	case kEntityGendarmes:
-		if (getProgress().field_E0)
-			return "XHAR4";
-
-		break;
-
-	case kEntityChapters:
-		if (getEvent(kEventCathDream) || getEvent(kEventCathWakingUp))
-			return "XTYL3";
-
-		return "XTYL1";
-
-	default:
-		break;
-	}
-
-	return NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Letters & Messages
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::readText(int id){
-	if (!_queue->isBuffered(kEntityTables4))
-		return;
-
-	if (id < 0 || (id > 8 && id < 50) || id > 64)
-		error("Sound::readText - attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
-
-	// Get proper message file (names are stored in sequence in the array but id is [1;8] - [50;64])
-	const char *text = messages[id <= 8 ? id : id - 41];
-
-	// Check if file is in cache for id [1;8]
-	if (id <= 8)
-		if (_queue->isBuffered(text))
-			_queue->removeFromQueue(text);
-
-	playSound(kEntityTables4, text, kFlagDefault);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound bites
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compartment) {
-
-#define PLAY_WARNING(index, sound1, sound2, sound3, sound4, sound5, sound6) { \
-	if (_lastWarning[index] + 450 >= getState()->timeTicks) { \
-		if (rnd(2)) \
-			playSound(kEntityMertens, sound1, kFlagDefault); \
-		else \
-			playSound(kEntityMertens, rnd(2) ? sound2 : sound3, kFlagDefault); \
-	} else { \
-		if (rnd(2)) \
-			playSound(kEntityMertens, sound4, kFlagDefault); \
-		else \
-			playSound(kEntityMertens, rnd(2) ? sound5 : sound6, kFlagDefault); \
-	} \
-	_lastWarning[index] = getState()->timeTicks; \
-}
-
-	if (entity != kEntityMertens && entity != kEntityCoudert)
-		return;
-
-	//////////////////////////////////////////////////////////////////////////
-	// Mertens
-	if (entity == kEntityMertens) {
-
-		switch (compartment) {
-		default:
-			break;
-
-		case kObjectCompartment2:
-			PLAY_WARNING(0, "Con1502A", "Con1500B", "Con1500C", "Con1502", "Con1500", "Con1500A");
-			break;
-
-		case kObjectCompartment3:
-			PLAY_WARNING(1, "Con1501A", "Con1500B", "Con1500C", "Con1501", "Con1500", "Con1500A");
-			break;
-
-		case kObjectCompartment4:
-			PLAY_WARNING(2, "Con1503", "Con1500B", "Con1500C", "Con1503", "Con1500", "Con1500A");
-			break;
-
-		case kObjectCompartment5:
-		case kObjectCompartment6:
-		case kObjectCompartment7:
-		case kObjectCompartment8:
-			++_lastWarning[3];
-
-			switch (_lastWarning[3]) {
-			default:
-				break;
-
-			case 1:
-				getSound()->playSound(kEntityMertens, "Con1503C", kFlagDefault);
-				break;
-
-			case 2:
-				getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503E" : "Con1503A", kFlagDefault);
-				break;
-
-			case 3:
-				getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503B" : "Con1503D", kFlagDefault);
-				_lastWarning[3] = 0;
-				break;
-			}
-		}
-
-		return;
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Coudert
-	switch (compartment) {
-		default:
-			break;
-
-		case kObjectCompartmentA:
-			if (_lastWarning[4] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1508" : "Jac1508A", kFlagDefault);
-			break;
-
-		case kObjectCompartmentB:
-			if (_lastWarning[5] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (getProgress().field_40 || (getState()->time > kTimeCityLinz && getState()->time < kTime2133000))
-				getSound()->playSound(kEntityCoudert, "Jac1507A", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, "Jac1507", kFlagDefault);
-			break;
-
-		case kObjectCompartmentC:
-			if (_lastWarning[6] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (getProgress().chapter < kChapter3)
-				getSound()->playSound(kEntityCoudert, "Jac1506", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1506A" : "Jac1506B", kFlagDefault);
-			break;
-
-		case kObjectCompartmentD:
-			if (_lastWarning[7] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			getSound()->playSound(kEntityCoudert, "Jac1505", kFlagDefault);
-			break;
-
-		case kObjectCompartmentE:
-			if (_lastWarning[8] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (getProgress().field_40 || (getState()->time > kTime2115000 && getState()->time < kTime2133000)) {
-				getSound()->playSound(kEntityCoudert, "Jac1504B", kFlagDefault);
-				break;
-			}
-
-			if (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840))
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1504" : "Jac1504A", kFlagDefault);
-			break;
-
-		case kObjectCompartmentF:
-			if (_lastWarning[9] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (getProgress().field_40 || (getState()->time > kTime2083500 && getState()->time < kTime2133000)) {
-				getSound()->playSound(kEntityCoudert, "Jac1503B", kFlagDefault);
-				break;
-			}
-
-			if (rnd(2) || getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070))
-				getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, "Jac1503A", kFlagDefault);
-			break;
-
-		case kObjectCompartmentG:
-			if (_lastWarning[10] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (rnd(2) || getEntities()->isInsideCompartment(kEntityMilos, kCarRedSleeping, kPosition_3050))
-				getSound()->playSound(kEntityCoudert, "Jac1502", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, "Jac1502A", kFlagDefault);
-			break;
-
-		case kObjectCompartmentH:
-			if (_lastWarning[11] + 450 >= getState()->timeTicks) {
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-				break;
-			}
-
-			if (getEntities()->isInsideCompartment(kEntityIvo, kCarRedSleeping, kPosition_2740))
-				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
-			else
-				getSound()->playSound(kEntityCoudert, "Jac1501", kFlagDefault);
-			break;
-	}
-
-	// Update ticks (Compartments A - H are indexes 4 - 11)
-	_lastWarning[compartment - 28] = getState()->timeTicks;
-}
-
-void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) {
-	if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
-		return;
-
-	if (entity2 == kEntityFrancois || entity2 == kEntityMax)
-		return;
-
-	if (entity == kEntityFrancois && getEntityData(kEntityFrancois)->field_4A3 != 30)
-		return;
-
-	if (flag == kFlagNone)
-		flag = getSoundFlag(entity);
-
-	switch (entity) {
-	default:
-		break;
-
-	case kEntityAnna:
-		playSound(kEntityPlayer, "ANN1107A", flag);
-		break;
-
-	case kEntityAugust:
-		switch(rnd(4)) {
-		default:
-			break;
-
-		case 0:
-			playSound(kEntityPlayer, "AUG1100A", flag);
-			break;
-
-		case 1:
-			playSound(kEntityPlayer, "AUG1100B", flag);
-			break;
-
-		case 2:
-			playSound(kEntityPlayer, "AUG1100C", flag);
-			break;
-
-		case 3:
-			playSound(kEntityPlayer, "AUG1100D", flag);
-			break;
-		}
-		break;
-
-	case kEntityMertens:
-		if (Entities::isFemale(entity2)) {
-			playSound(kEntityPlayer, (rnd(2) ? "CON1111" : "CON1111A"), flag);
-		} else {
-			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
-				switch(rnd(3)) {
-				default:
-					break;
-
-				case 0:
-					playSound(kEntityPlayer, "CON1110A", flag);
-					break;
-
-				case 1:
-					playSound(kEntityPlayer, "CON1110C", flag);
-					break;
-
-				case 2:
-					playSound(kEntityPlayer, "CON1110", flag);
-					break;
-				}
-			} else {
-				if (isNight()) {
-					playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"));
-				} else {
-					playSound(kEntityPlayer, "CON1110D");
-				}
-			}
-		}
-		break;
-
-	case kEntityCoudert:
-		if (Entities::isFemale(entity2)) {
-			playSound(kEntityPlayer, "JAC1111D", flag);
-		} else {
-			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
-				switch(rnd(4)) {
-				default:
-					break;
-
-				case 0:
-					playSound(kEntityPlayer, "JAC1111", flag);
-					break;
-
-				case 1:
-					playSound(kEntityPlayer, "JAC1111A", flag);
-					break;
-
-				case 2:
-					playSound(kEntityPlayer, "JAC1111B", flag);
-					break;
-
-				case 3:
-					playSound(kEntityPlayer, "JAC1111C", flag);
-					break;
-				}
-			} else {
-				playSound(kEntityPlayer, "JAC1113B", flag);
-			}
-		}
-		break;
-
-	case kEntityPascale:
-		playSound(kEntityPlayer, (rnd(2) ? "HDE1002" : "HED1002A"), flag);
-		break;
-
-	case kEntityServers0:
-	case kEntityServers1:
-		switch(rnd(3)) {
-		default:
-			break;
-
-		case 0:
-			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002" : "WAT1003", flag);
-			break;
-
-		case 1:
-			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002A" : "WAT1003A", flag);
-			break;
-
-		case 2:
-			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002B" : "WAT1003B", flag);
-			break;
-		}
-		break;
-
-	case kEntityVerges:
-		if (Entities::isFemale(entity2)) {
-			playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"));
-		} else {
-			playSound(kEntityPlayer, "TRA1112", flag);
-		}
-		break;
-
-	case kEntityTatiana:
-		playSound(kEntityPlayer, (rnd(2) ? "TAT1102A" : "TAT1102B"), flag);
-		break;
-
-	case kEntityAlexei:
-		playSound(kEntityPlayer, (rnd(2) ? "ALX1099C" : "ALX1099D"), flag);
-		break;
-
-	case kEntityAbbot:
-		if (Entities::isFemale(entity2)) {
-			playSound(kEntityPlayer, "ABB3002C", flag);
-		} else {
-			switch(rnd(3)) {
-			default:
-				break;
-
-			case 0:
-				playSound(kEntityPlayer, "ABB3002", flag);
-				break;
-
-			case 1:
-				playSound(kEntityPlayer, "ABB3002A", flag);
-				break;
-
-			case 2:
-				playSound(kEntityPlayer, "ABB3002B", flag);
-				break;
-			}
-		}
-		break;
-
-	case kEntityVesna:
-		switch(rnd(3)) {
-		default:
-			break;
-
-		case 0:
-			playSound(kEntityPlayer, "VES1109A", flag);
-			break;
-
-		case 1:
-			playSound(kEntityPlayer, "VES1109B", flag);
-			break;
-
-		case 2:
-			playSound(kEntityPlayer, "VES1109C", flag);
-			break;
-		}
-		break;
-
-	case kEntityKahina:
-		playSound(kEntityPlayer, (rnd(2) ? "KAH1001" : "KAH1001A"), flag);
-		break;
-
-	case kEntityFrancois:
-	case kEntityMmeBoutarel:
-		switch(rnd(4)) {
-		default:
-			break;
-
-		case 0:
-			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001" : "MME1103A", flag);
-			break;
-
-		case 1:
-			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001A" : "MME1103B", flag);
-			break;
-
-		case 2:
-			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001B" : "MME1103C", flag);
-			break;
-
-		case 3:
-			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001C" : "MME1103D", flag);
-			break;
-		}
-		break;
-
-	case kEntityBoutarel:
-		playSound(kEntityPlayer, "MRB1104", flag);
-		if (flag > 2)
-			getProgress().eventMetBoutarel = true;
-		break;
-
-	case kEntityRebecca:
-		playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "REB110A"), flag);
-		break;
-
-	case kEntitySophie: {
-		switch(rnd(3)) {
-		default:
-			break;
-
-		case 0:
-			playSound(kEntityPlayer, "SOP1105", flag);
-			break;
-
-		case 1:
-			playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105C" : "SOP1105A", flag);
-			break;
-
-		case 2:
-			playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105D" : "SOP1105B", flag);
-			break;
-		}
-		break;
-	}
-
-	case kEntityMahmud:
-		playSound(kEntityPlayer, "MAH1101", flag);
-		break;
-
-	case kEntityYasmin:
-		playSound(kEntityPlayer, "HAR1002", flag);
-		if (flag > 2)
-			getProgress().eventMetYasmin = true;
-		break;
-
-	case kEntityHadija:
-		playSound(kEntityPlayer, (rnd(2) ? "HAR1001" : "HAR1001A"), flag);
-		if (flag > 2)
-			getProgress().eventMetHadija = true;
-		break;
-
-	case kEntityAlouan:
-		playSound(kEntityPlayer, "HAR1004", flag);
-		break;
-	}
-}
-
-void SoundManager::excuseMeCath() {
-	switch(rnd(3)) {
-	default:
-		playSound(kEntityPlayer, "CAT1126B");
-		break;
-
-	case 1:
-		playSound(kEntityPlayer, "CAT1126C");
-		break;
-
-	case 2:
-		playSound(kEntityPlayer, "CAT1126D");
-		break;
-	}
-}
-
-const char *SoundManager::justCheckingCath() const {
-	switch(rnd(4)) {
-	default:
-		break;
-
-	case 0:
-		return "CAT5001";
-
-	case 1:
-		return "CAT5001A";
-
-	case 2:
-		return "CAT5001B";
-
-	case 3:
-		return "CAT5001C";
-	}
-
-	return "CAT5001";
-}
-
-const char *SoundManager::wrongDoorCath() const {
-	switch(rnd(5)) {
-	default:
-		break;
-
-	case 0:
-		return "CAT1125";
-
-	case 1:
-		return "CAT1125A";
-
-	case 2:
-		return "CAT1125B";
-
-	case 3:
-		return "CAT1125C";
-
-	case 4:
-		return "CAT1125D";
-	}
-
-	return "CAT1125";
-}
-
-const char *SoundManager::justAMinuteCath() const {
-	switch(rnd(3)) {
-	default:
-		break;
-
-	case 0:
-		return "CAT1520";
-
-	case 1:
-		return "CAT1521";
-
-	case 2:
-		return "CAT1125";    // ?? is this a bug in the original?
-	}
-
-	return "CAT1520";
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Sound flags
-//////////////////////////////////////////////////////////////////////////
-SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
-	if (entity == kEntityPlayer)
-		return kFlagDefault;
-
-	if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
-		return kFlagNone;
-
-	// Compute sound value
-	SoundFlag ret = kFlag2;
-
-	// Get default value if valid
-	int index = ABS(getEntityData(entity)->entityPosition - getEntityData(kEntityPlayer)->entityPosition) / 230;
-	if (index < 32)
-		ret = soundFlags[index];
-
-	if (getEntityData(entity)->location == kLocationOutsideTrain) {
-		if (getEntityData(entity)->car != kCarKronos
-		&& !getEntities()->isOutsideAlexeiWindow()
-		&& !getEntities()->isOutsideAnnaWindow())
-			return kFlagNone;
-
-		return (SoundFlag)(ret / 6);
-	}
-
-	switch (getEntityData(entity)->car) {
-	default:
-		break;
-
-	case kCarKronos:
-		if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
-			ret = (SoundFlag)(ret * 2);
-		break;
-
-	case kCarGreenSleeping:
-	case kCarRedSleeping:
-		if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
-			ret = (SoundFlag)(ret * 2);
-
-		if (getEntityData(kEntityPlayer)->location
-		&& (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
-			ret = (SoundFlag)(ret * 2);
-		break;
-
-	case kCarRestaurant:
-		if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
-		&& (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
-			ret = (SoundFlag)(ret * 2);
-		else
-			ret = (SoundFlag)(ret * 4);
-		break;
-	}
-
-	return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Misc
-//////////////////////////////////////////////////////////////////////////
-void SoundManager::playLoopingSound(int param) {
-	SoundEntry *entry = _queue->getEntry(kSoundType1);
-
-	static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
-	                                             kPosition_6470, kPosition_5790,
-	                                             kPosition_4840, kPosition_4070,
-	                                             kPosition_3050, kPosition_2740 };
-
-	byte numLoops[8];
-	numLoops[1] = 4;
-	numLoops[2] = 2;
-	numLoops[3] = 2;
-	numLoops[4] = 2;
-	numLoops[5] = 2;
-	numLoops[6] = 2;
-
-	char tmp[80];
-	tmp[0] = 0;
-
-	int partNumber = 1;
-	int fnameLen = 6;
-
-	if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) {
-		if (_queue->getSoundState() & 2) {
-			strcpy(tmp, "STEAM.SND");
-
-			_loopingSoundDuration = 32767;
-		} else {
-			if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
-				partNumber = 6;
-			} else {
-				if (getEntities()->isInsideCompartments(kEntityPlayer)) {
-					int objNum = (getEntityData(kEntityPlayer)->car - 3) < 1 ? 9 : 40; // Weird numbers
-
-					numLoops[0] = 0;
-
-					for (int pos = 0; pos < 8; pos++) {
-						if (numLoops[0])
-							break;
-						if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
-							numLoops[0] = 1;
-							partNumber = (getObjects()->get((ObjectIndex)objNum).location - 2) < 1 ? 6 : 1;
-						}
-						objNum++;
-					}
-				} else {
-					switch (getEntityData(kEntityPlayer)->car) {
-					case 1:
-					case 6:
-						partNumber = 4;
-						break;
-					case 2:
-					case 3:
-					case 4:
-					case 5:
-						partNumber = 1;
-						break;
-					case 7:
-						partNumber = 5;
-						break;
-					case 8:
-						partNumber = 99;
-						break;
-					case 9:
-						partNumber = 3;
-						break;
-					default:
-						partNumber = 6;
-						break;
-					}
-				}
-			}
-
-			if (partNumber != 99)
-				sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A');
-		}
-
-		if (getFlags()->flag_3)
-			fnameLen = 5;
-
-		if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) {
-			_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
-
-			if (partNumber != 99) {
-				playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam);
-
-				if (entry)
-					entry->update(0);
-
-				SoundEntry *entry1 = _queue->getEntry(kSoundType1);
-				if (entry1)
-					entry1->update(7);
-			}
-		}
-	}
-}
-
-} // End of namespace LastExpress
diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h
deleted file mode 100644
index 797e526..0000000
--- a/engines/lastexpress/game/sound.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef LASTEXPRESS_SOUND_H
-#define LASTEXPRESS_SOUND_H
-
-#include "lastexpress/shared.h"
-
-#include "common/str.h"
-
-namespace LastExpress {
-
-class LastExpressEngine;
-class SoundQueue;
-
-class SoundManager {
-public:
-	SoundManager(LastExpressEngine *engine);
-	~SoundManager();
-
-	// Sound playing
-	void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0);
-	bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0);
-	void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
-	void playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4);
-	void playSteam(CityIndex index);
-	void playFightSound(byte action, byte a4);
-	void playLocomotiveSound();
-	void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
-	void playLoopingSound(int param);
-
-	// Dialog & Letters
-	void readText(int id);
-	const char *getDialogName(EntityIndex entity) const;
-
-	// Sound bites
-	void excuseMe(EntityIndex entity, EntityIndex entity2 = kEntityPlayer, SoundFlag flag = kFlagNone);
-	void excuseMeCath();
-	const char *justCheckingCath() const;
-	const char *wrongDoorCath() const;
-	const char *justAMinuteCath() const;
-
-	// Flags
-	SoundFlag getSoundFlag(EntityIndex index) const;
-
-	// Accessors
-	SoundQueue *getQueue() { return _queue; }
-	uint32 getData2() { return _data2; }
-
-private:
-	LastExpressEngine *_engine;
-	SoundQueue *_queue;
-
-	// Compartment warnings by Mertens or Coudert
-	uint32 _lastWarning[12];
-
-	// Looping sound
-	int _loopingSoundDuration;
-
-	// Unknown data
-	uint32 _data0;
-	uint32 _data1;
-	uint32 _data2;
-};
-
-} // End of namespace LastExpress
-
-#endif // LASTEXPRESS_SOUND_H
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 2829f60..5d83527 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -28,11 +28,11 @@
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/state.h"
-#include "lastexpress/game/sound.h"
 
 #include "lastexpress/menu/menu.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp
index 288e53f..bfead02 100644
--- a/engines/lastexpress/menu/menu.cpp
+++ b/engines/lastexpress/menu/menu.cpp
@@ -35,13 +35,13 @@
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/menu/clock.h"
 #include "lastexpress/menu/trainline.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk
index 355ecba..a11a7c4 100644
--- a/engines/lastexpress/module.mk
+++ b/engines/lastexpress/module.mk
@@ -61,13 +61,13 @@ MODULE_OBJS := \
 	game/savegame.o \
 	game/savepoint.o \
 	game/scenes.o \
-	game/sound.o \
 	game/state.o \
 	menu/clock.o \
 	menu/menu.o \
 	menu/trainline.o \
 	sound/entry.o \
 	sound/queue.o \
+	sound/sound.o \
 	debug.o \
 	detection.o \
 	graphics.o \
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 8174161..5cdcc15 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -24,10 +24,10 @@
 
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/savepoint.h"
-#include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
 #include "lastexpress/sound/queue.h"
+#include "lastexpress/sound/sound.h"
 
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
new file mode 100644
index 0000000..16e502a
--- /dev/null
+++ b/engines/lastexpress/sound/sound.cpp
@@ -0,0 +1,1379 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "lastexpress/sound/sound.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/entities.h"
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/sound/entry.h"
+#include "lastexpress/sound/queue.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/graphics.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+// Letters & messages
+static const char *const messages[24] = {
+	"",
+	"TXT1001",  // 1
+	"TXT1001A", // 2
+	"TXT1011",  // 3
+	"TXT1012",  // 4
+	"TXT1013",  // 5
+	"TXT1014",  // 6
+	"TXT1020",  // 7
+	"TXT1030",  // 8
+	"END1009B", // 50
+	"END1046",  // 51
+	"END1047",  // 52
+	"END1112",  // 53
+	"END1112A", // 54
+	"END1503",  // 55
+	"END1505A", // 56
+	"END1505B", // 57
+	"END1610",  // 58
+	"END1612A", // 59
+	"END1612C", // 61
+	"END1612D", // 62
+	"ENDALRM1", // 63
+	"ENDALRM2", // 64
+	"ENDALRM3"  // 65
+};
+
+static const char *const cities[17] = {
+	"EPERNAY",
+	"CHALONS",
+	"BARLEDUC",
+	"NANCY",
+	"LUNEVILL",
+	"AVRICOUR",
+	"DEUTSCHA",
+	"STRASBOU",
+	"BADENOOS",
+	"SALZBURG",
+	"ATTNANG",
+	"WELS",
+	"LINZ",
+	"VIENNA",
+	"POZSONY",
+	"GALANTA",
+	"POLICE"
+};
+
+static const char *const locomotiveSounds[5] = {
+	"ZFX1005",
+	"ZFX1006",
+	"ZFX1007",
+	"ZFX1007A",
+	"ZFX1007B"
+};
+
+static const SoundFlag soundFlags[32] = {
+	kFlagDefault,
+	kFlag15,
+	kFlag14,
+	kFlag13,
+	kFlag12,
+	kFlag11, kFlag11,
+	kFlag10, kFlag10,
+	kFlag9,  kFlag9,
+	kFlag8,  kFlag8,
+	kFlag7,  kFlag7, kFlag7,
+	kFlag6,  kFlag6, kFlag6,
+	kFlag5,  kFlag5, kFlag5, kFlag5,
+	kFlag4,  kFlag4, kFlag4, kFlag4,
+	kFlag3,  kFlag3, kFlag3, kFlag3, kFlag3
+};
+
+SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) {
+	_loopingSoundDuration = 0;
+
+	_queue = new SoundQueue(engine);
+
+	memset(&_lastWarning, 0, sizeof(_lastWarning));
+
+	// Initialize unknown data
+	_data0 = 0;
+	_data1 = 0;
+	_data2 = 0;
+}
+
+SoundManager::~SoundManager() {
+	SAFE_DELETE(_queue);
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound-related functions
+//////////////////////////////////////////////////////////////////////////
+void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
+	if (_queue->isBuffered(entity) && entity)
+		_queue->removeFromQueue(entity);
+
+	SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
+
+	// Add .SND at the end of the filename if needed
+	if (!filename.contains('.'))
+		filename += ".SND";
+
+	if (!playSoundWithSubtitles(filename, currentFlag, entity, a4))
+		if (entity)
+			getSavePoints()->push(kEntityPlayer, entity, kActionEndSound);
+}
+
+bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) {
+	SoundEntry *entry = new SoundEntry(_engine);
+
+	entry->open(filename, flag, 30);
+	entry->_entity = entity;
+
+	if (a4) {
+		entry->_field_48 = _data2 + 2 * a4;
+		entry->_status.status |= kSoundStatus_8000;
+	} else {
+		// Get subtitles name
+		while (filename.size() > 4)
+			filename.deleteLastChar();
+
+		entry->showSubtitle(filename);
+		entry->updateState();
+	}
+
+	return (entry->getType() != kSoundTypeNone);
+}
+
+void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
+	int values[5];
+
+	if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
+		return;
+
+	if (getEntities()->isInSalon(entity) != getEntities()->isInSalon(kEntityPlayer))
+		return;
+
+	int _action = (int)action;
+	SoundFlag flag = getSoundFlag(entity);
+
+	switch (action) {
+	case 36: {
+		int _param3 = (flag <= 9) ? flag + 7 : 16;
+
+		if (_param3 > 7) {
+			_data0 = (uint)_param3;
+			_data1 = _data2 + 2 * a3;
+		}
+		break;
+		}
+
+	case 37:
+		_data0 = 7;
+		_data1 = _data2 + 2 * a3;
+		break;
+
+	case 150:
+	case 156:
+	case 162:
+	case 168:
+	case 188:
+	case 198:
+		_action += 1 + (int)rnd(5);
+		break;
+
+	case 174:
+	case 184:
+	case 194:
+		_action += 1 + (int)rnd(3);
+		break;
+
+	case 180:
+		_action += 1 + (int)rnd(4);
+		break;
+
+	case 246:
+		values[0] = 0;
+		values[1] = 104;
+		values[2] = 105;
+		values[3] = 106;
+		values[4] = 116;
+		_action = values[rnd(5)];
+		break;
+
+	case 247:
+		values[0] = 11;
+		values[1] = 123;
+		values[2] = 124;
+		_action = values[rnd(3)];
+		break;
+
+	case 248:
+		values[0] = 0;
+		values[1] = 103;
+		values[2] = 108;
+		values[3] = 109;
+		_action = values[rnd(4)];
+		break;
+
+	case 249:
+		values[0] = 0;
+		values[1] = 56;
+		values[2] = 112;
+		values[3] = 113;
+		_action = values[rnd(4)];
+		break;
+
+	case 250:
+		values[0] = 0;
+		values[1] = 107;
+		values[2] = 115;
+		values[3] = 117;
+		_action = values[rnd(4)];
+		break;
+
+	case 251:
+		values[0] = 0;
+		values[1] = 11;
+		values[2] = 56;
+		values[3] = 113;
+		_action = values[rnd(4)];
+		break;
+
+	case 252:
+		values[0] = 0;
+		values[1] = 6;
+		values[2] = 109;
+		values[3] = 121;
+		_action = values[rnd(4)];
+		break;
+
+	case 254:
+		values[0] = 0;
+		values[1] = 104;
+		values[2] = 120;
+		values[3] = 121;
+		_action = values[rnd(4)];
+		break;
+
+	case 255:
+		values[0] = 0;
+		values[1] = 106;
+		values[2] = 115;
+		_action = values[rnd(3)];
+		break;
+
+	default:
+		break;
+	}
+
+	if (_action && flag)
+		playSoundWithSubtitles(Common::String::format("LIB%03d.SND", _action), flag, kEntityPlayer, a3);
+}
+
+void SoundManager::playSteam(CityIndex index) {
+	if (index >= ARRAYSIZE(cities))
+		error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
+
+	_queue->resetState(kSoundState2);
+
+	if (!_queue->getEntry(kSoundType1))
+		playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam);
+
+	// Get the new sound entry and show subtitles
+	SoundEntry *entry = _queue->getEntry(kSoundType1);
+	if (entry)
+		entry->showSubtitle(cities[index]);
+}
+
+void SoundManager::playFightSound(byte action, byte a4) {
+	int _action = (int)action;
+	int values[5];
+
+	switch (action) {
+	default:
+		break;
+
+	case 174:
+	case 184:
+	case 194:
+		values[0] = action + 1;
+		values[1] = action + 2;
+		values[2] = action + 3;
+		_action = values[rnd(3)];
+		break;
+
+	case 180:
+		values[0] = action + 1;
+		values[1] = action + 2;
+		values[2] = action + 3;
+		values[3] = action + 4;
+		_action = values[rnd(4)];
+		break;
+
+	case 150:
+	case 156:
+	case 162:
+	case 168:
+	case 188:
+	case 198:
+		values[0] = action + 1;
+		values[1] = action + 2;
+		values[2] = action + 3;
+		values[3] = action + 4;
+		values[4] = action + 5;
+		_action = values[rnd(5)];
+		break;
+	}
+
+	if (_action)
+		playSound(kEntityTrain, Common::String::format("LIB%03d.SND", _action), kFlagDefault, a4);
+}
+
+void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) {
+	if (_queue->isBuffered(getDialogName(entityDialog)))
+		_queue->removeFromQueue(getDialogName(entityDialog));
+
+	playSound(entity, getDialogName(entityDialog), flag, a4);
+}
+
+void SoundManager::playLocomotiveSound() {
+	playSound(kEntityPlayer, locomotiveSounds[rnd(5)], (SoundFlag)(rnd(15) + 2));
+}
+
+const char *SoundManager::getDialogName(EntityIndex entity) const {
+	switch (entity) {
+	case kEntityAnna:
+		if (getEvent(kEventAnnaDialogGoToJerusalem))
+			return "XANN12";
+
+		if (getEvent(kEventLocomotiveRestartTrain))
+			return "XANN11";
+
+		if (getEvent(kEventAnnaBaggageTies) || getEvent(kEventAnnaBaggageTies2) || getEvent(kEventAnnaBaggageTies3) || getEvent(kEventAnnaBaggageTies4))
+			return "XANN10";
+
+		if (getEvent(kEventAnnaTired) || getEvent(kEventAnnaTiredKiss))
+			return "XANN9";
+
+		if (getEvent(kEventAnnaBaggageArgument))
+			return "XANN8";
+
+		if (getEvent(kEventKronosVisit))
+			return "XANN7";
+
+		if (getEvent(kEventAbbotIntroduction))
+			return "XANN6A";
+
+		if (getEvent(kEventVassiliSeizure))
+			return "XANN6";
+
+		if (getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction))
+			return "XANN5";
+
+		if (getProgress().field_60)
+			return "XANN4";
+
+		if (getEvent(kEventAnnaGiveScarf) || getEvent(kEventAnnaGiveScarfDiner) || getEvent(kEventAnnaGiveScarfSalon)
+		 || getEvent(kEventAnnaGiveScarfMonogram) || getEvent(kEventAnnaGiveScarfDinerMonogram) || getEvent(kEventAnnaGiveScarfSalonMonogram))
+			return "XANN3";
+
+		if (getEvent(kEventDinerMindJoin))
+			return "XANN2";
+
+		if (getEvent(kEventGotALight) || getEvent(kEventGotALightD))
+			return "XANN1";
+
+		break;
+
+	case kEntityAugust:
+		if (getEvent(kEventAugustTalkCigar))
+			return "XAUG6";
+
+		if (getEvent(kEventAugustBringBriefcase))
+			return "XAUG5";
+
+		// Getting closer to Vienna...
+		if (getState()->time > kTime2200500 && !getEvent(kEventAugustMerchandise))
+			return "XAUG4A";
+
+		if (getEvent(kEventAugustMerchandise))
+			return "XAUG4";
+
+		if (getEvent(kEventDinerAugust) || getEvent(kEventDinerAugustAlexeiBackground) || getEvent(kEventMeetAugustTylerCompartment)
+		 || getEvent(kEventMeetAugustTylerCompartmentBed) || getEvent(kEventMeetAugustHisCompartment) || getEvent(kEventMeetAugustHisCompartmentBed))
+			return "XAUG3";
+
+		if (getEvent(kEventAugustPresentAnnaFirstIntroduction))
+			return "XAUG2";
+
+		if (getProgress().eventMertensAugustWaiting)
+			return "XAUG1";
+
+		break;
+
+	case kEntityTatiana:
+		if (getEvent(kEventTatianaTylerCompartment))
+			return "XTAT6";
+
+		if (getEvent(kEventTatianaCompartmentStealEgg))
+			return "XTAT5";
+
+		if (getEvent(kEventTatianaGivePoem))
+			return "XTAT3";
+
+		if (getProgress().field_64)
+			return "XTAT1";
+
+		break;
+
+	case kEntityVassili:
+		if (getEvent(kEventCathFreePassengers))
+			return "XVAS4";
+
+		if (getEvent(kEventVassiliCompartmentStealEgg))
+			return "XVAS3";
+
+		if (getEvent(kEventAbbotIntroduction))
+			return "XVAS2";
+
+		if (getEvent(kEventVassiliSeizure))
+			return "XVAS1A";
+
+		if (getProgress().field_64)
+			return "XVAS1";
+
+		break;
+
+	case kEntityAlexei:
+		if (getProgress().field_88)
+			return "XALX6";
+
+		if (getProgress().field_8C)
+			return "XALX5";
+
+		if (getProgress().field_90)
+			return "XALX4A";
+
+		if (getProgress().field_68)
+			return "XALX4";
+
+		if (getEvent(kEventAlexeiSalonPoem))
+			return "XALX3";
+
+		if (getEvent(kEventAlexeiSalonVassili))
+			return "XALX2";
+
+		if (getEvent(kEventAlexeiDiner) || getEvent(kEventAlexeiDinerOriginalJacket))
+			return "XALX1";
+
+		break;
+
+	case kEntityAbbot:
+		if (getEvent(kEventAbbotDrinkDefuse))
+			return "XABB4";
+
+		if (getEvent(kEventAbbotInvitationDrink) || getEvent(kEventDefuseBomb))
+			return "XABB3";
+
+		if (getEvent(kEventAbbotWrongCompartment) || getEvent(kEventAbbotWrongCompartmentBed))
+			return "XABB2";
+
+		if (getEvent(kEventAbbotIntroduction))
+			return "XABB1";
+
+		break;
+
+	case kEntityMilos:
+		if (getEvent(kEventLocomotiveMilosDay) || getEvent(kEventLocomotiveMilosNight))
+			return "XMIL5";
+
+		if (getEvent(kEventMilosCompartmentVisitTyler) && (getProgress().chapter == kChapter3 || getProgress().chapter == kChapter4))
+			return "XMIL4";
+
+		if (getEvent(kEventMilosCorridorThanks) || getProgress().chapter == kChapter5)
+			return "XMIL3";
+
+		if (getEvent(kEventMilosCompartmentVisitAugust))
+			return "XMIL2";
+
+		if (getEvent(kEventMilosTylerCompartmentDefeat))
+			return "XMIL1";
+
+		break;
+
+	case kEntityVesna:
+		if (getProgress().field_94)
+			return "XVES2";
+
+		if (getProgress().field_98)
+			return "XVES1";
+
+		break;
+
+	case kEntityKronos:
+		if (getEvent(kEventKronosReturnBriefcase))
+			return "XKRO6";
+
+		if (getEvent(kEventKronosBringEggCeiling) || getEvent(kEventKronosBringEgg))
+			return "XKRO5";
+
+		if (getEvent(kEventKronosConversation) || getEvent(kEventKronosConversationFirebird)) {
+			ObjectLocation location = getInventory()->get(kItemFirebird)->location;
+			if (location != kObjectLocation6 && location != kObjectLocation5 && location != kObjectLocation2 && location != kObjectLocation1)
+				return "XKRO4A";
+		}
+
+		if (getEvent(kEventKronosConversationFirebird))
+			return "XKRO4";
+
+		if (getEvent(kEventKronosConversation)) {
+			if (!getEvent(kEventMilosCompartmentVisitAugust))
+				return "XKRO3";
+			else
+				return "XKRO2";
+		}
+
+		if (getProgress().eventMertensKronosInvitation)
+			return "XKRO1";
+
+		break;
+
+	case kEntityFrancois:
+		if (getProgress().field_9C)
+			return "XFRA3";
+
+		if (getProgress().field_A0
+		 || getEvent(kEventFrancoisWhistle) || getEvent(kEventFrancoisWhistleD)
+		 || getEvent(kEventFrancoisWhistleNight) || getEvent(kEventFrancoisWhistleNightD))
+			return "XFRA2";
+
+		if (getState()->time > kTimeParisEpernay) // Between Paris and Epernay
+			return "XFRA1";
+
+		break;
+
+	case kEntityMmeBoutarel:
+		if (getProgress().field_A4)
+			return "XMME4";
+
+		if (getProgress().field_A8)
+			return "XMME3";
+
+		if (getProgress().field_A0)
+			return "XMME2";
+
+		if (getProgress().field_AC)
+			return "XMME1";
+
+		break;
+
+	case kEntityBoutarel:
+		if (getProgress().eventMetBoutarel)
+			return "XMRB1";
+
+		break;
+
+	case kEntityRebecca:
+		if (getProgress().field_B4)
+			return "XREB1A";
+
+		if (getProgress().field_B8)
+			return "XREB1";
+
+		break;
+
+	case kEntitySophie:
+		if (getProgress().field_B0)
+			return "XSOP2";
+
+		if (getProgress().field_BC)
+			return "XSOP1B";
+
+		if (getProgress().field_B4)
+			return "XSOP1A";
+
+		if (getProgress().field_B8)
+			return "XSOP1";
+
+		break;
+
+	case kEntityMahmud:
+		if (getProgress().field_C4)
+			return "XMAH1";
+
+		break;
+
+	case kEntityYasmin:
+		if (getProgress().eventMetYasmin)
+			return "XHAR2";
+
+		break;
+
+	case kEntityHadija:
+		if (getProgress().eventMetHadija)
+			return "XHAR1";
+
+		break;
+
+	case kEntityAlouan:
+		if (getProgress().field_DC)
+			return "XHAR3";
+
+		break;
+
+	case kEntityGendarmes:
+		if (getProgress().field_E0)
+			return "XHAR4";
+
+		break;
+
+	case kEntityChapters:
+		if (getEvent(kEventCathDream) || getEvent(kEventCathWakingUp))
+			return "XTYL3";
+
+		return "XTYL1";
+
+	default:
+		break;
+	}
+
+	return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Letters & Messages
+//////////////////////////////////////////////////////////////////////////
+void SoundManager::readText(int id){
+	if (!_queue->isBuffered(kEntityTables4))
+		return;
+
+	if (id < 0 || (id > 8 && id < 50) || id > 64)
+		error("Sound::readText - attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
+
+	// Get proper message file (names are stored in sequence in the array but id is [1;8] - [50;64])
+	const char *text = messages[id <= 8 ? id : id - 41];
+
+	// Check if file is in cache for id [1;8]
+	if (id <= 8)
+		if (_queue->isBuffered(text))
+			_queue->removeFromQueue(text);
+
+	playSound(kEntityTables4, text, kFlagDefault);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound bites
+//////////////////////////////////////////////////////////////////////////
+void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compartment) {
+
+#define PLAY_WARNING(index, sound1, sound2, sound3, sound4, sound5, sound6) { \
+	if (_lastWarning[index] + 450 >= getState()->timeTicks) { \
+		if (rnd(2)) \
+			playSound(kEntityMertens, sound1, kFlagDefault); \
+		else \
+			playSound(kEntityMertens, rnd(2) ? sound2 : sound3, kFlagDefault); \
+	} else { \
+		if (rnd(2)) \
+			playSound(kEntityMertens, sound4, kFlagDefault); \
+		else \
+			playSound(kEntityMertens, rnd(2) ? sound5 : sound6, kFlagDefault); \
+	} \
+	_lastWarning[index] = getState()->timeTicks; \
+}
+
+	if (entity != kEntityMertens && entity != kEntityCoudert)
+		return;
+
+	//////////////////////////////////////////////////////////////////////////
+	// Mertens
+	if (entity == kEntityMertens) {
+
+		switch (compartment) {
+		default:
+			break;
+
+		case kObjectCompartment2:
+			PLAY_WARNING(0, "Con1502A", "Con1500B", "Con1500C", "Con1502", "Con1500", "Con1500A");
+			break;
+
+		case kObjectCompartment3:
+			PLAY_WARNING(1, "Con1501A", "Con1500B", "Con1500C", "Con1501", "Con1500", "Con1500A");
+			break;
+
+		case kObjectCompartment4:
+			PLAY_WARNING(2, "Con1503", "Con1500B", "Con1500C", "Con1503", "Con1500", "Con1500A");
+			break;
+
+		case kObjectCompartment5:
+		case kObjectCompartment6:
+		case kObjectCompartment7:
+		case kObjectCompartment8:
+			++_lastWarning[3];
+
+			switch (_lastWarning[3]) {
+			default:
+				break;
+
+			case 1:
+				getSound()->playSound(kEntityMertens, "Con1503C", kFlagDefault);
+				break;
+
+			case 2:
+				getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503E" : "Con1503A", kFlagDefault);
+				break;
+
+			case 3:
+				getSound()->playSound(kEntityMertens, rnd(2) ? "Con1503B" : "Con1503D", kFlagDefault);
+				_lastWarning[3] = 0;
+				break;
+			}
+		}
+
+		return;
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	// Coudert
+	switch (compartment) {
+		default:
+			break;
+
+		case kObjectCompartmentA:
+			if (_lastWarning[4] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1508" : "Jac1508A", kFlagDefault);
+			break;
+
+		case kObjectCompartmentB:
+			if (_lastWarning[5] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (getProgress().field_40 || (getState()->time > kTimeCityLinz && getState()->time < kTime2133000))
+				getSound()->playSound(kEntityCoudert, "Jac1507A", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, "Jac1507", kFlagDefault);
+			break;
+
+		case kObjectCompartmentC:
+			if (_lastWarning[6] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (getProgress().chapter < kChapter3)
+				getSound()->playSound(kEntityCoudert, "Jac1506", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1506A" : "Jac1506B", kFlagDefault);
+			break;
+
+		case kObjectCompartmentD:
+			if (_lastWarning[7] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			getSound()->playSound(kEntityCoudert, "Jac1505", kFlagDefault);
+			break;
+
+		case kObjectCompartmentE:
+			if (_lastWarning[8] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (getProgress().field_40 || (getState()->time > kTime2115000 && getState()->time < kTime2133000)) {
+				getSound()->playSound(kEntityCoudert, "Jac1504B", kFlagDefault);
+				break;
+			}
+
+			if (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840))
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1504" : "Jac1504A", kFlagDefault);
+			break;
+
+		case kObjectCompartmentF:
+			if (_lastWarning[9] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (getProgress().field_40 || (getState()->time > kTime2083500 && getState()->time < kTime2133000)) {
+				getSound()->playSound(kEntityCoudert, "Jac1503B", kFlagDefault);
+				break;
+			}
+
+			if (rnd(2) || getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070))
+				getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, "Jac1503A", kFlagDefault);
+			break;
+
+		case kObjectCompartmentG:
+			if (_lastWarning[10] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (rnd(2) || getEntities()->isInsideCompartment(kEntityMilos, kCarRedSleeping, kPosition_3050))
+				getSound()->playSound(kEntityCoudert, "Jac1502", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, "Jac1502A", kFlagDefault);
+			break;
+
+		case kObjectCompartmentH:
+			if (_lastWarning[11] + 450 >= getState()->timeTicks) {
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+				break;
+			}
+
+			if (getEntities()->isInsideCompartment(kEntityIvo, kCarRedSleeping, kPosition_2740))
+				getSound()->playSound(kEntityCoudert, rnd(2) ? "Jac1500" : "Jac1500A", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, "Jac1501", kFlagDefault);
+			break;
+	}
+
+	// Update ticks (Compartments A - H are indexes 4 - 11)
+	_lastWarning[compartment - 28] = getState()->timeTicks;
+}
+
+void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) {
+	if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain)
+		return;
+
+	if (entity2 == kEntityFrancois || entity2 == kEntityMax)
+		return;
+
+	if (entity == kEntityFrancois && getEntityData(kEntityFrancois)->field_4A3 != 30)
+		return;
+
+	if (flag == kFlagNone)
+		flag = getSoundFlag(entity);
+
+	switch (entity) {
+	default:
+		break;
+
+	case kEntityAnna:
+		playSound(kEntityPlayer, "ANN1107A", flag);
+		break;
+
+	case kEntityAugust:
+		switch(rnd(4)) {
+		default:
+			break;
+
+		case 0:
+			playSound(kEntityPlayer, "AUG1100A", flag);
+			break;
+
+		case 1:
+			playSound(kEntityPlayer, "AUG1100B", flag);
+			break;
+
+		case 2:
+			playSound(kEntityPlayer, "AUG1100C", flag);
+			break;
+
+		case 3:
+			playSound(kEntityPlayer, "AUG1100D", flag);
+			break;
+		}
+		break;
+
+	case kEntityMertens:
+		if (Entities::isFemale(entity2)) {
+			playSound(kEntityPlayer, (rnd(2) ? "CON1111" : "CON1111A"), flag);
+		} else {
+			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+				switch(rnd(3)) {
+				default:
+					break;
+
+				case 0:
+					playSound(kEntityPlayer, "CON1110A", flag);
+					break;
+
+				case 1:
+					playSound(kEntityPlayer, "CON1110C", flag);
+					break;
+
+				case 2:
+					playSound(kEntityPlayer, "CON1110", flag);
+					break;
+				}
+			} else {
+				if (isNight()) {
+					playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"));
+				} else {
+					playSound(kEntityPlayer, "CON1110D");
+				}
+			}
+		}
+		break;
+
+	case kEntityCoudert:
+		if (Entities::isFemale(entity2)) {
+			playSound(kEntityPlayer, "JAC1111D", flag);
+		} else {
+			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+				switch(rnd(4)) {
+				default:
+					break;
+
+				case 0:
+					playSound(kEntityPlayer, "JAC1111", flag);
+					break;
+
+				case 1:
+					playSound(kEntityPlayer, "JAC1111A", flag);
+					break;
+
+				case 2:
+					playSound(kEntityPlayer, "JAC1111B", flag);
+					break;
+
+				case 3:
+					playSound(kEntityPlayer, "JAC1111C", flag);
+					break;
+				}
+			} else {
+				playSound(kEntityPlayer, "JAC1113B", flag);
+			}
+		}
+		break;
+
+	case kEntityPascale:
+		playSound(kEntityPlayer, (rnd(2) ? "HDE1002" : "HED1002A"), flag);
+		break;
+
+	case kEntityServers0:
+	case kEntityServers1:
+		switch(rnd(3)) {
+		default:
+			break;
+
+		case 0:
+			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002" : "WAT1003", flag);
+			break;
+
+		case 1:
+			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002A" : "WAT1003A", flag);
+			break;
+
+		case 2:
+			playSound(kEntityPlayer, (entity == kEntityServers0) ? "WAT1002B" : "WAT1003B", flag);
+			break;
+		}
+		break;
+
+	case kEntityVerges:
+		if (Entities::isFemale(entity2)) {
+			playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"));
+		} else {
+			playSound(kEntityPlayer, "TRA1112", flag);
+		}
+		break;
+
+	case kEntityTatiana:
+		playSound(kEntityPlayer, (rnd(2) ? "TAT1102A" : "TAT1102B"), flag);
+		break;
+
+	case kEntityAlexei:
+		playSound(kEntityPlayer, (rnd(2) ? "ALX1099C" : "ALX1099D"), flag);
+		break;
+
+	case kEntityAbbot:
+		if (Entities::isFemale(entity2)) {
+			playSound(kEntityPlayer, "ABB3002C", flag);
+		} else {
+			switch(rnd(3)) {
+			default:
+				break;
+
+			case 0:
+				playSound(kEntityPlayer, "ABB3002", flag);
+				break;
+
+			case 1:
+				playSound(kEntityPlayer, "ABB3002A", flag);
+				break;
+
+			case 2:
+				playSound(kEntityPlayer, "ABB3002B", flag);
+				break;
+			}
+		}
+		break;
+
+	case kEntityVesna:
+		switch(rnd(3)) {
+		default:
+			break;
+
+		case 0:
+			playSound(kEntityPlayer, "VES1109A", flag);
+			break;
+
+		case 1:
+			playSound(kEntityPlayer, "VES1109B", flag);
+			break;
+
+		case 2:
+			playSound(kEntityPlayer, "VES1109C", flag);
+			break;
+		}
+		break;
+
+	case kEntityKahina:
+		playSound(kEntityPlayer, (rnd(2) ? "KAH1001" : "KAH1001A"), flag);
+		break;
+
+	case kEntityFrancois:
+	case kEntityMmeBoutarel:
+		switch(rnd(4)) {
+		default:
+			break;
+
+		case 0:
+			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001" : "MME1103A", flag);
+			break;
+
+		case 1:
+			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001A" : "MME1103B", flag);
+			break;
+
+		case 2:
+			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001B" : "MME1103C", flag);
+			break;
+
+		case 3:
+			playSound(kEntityPlayer, (entity == kEntityFrancois) ? "FRA1001C" : "MME1103D", flag);
+			break;
+		}
+		break;
+
+	case kEntityBoutarel:
+		playSound(kEntityPlayer, "MRB1104", flag);
+		if (flag > 2)
+			getProgress().eventMetBoutarel = true;
+		break;
+
+	case kEntityRebecca:
+		playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "REB110A"), flag);
+		break;
+
+	case kEntitySophie: {
+		switch(rnd(3)) {
+		default:
+			break;
+
+		case 0:
+			playSound(kEntityPlayer, "SOP1105", flag);
+			break;
+
+		case 1:
+			playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105C" : "SOP1105A", flag);
+			break;
+
+		case 2:
+			playSound(kEntityPlayer, Entities::isFemale(entity2) ? "SOP1105D" : "SOP1105B", flag);
+			break;
+		}
+		break;
+	}
+
+	case kEntityMahmud:
+		playSound(kEntityPlayer, "MAH1101", flag);
+		break;
+
+	case kEntityYasmin:
+		playSound(kEntityPlayer, "HAR1002", flag);
+		if (flag > 2)
+			getProgress().eventMetYasmin = true;
+		break;
+
+	case kEntityHadija:
+		playSound(kEntityPlayer, (rnd(2) ? "HAR1001" : "HAR1001A"), flag);
+		if (flag > 2)
+			getProgress().eventMetHadija = true;
+		break;
+
+	case kEntityAlouan:
+		playSound(kEntityPlayer, "HAR1004", flag);
+		break;
+	}
+}
+
+void SoundManager::excuseMeCath() {
+	switch(rnd(3)) {
+	default:
+		playSound(kEntityPlayer, "CAT1126B");
+		break;
+
+	case 1:
+		playSound(kEntityPlayer, "CAT1126C");
+		break;
+
+	case 2:
+		playSound(kEntityPlayer, "CAT1126D");
+		break;
+	}
+}
+
+const char *SoundManager::justCheckingCath() const {
+	switch(rnd(4)) {
+	default:
+		break;
+
+	case 0:
+		return "CAT5001";
+
+	case 1:
+		return "CAT5001A";
+
+	case 2:
+		return "CAT5001B";
+
+	case 3:
+		return "CAT5001C";
+	}
+
+	return "CAT5001";
+}
+
+const char *SoundManager::wrongDoorCath() const {
+	switch(rnd(5)) {
+	default:
+		break;
+
+	case 0:
+		return "CAT1125";
+
+	case 1:
+		return "CAT1125A";
+
+	case 2:
+		return "CAT1125B";
+
+	case 3:
+		return "CAT1125C";
+
+	case 4:
+		return "CAT1125D";
+	}
+
+	return "CAT1125";
+}
+
+const char *SoundManager::justAMinuteCath() const {
+	switch(rnd(3)) {
+	default:
+		break;
+
+	case 0:
+		return "CAT1520";
+
+	case 1:
+		return "CAT1521";
+
+	case 2:
+		return "CAT1125";    // ?? is this a bug in the original?
+	}
+
+	return "CAT1520";
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sound flags
+//////////////////////////////////////////////////////////////////////////
+SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
+	if (entity == kEntityPlayer)
+		return kFlagDefault;
+
+	if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
+		return kFlagNone;
+
+	// Compute sound value
+	SoundFlag ret = kFlag2;
+
+	// Get default value if valid
+	int index = ABS(getEntityData(entity)->entityPosition - getEntityData(kEntityPlayer)->entityPosition) / 230;
+	if (index < 32)
+		ret = soundFlags[index];
+
+	if (getEntityData(entity)->location == kLocationOutsideTrain) {
+		if (getEntityData(entity)->car != kCarKronos
+		&& !getEntities()->isOutsideAlexeiWindow()
+		&& !getEntities()->isOutsideAnnaWindow())
+			return kFlagNone;
+
+		return (SoundFlag)(ret / 6);
+	}
+
+	switch (getEntityData(entity)->car) {
+	default:
+		break;
+
+	case kCarKronos:
+		if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
+			ret = (SoundFlag)(ret * 2);
+		break;
+
+	case kCarGreenSleeping:
+	case kCarRedSleeping:
+		if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
+			ret = (SoundFlag)(ret * 2);
+
+		if (getEntityData(kEntityPlayer)->location
+		&& (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
+			ret = (SoundFlag)(ret * 2);
+		break;
+
+	case kCarRestaurant:
+		if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
+		&& (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
+			ret = (SoundFlag)(ret * 2);
+		else
+			ret = (SoundFlag)(ret * 4);
+		break;
+	}
+
+	return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Misc
+//////////////////////////////////////////////////////////////////////////
+void SoundManager::playLoopingSound(int param) {
+	SoundEntry *entry = _queue->getEntry(kSoundType1);
+
+	static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
+	                                             kPosition_6470, kPosition_5790,
+	                                             kPosition_4840, kPosition_4070,
+	                                             kPosition_3050, kPosition_2740 };
+
+	byte numLoops[8];
+	numLoops[1] = 4;
+	numLoops[2] = 2;
+	numLoops[3] = 2;
+	numLoops[4] = 2;
+	numLoops[5] = 2;
+	numLoops[6] = 2;
+
+	char tmp[80];
+	tmp[0] = 0;
+
+	int partNumber = 1;
+	int fnameLen = 6;
+
+	if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) {
+		if (_queue->getSoundState() & 2) {
+			strcpy(tmp, "STEAM.SND");
+
+			_loopingSoundDuration = 32767;
+		} else {
+			if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
+				partNumber = 6;
+			} else {
+				if (getEntities()->isInsideCompartments(kEntityPlayer)) {
+					int objNum = (getEntityData(kEntityPlayer)->car - 3) < 1 ? 9 : 40; // Weird numbers
+
+					numLoops[0] = 0;
+
+					for (int pos = 0; pos < 8; pos++) {
+						if (numLoops[0])
+							break;
+						if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
+							numLoops[0] = 1;
+							partNumber = (getObjects()->get((ObjectIndex)objNum).location - 2) < 1 ? 6 : 1;
+						}
+						objNum++;
+					}
+				} else {
+					switch (getEntityData(kEntityPlayer)->car) {
+					case 1:
+					case 6:
+						partNumber = 4;
+						break;
+					case 2:
+					case 3:
+					case 4:
+					case 5:
+						partNumber = 1;
+						break;
+					case 7:
+						partNumber = 5;
+						break;
+					case 8:
+						partNumber = 99;
+						break;
+					case 9:
+						partNumber = 3;
+						break;
+					default:
+						partNumber = 6;
+						break;
+					}
+				}
+			}
+
+			if (partNumber != 99)
+				sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A');
+		}
+
+		if (getFlags()->flag_3)
+			fnameLen = 5;
+
+		if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) {
+			_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
+
+			if (partNumber != 99) {
+				playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam);
+
+				if (entry)
+					entry->update(0);
+
+				SoundEntry *entry1 = _queue->getEntry(kSoundType1);
+				if (entry1)
+					entry1->update(7);
+			}
+		}
+	}
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/sound.h b/engines/lastexpress/sound/sound.h
new file mode 100644
index 0000000..797e526
--- /dev/null
+++ b/engines/lastexpress/sound/sound.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LASTEXPRESS_SOUND_H
+#define LASTEXPRESS_SOUND_H
+
+#include "lastexpress/shared.h"
+
+#include "common/str.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SoundQueue;
+
+class SoundManager {
+public:
+	SoundManager(LastExpressEngine *engine);
+	~SoundManager();
+
+	// Sound playing
+	void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0);
+	bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0);
+	void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
+	void playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4);
+	void playSteam(CityIndex index);
+	void playFightSound(byte action, byte a4);
+	void playLocomotiveSound();
+	void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
+	void playLoopingSound(int param);
+
+	// Dialog & Letters
+	void readText(int id);
+	const char *getDialogName(EntityIndex entity) const;
+
+	// Sound bites
+	void excuseMe(EntityIndex entity, EntityIndex entity2 = kEntityPlayer, SoundFlag flag = kFlagNone);
+	void excuseMeCath();
+	const char *justCheckingCath() const;
+	const char *wrongDoorCath() const;
+	const char *justAMinuteCath() const;
+
+	// Flags
+	SoundFlag getSoundFlag(EntityIndex index) const;
+
+	// Accessors
+	SoundQueue *getQueue() { return _queue; }
+	uint32 getData2() { return _data2; }
+
+private:
+	LastExpressEngine *_engine;
+	SoundQueue *_queue;
+
+	// Compartment warnings by Mertens or Coudert
+	uint32 _lastWarning[12];
+
+	// Looping sound
+	int _loopingSoundDuration;
+
+	// Unknown data
+	uint32 _data0;
+	uint32 _data1;
+	uint32 _data2;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SOUND_H


Commit: b4ac4988cca41c2a59e4de99b8fe5392372e21dd
    https://github.com/scummvm/scummvm/commit/b4ac4988cca41c2a59e4de99b8fe5392372e21dd
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-28T19:54:51-07:00

Commit Message:
LASTEXPRESS: Cleanup comments

Changed paths:
    engines/lastexpress/data/animation.cpp
    engines/lastexpress/data/background.cpp
    engines/lastexpress/data/font.cpp
    engines/lastexpress/data/scene.cpp
    engines/lastexpress/data/sequence.cpp
    engines/lastexpress/data/snd.cpp
    engines/lastexpress/data/subtitle.cpp
    engines/lastexpress/entities/entity.cpp
    engines/lastexpress/entities/entity.h
    engines/lastexpress/entities/entity_intern.h
    engines/lastexpress/entities/train.cpp
    engines/lastexpress/fight/fight.cpp
    engines/lastexpress/game/action.cpp
    engines/lastexpress/game/beetle.cpp
    engines/lastexpress/game/entities.cpp
    engines/lastexpress/game/inventory.cpp
    engines/lastexpress/game/logic.cpp
    engines/lastexpress/game/object.cpp
    engines/lastexpress/game/savegame.cpp
    engines/lastexpress/game/savepoint.cpp
    engines/lastexpress/game/scenes.cpp
    engines/lastexpress/game/state.cpp
    engines/lastexpress/game/state.h
    engines/lastexpress/graphics.cpp
    engines/lastexpress/lastexpress.cpp
    engines/lastexpress/menu/clock.cpp
    engines/lastexpress/menu/menu.cpp
    engines/lastexpress/menu/trainline.cpp
    engines/lastexpress/resource.cpp
    engines/lastexpress/sound/entry.cpp
    engines/lastexpress/sound/queue.cpp
    engines/lastexpress/sound/sound.cpp



diff --git a/engines/lastexpress/data/animation.cpp b/engines/lastexpress/data/animation.cpp
index 1cbf767..28d30ec 100644
--- a/engines/lastexpress/data/animation.cpp
+++ b/engines/lastexpress/data/animation.cpp
@@ -77,7 +77,7 @@ bool Animation::load(Common::SeekableReadStream *stream, int flag) {
 
 	// Check if there is enough data
 	if (_stream->size() - _stream->pos() < (signed)(numChunks * sizeof(Chunk))) {
-		debugC(2, kLastExpressDebugGraphics, "NIS file seems to be corrupted!");
+		debugC(2, kLastExpressDebugGraphics, "NIS file seems to be corrupted");
 		return false;
 	}
 
@@ -101,10 +101,10 @@ bool Animation::load(Common::SeekableReadStream *stream, int flag) {
 
 bool Animation::process() {
 	if (!_currentChunk)
-		error("Animation::process - internal error: the current chunk iterator is invalid!");
+		error("[Animation::process] Current chunk iterator is invalid");
 
 	if (_stream == NULL || _chunks.size() == 0)
-		error("Trying to show an animation before loading data");
+		error("[Animation::process] Trying to show an animation before loading data");
 
 	// TODO: - subtract the time paused by the GUI
 	//       - Re-implement to be closer to the original engine
@@ -191,7 +191,7 @@ bool Animation::process() {
 			break;
 
 		default:
-			error("  UNKNOWN chunk type=%x frame=%d size=%d", _currentChunk->type, _currentChunk->frame, _currentChunk->size);
+			error("[Animation::process] UNKNOWN chunk type=%x frame=%d size=%d", _currentChunk->type, _currentChunk->frame, _currentChunk->size);
 			break;
 		}
 		_currentChunk++;
@@ -206,7 +206,7 @@ bool Animation::hasEnded() {
 
 Common::Rect Animation::draw(Graphics::Surface *surface) {
 	if (!_overlay)
-		error("Animation::draw - internal error: the current overlay animation frame is invalid!");
+		error("[Animation::draw] Current overlay animation frame is invalid");
 
 	// Paint the background
 	if (_backgroundCurrent == 1 && _background1)
@@ -242,7 +242,7 @@ AnimFrame *Animation::processChunkFrame(Common::SeekableReadStream *in, const Ch
 
 void Animation::processChunkAudio(Common::SeekableReadStream *in, const Chunk &c) {
 	if (!_audio)
-		error("Animation::processChunkAudio - internal error: the audio stream is invalid!");
+		error("[Animation::processChunkAudio] Audio stream is invalid");
 
 	// Skip the Snd header, to queue just the audio blocks
 	uint32 size = c.size;
diff --git a/engines/lastexpress/data/background.cpp b/engines/lastexpress/data/background.cpp
index de6fd7e..3d866c2 100644
--- a/engines/lastexpress/data/background.cpp
+++ b/engines/lastexpress/data/background.cpp
@@ -85,7 +85,7 @@ bool Background::load(Common::SeekableReadStream *stream) {
 
 Common::Rect Background::draw(Graphics::Surface *surface) {
 	if (!_data) {
-		debugC(2, kLastExpressDebugGraphics, "Trying to show a background before loading data!");
+		debugC(2, kLastExpressDebugGraphics, "Trying to show a background before loading data");
 		return Common::Rect();
 	}
 
diff --git a/engines/lastexpress/data/font.cpp b/engines/lastexpress/data/font.cpp
index 9a60b88..79cf64e 100644
--- a/engines/lastexpress/data/font.cpp
+++ b/engines/lastexpress/data/font.cpp
@@ -89,17 +89,17 @@ bool Font::load(Common::SeekableReadStream *stream) {
 uint16 Font::getCharGlyph(uint16 c) const {
 	//warning("%c", c);
 	if (c >= 0x200)
-		error("Express::Font: Invalid character %d", c);
+		error("[Font::getCharGlyph] Invalid character %d", c);
 
 	return _charMap[c];
 }
 
 byte *Font::getGlyphImg(uint16 g) {
 	if (!_glyphs)
-		error("Express::getGlyphImg: Invalid glyphs!");
+		error("[Font::getGlyphImg] Invalid glyphs");
 
 	if (g >= _numGlyphs)
-		error("Express::getGlyphImg: Invalid glyph %d (%d available)", g, _numGlyphs);
+		error("[Font::getGlyphImg] Invalid glyph %d (%d available)", g, _numGlyphs);
 
 	return _glyphs + g * 18 * 8;
 }
@@ -140,7 +140,7 @@ uint8 Font::getCharWidth(uint16 c) const{
 		return 10;
 	} else {
 		if (!_glyphWidths)
-			error("Express::getCharWidth: Invalid glyphs widths!");
+			error("[Font::getCharWidth] Invalid glyphs widths");
 
 		return _glyphWidths[getCharGlyph(c)];
 	}
diff --git a/engines/lastexpress/data/scene.cpp b/engines/lastexpress/data/scene.cpp
index 2ec8e69..8f279ff 100644
--- a/engines/lastexpress/data/scene.cpp
+++ b/engines/lastexpress/data/scene.cpp
@@ -187,10 +187,10 @@ bool Scene::checkHotSpot(const Common::Point &coord, SceneHotspot **hotspot) {
 
 SceneHotspot *Scene::getHotspot(uint index) {
 	if (_hotspots.empty())
-		error("Scene::getHotspot: scene does not have any hotspots!");
+		error("[Scene::getHotspot] Scene does not have any hotspots");
 
 	if (index >= _hotspots.size())
-		error("Scene::getHotspot: invalid index (was: %d, max: %d)", index, _hotspots.size() - 1);
+		error("[Scene::getHotspot] Invalid index (was: %d, max: %d)", index, _hotspots.size() - 1);
 
 	return _hotspots[index];
 }
@@ -202,7 +202,7 @@ Common::Rect Scene::draw(Graphics::Surface *surface) {
 	Common::String sceneName(_name);
 	sceneName.trim();
 	if (sceneName.empty())
-		error("Scene::draw: This scene is not a valid drawing scene!");
+		error("[Scene::draw] This scene is not a valid drawing scene");
 
 	// Load background
 	Background *background = ((LastExpressEngine *)g_engine)->getResourceManager()->loadBackground(sceneName);
@@ -260,7 +260,7 @@ bool SceneLoader::load(Common::SeekableReadStream *stream) {
 	// Read the default scene to get the total number of scenes
 	Scene *header = Scene::load(_stream);
 	if (!header)
-		error("SceneLoader::load: Invalid data file!");
+		error("[SceneLoader::load] Invalid data file");
 
 	debugC(2, kLastExpressDebugScenes, "   found %d entries", header->entityPosition); /* Header entityPosition is the scene count */
 
diff --git a/engines/lastexpress/data/sequence.cpp b/engines/lastexpress/data/sequence.cpp
index a27c27d..a62348f 100644
--- a/engines/lastexpress/data/sequence.cpp
+++ b/engines/lastexpress/data/sequence.cpp
@@ -115,7 +115,7 @@ AnimFrame::AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f) : _pale
 		decompFF(in, f);
 		break;
 	default:
-		error("Unknown frame compression: %d", f.compressionType);
+		error("[AnimFrame::AnimFrame] Unknown frame compression: %d", f.compressionType);
 	}
 
 	readPalette(in, f);
@@ -379,11 +379,11 @@ bool Sequence::load(Common::SeekableReadStream *stream, byte field30) {
 		// Move stream to start of frame
 		_stream->seek((int32)(_sequenceHeaderSize + i * _sequenceFrameSize), SEEK_SET);
 		if (_stream->eos())
-			error("Couldn't seek to the current frame data");
+			error("[Sequence::load] Couldn't seek to the current frame data");
 
 		// Check if there is enough data
 		if ((unsigned)(_stream->size() - _stream->pos()) < _sequenceFrameSize)
-			error("The sequence frame does not have a valid header");
+			error("[Sequence::load] The sequence frame does not have a valid header");
 
 		FrameInfo info;
 		info.read(_stream, true);
@@ -397,10 +397,10 @@ bool Sequence::load(Common::SeekableReadStream *stream, byte field30) {
 
 FrameInfo *Sequence::getFrameInfo(uint16 index) {
 	if (_frames.size() == 0)
-		error("Trying to decode a sequence before loading its data");
+		error("[Sequence::getFrameInfo] Trying to decode a sequence before loading its data");
 
 	if (index > _frames.size() - 1)
-		error("Invalid sequence frame requested: %d, max %d", index, _frames.size() - 1);
+		error("[Sequence::getFrameInfo] Invalid sequence frame requested: %d, max %d", index, _frames.size() - 1);
 
 	return &_frames[index];
 }
@@ -463,14 +463,14 @@ bool SequenceFrame::nextFrame() {
 
 FrameInfo *SequenceFrame::getInfo() {
 	if (!_sequence)
-		error("SequenceFrame::getFrameInfo: Invalid sequence!");
+		error("[SequenceFrame::getInfo] Invalid sequence");
 
 	return _sequence->getFrameInfo(_frame);
 }
 
 Common::String SequenceFrame::getName() {
 	if (!_sequence)
-		error("SequenceFrame::getName: Invalid sequence!");
+		error("[SequenceFrame::getName] Invalid sequence");
 
 	return _sequence->getName();
 }
diff --git a/engines/lastexpress/data/snd.cpp b/engines/lastexpress/data/snd.cpp
index 3ffe3ca..d92ebbc 100644
--- a/engines/lastexpress/data/snd.cpp
+++ b/engines/lastexpress/data/snd.cpp
@@ -152,7 +152,7 @@ void AppendableSound::queueBuffer(const byte *data, uint32 size) {
 
 void AppendableSound::queueBuffer(Common::SeekableReadStream *bufferIn) {
 	if (!_as)
-		error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+		error("[AppendableSound::queueBuffer] Audio stream is invalid");
 
 	// Setup the ADPCM decoder
 	uint32 sizeIn = (uint32)bufferIn->size();
@@ -164,7 +164,7 @@ void AppendableSound::queueBuffer(Common::SeekableReadStream *bufferIn) {
 
 void AppendableSound::finish() {
 	if (!_as)
-		error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+		error("[AppendableSound::finish] Audio stream is invalid");
 
 	if (!_finished)
 		_as->finish();
diff --git a/engines/lastexpress/data/subtitle.cpp b/engines/lastexpress/data/subtitle.cpp
index c3a7397..0be832c 100644
--- a/engines/lastexpress/data/subtitle.cpp
+++ b/engines/lastexpress/data/subtitle.cpp
@@ -168,13 +168,13 @@ bool SubtitleManager::load(Common::SeekableReadStream *stream) {
 	// Read header to get the number of subtitles
 	uint32 numSubtitles = stream->readUint16LE();
 	if (stream->eos())
-		error("Cannot read from subtitle file");
+		error("[SubtitleManager::load] Cannot read from subtitle file");
 
 	debugC(3, kLastExpressDebugSubtitle, "Number of subtitles in file: %d", numSubtitles);
 
 	// TODO: Check that stream contain enough data
 	//if (stream->size() < (signed)(numSubtitles * sizeof(SubtitleData))) {
-		//debugC(2, kLastExpressDebugSubtitle, "Subtitle file does not contain valid data!");
+		//debugC(2, kLastExpressDebugSubtitle, "Subtitle file does not contain valid data");
 		//return false;
 	//}
 
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index 60efd70..e136ca4 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -105,24 +105,24 @@ void EntityData::EntityCallData::saveLoadWithSerializer(Common::Serializer &s) {
 //////////////////////////////////////////////////////////////////////////
 EntityData::EntityParameters *EntityData::getParameters(uint callback, byte index) const {
 	if (callback >= 9)
-		error("EntityData::getParameters: invalid callback value (was: %d, max: 9)", callback);
+		error("[EntityData::getParameters] Invalid callback value (was: %d, max: 9)", callback);
 
 	if (index >= 4)
-		error("EntityData::getParameters: invalid index value (was: %d, max: 4)", index);
+		error("[EntityData::getParameters] Invalid index value (was: %d, max: 4)", index);
 
 	return _parameters[callback].parameters[index];
 }
 
 int EntityData::getCallback(uint callback) const {
 	if (callback >= 16)
-		error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+		error("[EntityData::getCallback] Invalid callback value (was: %d, max: 16)", callback);
 
 	return _data.callbacks[callback];
 }
 
 void EntityData::setCallback(uint callback, byte index) {
 	if (callback >= 16)
-		error("EntityData::getParameters: invalid callback value (was: %d, max: 16)", callback);
+		error("[EntityData::setCallback] Invalid callback value (was: %d, max: 16)", callback);
 
 	_data.callbacks[callback] = index;
 }
@@ -137,7 +137,7 @@ void EntityData::updateParameters(uint32 index) const {
 	else if (index < 32)
 		getParameters(8, 3)->update(index - 24);
 	else
-		error("EntityData::updateParameters: invalid param index to update (was:%d, max:32)!", index);
+		error("[EntityData::updateParameters] Invalid param index to update (was:%d, max:32)", index);
 }
 
 void EntityData::saveLoadWithSerializer(Common::Serializer &s) {
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 6a4f416..039f461 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -85,7 +85,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersIIII::update: invalid index (was: %d)", index);
+				error("[EntityParametersIIII::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 1: param2 = 1; break;
@@ -134,7 +134,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersSIII::update: invalid index (was: %d)", index);
+				error("[EntityParametersSIII::update] Invalid index (was: %d)", index);
 
 			case 3: param4 = 1; break;
 			case 4: param5 = 1; break;
@@ -174,7 +174,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersSIIS::update: invalid index (was: %d)", index);
+				error("[EntityParametersSIIS::update] Invalid index (was: %d)", index);
 
 			case 3: param4 = 1; break;
 			case 4: param5 = 1; break;
@@ -209,7 +209,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersISSI::update: invalid index (was: %d)", index);
+				error("[EntityParametersISSI::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 7: param8 = 1; break;
@@ -248,7 +248,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersISII::update: invalid index (was: %d)", index);
+				error("[EntityParametersISII::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 4: param5 = 1; break;
@@ -288,7 +288,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersSSII::update: invalid index (was: %d)", index);
+				error("[EntityParametersSSII::update] Invalid index (was: %d)", index);
 
 			case 6: param7 = 1; break;
 			case 7: param8 = 1; break;
@@ -319,7 +319,7 @@ public:
 		}
 
 		void update(uint32) {
-			error("EntityParametersSSS::update: cannot update this type of parameters");
+			error("[EntityParametersSSS::update] Cannot update this type of parameters");
 		}
 
 		void saveLoadWithSerializer(Common::Serializer &s) {
@@ -349,7 +349,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersIISS::update: invalid index (was: %d)", index);
+				error("[EntityParametersIISS::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 1: param2 = 1; break;
@@ -388,7 +388,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersIISI::update: invalid index (was: %d)", index);
+				error("[EntityParametersIISI::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 1: param2 = 1; break;
@@ -432,7 +432,7 @@ public:
 		void update(uint32 index) {
 			switch (index) {
 			default:
-				error("EntityParametersIIIS::update: invalid index (was: %d)", index);
+				error("[EntityParametersIIIS::update] Invalid index (was: %d)", index);
 
 			case 0: param1 = 1; break;
 			case 1: param2 = 1; break;
diff --git a/engines/lastexpress/entities/entity_intern.h b/engines/lastexpress/entities/entity_intern.h
index 43d7f70..bf75e02 100644
--- a/engines/lastexpress/entities/entity_intern.h
+++ b/engines/lastexpress/entities/entity_intern.h
@@ -96,7 +96,7 @@ void class::setup_##name() { \
 #define EXPOSE_PARAMS(type) \
 	type *params = (type*)_data->getCurrentParameters(); \
 	if (!params) \
-		error("Trying to call an entity function with invalid parameters!"); \
+		error("[EXPOSE_PARAMS] Trying to call an entity function with invalid parameters"); \
 
 
 // function signature without setup (we keep the index for consistency but never use it)
@@ -413,7 +413,7 @@ void class::setup_##name() { \
 //////////////////////////////////////////////////////////////////////////
 #define CALLBACK_ACTION() { \
 	if (getData()->currentCall == 0) \
-		error("CALLBACK_ACTION: currentCall is already 0, cannot proceed!"); \
+		error("[CALLBACK_ACTION] currentCall is already 0, cannot proceed"); \
 	getData()->currentCall--; \
 	getSavePoints()->setCallback(_entityIndex, _callbacks[_data->getCurrentCallback()]); \
 	getSavePoints()->call(_entityIndex, _entityIndex, kActionCallback); \
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index 7d90ea5..bced1da 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -92,7 +92,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
 
 	switch (params->param1) {
 	default:
-		error("Train::harem: Invalid value for parameter 1: %d", params->param1);
+		error("[Train::harem] Invalid value for parameter 1: %d", params->param1);
 		break;
 
 	case kObjectCompartment5:
diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp
index 38a93cf..b832d46 100644
--- a/engines/lastexpress/fight/fight.cpp
+++ b/engines/lastexpress/fight/fight.cpp
@@ -162,7 +162,7 @@ void Fight::handleTick(const Common::Event &ev, bool isProcessing) {
 
 	// Blink egg
 	if (getGlobalTimer()) {
-		warning("Fight::handleMouseMove - egg blinking not implemented!");
+		warning("[Fight::handleTick] Egg blinking not implemented");
 	}
 
 	if (!_data || _data->index)
@@ -197,7 +197,7 @@ void Fight::handleTick(const Common::Event &ev, bool isProcessing) {
 //////////////////////////////////////////////////////////////////////////
 Fight::FightEndType Fight::setup(FightType type) {
 	if (_data)
-		error("Fight::setup - calling fight setup again while a fight is already in progress!");
+		error("[Fight::setup] Calling fight setup again while a fight is already in progress");
 
 	//////////////////////////////////////////////////////////////////////////
 	// Prepare UI & state
@@ -320,7 +320,7 @@ void Fight::clearData() {
 //////////////////////////////////////////////////////////////////////////
 void Fight::loadData(FightType type) {
 	if (!_data)
-		error("Fight::loadData - invalid data!");
+		error("[Fight::loadData] Data not initialized");
 
 	switch (type) {
 	default:
@@ -353,7 +353,7 @@ void Fight::loadData(FightType type) {
 	}
 
 	if (!_data->player || !_data->opponent)
-		error("Fight::loadData - error loading fight data (type=%d)", type);
+		error("[Fight::loadData] Error loading fight data (type=%d)", type);
 
 	// Setup opponent pointers
 	setOpponents();
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index 2c7b5b3..2ef4c20 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -407,7 +407,7 @@ SceneIndex Action::processHotspot(const SceneHotspot &hotspot) {
 //////////////////////////////////////////////////////////////////////////
 // Action 0
 IMPLEMENT_ACTION(dummy)
-	warning("Action::action_dummy: Dummy action function called (hotspot action: %d)!", hotspot.action);
+	warning("[Action::action_dummy] Dummy action function called (hotspot action: %d)", hotspot.action);
 
 	return kSceneInvalid;
 }
@@ -1910,7 +1910,7 @@ LABEL_KEY:
 // Play an animation and add delta time to global game time
 void Action::playAnimation(EventIndex index, bool debugMode) const {
 	if (index >= _animationListSize)
-		error("Action::playAnimation: invalid event index (value=%i, max=%i)", index, _animationListSize);
+		error("[Action::playAnimation] Invalid event index (value=%i, max=%i)", index, _animationListSize);
 
 	// In debug mode, just show the animation
 	if (debugMode) {
diff --git a/engines/lastexpress/game/beetle.cpp b/engines/lastexpress/game/beetle.cpp
index cb6f0a3..ab707dd 100644
--- a/engines/lastexpress/game/beetle.cpp
+++ b/engines/lastexpress/game/beetle.cpp
@@ -131,7 +131,7 @@ bool Beetle::isLoaded() const {
 
 bool Beetle::catchBeetle() {
 	if (!_data)
-		error("Beetle::catchBeetle: sequences have not been loaded!");
+		error("[Beetle::catchBeetle] Sequences have not been loaded");
 
 	if (getInventory()->getSelectedItem() == kItemMatchBox
 	 && getInventory()->hasItem(kItemMatch)
@@ -148,14 +148,14 @@ bool Beetle::catchBeetle() {
 
 bool Beetle::isCatchable() const {
 	if (!_data)
-		error("Beetle::isCatchable: sequences have not been loaded!");
+		error("[Beetle::isCatchable] Sequences have not been loaded");
 
 	return (_data->indexes[_data->offset] >= 30);
 }
 
 void Beetle::update() {
 	if (!_data)
-		error("Beetle::update: sequences have not been loaded!");
+		error("[Beetle::update] Sequences have not been loaded");
 
 	if (!_data->isLoaded)
 		return;
@@ -194,7 +194,7 @@ void Beetle::update() {
 
 void Beetle::drawUpdate() {
 	if (!_data)
-		error("Beetle::drawUpdate: sequences have not been loaded!");
+		error("[Beetle::drawUpdate] Sequences have not been loaded");
 
 	if (_data->frame != NULL) {
 		getScenes()->setCoordinates(_data->frame);
@@ -366,7 +366,7 @@ void Beetle::drawUpdate() {
 
 void Beetle::move() {
 	if (!_data)
-		error("Beetle::move: sequences have not been loaded!");
+		error("[Beetle::move] Sequences have not been loaded");
 
 	if (_data->indexes[_data->offset] >= 24 && _data->indexes[_data->offset] <= 29)
 		return;
@@ -444,7 +444,7 @@ update_data:
 // Update the beetle sequence to show the correct frames in the correct place
 void Beetle::updateFrame(SequenceFrame *frame) const {
 	if (!_data)
-		error("Beetle::updateSequence: sequences have not been loaded!");
+		error("[Beetle::updateFrame] Sequences have not been loaded");
 
 	if (!frame)
 		return;
@@ -459,7 +459,7 @@ void Beetle::updateFrame(SequenceFrame *frame) const {
 
 void Beetle::updateData(uint32 index) {
 	if (!_data)
-		error("Beetle::updateData: sequences have not been loaded!");
+		error("[Beetle::updateData] Sequences have not been loaded");
 
 	if (!_data->isLoaded)
 		return;
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index a565318..f6bb203 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -202,7 +202,7 @@ Entity *Entities::get(EntityIndex entity) {
 	assert((uint)entity < _entities.size());
 
 	if (entity == kEntityPlayer)
-		error("Cannot get entity for index == 0!");
+		error("[Entities::get] Cannot get entity for kEntityPlayer");
 
 	return _entities[entity];
 }
@@ -220,24 +220,24 @@ int Entities::getPosition(CarIndex car, Position position) const {
 	int index = 100 * car + position;
 
 	if (car > 10)
-		error("Entities::getPosition: trying to access an invalid car (was: %d, valid:0-9)", car);
+		error("[Entities::getPosition] Trying to access an invalid car (was: %d, valid:0-9)", car);
 
 	if (position > 100)
-		error("Entities::getPosition: trying to access an invalid position (was: %d, valid:0-100)", position);
+		error("[Entities::getPosition] Trying to access an invalid position (was: %d, valid:0-100)", position);
 
 	return _positions[index];
 }
 
 int Entities::getCompartments(int index) const {
 	if (index >= _compartmentsCount)
-		error("Entities::getCompartments: trying to access an invalid compartment (was: %d, valid:0-15)", index);
+		error("[Entities::getCompartments] Trying to access an invalid compartment (was: %d, valid:0-15)", index);
 
 	return _compartments[index];
 }
 
 int Entities::getCompartments1(int index) const {
 	if (index >= _compartmentsCount)
-		error("Entities::getCompartments: trying to access an invalid compartment (was: %d, valid:0-15)", index);
+		error("[Entities::getCompartments] Trying to access an invalid compartment (was: %d, valid:0-15)", index);
 
 	return _compartments1[index];
 }
@@ -1782,7 +1782,7 @@ void Entities::enterCompartment(EntityIndex entity, ObjectIndex compartment, boo
 	// Update compartments
 	int index = (compartment < 32 ? compartment - 1 : compartment - 24);
 	if (index >= 16)
-		error("Entities::exitCompartment: invalid compartment index!");
+		error("[Entities::enterCompartment] Invalid compartment index");
 
 	if (useCompartment1)
 		_compartments1[index] |= STORE_VALUE(entity);
@@ -1868,7 +1868,7 @@ void Entities::exitCompartment(EntityIndex entity, ObjectIndex compartment, bool
 	// Update compartments
 	int index = (compartment < 32 ? compartment - 1 : compartment - 24);
 	if (index >= 16)
-		error("Entities::exitCompartment: invalid compartment index!");
+		error("[Entities::exitCompartment] Invalid compartment index");
 
 	if (useCompartment1)
 		_compartments1[index] &= ~STORE_VALUE(entity);
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index d902c88..e417b1e 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -439,7 +439,7 @@ void Inventory::showHourGlass(){
 //////////////////////////////////////////////////////////////////////////
 Inventory::InventoryEntry *Inventory::get(InventoryItem item) {
 	if (item >= kPortraitOriginal)
-		error("Inventory::getEntry: Invalid inventory item!");
+		error("[Inventory::get] Invalid inventory item");
 
 	return &_entries[item];
 }
@@ -623,7 +623,7 @@ void Inventory::drawEgg() {
 // Blinking egg: we need to blink the egg for delta time, with the blinking getting faster until it's always lit.
 void Inventory::drawBlinkingEgg() {
 
-	warning("Inventory::drawEgg - blinking not implemented!");
+	warning("[Inventory::drawBlinkingEgg] Blinking not implemented");
 
 	//// TODO show egg (with or without mouseover)
 
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index 2b7b1cf..aeac8cf 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -413,7 +413,7 @@ void Logic::eventTick(const Common::Event &) {
 void Logic::resetState() {
 	getState()->scene = kSceneDefault;
 
-	warning("Logic::resetState: not implemented! You need to restart the engine until this is implemented.");
+	warning("[Logic::resetState] Not implemented! You need to restart the engine until this is implemented.");
 }
 
 /**
@@ -506,7 +506,7 @@ void Logic::playFinalSequence() const {
 }
 
 void Logic::showCredits() const {
-	error("Logic::showCredits: not implemented!");
+	error("[Logic::showCredits] Not implemented");
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/game/object.cpp b/engines/lastexpress/game/object.cpp
index a600075..d9e9e42 100644
--- a/engines/lastexpress/game/object.cpp
+++ b/engines/lastexpress/game/object.cpp
@@ -39,7 +39,7 @@ Objects::Objects(LastExpressEngine *engine) : _engine(engine) {}
 
 const Objects::Object Objects::get(ObjectIndex index) const {
 	if (index >= kObjectMax)
-		error("Objects::get - internal error: invalid object index (%d)", index);
+		error("[Objects::get] Invalid object index (%d)", index);
 
 	return _objects[index];
 }
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 8dfc214..ebada5d 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -75,10 +75,10 @@ void SaveLoad::initStream() {
 void SaveLoad::flushStream(GameId id) {
 	Common::OutSaveFile *save = openForSaving(id);
 	if (!save)
-		error("SaveLoad::flushStream: cannot open savegame (%s)!", getFilename(id).c_str());
+		error("[SaveLoad::flushStream] Cannot open savegame (%s)", getFilename(id).c_str());
 
 	if (!_savegame)
-		error("SaveLoad::flushStream: savegame stream is invalid");
+		error("[SaveLoad::flushStream] Savegame stream is invalid");
 
 	save->write(_savegame->getData(), (uint32)_savegame->size());
 
@@ -109,7 +109,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
 	SavegameMainHeader mainHeader;
 	mainHeader.saveLoadWithSerializer(ser);
 	if (!mainHeader.isValid())
-		error("SaveLoad::init - Savegame seems to be corrupted (invalid header)");
+		error("[SaveLoad::init] Savegame seems to be corrupted (invalid header)");
 
 	// Reset cached entry headers if needed
 	if (resetHeaders) {
@@ -148,10 +148,10 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
 void SaveLoad::loadStream(GameId id) {
 	Common::InSaveFile *save = openForLoading(id);
 	if (save->size() < 32)
-		error("SaveLoad::init - Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
+		error("[SaveLoad::loadStream] Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
 
 	if (!_savegame)
-		error("SaveLoad::loadStream: savegame stream is invalid");
+		error("[SaveLoad::loadStream] Savegame stream is invalid");
 
 	// Load all savegame data
 	uint8* buf = new uint8[8192];
@@ -192,7 +192,7 @@ void SaveLoad::clear(bool clearStream) {
 // Load game
 void SaveLoad::loadGame(GameId id) {
 	if (!_savegame)
-		error("SaveLoad::loadGame: No savegame stream present!");
+		error("[SaveLoad::loadGame] No savegame stream present");
 
 	// Rewind current savegame
 	_savegame->seek(0);
@@ -200,12 +200,12 @@ void SaveLoad::loadGame(GameId id) {
 	// Validate main header
 	SavegameMainHeader header;
 	if (!loadMainHeader(_savegame, &header)) {
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
+		debugC(2, kLastExpressDebugSavegame, "Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
 		return;
 	}
 
 	if (!_savegame)
-		error("SaveLoad::loadGame: No savegame stream present!");
+		error("[SaveLoad::loadGame] No savegame stream present");
 
 	// Load the last entry
 	_savegame->seek(header.offsetEntry);
@@ -230,7 +230,7 @@ void SaveLoad::loadGame(GameId id) {
 
 // Load a specific game entry
 void SaveLoad::loadGame(GameId id, uint32 index) {
-	error("SaveLoad::loadGame: not implemented! (only loading the last entry is working for now)");
+	error("[SaveLoad::loadGame] Not implemented! (only loading the last entry is working for now)");
 }
 
 // Save game
@@ -241,12 +241,12 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
 	// Validate main header
 	SavegameMainHeader header;
 	if (!loadMainHeader(_savegame, &header)) {
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
+		debugC(2, kLastExpressDebugSavegame, "Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
 		return;
 	}
 
 	if (!_savegame)
-		error("SaveLoad::saveGame: savegame stream is invalid");
+		error("[SaveLoad::saveGame] Savegame stream is invalid");
 
 	// Validate the current entry if it exists
 	if (header.count > 0) {
@@ -258,7 +258,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
 		entry.saveLoadWithSerializer(ser);
 
 		if (!entry.isValid()) {
-			warning("SaveLoad::saveGame: Invalid entry. This savegame might be corrupted!");
+			warning("[SaveLoad::saveGame] Invalid entry. This savegame might be corrupted");
 			_savegame->seek(header.offset);
 		} else if (getState()->time < entry.time || (type == kSavegameTypeTickInterval && getState()->time == entry.time)) {
 			// Not ready to save a game, skipping!
@@ -296,7 +296,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
 
 	// Validate the main header
 	if (!header.isValid())
-		error("SaveLoad::saveGame: main game header is invalid!");
+		error("[SaveLoad::saveGame] Main game header is invalid");
 
 	// Write the main header
 	_savegame->seek(0);
@@ -307,7 +307,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
 }
 
 void SaveLoad::saveVolumeBrightness() {
-	warning("SaveLoad::saveVolumeBrightness: not implemented!");
+	warning("[SaveLoad::saveVolumeBrightness] Not implemented");
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -319,7 +319,7 @@ bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *he
 
 	// Check there is enough data (32 bytes)
 	if (stream->size() < 32) {
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::loadMainHeader - Savegame seems to be corrupted (not enough data: %i bytes)!", stream->size());
+		debugC(2, kLastExpressDebugSavegame, "Savegame seems to be corrupted (not enough data: %i bytes)", stream->size());
 		return false;
 	}
 
@@ -331,7 +331,7 @@ bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *he
 
 	// Validate the header
 	if (!header->isValid()) {
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::loadMainHeader - Cannot validate main header!");
+		debugC(2, kLastExpressDebugSavegame, "Cannot validate main header");
 		return false;
 	}
 
@@ -348,11 +348,11 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
 	uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
 	debugC(kLastExpressDebugSavegame, "Savegame: Writing " #name ": %d bytes", _count); \
 	if (_count != val)\
-		error("SaveLoad::writeEntry: Number of bytes written (%d) differ from expected count (%d)", _count, val); \
+		error("[SaveLoad::writeEntry] Number of bytes written (%d) differ from expected count (%d)", _count, val); \
 }
 
 	if (!_savegame)
-		error("SaveLoad::writeEntry: savegame stream is invalid");
+		error("[SaveLoad::writeEntry] Savegame stream is invalid");
 
 	SavegameEntryHeader header;
 
@@ -395,7 +395,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
 
 	// Validate entry header
 	if (!header.isValid())
-		error("SaveLoad::writeEntry: entry header is invalid");
+		error("[SaveLoad::writeEntry] Entry header is invalid");
 
 	// Save the header with the updated info
 	_savegame->seek(originalPosition);
@@ -412,7 +412,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 	uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
 	debugC(kLastExpressDebugSavegame, "Savegame: Reading " #name ": %d bytes", _count); \
 	if (_count != val) \
-		error("SaveLoad::readEntry: Number of bytes read (%d) differ from expected count (%d)", _count, val); \
+		error("[SaveLoad::readEntry] Number of bytes read (%d) differ from expected count (%d)", _count, val); \
 }
 
 #define LOAD_ENTRY_ONLY(name, func) { \
@@ -423,10 +423,10 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 }
 
 	if (!type || !entity || !val)
-		error("SaveLoad::readEntry: Invalid parameters passed!");
+		error("[SaveLoad::readEntry] Invalid parameters passed");
 
 	if (!_savegame)
-		error("SaveLoad::readEntry: No savegame stream present!");
+		error("[SaveLoad::readEntry] No savegame stream present");
 
 	// Load entry header
 	SavegameEntryHeader entry;
@@ -434,7 +434,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 	entry.saveLoadWithSerializer(ser);
 
 	if (!entry.isValid())
-		error("SaveLoad::readEntry: entry header is invalid!");
+		error("[SaveLoad::readEntry] Entry header is invalid");
 
 	// Init type, entity & value
 	*type = entry.type;
@@ -469,7 +469,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 
 SaveLoad::SavegameEntryHeader *SaveLoad::getEntry(uint32 index) {
 	if (index >= _gameHeaders.size())
-		error("SaveLoad::getEntry: invalid index (was:%d, max:%d)", index, _gameHeaders.size() - 1);
+		error("[SaveLoad::getEntry] Invalid index (was:%d, max:%d)", index, _gameHeaders.size() - 1);
 
 	return _gameHeaders[index];
 }
@@ -489,7 +489,7 @@ bool SaveLoad::isSavegamePresent(GameId id) {
 // Check if the game has been started in the specific savegame
 bool SaveLoad::isSavegameValid(GameId id) {
 	if (!isSavegamePresent(id)) {
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::isSavegameValid - Savegame does not exist: %s", getFilename(id).c_str());
+		debugC(2, kLastExpressDebugSavegame, "Savegame does not exist: %s", getFilename(id).c_str());
 		return false;
 	}
 
@@ -552,7 +552,7 @@ bool SaveLoad::isGameFinished(uint32 menuIndex, uint32 savegameIndex) {
 // Get the file name from the savegame ID
 Common::String SaveLoad::getFilename(GameId id) {
 	if (id >= 6)
-		error("SaveLoad::getName - attempting to use an invalid game id. Valid values: 0 - 5, was %d", id);
+		error("[SaveLoad::getFilename] Attempting to use an invalid game id. Valid values: 0 - 5, was %d", id);
 
 	return gameInfo[id].saveFile;
 }
@@ -561,7 +561,7 @@ Common::InSaveFile *SaveLoad::openForLoading(GameId id) {
 	Common::InSaveFile *load = g_system->getSavefileManager()->openForLoading(getFilename(id));
 
 	if (!load)
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::openForLoading - Cannot open savegame for loading: %s", getFilename(id).c_str());
+		debugC(2, kLastExpressDebugSavegame, "Cannot open savegame for loading: %s", getFilename(id).c_str());
 
 	return load;
 }
@@ -570,7 +570,7 @@ Common::OutSaveFile *SaveLoad::openForSaving(GameId id) {
 	Common::OutSaveFile *save = g_system->getSavefileManager()->openForSaving(getFilename(id));
 
 	if (!save)
-		debugC(2, kLastExpressDebugSavegame, "SaveLoad::openForSaving - Cannot open savegame for writing: %s", getFilename(id).c_str());
+		debugC(2, kLastExpressDebugSavegame, "Cannot open savegame for writing: %s", getFilename(id).c_str());
 
 	return save;
 }
diff --git a/engines/lastexpress/game/savepoint.cpp b/engines/lastexpress/game/savepoint.cpp
index 7ec7c24..64ae26c 100644
--- a/engines/lastexpress/game/savepoint.cpp
+++ b/engines/lastexpress/game/savepoint.cpp
@@ -128,17 +128,17 @@ void SavePoints::addData(EntityIndex entity, ActionIndex action, uint32 param) {
 //////////////////////////////////////////////////////////////////////////
 void SavePoints::setCallback(EntityIndex index, Entity::Callback *callback) {
 	if (index >= 40)
-		error("SavePoints::setCallback - attempting to use an invalid entity index. Valid values 0-39, was %d", index);
+		error("[SavePoints::setCallback] Attempting to use an invalid entity index. Valid values 0-39, was %d", index);
 
 	if (!callback || !callback->isValid())
-		error("SavePoints::setCallback - attempting to set an invalid callback for entity %s", ENTITY_NAME(index));
+		error("[SavePoints::setCallback] Attempting to set an invalid callback for entity %s", ENTITY_NAME(index));
 
 	_callbacks[index] = callback;
 }
 
 Entity::Callback *SavePoints::getCallback(EntityIndex index) const {
 	if (index >= 40)
-		error("SavePoints::getCallback - attempting to use an invalid entity index. Valid values 0-39, was %d", index);
+		error("[SavePoints::getCallback] Attempting to use an invalid entity index. Valid values 0-39, was %d", index);
 
 	return _callbacks[index];
 }
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index 65efc80..b886951 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -81,12 +81,12 @@ void SceneManager::loadSceneDataFile(ArchiveIndex archive) {
 	case kArchiveCd2:
 	case kArchiveCd3:
 		if (!_sceneLoader->load(getArchive(Common::String::format("CD%iTRAIN.DAT", archive))))
-			error("SceneManager::loadSceneDataFile: cannot load data file CD%iTRAIN.DAT", archive);
+			error("[SceneManager::loadSceneDataFile] Cannot load data file CD%iTRAIN.DAT", archive);
 		break;
 
 	default:
 	case kArchiveAll:
-		error("SceneManager::loadSceneDataFile: Invalid archive index (must be [1-3], was %d", archive);
+		error("[SceneManager::loadSceneDataFile] Invalid archive index (must be [1-3], was %d", archive);
 		break;
 	}
 }
@@ -464,7 +464,7 @@ bool SceneManager::checkPosition(SceneIndex index, CheckPositionType type) const
 
 	switch (type) {
 	default:
-		error("SceneManager::checkPosition: Invalid position type: %d", type);
+		error("[SceneManager::checkPosition] Invalid position type: %d", type);
 
 	case kCheckPositionLookingUp:
 		return isInSleepingCar && (position >= 1 && position <= 19);
diff --git a/engines/lastexpress/game/state.cpp b/engines/lastexpress/game/state.cpp
index 0cf2ddb..f3fd972 100644
--- a/engines/lastexpress/game/state.cpp
+++ b/engines/lastexpress/game/state.cpp
@@ -57,7 +57,7 @@ bool State::isNightTime() const {
 
 void State::getHourMinutes(uint32 time, uint8 *hours, uint8 *minutes) {
 	if (hours == NULL || minutes == NULL)
-		error("State::getHourMinutes: invalid parameters passed!");
+		error("[State::getHourMinutes] Invalid parameters passed");
 
 	*hours = (uint8)((time % 1296000) / 54000);
 	*minutes =  (uint8)((time % 54000) / 900);
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 8f71e7d..c937fdc 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -325,7 +325,7 @@ public:
 
 			switch (index) {
 			default:
-				error("GameProgress::isEqual: invalid index value (was: %d, max:127)", index);
+				error("[GameProgress::getValueName] Invalid index value (was: %d, max:127)", index);
 				break;
 
 			EXPOSE_VALUE(0, field_0);
diff --git a/engines/lastexpress/graphics.cpp b/engines/lastexpress/graphics.cpp
index abbdf2b..e129457 100644
--- a/engines/lastexpress/graphics.cpp
+++ b/engines/lastexpress/graphics.cpp
@@ -72,7 +72,7 @@ void GraphicsManager::clear(BackgroundType type) {
 void GraphicsManager::clear(BackgroundType type, const Common::Rect &rect) {
 	switch (type) {
 		default:
-			error("GraphicsManager::clear() - Unknown background type: %d", type);
+			error("[GraphicsManager::clear] Unknown background type: %d", type);
 			break;
 
 		case kBackgroundA:
@@ -105,7 +105,7 @@ bool GraphicsManager::draw(Drawable *drawable, BackgroundType type, bool transit
 Graphics::Surface *GraphicsManager::getSurface(BackgroundType type) {
 	switch (type) {
 		default:
-			error("GraphicsManager::getSurface() - Unknown surface type: %d", type);
+			error("[GraphicsManager::getSurface] Unknown surface type: %d", type);
 			break;
 
 		case kBackgroundA:
@@ -121,7 +121,7 @@ Graphics::Surface *GraphicsManager::getSurface(BackgroundType type) {
 			return &_inventory;
 
 		case kBackgroundAll:
-			error("GraphicsManager::getSurface() - cannot return a surface for kBackgroundAll!");
+			error("[GraphicsManager::getSurface] Cannot return a surface for kBackgroundAll");
 			break;
 	}
 }
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 5d83527..885ca8b 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -185,7 +185,7 @@ void LastExpressEngine::pollEvents() {
 bool LastExpressEngine::handleEvents() {
 	// Make sure all the subsystems have been initialized
 	if (!_debugger || !_graphicsMan)
-		error("LastExpressEngine::handleEvents: called before the required subsystems have been initialized!");
+		error("[LastExpressEngine::handleEvents] Called before the required subsystems have been initialized");
 
 	// Execute stored commands
 	if (_debugger->hasCommand()) {
diff --git a/engines/lastexpress/menu/clock.cpp b/engines/lastexpress/menu/clock.cpp
index b0e6a26..dedf045 100644
--- a/engines/lastexpress/menu/clock.cpp
+++ b/engines/lastexpress/menu/clock.cpp
@@ -62,7 +62,7 @@ void Clock::draw(uint32 time) {
 
 	// Check that sequences have been loaded
 	if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
-		error("Clock::process: clock sequences have not been loaded correctly!");
+		error("[Clock::draw] Clock sequences have not been loaded correctly");
 
 	// Clear existing frames
 	clear();
diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp
index bfead02..f1a8beb 100644
--- a/engines/lastexpress/menu/menu.cpp
+++ b/engines/lastexpress/menu/menu.cpp
@@ -860,7 +860,7 @@ void Menu::init(bool doSavegame, SavegameType type, uint32 value) {
 			useSameIndex = false;
 
 			// TODO remove existing savegame and reset index & savegame name
-			warning("Menu::initGame: not implemented!");
+			warning("[Menu::initGame] Not implemented");
 		}
 
 		doSavegame = false;
diff --git a/engines/lastexpress/menu/trainline.cpp b/engines/lastexpress/menu/trainline.cpp
index df08abf..f819776 100644
--- a/engines/lastexpress/menu/trainline.cpp
+++ b/engines/lastexpress/menu/trainline.cpp
@@ -97,7 +97,7 @@ void TrainLine::draw(uint32 time) {
 
 	// Check that sequences have been loaded
 	if (!_frameLine1 || !_frameLine2)
-		error("TrainLine::process: Line sequences have not been loaded correctly!");
+		error("[TrainLine::draw] Line sequences have not been loaded correctly");
 
 	// Clear existing frames
 	clear();
diff --git a/engines/lastexpress/resource.cpp b/engines/lastexpress/resource.cpp
index f376a3a..3910aaa 100644
--- a/engines/lastexpress/resource.cpp
+++ b/engines/lastexpress/resource.cpp
@@ -52,7 +52,7 @@ bool ResourceManager::isArchivePresent(ArchiveIndex type) {
 	switch (type) {
 	default:
 	case kArchiveAll:
-		error("ResourceManager::isArchivePresent: Only checks for single CDs are valid!");
+		error("[ResourceManager::isArchivePresent] Only checks for single CDs are valid");
 
 	case kArchiveCd1:
 		return Common::File::exists(archiveCD1Path);
@@ -134,7 +134,7 @@ Common::SeekableReadStream *ResourceManager::getFileStream(const Common::String
 	// Check if the file exits in the archive
 	if (!hasFile(name)) {
 //#ifdef _DEBUG
-//		error("ResourceManager::getFileStream: cannot open file: %s", name.c_str());
+//		error("[ResourceManager::getFileStream] Cannot open file: %s", name.c_str());
 //#endif
 		debugC(2, kLastExpressDebugResource, "Error opening file: %s", name.c_str());
 		return NULL;
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 5cdcc15..f3f06b8 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -211,7 +211,7 @@ void SoundEntry::loadSoundData(Common::String name) {
 		_stream = getArchive("DEFAULT.SND");
 
 	if (_stream) {
-		warning("Sound::loadSoundData: not implemented!");
+		warning("[Sound::loadSoundData] Not implemented");
 	} else {
 		_status.status = kSoundStatusRemoved;
 	}
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
index 9126f57..7eb67b3 100644
--- a/engines/lastexpress/sound/queue.cpp
+++ b/engines/lastexpress/sound/queue.cpp
@@ -115,7 +115,7 @@ void SoundQueue::removeFromQueue(Common::String filename) {
 void SoundQueue::updateQueue() {
 	Common::StackLock locker(_mutex);
 
-	warning("Sound::updateQueue: not implemented!");
+	warning("[Sound::updateQueue] Not implemented");
 }
 
 void SoundQueue::resetQueue() {
@@ -413,7 +413,7 @@ void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) {
 		for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
 			(*i)->saveLoadWithSerializer(s);
 	} else {
-		warning("Sound::saveLoadWithSerializer: loading not implemented");
+		warning("[Sound::saveLoadWithSerializer] Loading not implemented");
 		s.skip(numEntries * 64);
 	}
 }
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 16e502a..45f8140 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -300,7 +300,7 @@ void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
 
 void SoundManager::playSteam(CityIndex index) {
 	if (index >= ARRAYSIZE(cities))
-		error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
+		error("[SoundManager::playSteam] Invalid city index (was %d, max %d)", index, ARRAYSIZE(cities));
 
 	_queue->resetState(kSoundState2);
 
@@ -676,7 +676,7 @@ void SoundManager::readText(int id){
 		return;
 
 	if (id < 0 || (id > 8 && id < 50) || id > 64)
-		error("Sound::readText - attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
+		error("[Sound::readText] Attempting to use invalid id. Valid values [1;8] - [50;64], was %d", id);
 
 	// Get proper message file (names are stored in sequence in the array but id is [1;8] - [50;64])
 	const char *text = messages[id <= 8 ? id : id - 41];


Commit: 04933a1937ef0de703a932e1392578aea4d38d64
    https://github.com/scummvm/scummvm/commit/04933a1937ef0de703a932e1392578aea4d38d64
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-28T20:17:13-07:00

Commit Message:
LASTEXPRESS: Make SoundEntry members private

Changed paths:
    engines/lastexpress/sound/entry.cpp
    engines/lastexpress/sound/entry.h
    engines/lastexpress/sound/queue.cpp
    engines/lastexpress/sound/sound.cpp



diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index f3f06b8..c34bb4f 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -307,6 +307,13 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
 	}
 }
 
+void SoundEntry::loadStream() {
+	if (!_soundStream)
+		_soundStream = new StreamedSound();
+
+	_soundStream->load(_stream);
+}
+
 //////////////////////////////////////////////////////////////////////////
 // SubtitleEntry
 //////////////////////////////////////////////////////////////////////////
@@ -352,10 +359,10 @@ void SubtitleEntry::setupAndDraw() {
 		_data->load(getArchive(_filename));
 	}
 
-	if (_data->getMaxTime() > _sound->_time) {
+	if (_data->getMaxTime() > _sound->getTime()) {
 		_status.status = kSoundStatus_400;
 	} else {
-		_data->setTime((uint16)_sound->_time);
+		_data->setTime((uint16)_sound->getTime());
 
 		if (getSoundQueue()->getSubtitleFlag() & 1)
 			drawOnScreen();
diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h
index 929d346..6079533 100644
--- a/engines/lastexpress/sound/entry.h
+++ b/engines/lastexpress/sound/entry.h
@@ -86,6 +86,7 @@ enum SoundStatus {
 	kSoundStatus_8000     = 0x8000,
 	kSoundStatus_20000    = 0x20000,
 	kSoundStatus_100000   = 0x100000,
+	kSoundStatus_20000000 = 0x20000000,
 	kSoundStatus_40000000 = 0x40000000,
 
 	kSoundStatusClear0    = 0x10,
@@ -127,6 +128,8 @@ public:
 	void updateState();
 	void reset();
 
+	void loadStream();
+
 	// Subtitles
 	void showSubtitle(Common::String filename);
 
@@ -134,22 +137,34 @@ public:
 	void saveLoadWithSerializer(Common::Serializer &ser);
 
 	// Accessors
-	void setType(SoundType type) { _type = type; }
-	SoundType getType() { return _type; }
-
+	void setStatus(int status)         { _status.status = status; }
+	void setType(SoundType type)       { _type = type; }
 	void setEntity(EntityIndex entity) { _entity = entity; }
-	EntityIndex getEntity() { return _entity; }
+	void setField48(int val)           { _field_48 = val; }
+
+	SoundStatusUnion getStatus()   { return _status; }
+	SoundType        getType()     { return _type; }
+	uint32           getTime()     { return _time; }
+	EntityIndex      getEntity()   { return _entity; }
+	uint32           getPriority() { return _priority; }
+	Common::String   getName2()    { return _name2; }
+
+	// Streams
+	Common::SeekableReadStream *getStream() { return _stream; }
+	StreamedSound              *getStreamedSound() { return _soundStream; }
+
+public:
+	// TODO replace by on-the-fly allocated buffer
+	void *_soundData;
 
 private:
 	LastExpressEngine *_engine;
 
-public:
 	SoundStatusUnion _status;
 	SoundType _type;    // int
 	//int _data;
 	//int _endOffset;
 	int _currentDataPtr;
-	void *_soundData;
 	//int _currentBufferPtr;
 	int _blockCount;
 	uint32 _time;
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
index 7eb67b3..cbd942f 100644
--- a/engines/lastexpress/sound/queue.cpp
+++ b/engines/lastexpress/sound/queue.cpp
@@ -76,15 +76,13 @@ void SoundQueue::handleTimer() {
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
 		SoundEntry *entry = (*i);
-		if (entry->_stream == NULL) {
+		if (entry->getStream() == NULL) {
 			SAFE_DELETE(*i);
 			i = _soundList.reverse_erase(i);
 			continue;
-		} else if (!entry->_soundStream) {
-			entry->_soundStream = new StreamedSound();
-
+		} else if (!entry->getStreamedSound()) {
 			// TODO: stream any sound in the queue after filtering
-			entry->_soundStream->load(entry->_stream);
+			entry->loadStream();
 		}
 	}
 }
@@ -180,7 +178,7 @@ void SoundQueue::clearStatus() {
 	Common::StackLock locker(_mutex);
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->_status.status |= kSoundStatusClear3;
+		(*i)->setStatus((*i)->getStatus().status | kSoundStatusClear3);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -243,7 +241,7 @@ SoundEntry *SoundQueue::getEntry(Common::String name) {
 		name += ".SND";
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
-		if ((*i)->_name2 == name)
+		if ((*i)->getName2() == name)
 			return *i;
 	}
 
@@ -264,7 +262,7 @@ uint32 SoundQueue::getEntryTime(EntityIndex index) {
 
 	SoundEntry *entry = getEntry(index);
 	if (entry)
-		return entry->_time;
+		return entry->getTime();
 
 	return 0;
 }
@@ -298,16 +296,16 @@ void SoundQueue::updateSubtitles() {
 	for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
 		uint32 current_index = 0;
 		SoundEntry *soundEntry = (*i)->getSoundEntry();
-		SoundStatus status = (SoundStatus)soundEntry->_status.status;
+		SoundStatus status = (SoundStatus)soundEntry->getStatus().status;
 
 		if (!(status & kSoundStatus_40)
 		 || status & kSoundStatus_180
-		 || soundEntry->_time == 0
+		 || soundEntry->getTime() == 0
 		 || (status & kSoundStatusClear1) < 6
-		 || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) {
+		 || ((getFlags()->nis & 0x8000) && soundEntry->getPriority() < 90)) {
 			 current_index = 0;
 		} else {
-			current_index = soundEntry->_priority + (status & kSoundStatusClear1);
+			current_index = soundEntry->getPriority() + (status & kSoundStatusClear1);
 
 			if (_currentSubtitle == (*i))
 				current_index += 4;
@@ -348,8 +346,8 @@ bool SoundQueue::setupCache(SoundEntry *entry) {
 		uint32 size = 1000;
 
 		for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
-			if (!((*i)->_status.status & kSoundStatus_180)) {
-				uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1);
+			if (!((*i)->getStatus().status & kSoundStatus_180)) {
+				uint32 newSize = (*i)->getPriority() + ((*i)->getStatus().status & kSoundStatusClear1);
 
 				if (newSize < size) {
 					cacheEntry = (*i);
@@ -358,7 +356,7 @@ bool SoundQueue::setupCache(SoundEntry *entry) {
 			}
 		}
 
-		if (entry->_priority <= size)
+		if (entry->getPriority() <= size)
 			return false;
 
 		if (!cacheEntry)
@@ -367,7 +365,7 @@ bool SoundQueue::setupCache(SoundEntry *entry) {
 		cacheEntry->setInCache();
 
 		// TODO: Wait until the cache entry is ready to be removed
-		while (!(cacheEntry->_status.status1 & 1))
+		while (!(cacheEntry->getStatus().status1 & 1))
 			;
 
 		if (cacheEntry->_soundData)
@@ -427,7 +425,7 @@ uint32 SoundQueue::count() {
 
 	uint32 numEntries = 0;
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		if ((*i)->_name2.matchString("NISSND?"))
+		if ((*i)->getName2().matchString("NISSND?"))
 			++numEntries;
 
 	return numEntries;
@@ -749,9 +747,9 @@ 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) {
-		entry->_status.status |= 0x20000000;
+		entry->setStatus(entry->getStatus().status | kSoundStatus_20000000);
 	} else {
-		int variant = entry->_status.status & 0x1f;
+		int variant = entry->getStatus().status & 0x1f;
 
 		soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
 	}
@@ -789,7 +787,7 @@ void SoundQueue::stopAllSound() {
 	Common::StackLock locker(_mutex);
 
 	for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
-		(*i)->_soundStream->stop();
+		(*i)->getStreamedSound()->stop();
 }
 
 } // End of namespace LastExpress
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 45f8140..c726769 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -155,11 +155,11 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
 	SoundEntry *entry = new SoundEntry(_engine);
 
 	entry->open(filename, flag, 30);
-	entry->_entity = entity;
+	entry->setEntity(entity);
 
 	if (a4) {
-		entry->_field_48 = _data2 + 2 * a4;
-		entry->_status.status |= kSoundStatus_8000;
+		entry->setField48(_data2 + 2 * a4);
+		entry->setStatus(entry->getStatus().status | kSoundStatus_8000);
 	} else {
 		// Get subtitles name
 		while (filename.size() > 4)
@@ -1359,7 +1359,7 @@ void SoundManager::playLoopingSound(int param) {
 		if (getFlags()->flag_3)
 			fnameLen = 5;
 
-		if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) {
+		if (!entry || scumm_strnicmp(entry->getName2().c_str(), tmp, fnameLen)) {
 			_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
 
 			if (partNumber != 99) {






More information about the Scummvm-git-logs mailing list