aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound
diff options
context:
space:
mode:
authorColin Snover2017-02-09 12:14:46 -0600
committerColin Snover2017-04-23 13:07:25 -0500
commita867fb70ddc145b03b8b782401364681e8c5560c (patch)
tree35ca2b71395929de72f1e15b5e22f75f1fe82066 /engines/sci/sound
parentb5ecbff39b2f33748aec02ecf789037554ea34bb (diff)
downloadscummvm-rg350-a867fb70ddc145b03b8b782401364681e8c5560c.tar.gz
scummvm-rg350-a867fb70ddc145b03b8b782401364681e8c5560c.tar.bz2
scummvm-rg350-a867fb70ddc145b03b8b782401364681e8c5560c.zip
SCI32: Fix audio playback with monitored channel in SCI3
SCI3 changes the way that monitored channel works. In SCI2/2.1, when a channel is monitored, it is the only audible channel. In SCI3, monitored channels mix normally. This is very noticeable in LSL7, where music disappears totally during speech if the monitored channel is the only channel played back.
Diffstat (limited to 'engines/sci/sound')
-rw-r--r--engines/sci/sound/audio32.cpp54
-rw-r--r--engines/sci/sound/audio32.h4
2 files changed, 38 insertions, 20 deletions
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index e9e90e41a7..5d008bff46 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -217,6 +217,8 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
freeUnusedChannels();
+ const bool playOnlyMonitoredChannel = getSciVersion() != SCI_VERSION_3 && _monitoredChannelIndex != -1;
+
// The caller of `readBuffer` is a rate converter,
// which reuses (without clearing) an intermediate
// buffer, so we need to zero the intermediate buffer
@@ -248,7 +250,7 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
// 0 | 2 (>> 1)
// 1 | 4 (>> 2)
// 2 | 6...
- if (_monitoredChannelIndex == -1 && _numActiveChannels > 1) {
+ if (!playOnlyMonitoredChannel && _numActiveChannels > 1) {
attenuationAmount = _numActiveChannels + 1;
attenuationStepAmount = 1;
} else {
@@ -299,7 +301,7 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
rightVolume = channel.volume * channel.pan / 100 * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
}
- if (_monitoredChannelIndex == -1 && _attenuatedMixing) {
+ if (!playOnlyMonitoredChannel && _attenuatedMixing) {
leftVolume >>= attenuationAmount;
rightVolume >>= attenuationAmount;
}
@@ -326,7 +328,7 @@ int Audio32::readBuffer(Audio::st_sample_t *buffer, const int numSamples) {
maxSamplesWritten = _numMonitoredSamples;
}
} else if (!channel.stream->endOfStream() || channel.loop) {
- if (_monitoredChannelIndex != -1) {
+ if (playOnlyMonitoredChannel) {
// Audio that is not on the monitored channel is silent
// when the monitored channel is active, but the stream still
// needs to be read in order to ensure that sound effects sync
@@ -942,14 +944,23 @@ reg_t Audio32::kernelPlay(const bool autoPlay, const int argc, const reg_t *cons
loop = (bool)argv[5].toSint16();
}
- if (argc < 7 || argv[6].toSint16() < 0 || argv[6].toSint16() > Audio32::kMaxVolume) {
- volume = Audio32::kMaxVolume;
-
- if (argc >= 7) {
- monitor = true;
+ if (getSciVersion() == SCI_VERSION_3) {
+ if (argc < 7) {
+ volume = Audio32::kMaxVolume;
+ } else {
+ volume = argv[6].toSint16() & Audio32::kMaxVolume;
+ monitor = argv[6].toSint16() & Audio32::kMonitorAudioFlagSci3;
}
} else {
- volume = argv[6].toSint16();
+ if (argc < 7 || argv[6].toSint16() < 0 || argv[6].toSint16() > Audio32::kMaxVolume) {
+ volume = Audio32::kMaxVolume;
+
+ if (argc >= 7) {
+ monitor = true;
+ }
+ } else {
+ volume = argv[6].toSint16();
+ }
}
} else {
resourceId = ResourceId(kResourceTypeAudio, argv[0].toUint16());
@@ -960,18 +971,23 @@ reg_t Audio32::kernelPlay(const bool autoPlay, const int argc, const reg_t *cons
loop = (bool)argv[1].toSint16();
}
- // TODO: SCI3 uses the 0x80 bit as a flag to
- // indicate "priority channel", but the volume is clamped
- // in this call to 0x7F so that flag never makes it into
- // the audio subsystem
- if (argc < 3 || argv[2].toSint16() < 0 || argv[2].toSint16() > Audio32::kMaxVolume) {
- volume = Audio32::kMaxVolume;
-
- if (argc >= 3) {
- monitor = true;
+ if (getSciVersion() == SCI_VERSION_3) {
+ if (argc < 3) {
+ volume = Audio32::kMaxVolume;
+ } else {
+ volume = argv[2].toSint16() & Audio32::kMaxVolume;
+ monitor = argv[2].toSint16() & Audio32::kMonitorAudioFlagSci3;
}
} else {
- volume = argv[2].toSint16();
+ if (argc < 3 || argv[2].toSint16() < 0 || argv[2].toSint16() > Audio32::kMaxVolume) {
+ volume = Audio32::kMaxVolume;
+
+ if (argc >= 3) {
+ monitor = true;
+ }
+ } else {
+ volume = argv[2].toSint16();
+ }
}
soundNode = argc == 4 ? argv[3] : NULL_REG;
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index 8a1d8cfb43..f631de2bdf 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -164,7 +164,9 @@ public:
/**
* The maximum channel volume.
*/
- kMaxVolume = 127
+ kMaxVolume = 127,
+
+ kMonitorAudioFlagSci3 = 0x80
};
private: