mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-15 08:39:45 +00:00
Patch #1839861 (Possible workaround for bugs related to cloneToFadeOutTrack): Fixes bug #1848399 and apparently also #1527274 & #1763227
svn-id: r30111
This commit is contained in:
parent
a8d3967f63
commit
305f60e0db
@ -158,7 +158,6 @@ void IMuseDigital::saveOrLoad(Serializer *ser) {
|
||||
if (!ser->isSaving()) {
|
||||
if (!track->used)
|
||||
continue;
|
||||
track->readyToRemove = false;
|
||||
if ((track->toBeRemoved) || (track->souStreamUsed) || (track->curRegion == -1)) {
|
||||
track->streamSou= NULL;
|
||||
track->stream = NULL;
|
||||
@ -231,9 +230,10 @@ void IMuseDigital::callback() {
|
||||
|
||||
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
|
||||
Track *track = _track[l];
|
||||
if (track->used && !track->readyToRemove) {
|
||||
if (track->used) {
|
||||
// Remove tracks if necessary
|
||||
if (track->toBeRemoved) {
|
||||
track->readyToRemove = true;
|
||||
flushTrack(track);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -249,7 +249,9 @@ void IMuseDigital::callback() {
|
||||
track->volFadeUsed = false;
|
||||
}
|
||||
if (track->vol == 0) {
|
||||
track->toBeRemoved = true;
|
||||
// Fade out complete -> remove this track
|
||||
flushTrack(track);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (track->volFadeStep > 0) {
|
||||
@ -357,6 +359,8 @@ void IMuseDigital::callback() {
|
||||
} while (feedSize != 0);
|
||||
} else if (track->streamSou) {
|
||||
if (_mixer->isReady()) {
|
||||
// FIXME: Can't we replace track->mixerStreamRunning by
|
||||
// _mixer->isSoundHandleActive(track->mixChanHandle) ?
|
||||
if (!track->mixerStreamRunning) {
|
||||
track->mixerStreamRunning = true;
|
||||
_mixer->playInputStream(type, &track->mixChanHandle, track->streamSou, -1, vol, pan, false);
|
||||
@ -375,7 +379,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {
|
||||
debug(5, "switchToNextRegion(track:%d)", track->trackId);
|
||||
|
||||
if (track->trackId >= MAX_DIGITAL_TRACKS) {
|
||||
track->toBeRemoved = true;
|
||||
flushTrack(track);
|
||||
debug(5, "exit (fadetrack can't go next region) switchToNextRegion(trackId:%d)", track->trackId);
|
||||
return;
|
||||
}
|
||||
@ -383,7 +387,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {
|
||||
int num_regions = _sound->getNumRegions(track->soundDesc);
|
||||
|
||||
if (++track->curRegion == num_regions) {
|
||||
track->toBeRemoved = true;
|
||||
flushTrack(track);
|
||||
debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track->trackId);
|
||||
return;
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ private:
|
||||
char soundName[15]; // sound name but also filename of sound in bundle data
|
||||
bool used; // flag mean that track is used
|
||||
bool toBeRemoved; // flag mean that track need to be free
|
||||
bool readyToRemove; // flag mean that track is ready to stop
|
||||
bool mixerStreamRunning; // flag mean sound mixer's stream is running
|
||||
bool souStreamUsed; // flag mean that track use stream from sou file
|
||||
bool sndDataExtComp;// flag mean that sound data is compressed by scummvm tools
|
||||
@ -152,6 +151,8 @@ private:
|
||||
void setDigMusicSequence(int seqId);
|
||||
void playDigMusic(const char *songName, const imuseDigTable *table, int attribPos, bool sequence);
|
||||
|
||||
void flushTrack(Track *track);
|
||||
|
||||
public:
|
||||
IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, int fps);
|
||||
virtual ~IMuseDigital();
|
||||
|
@ -163,32 +163,37 @@ void IMuseDigital::parseScriptCmds(int cmd, int b, int c, int d, int e, int f, i
|
||||
}
|
||||
}
|
||||
|
||||
void IMuseDigital::flushTrack(Track *track) {
|
||||
track->toBeRemoved = true;
|
||||
if (track->stream) {
|
||||
// Finalize the appendable stream
|
||||
track->stream->finish();
|
||||
// There might still be some data left in the buffers of the
|
||||
// appendable stream. We play it nice and wait till all of it
|
||||
// played.
|
||||
if (track->stream->endOfStream()) {
|
||||
_mixer->stopHandle(track->mixChanHandle);
|
||||
delete track->stream;
|
||||
track->stream = NULL;
|
||||
_sound->closeSound(track->soundDesc);
|
||||
track->soundDesc = NULL;
|
||||
track->used = false;
|
||||
}
|
||||
} else if (track->streamSou) {
|
||||
_mixer->stopHandle(track->mixChanHandle);
|
||||
delete track->streamSou;
|
||||
track->streamSou = NULL;
|
||||
track->used = false;
|
||||
}
|
||||
}
|
||||
|
||||
void IMuseDigital::flushTracks() {
|
||||
Common::StackLock lock(_mutex, "IMuseDigital::flushTracks()");
|
||||
debug(5, "flushTracks()");
|
||||
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
|
||||
Track *track = _track[l];
|
||||
if (track->used && track->readyToRemove) {
|
||||
if (track->stream) {
|
||||
// Finalize the appendable stream
|
||||
track->stream->finish();
|
||||
// There might still be some data left in the buffers of the
|
||||
// appendable stream. We play it nice and wait till all of it
|
||||
// played.
|
||||
if (track->stream->endOfStream()) {
|
||||
_mixer->stopHandle(track->mixChanHandle);
|
||||
delete track->stream;
|
||||
track->stream = NULL;
|
||||
_sound->closeSound(track->soundDesc);
|
||||
track->soundDesc = NULL;
|
||||
track->used = false;
|
||||
}
|
||||
} else if (track->streamSou) {
|
||||
_mixer->stopHandle(track->mixChanHandle);
|
||||
delete track->streamSou;
|
||||
track->streamSou = NULL;
|
||||
track->used = false;
|
||||
}
|
||||
if (track->used && track->toBeRemoved) {
|
||||
flushTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,7 +293,7 @@ int IMuseDigital::getSoundStatus(int sound) const {
|
||||
Track *track = _track[l];
|
||||
if (track->soundId == sound) {
|
||||
if ((track->streamSou && _mixer->isSoundHandleActive(track->mixChanHandle)) ||
|
||||
(track->stream && track->used && !track->readyToRemove)) {
|
||||
(track->stream && !track->stream->endOfStream())) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,22 @@ int IMuseDigital::allocSlot(int priority) {
|
||||
}
|
||||
if (lowest_priority <= priority) {
|
||||
assert(trackId != -1);
|
||||
_track[trackId]->toBeRemoved = true;
|
||||
Track *track = _track[trackId];
|
||||
while (1) {
|
||||
if (!track->used) {
|
||||
break;
|
||||
}
|
||||
// The designated track is not yet available. So, we call flushTrack()
|
||||
// to get it processed (and thus made ready for us). Since the actual
|
||||
// processing is done by another thread, we also call parseEvents to
|
||||
// give it some time (and to avoid busy waiting/looping).
|
||||
flushTrack(track);
|
||||
_mutex.unlock();
|
||||
#ifndef __PLAYSTATION2__
|
||||
_vm->parseEvents();
|
||||
#endif
|
||||
_mutex.lock();
|
||||
}
|
||||
debug(5, "IMuseDigital::allocSlot(): Removed sound %d from track %d", _track[trackId]->soundId, trackId);
|
||||
} else {
|
||||
debug(5, "IMuseDigital::allocSlot(): Priority sound too low");
|
||||
@ -71,6 +86,7 @@ int IMuseDigital::allocSlot(int priority) {
|
||||
}
|
||||
|
||||
void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority) {
|
||||
Common::StackLock lock(_mutex, "IMuseDigital::startSound()");
|
||||
debug(5, "IMuseDigital::startSound(%d)", soundId);
|
||||
|
||||
int l = allocSlot(priority);
|
||||
@ -80,21 +96,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
|
||||
}
|
||||
|
||||
Track *track = _track[l];
|
||||
while (1) {
|
||||
_mutex.lock();
|
||||
if (!track->used) {
|
||||
break;
|
||||
}
|
||||
// The designated track is not yet available. So, we call flushTracks()
|
||||
// to get it processed (and thus made ready for us). Since the actual
|
||||
// processing is done by another thread, we also call parseEvents to
|
||||
// give it some time (and to avoid busy waiting/looping).
|
||||
flushTracks();
|
||||
_mutex.unlock();
|
||||
#ifndef __PLAYSTATION2__
|
||||
_vm->parseEvents();
|
||||
#endif
|
||||
}
|
||||
|
||||
track->pan = 64;
|
||||
track->vol = volume * 1000;
|
||||
@ -113,7 +114,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
|
||||
track->dataMod12Bit = 0;
|
||||
track->mixerFlags = 0;
|
||||
track->toBeRemoved = false;
|
||||
track->readyToRemove = false;
|
||||
track->soundType = soundType;
|
||||
|
||||
int bits = 0, freq = 0, channels = 0;
|
||||
@ -191,7 +191,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
|
||||
}
|
||||
|
||||
track->used = true;
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void IMuseDigital::setPriority(int soundId, int priority) {
|
||||
@ -309,7 +308,7 @@ void IMuseDigital::fadeOutMusic(int fadeDelay) {
|
||||
Track *track = _track[l];
|
||||
if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
|
||||
cloneToFadeOutTrack(track, fadeDelay);
|
||||
track->toBeRemoved = true;
|
||||
flushTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,9 +318,14 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDel
|
||||
Track *fadeTrack = 0;
|
||||
|
||||
debug(0, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track->trackId, fadeDelay);
|
||||
|
||||
if (track->toBeRemoved) {
|
||||
error("IMuseDigital::cloneToFadeOutTrack: Tried to clone a track to be removed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_track[track->trackId + MAX_DIGITAL_TRACKS]->used) {
|
||||
warning("IMuseDigital::cloneToFadeOutTrack: Not free fade track");
|
||||
warning("IMuseDigital::cloneToFadeOutTrack: No free fade track");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -360,7 +364,6 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDel
|
||||
}
|
||||
fadeTrack->stream = Audio::makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundDesc), makeMixerFlags(fadeTrack->mixerFlags));
|
||||
_mixer->playInputStream(type, &fadeTrack->mixChanHandle, fadeTrack->stream, -1, fadeTrack->vol / 1000, fadeTrack->pan, false);
|
||||
|
||||
fadeTrack->mixerStreamRunning = true;
|
||||
fadeTrack->used = true;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user