aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound
diff options
context:
space:
mode:
authorColin Snover2017-06-16 16:32:16 -0500
committerColin Snover2017-06-18 21:42:58 -0500
commitd556dcc57bf50a03d81ab7a1ef59a9e5758465bf (patch)
tree977a4935fdff18a022860871475a40af25c01e95 /engines/sci/sound
parent733eaeb499bb39f75e7dd218df4c71b06b7e1610 (diff)
downloadscummvm-rg350-d556dcc57bf50a03d81ab7a1ef59a9e5758465bf.tar.gz
scummvm-rg350-d556dcc57bf50a03d81ab7a1ef59a9e5758465bf.tar.bz2
scummvm-rg350-d556dcc57bf50a03d81ab7a1ef59a9e5758465bf.zip
SCI: Switch SCI2 games to use Audio32
Upon investigation of Sound code across SCI32 games, it was determined that there are actually (at least) 3 different revisions, not just a single SCI2.1 version. This patch only changes the parts of Sound code that are relevant to the correct use of Audio32. Fixes Trac#9736, Trac#9756, Trac#9767, Trac#9791.
Diffstat (limited to 'engines/sci/sound')
-rw-r--r--engines/sci/sound/audio32.cpp21
-rw-r--r--engines/sci/sound/midiparser_sci.cpp47
-rw-r--r--engines/sci/sound/music.cpp12
-rw-r--r--engines/sci/sound/soundcmd.cpp37
4 files changed, 51 insertions, 66 deletions
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index 5e75095e5a..cfbab8b055 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -114,7 +114,9 @@ Audio32::Audio32(ResourceManager *resMan) :
_monitoredBufferSize(0),
_numMonitoredSamples(0) {
- if (getSciVersion() < SCI_VERSION_3) {
+ if (getSciVersion() < SCI_VERSION_2_1_EARLY) {
+ _channels.resize(10);
+ } else if (getSciVersion() < SCI_VERSION_3) {
_channels.resize(5);
} else {
_channels.resize(8);
@@ -311,7 +313,22 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
Audio::st_volume_t leftVolume, rightVolume;
if (channel.pan == -1 || !isStereo()) {
- leftVolume = rightVolume = channel.volume * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
+ int volume = channel.volume;
+ if (getSciVersion() == SCI_VERSION_2) {
+ // NOTE: In SSCI, audio is decompressed into a temporary
+ // buffer, then the samples in that buffer are looped over,
+ // shifting each sample right 3, 2, or 1 bits to reduce the
+ // volume.
+ if (volume > 0 && volume <= 42) {
+ volume = 15;
+ } else if (volume > 42 && volume <= 84) {
+ volume = 31;
+ } else if (volume > 84 && volume < kMaxVolume) {
+ volume = 63;
+ }
+ }
+
+ leftVolume = rightVolume = volume * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
} else {
// TODO: This should match the SCI3 algorithm,
// which seems to halve the volume of each
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index a25ce2887b..bdd0d1b36e 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -752,18 +752,12 @@ bool MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
case kUpdateCue:
if (!_jumpingToTick) {
int inc;
- switch (_soundVersion) {
- case SCI_VERSION_0_EARLY:
- case SCI_VERSION_0_LATE:
+ if (_soundVersion <= SCI_VERSION_0_LATE) {
inc = info.basic.param2;
- break;
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
- case SCI_VERSION_2_1_EARLY:
+ } else if (_soundVersion >= SCI_VERSION_1_EARLY && _soundVersion <= SCI_VERSION_2_1_MIDDLE) {
inc = 1;
- break;
- default:
- error("unsupported _soundVersion");
+ } else {
+ error("Unsupported _soundVersion %s", getSciVersionDesc(_soundVersion));
}
_pSnd->dataInc += inc;
debugC(4, kDebugLevelSound, "datainc %04x", inc);
@@ -895,22 +889,14 @@ void MidiParser_SCI::allNotesOff() {
void MidiParser_SCI::setMasterVolume(byte masterVolume) {
assert(masterVolume <= MUSIC_MASTERVOLUME_MAX);
_masterVolume = masterVolume;
- switch (_soundVersion) {
- case SCI_VERSION_0_EARLY:
- case SCI_VERSION_0_LATE:
+ if (_soundVersion <= SCI_VERSION_0_LATE) {
// update driver master volume
setVolume(_volume);
- break;
-
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
- case SCI_VERSION_2_1_EARLY:
+ } else if (_soundVersion >= SCI_VERSION_1_EARLY && _soundVersion <= SCI_VERSION_2_1_MIDDLE) {
// directly set master volume (global volume is merged with channel volumes)
((MidiPlayer *)_driver)->setVolume(masterVolume);
- break;
-
- default:
- error("MidiParser_SCI::setVolume: Unsupported soundVersion");
+ } else {
+ error("MidiParser_SCI::setVolume: Unsupported soundVersion %s", getSciVersionDesc(_soundVersion));
}
}
@@ -918,26 +904,17 @@ void MidiParser_SCI::setVolume(byte volume) {
assert(volume <= MUSIC_VOLUME_MAX);
_volume = volume;
- switch (_soundVersion) {
- case SCI_VERSION_0_EARLY:
- case SCI_VERSION_0_LATE: {
+ if (_soundVersion <= SCI_VERSION_0_LATE) {
// SCI0 adlib driver doesn't support channel volumes, so we need to go this way
int16 globalVolume = _volume * _masterVolume / MUSIC_VOLUME_MAX;
((MidiPlayer *)_driver)->setVolume(globalVolume);
- break;
- }
-
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
- case SCI_VERSION_2_1_EARLY:
+ } else if (_soundVersion >= SCI_VERSION_1_EARLY && _soundVersion <= SCI_VERSION_2_1_MIDDLE) {
// Send previous channel volumes again to actually update the volume
for (int i = 0; i < 15; i++)
if (_channelRemap[i] != -1)
sendToDriver(0xB0 + i, 7, _channelVolume[i]);
- break;
-
- default:
- error("MidiParser_SCI::setVolume: Unsupported soundVersion");
+ } else {
+ error("MidiParser_SCI::setVolume: Unsupported soundVersion %s", getSciVersionDesc(_soundVersion));
}
}
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 987983a7f9..ae89ee832b 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -215,7 +215,7 @@ void SciMusic::pauseAll(bool pause) {
#ifdef ENABLE_SCI32
// The entire DAC will have been paused by the caller;
// do not pause the individual samples too
- if (_soundVersion >= SCI_VERSION_2_1_EARLY && (*i)->isSample) {
+ if (_soundVersion >= SCI_VERSION_2 && (*i)->isSample) {
continue;
}
#endif
@@ -483,7 +483,11 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
if (pSnd->isSample) {
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
+ if (_soundVersion >= SCI_VERSION_2) {
+ // TODO: Sound number, loop state, and volume come from soundObj
+ // in SSCI. Getting them from MusicEntry could cause a bug if the
+ // soundObj was updated by a game script and not copied back to
+ // MusicEntry.
g_sci->_audio32->restart(ResourceId(kResourceTypeAudio, pSnd->resourceId), true, pSnd->loop != 0 && pSnd->loop != 1, pSnd->volume, pSnd->soundObj, false);
return;
} else
@@ -567,7 +571,7 @@ void SciMusic::soundStop(MusicEntry *pSnd) {
pSnd->isQueued = false;
if (pSnd->isSample) {
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
+ if (_soundVersion >= SCI_VERSION_2) {
g_sci->_audio32->stop(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
} else {
#endif
@@ -642,7 +646,7 @@ void SciMusic::soundKill(MusicEntry *pSnd) {
if (pSnd->isSample) {
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
+ if (_soundVersion >= SCI_VERSION_2) {
g_sci->_audio32->stop(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
} else {
#endif
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 07e01fb759..f7cb6cda5c 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -48,7 +48,7 @@ SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segM
// resource number, but it's totally unrelated to the menu music).
// The GK1 demo (very late SCI1.1) does the same thing
// TODO: Check the QFG4 demo
- _useDigitalSFX = (getSciVersion() >= SCI_VERSION_2 || g_sci->getGameId() == GID_GK1DEMO || ConfMan.getBool("prefer_digitalsfx"));
+ _useDigitalSFX = (_soundVersion >= SCI_VERSION_2 || g_sci->getGameId() == GID_GK1DEMO || ConfMan.getBool("prefer_digitalsfx"));
_music = new SciMusic(_soundVersion, _useDigitalSFX);
_music->init();
@@ -100,8 +100,8 @@ void SoundCommandParser::initSoundResource(MusicEntry *newSound) {
if (_useDigitalSFX || !newSound->soundRes) {
int sampleLen;
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
- newSound->isSample = g_sci->getResMan()->testResource(ResourceId(kResourceTypeAudio, newSound->resourceId));
+ if (_soundVersion >= SCI_VERSION_2) {
+ newSound->isSample = g_sci->getResMan()->testResource(ResourceId(kResourceTypeAudio, newSound->resourceId)) != nullptr;
} else {
#endif
newSound->pStreamAud = _audio->getAudioStream(newSound->resourceId, 65535, &sampleLen);
@@ -316,8 +316,8 @@ reg_t SoundCommandParser::kDoSoundPause(EngineState *s, int argc, reg_t *argv) {
reg_t obj = argv[0];
const bool shouldPause = argc > 1 ? argv[1].toUint16() : false;
if (
- (_soundVersion < SCI_VERSION_2_1_EARLY && !obj.getSegment()) ||
- (_soundVersion >= SCI_VERSION_2_1_EARLY && obj.isNull())
+ (_soundVersion < SCI_VERSION_2 && !obj.getSegment()) ||
+ (_soundVersion >= SCI_VERSION_2 && obj.isNull())
) {
_music->pauseAll(shouldPause);
#ifdef ENABLE_SCI32
@@ -501,7 +501,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
if (musicSlot->isSample) {
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
+ if (_soundVersion >= SCI_VERSION_2) {
const int position = g_sci->_audio32->getPosition(ResourceId(kResourceTypeAudio, musicSlot->resourceId), musicSlot->soundObj);
if (position == -1) {
@@ -717,9 +717,8 @@ reg_t SoundCommandParser::kDoSoundSetVolume(EngineState *s, int argc, reg_t *arg
// SSCI unconditionally sets volume if it is digital audio
if (_soundVersion >= SCI_VERSION_2_1_EARLY && musicSlot->isSample) {
_music->soundSetVolume(musicSlot, value);
- }
+ } else
#endif
-
if (musicSlot->volume != value) {
musicSlot->volume = value;
_music->soundSetVolume(musicSlot, value);
@@ -783,27 +782,15 @@ reg_t SoundCommandParser::kDoSoundSetLoop(EngineState *s, int argc, reg_t *argv)
return s->r_acc;
}
-#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
- if (value != -1) {
- value = 1;
- }
- }
-#endif
-
- if (value == -1) {
- musicSlot->loop = 0xFFFF;
- } else {
- musicSlot->loop = 1; // actually plays the music once
- }
-
- writeSelectorValue(_segMan, obj, SELECTOR(loop), musicSlot->loop);
+ const uint16 loopCount = value == -1 ? 0xFFFF : 1;
+ writeSelectorValue(_segMan, obj, SELECTOR(loop), loopCount);
#ifdef ENABLE_SCI32
- if (_soundVersion >= SCI_VERSION_2_1_EARLY && musicSlot->isSample) {
+ if (_soundVersion >= SCI_VERSION_2_1_MIDDLE && musicSlot->isSample) {
g_sci->_audio32->setLoop(ResourceId(kResourceTypeAudio, musicSlot->resourceId), musicSlot->soundObj, value == -1);
- }
+ } else
#endif
+ musicSlot->loop = loopCount;
return s->r_acc;
}