aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Kołodziejski2004-04-11 14:48:50 +0000
committerPaweł Kołodziejski2004-04-11 14:48:50 +0000
commitdef44acc6f03b3c752002f140e6accb74477e527 (patch)
tree5f449975e39d0b6813c66f44bf1cdbced7512288
parent26c8f9340db3db6f7296053a8e67a31293cce73b (diff)
downloadscummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.tar.gz
scummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.tar.bz2
scummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.zip
implemented 'fade buffers' stuff
svn-id: r13542
-rw-r--r--TODO1
-rw-r--r--scumm/imuse_digi/dimuse.cpp181
-rw-r--r--scumm/imuse_digi/dimuse.h8
-rw-r--r--scumm/imuse_digi/dimuse_script.cpp62
-rw-r--r--scumm/imuse_digi/dimuse_sndmgr.cpp17
-rw-r--r--scumm/imuse_digi/dimuse_sndmgr.h5
-rw-r--r--scumm/imuse_digi/dimuse_track.cpp202
7 files changed, 289 insertions, 187 deletions
diff --git a/TODO b/TODO
index ae72c1c348..de17c99e8c 100644
--- a/TODO
+++ b/TODO
@@ -256,7 +256,6 @@ SCUMM
* Fix codec44 for nut fonts
* iMUSE Digital:
- Fix music code (done, but not tested yet)
- - Implement 'fade buffers' stuff, to handle fadeParam in JUMP opcode
- Implement pool method data transfer between imuse and sound mixer
- Add save/load code
- Add code for MP3 and Ogg Vorbis compressed datafiles
diff --git a/scumm/imuse_digi/dimuse.cpp b/scumm/imuse_digi/dimuse.cpp
index 86b955cd7c..7a1add676c 100644
--- a/scumm/imuse_digi/dimuse.cpp
+++ b/scumm/imuse_digi/dimuse.cpp
@@ -50,6 +50,10 @@ IMuseDigital::IMuseDigital(ScummEngine *scumm)
_volSfx = 0;
_volMusic = 0;
resetState();
+ for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ _track[l] = new Track;
+ _track[l]->used = false;
+ }
_vm->_timer->installTimerProc(timer_handler, 1000000 / 25, this);
}
@@ -59,6 +63,9 @@ IMuseDigital::~IMuseDigital() {
Common::StackLock lock(_mutex, "IMuseDigital::~IMuseDigital()");
_vm->_timer->removeTimerProc(timer_handler);
}
+ for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ delete _track[l];
+ }
delete _sound;
g_system->deleteMutex(_mutex);
}
@@ -78,113 +85,114 @@ void IMuseDigital::callback() {
if (_pause || !_vm)
return;
- for (l = 0; l < MAX_DIGITAL_TRACKS;l ++) {
- if (_track[l].used) {
- if (_track[l].stream2) {
- if (!_track[l].handle.isActive() && _track[l].started) {
- debug(5, "IMuseDigital::callback() A: stopped sound: %d", _track[l].soundId);
- delete _track[l].stream2;
- _track[l].stream2 = NULL;
- _track[l].used = false;
+ for (l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ if (_track[l]->used) {
+ if (_track[l]->stream2) {
+ if (!_track[l]->handle.isActive() && _track[l]->started) {
+ debug(5, "IMuseDigital::callback() A: stopped sound: %d", _track[l]->soundId);
+ delete _track[l]->stream2;
+ _track[l]->stream2 = NULL;
+ _track[l]->used = false;
continue;
}
- } else if (_track[l].stream) {
- if (_track[l].toBeRemoved) {
- debug(5, "IMuseDigital::callback() B: stopped sound: %d", _track[l].soundId);
- _track[l].stream->finish();
- _track[l].stream = NULL;
- _sound->closeSound(_track[l].soundHandle);
- _track[l].used = false;
+ } else if (_track[l]->stream) {
+ if (_track[l]->toBeRemoved) {
+ debug(5, "IMuseDigital::callback() B: stopped sound: %d", _track[l]->soundId);
+ _track[l]->stream->finish();
+ _track[l]->stream = NULL;
+ _sound->closeSound(_track[l]->soundHandle);
+ _track[l]->soundHandle = NULL;
+ _track[l]->used = false;
continue;
}
}
- if (_track[l].volFadeUsed) {
- if (_track[l].volFadeStep < 0) {
- if (_track[l].vol > _track[l].volFadeDest) {
- _track[l].vol += _track[l].volFadeStep;
- if (_track[l].vol < _track[l].volFadeDest) {
- _track[l].vol = _track[l].volFadeDest;
- _track[l].volFadeUsed = false;
+ if (_track[l]->volFadeUsed) {
+ if (_track[l]->volFadeStep < 0) {
+ if (_track[l]->vol > _track[l]->volFadeDest) {
+ _track[l]->vol += _track[l]->volFadeStep;
+ if (_track[l]->vol < _track[l]->volFadeDest) {
+ _track[l]->vol = _track[l]->volFadeDest;
+ _track[l]->volFadeUsed = false;
}
- if (_track[l].vol == 0) {
- _track[l].toBeRemoved = true;
+ if (_track[l]->vol == 0) {
+ _track[l]->toBeRemoved = true;
}
}
- } else if (_track[l].volFadeStep > 0) {
- if (_track[l].vol < _track[l].volFadeDest) {
- _track[l].vol += _track[l].volFadeStep;
- if (_track[l].vol > _track[l].volFadeDest) {
- _track[l].vol = _track[l].volFadeDest;
- _track[l].volFadeUsed = false;
+ } else if (_track[l]->volFadeStep > 0) {
+ if (_track[l]->vol < _track[l]->volFadeDest) {
+ _track[l]->vol += _track[l]->volFadeStep;
+ if (_track[l]->vol > _track[l]->volFadeDest) {
+ _track[l]->vol = _track[l]->volFadeDest;
+ _track[l]->volFadeUsed = false;
}
}
}
- debug(5, "Fade: sound(%d), Vol(%d)", _track[l].soundId, _track[l].vol / 1000);
+ debug(5, "Fade: sound(%d), Vol(%d)", _track[l]->soundId, _track[l]->vol / 1000);
}
- int pan = (_track[l].pan != 64) ? 2 * _track[l].pan - 127 : 0;
- int vol = _track[l].vol / 1000;
+ int pan = (_track[l]->pan != 64) ? 2 * _track[l]->pan - 127 : 0;
+ int vol = _track[l]->vol / 1000;
- if (_track[l].volGroupId == 1)
+ if (_track[l]->volGroupId == 1)
vol = (vol * _volVoice) / 128;
- if (_track[l].volGroupId == 2)
+ if (_track[l]->volGroupId == 2)
vol = (vol * _volSfx) / 128;
- if (_track[l].volGroupId == 3)
+ if (_track[l]->volGroupId == 3)
vol = (vol * _volMusic) / 128;
if (_vm->_mixer->isReady()) {
- if (_track[l].stream2) {
- if (!_track[l].started) {
- _track[l].started = true;
- _vm->_mixer->playInputStream(&_track[l].handle, _track[l].stream2, false, _track[l].vol / 1000, _track[l].pan, -1, false);
+ if (_track[l]->stream2) {
+ if (!_track[l]->started) {
+ _track[l]->started = true;
+ _vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream2, false, _track[l]->vol / 1000, _track[l]->pan, -1, false);
} else {
- _vm->_mixer->setChannelVolume(_track[l].handle, vol);
- _vm->_mixer->setChannelBalance(_track[l].handle, pan);
+ _vm->_mixer->setChannelVolume(_track[l]->handle, vol);
+ _vm->_mixer->setChannelBalance(_track[l]->handle, pan);
}
continue;
}
}
- if (_track[l].stream) {
- int32 mixer_size = _track[l].pullSize;
+ if (_track[l]->stream) {
+ int32 mixer_size = _track[l]->pullSize;
byte *data = NULL;
int32 result = 0;
- if (_track[l].stream->endOfData()) {
+ if (_track[l]->stream->endOfData()) {
mixer_size *= 2;
}
- if (_track[l].curRegion == -1)
+ if (_track[l]->curRegion == -1)
switchToNextRegion(l);
- int bits = _sound->getBits(_track[l].soundHandle);
+ int bits = _sound->getBits(_track[l]->soundHandle);
do {
if (bits == 12) {
byte *ptr = NULL;
- mixer_size += _track[l].mod;
+ mixer_size += _track[l]->mod;
int mixer_size_12 = (mixer_size * 3) / 4;
int length = (mixer_size_12 / 3) * 4;
- _track[l].mod = mixer_size - length;
+ _track[l]->mod = mixer_size - length;
- int32 offset = (_track[l].regionOffset * 3) / 4;
- int result2 = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &ptr, offset, mixer_size_12);
+ int32 offset = (_track[l]->regionOffset * 3) / 4;
+ int result2 = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &ptr, offset, mixer_size_12);
result = BundleCodecs::decode12BitsSample(ptr, &data, result2);
free(ptr);
} else if (bits == 16) {
- result = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &data, _track[l].regionOffset, mixer_size);
- if (_sound->getChannels(_track[l].soundHandle) == 1) {
+ result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+ if (_sound->getChannels(_track[l]->soundHandle) == 1) {
result &= ~1;
}
- if (_sound->getChannels(_track[l].soundHandle) == 2) {
+ if (_sound->getChannels(_track[l]->soundHandle) == 2) {
if (result & 2)
result &= ~2;
}
} else if (bits == 8) {
- result = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &data, _track[l].regionOffset, mixer_size);
- if (_sound->getChannels(_track[l].soundHandle) == 2) {
+ result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+ if (_sound->getChannels(_track[l]->soundHandle) == 2) {
result &= ~1;
}
}
@@ -193,17 +201,17 @@ void IMuseDigital::callback() {
result = mixer_size;
if (_vm->_mixer->isReady()) {
- _vm->_mixer->setChannelVolume(_track[l].handle, vol);
- _vm->_mixer->setChannelBalance(_track[l].handle, pan);
- _track[l].stream->append(data, result);
- _track[l].regionOffset += result;
- _track[l].trackOffset += result;
+ _vm->_mixer->setChannelVolume(_track[l]->handle, vol);
+ _vm->_mixer->setChannelBalance(_track[l]->handle, pan);
+ _track[l]->stream->append(data, result);
+ _track[l]->regionOffset += result;
+ _track[l]->trackOffset += result;
free(data);
}
- if (_sound->isEndOfRegion(_track[l].soundHandle, _track[l].curRegion)) {
+ if (_sound->isEndOfRegion(_track[l]->soundHandle, _track[l]->curRegion)) {
switchToNextRegion(l);
- if (_track[l].toBeRemoved)
+ if (_track[l]->toBeRemoved)
break;
}
mixer_size -= result;
@@ -215,36 +223,51 @@ void IMuseDigital::callback() {
}
void IMuseDigital::switchToNextRegion(int track) {
- int num_regions = _sound->getNumRegions(_track[track].soundHandle);
+ if (track >= MAX_DIGITAL_TRACKS) {
+ _track[track]->toBeRemoved = true;
+ return;
+ }
+
+ int num_regions = _sound->getNumRegions(_track[track]->soundHandle);
- if (++_track[track].curRegion == num_regions) {
- _track[track].toBeRemoved = true;
+ if (++_track[track]->curRegion == num_regions) {
+ _track[track]->toBeRemoved = true;
return;
}
- int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track].soundHandle, _track[track].curRegion, _track[track].curHookId);
+ int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, _track[track]->curHookId);
if (jumpId == -1)
- jumpId = _sound->getJumpIdByRegionAndHookId(_track[track].soundHandle, _track[track].curRegion, 0);
+ jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, 0);
if (jumpId != -1) {
- int region = _sound->getRegionIdByJumpId(_track[track].soundHandle, jumpId);
+ int region = _sound->getRegionIdByJumpId(_track[track]->soundHandle, jumpId);
assert(region != -1);
- int sampleHookId = _sound->getJumpHookId(_track[track].soundHandle, jumpId);
+ int sampleHookId = _sound->getJumpHookId(_track[track]->soundHandle, jumpId);
assert(sampleHookId != -1);
+ int fadeDelay = (60 * _sound->getJumpFade(_track[track]->soundHandle, jumpId)) / 1000;
if (sampleHookId != 0) {
- if (_track[track].curHookId == sampleHookId) {
- _track[track].curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId);
- _track[track].curHookId = 0;
+ if (_track[track]->curHookId == sampleHookId) {
+ int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
+ _track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
+ _track[fadeTrack]->regionOffset = 0;
+ debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
+ _track[track]->curRegion = region;
+ debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
+ _track[track]->curHookId = 0;
+ _track[fadeTrack]->curHookId = 0;
}
} else {
- _track[track].curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId);
+ int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
+ _track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
+ _track[fadeTrack]->regionOffset = 0;
+ debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
+ _track[track]->curRegion = region;
+ debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
}
}
- debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId);
- _track[track].dataOffset = _sound->getRegionOffset(_track[track].soundHandle, _track[track].curRegion);
- _track[track].regionOffset = 0;
+ debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
+ _track[track]->dataOffset = _sound->getRegionOffset(_track[track]->soundHandle, _track[track]->curRegion);
+ _track[track]->regionOffset = 0;
}
} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse.h b/scumm/imuse_digi/dimuse.h
index 61a4c8da4c..1e1763762a 100644
--- a/scumm/imuse_digi/dimuse.h
+++ b/scumm/imuse_digi/dimuse.h
@@ -34,6 +34,7 @@
namespace Scumm {
#define MAX_DIGITAL_TRACKS 8
+#define MAX_DIGITAL_FADETRACKS 8
struct imuseDigTable;
struct imuseComiTable;
@@ -63,6 +64,8 @@ private:
int iteration;
int mod;
int32 pullSize;
+ int32 mixerFlags;
+
ImuseDigiSndMgr::soundStruct *soundHandle;
PlayingSoundHandle handle;
AppendableAudioStream *stream;
@@ -71,7 +74,7 @@ private:
Track();
};
- Track _track[MAX_DIGITAL_TRACKS];
+ Track *_track[MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS];
OSystem::MutexRef _mutex;
ScummEngine *_vm;
@@ -94,12 +97,14 @@ private:
void switchToNextRegion(int track);
void allocSlot(int priority);
void startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority);
+ void selectVolumeGroup(int soundId, int volGroupId);
int32 getPosInMs(int soundId);
void getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height);
int getSoundIdByName(const char *soundName);
void fadeOutMusic(int fadeDelay);
+ int cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack);
void setFtMusicState(int stateId);
void setFtMusicSequence(int seqId);
@@ -139,7 +144,6 @@ public:
void setVolume(int soundId, int volume);
void setPan(int soundId, int pan);
void setFade(int soundId, int destVolume, int delay60HzTicks);
- void selectVolumeGroup(int soundId, int volGroupId);
void setMasterVolume(int vol) {}
void stopSound(int soundId);
void stopAllSounds() { stopAllSounds(false); }
diff --git a/scumm/imuse_digi/dimuse_script.cpp b/scumm/imuse_digi/dimuse_script.cpp
index fb26ce6120..abc0acc5f5 100644
--- a/scumm/imuse_digi/dimuse_script.cpp
+++ b/scumm/imuse_digi/dimuse_script.cpp
@@ -163,7 +163,7 @@ void IMuseDigital::refreshScripts() {
Common::StackLock lock(_mutex, "IMuseDigital::refreshScripts()");
bool found = false;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
+ if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
found = true;
}
}
@@ -175,7 +175,7 @@ void IMuseDigital::refreshScripts() {
void IMuseDigital::startVoice(int soundId, AudioStream *input) {
debug(5, "startVoiceStream(%d)", soundId);
- startSound(soundId, NULL, 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
+ startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
}
void IMuseDigital::startVoice(int soundId, const char *soundName) {
@@ -185,7 +185,7 @@ void IMuseDigital::startVoice(int soundId, const char *soundName) {
void IMuseDigital::startMusic(int soundId, int volume) {
debug(5, "startMusicResource(%d)", soundId);
- startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
+ startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
}
void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) {
@@ -195,7 +195,7 @@ void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, in
void IMuseDigital::startSfx(int soundId, int priority) {
debug(5, "startSfx(%d)", soundId);
- startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
+ startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
}
void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
@@ -205,8 +205,8 @@ void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width
msPos /= 16;
if (msPos < 65536) {
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _sound->getSyncSizeAndPtrById(_track[l].soundHandle, syncId, sync_size, &sync_ptr);
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _sound->getSyncSizeAndPtrById(_track[l]->soundHandle, syncId, sync_size, &sync_ptr);
if ((sync_size != 0) && (sync_ptr != NULL)) {
sync_size /= 4;
while (sync_size--) {
@@ -231,8 +231,8 @@ void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width
int32 IMuseDigital::getPosInMs(int soundId) {
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && (_track[l].used)) {
- int32 pos = (5 * (_track[l].dataOffset + _track[l].regionOffset)) / (_track[l].iteration / 200);
+ if ((_track[l]->soundId == soundId) && (_track[l]->used)) {
+ int32 pos = (5 * (_track[l]->dataOffset + _track[l]->regionOffset)) / (_track[l]->iteration / 200);
return pos;
}
}
@@ -244,7 +244,7 @@ int IMuseDigital::getSoundStatus(int sound) const {
Common::StackLock lock(_mutex, "IMuseDigital::getSoundStatus()");
debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == sound) && _track[l].used) {
+ if ((_track[l]->soundId == sound) && _track[l]->used) {
return 1;
}
}
@@ -256,12 +256,12 @@ void IMuseDigital::stopSound(int soundId) {
Common::StackLock lock(_mutex, "IMuseDigital::stopSound()");
debug(5, "IMuseDigital::stopSound(%d)", soundId);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- if (_track[l].stream) {
- _track[l].toBeRemoved = true;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ if (_track[l]->stream) {
+ _track[l]->toBeRemoved = true;
}
- else if (_track[l].stream2)
- _vm->_mixer->stopHandle(_track[l].handle);
+ else if (_track[l]->stream2)
+ _vm->_mixer->stopHandle(_track[l]->handle);
}
}
}
@@ -271,8 +271,8 @@ int32 IMuseDigital::getCurMusicPosInMs() {
int soundId = -1;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
- soundId = _track[l].soundId;
+ if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ soundId = _track[l]->soundId;
}
}
@@ -306,8 +306,8 @@ int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
int soundId = -1;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
- soundId = _track[l].soundId;
+ if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ soundId = _track[l]->soundId;
}
}
@@ -324,8 +324,8 @@ int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
int soundId = -1;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
- soundId = _track[l].soundId;
+ if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ soundId = _track[l]->soundId;
}
}
@@ -341,12 +341,12 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {
debug(5, "IMuseDigital::stopAllSounds");
{
Common::StackLock lock(_mutex, "IMuseDigital::stopAllSounds()");
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (_track[l].used) {
- if (_track[l].stream) {
- _track[l].toBeRemoved = true;
- } else if (_track[l].stream2)
- _vm->_mixer->stopHandle(_track[l].handle);
+ for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ if (_track[l]->used) {
+ if (_track[l]->stream) {
+ _track[l]->toBeRemoved = true;
+ } else if (_track[l]->stream2)
+ _vm->_mixer->stopHandle(_track[l]->handle);
}
}
}
@@ -355,8 +355,8 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {
bool used;
do {
used = false;
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (_track[l].used)
+ for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ if (_track[l]->used)
used = true;
}
g_system->delay_msecs(10);
@@ -366,9 +366,9 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {
void IMuseDigital::pause(bool p) {
Common::StackLock lock(_mutex, "IMuseDigital::pause()");
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (_track[l].used) {
- _vm->_mixer->pauseHandle(_track[l].handle, p);
+ for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ if (_track[l]->used) {
+ _vm->_mixer->pauseHandle(_track[l]->handle, p);
}
}
_pause = p;
diff --git a/scumm/imuse_digi/dimuse_sndmgr.cpp b/scumm/imuse_digi/dimuse_sndmgr.cpp
index 63d2d2c0f0..7664c08713 100644
--- a/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -286,7 +286,8 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
bool result = false;
byte *ptr = NULL;
- if (soundName == NULL) {
+ if (soundName[0] == 0) {
+ _sounds[slot].name[0] = 0;
if ((soundType == IMUSE_RESOURCE)) {
ptr = _vm->getResourceAddress(rtSound, soundId);
if (ptr == NULL) {
@@ -294,6 +295,9 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
return NULL;
}
_sounds[slot].resPtr = ptr;
+ _sounds[slot].soundId = soundId;
+ _sounds[slot].type = soundType;
+ _sounds[slot].volGroupId = volGroupId;
result = true;
} else if (soundType == IMUSE_BUNDLE) {
bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
@@ -304,8 +308,9 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
else
error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
_sounds[slot].bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside);
- _sounds[slot].name[0] = 0;
_sounds[slot].soundId = soundId;
+ _sounds[slot].type = soundType;
+ _sounds[slot].volGroupId = volGroupId;
} else {
error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
}
@@ -321,6 +326,8 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
_sounds[slot].bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside);
strcpy(_sounds[slot].name, soundName);
_sounds[slot].soundId = soundId;
+ _sounds[slot].type = soundType;
+ _sounds[slot].volGroupId = volGroupId;
} else {
error("ImuseDigiSndMgr::openSound() Don't know how load sound: %s", soundName);
}
@@ -350,6 +357,12 @@ void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
memset(soundHandle, 0, sizeof(soundStruct));
}
+ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) {
+ assert(soundHandle && checkForProperHandle(soundHandle));
+
+ return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId);
+}
+
bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
if (soundHandle == &_sounds[l])
diff --git a/scumm/imuse_digi/dimuse_sndmgr.h b/scumm/imuse_digi/dimuse_sndmgr.h
index c6055e5e0a..ba9f28b852 100644
--- a/scumm/imuse_digi/dimuse_sndmgr.h
+++ b/scumm/imuse_digi/dimuse_sndmgr.h
@@ -81,6 +81,8 @@ public:
char name[15];
int16 soundId;
BundleMgr *bundle;
+ int type;
+ int volGroupId;
};
private:
@@ -105,8 +107,9 @@ public:
ImuseDigiSndMgr(ScummEngine *scumm);
~ImuseDigiSndMgr();
- soundStruct * openSound(int32 soundId, const char *soundName, int soundType, int volGroupId);
+ soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId);
void closeSound(soundStruct *soundHandle);
+ soundStruct *cloneSound(soundStruct *soundHandle);
int getFreq(soundStruct *soundHandle);
int getBits(soundStruct *soundHandle);
diff --git a/scumm/imuse_digi/dimuse_track.cpp b/scumm/imuse_digi/dimuse_track.cpp
index be15e46fa9..8f70edabe3 100644
--- a/scumm/imuse_digi/dimuse_track.cpp
+++ b/scumm/imuse_digi/dimuse_track.cpp
@@ -38,33 +38,33 @@ void IMuseDigital::allocSlot(int priority) {
bool found_free = false;
for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (!_track[l].used && !_track[l].handle.isActive())
+ if (!_track[l]->used && !_track[l]->handle.isActive())
found_free = true;
}
if (!found_free) {
warning("IMuseDigital::startSound(): All slots are full");
for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (_track[l].used && _track[l].handle.isActive() &&
- (lower_priority > _track[l].priority) && (!_track[l].stream2))
- lower_priority = _track[l].priority;
+ if (_track[l]->used && _track[l]->handle.isActive() &&
+ (lower_priority > _track[l]->priority) && (!_track[l]->stream2))
+ lower_priority = _track[l]->priority;
}
if (lower_priority <= priority) {
int track_id = -1;
for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (_track[l].used && _track[l].handle.isActive() &&
- (lower_priority == _track[l].priority) && (!_track[l].stream2)) {
+ if (_track[l]->used && _track[l]->handle.isActive() &&
+ (lower_priority == _track[l]->priority) && (!_track[l]->stream2)) {
track_id = l;
}
}
assert(track_id != -1);
- _track[track_id].stream->finish();
- _track[track_id].stream = NULL;
- _vm->_mixer->stopHandle(_track[track_id].handle);
- _sound->closeSound(_track[track_id].soundHandle);
- _track[track_id].used = false;
- assert(!_track[track_id].handle.isActive());
- warning("IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id].soundId, track_id);
+ _track[track_id]->stream->finish();
+ _track[track_id]->stream = NULL;
+ _vm->_mixer->stopHandle(_track[track_id]->handle);
+ _sound->closeSound(_track[track_id]->soundHandle);
+ _track[track_id]->used = false;
+ assert(!_track[track_id]->handle.isActive());
+ warning("IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id]->soundId, track_id);
} else {
warning("IMuseDigital::startSound(): Priority sound too low");
return;
@@ -80,46 +80,47 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
allocSlot(priority);
for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (!_track[l].used && !_track[l].handle.isActive()) {
- _track[l].pan = 64;
- _track[l].vol = volume * 1000;
- _track[l].volFadeDest = 0;
- _track[l].volFadeStep = 0;
- _track[l].volFadeDelay = 0;
- _track[l].volFadeUsed = false;
- _track[l].soundId = soundId;
- _track[l].started = false;
- _track[l].volGroupId = volGroupId;
- _track[l].curHookId = hookId;
- _track[l].priority = priority;
- _track[l].curRegion = -1;
- _track[l].dataOffset = 0;
- _track[l].regionOffset = 0;
- _track[l].trackOffset = 0;
- _track[l].mod = 0;
- _track[l].toBeRemoved = false;
-
- int bits = 0, freq = 0, channels = 0, mixerFlags = 0;
+ if (!_track[l]->used && !_track[l]->handle.isActive()) {
+ _track[l]->pan = 64;
+ _track[l]->vol = volume * 1000;
+ _track[l]->volFadeDest = 0;
+ _track[l]->volFadeStep = 0;
+ _track[l]->volFadeDelay = 0;
+ _track[l]->volFadeUsed = false;
+ _track[l]->soundId = soundId;
+ _track[l]->started = false;
+ _track[l]->volGroupId = volGroupId;
+ _track[l]->curHookId = hookId;
+ _track[l]->priority = priority;
+ _track[l]->curRegion = -1;
+ _track[l]->dataOffset = 0;
+ _track[l]->regionOffset = 0;
+ _track[l]->trackOffset = 0;
+ _track[l]->mod = 0;
+ _track[l]->mixerFlags = 0;
+ _track[l]->toBeRemoved = false;
+
+ int bits = 0, freq = 0, channels = 0;
if (input) {
- _track[l].iteration = 1; // ?
+ _track[l]->iteration = 1; // ?
// Do nothing here, we already have an audio stream
} else {
- _track[l].soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId);
+ _track[l]->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId);
- if (_track[l].soundHandle == NULL)
+ if (_track[l]->soundHandle == NULL)
return;
- bits = _sound->getBits(_track[l].soundHandle);
- channels = _sound->getChannels(_track[l].soundHandle);
- freq = _sound->getFreq(_track[l].soundHandle);
+ bits = _sound->getBits(_track[l]->soundHandle);
+ channels = _sound->getChannels(_track[l]->soundHandle);
+ freq = _sound->getFreq(_track[l]->soundHandle);
if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
Actor *a = _vm->derefActor(_vm->_actorToPrintStrFor, "IMuseDigital::startSound");
freq = (freq * a->talkFrequency) / 256;
- _track[l].pan = a->talkPan;
- _track[l].vol = a->talkVolume * 1000;
+ _track[l]->pan = a->talkPan;
+ _track[l]->vol = a->talkVolume * 1000;
}
}
@@ -135,32 +136,32 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
// subclass).
freq -= (freq % 25);
- _track[l].iteration = _track[l].pullSize = freq * channels;
+ _track[l]->iteration = _track[l]->pullSize = freq * channels;
if (channels == 2)
- mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
+ _track[l]->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
if ((bits == 12) || (bits == 16)) {
- mixerFlags |= SoundMixer::FLAG_16BITS;
- _track[l].iteration = _track[l].pullSize *= 2;
+ _track[l]->mixerFlags |= SoundMixer::FLAG_16BITS;
+ _track[l]->iteration = _track[l]->pullSize *= 2;
} else if (bits == 8) {
- mixerFlags |= SoundMixer::FLAG_UNSIGNED;
+ _track[l]->mixerFlags |= SoundMixer::FLAG_UNSIGNED;
} else
error("IMuseDigital::startSound(): Can't handle %d bit samples", bits);
- _track[l].pullSize /= 25; // We want a "frame rate" of 25 audio blocks per second
+ _track[l]->pullSize /= 25; // We want a "frame rate" of 25 audio blocks per second
}
if (input) {
- _track[l].stream2 = input;
- _track[l].stream = NULL;
+ _track[l]->stream2 = input;
+ _track[l]->stream = NULL;
} else {
- _track[l].stream2 = NULL;
- _track[l].stream = makeAppendableAudioStream(freq, mixerFlags, 100000);
- _vm->_mixer->playInputStream(&_track[l].handle, _track[l].stream, false, _track[l].vol / 1000, _track[l].pan, -1);
+ _track[l]->stream2 = NULL;
+ _track[l]->stream = makeAppendableAudioStream(freq, _track[l]->mixerFlags, 100000);
+ _vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream, false, _track[l]->vol / 1000, _track[l]->pan, -1);
}
- _track[l].used = true;
+ _track[l]->used = true;
return;
}
}
@@ -175,8 +176,8 @@ void IMuseDigital::setPriority(int soundId, int priority) {
assert ((priority >= 0) && (priority <= 127));
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _track[l].priority = priority;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _track[l]->priority = priority;
}
}
}
@@ -185,8 +186,8 @@ void IMuseDigital::setVolume(int soundId, int volume) {
Common::StackLock lock(_mutex, "IMuseDigital::setVolume()");
debug(5, "IMuseDigital::setVolume(%d, %d)", soundId, volume);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _track[l].vol = volume * 1000;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _track[l]->vol = volume * 1000;
}
}
}
@@ -195,8 +196,8 @@ void IMuseDigital::setPan(int soundId, int pan) {
Common::StackLock lock(_mutex, "IMuseDigital::setPan()");
debug(5, "IMuseDigital::setPan(%d, %d)", soundId, pan);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _track[l].pan = pan;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _track[l]->pan = pan;
}
}
}
@@ -210,8 +211,8 @@ void IMuseDigital::selectVolumeGroup(int soundId, int volGroupId) {
volGroupId = 3;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _track[l].volGroupId = volGroupId;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _track[l]->volGroupId = volGroupId;
}
}
}
@@ -220,11 +221,11 @@ void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {
Common::StackLock lock(_mutex, "IMuseDigital::setFade()");
debug(5, "IMuseDigital::setFade(%d, %d, %d)", soundId, destVolume, delay60HzTicks);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].soundId == soundId) && _track[l].used) {
- _track[l].volFadeDelay = delay60HzTicks;
- _track[l].volFadeDest = destVolume * 1000;
- _track[l].volFadeStep = (_track[l].volFadeDest - _track[l].vol) * 60 * 40 / (1000 * delay60HzTicks);
- _track[l].volFadeUsed = true;
+ if ((_track[l]->soundId == soundId) && _track[l]->used) {
+ _track[l]->volFadeDelay = delay60HzTicks;
+ _track[l]->volFadeDest = destVolume * 1000;
+ _track[l]->volFadeStep = (_track[l]->volFadeDest - _track[l]->vol) * 60 * 40 / (1000 * delay60HzTicks);
+ _track[l]->volFadeUsed = true;
}
}
}
@@ -233,13 +234,72 @@ void IMuseDigital::fadeOutMusic(int fadeDelay) {
Common::StackLock lock(_mutex, "IMuseDigital::fadeOutMusic()");
debug(5, "IMuseDigital::fadeOutMusic");
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
- _track[l].volFadeDelay = fadeDelay;
- _track[l].volFadeDest = 0;
- _track[l].volFadeStep = (_track[l].volFadeDest - _track[l].vol) * 60 * 40 / (1000 * fadeDelay);
- _track[l].volFadeUsed = true;
+ if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ cloneToFadeOutTrack(l, fadeDelay, true);
}
}
}
+int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack) {
+ Common::StackLock lock(_mutex, "IMuseDigital::cloneToFadeOutTrack()");
+ debug(5, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track, fadeDelay);
+ int fadeTrack = -1;
+
+ for (int l = MAX_DIGITAL_TRACKS; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+ if (!_track[l]->used) {
+ fadeTrack = l;
+ break;
+ }
+ }
+ if (fadeTrack == -1)
+ error("IMuseDigital::cloneToFadeTrack() Can't find free fade track");
+
+ // swap track to fade track
+ Track *tmpTrack = _track[track];
+ _track[track] = _track[fadeTrack];
+ _track[fadeTrack] = tmpTrack;
+
+ // copy track params from swaped fade track to new track
+ _track[track]->pan = _track[fadeTrack]->pan;
+ _track[track]->vol = _track[fadeTrack]->vol;
+ _track[track]->volGroupId = _track[fadeTrack]->volGroupId;
+ _track[track]->volFadeDelay = _track[fadeTrack]->volFadeDelay;
+ _track[track]->volFadeDest = _track[fadeTrack]->volFadeDest;
+ _track[track]->volFadeStep = _track[fadeTrack]->volFadeStep;
+ _track[track]->volFadeUsed = _track[fadeTrack]->volFadeUsed;
+ _track[track]->priority = _track[fadeTrack]->priority;
+ _track[track]->soundId = _track[fadeTrack]->soundId;
+ _track[track]->dataOffset = _track[fadeTrack]->dataOffset;
+ _track[track]->regionOffset = _track[fadeTrack]->regionOffset;
+ _track[track]->trackOffset = _track[fadeTrack]->trackOffset;
+ _track[track]->curRegion = _track[fadeTrack]->curRegion;
+ _track[track]->curHookId = _track[fadeTrack]->curHookId;
+ _track[track]->iteration = _track[fadeTrack]->iteration;
+ _track[track]->mixerFlags = _track[fadeTrack]->mixerFlags;
+ _track[track]->mod = _track[fadeTrack]->mod;
+ _track[track]->pullSize = _track[fadeTrack]->pullSize;
+ _track[track]->used = _track[fadeTrack]->used;
+ _track[track]->toBeRemoved = _track[fadeTrack]->toBeRemoved;
+ _track[track]->started = _track[fadeTrack]->started;
+ _track[track]->stream2 = _track[fadeTrack]->stream2;
+
+ _track[track]->soundHandle = NULL;
+ _track[track]->stream = NULL;
+
+ _track[fadeTrack]->volFadeDelay = fadeDelay;
+ _track[fadeTrack]->volFadeDest = 0;
+ _track[fadeTrack]->volFadeStep = (_track[fadeTrack]->volFadeDest - _track[fadeTrack]->vol) * 60 * 40 / (1000 * fadeDelay);
+ _track[fadeTrack]->volFadeUsed = true;
+
+ if (killNormalTrack) {
+ _track[track]->used = false;
+ } else {
+ _track[track]->soundHandle = _sound->cloneSound(_track[fadeTrack]->soundHandle);
+ _track[track]->stream = makeAppendableAudioStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, 100000);
+ _vm->_mixer->playInputStream(&_track[track]->handle, _track[track]->stream, false, _track[track]->vol / 1000, _track[track]->pan, -1);
+ }
+
+ return fadeTrack;
+}
+
} // End of namespace Scumm