aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/sound
diff options
context:
space:
mode:
authorPaul Gilbert2016-11-07 19:33:00 -0500
committerPaul Gilbert2016-11-07 19:33:00 -0500
commit1e3f4f6887d2987088b6c720686cdc32c479215a (patch)
tree77885fd54660b47d3ed4635dda809c6bae21be2e /engines/titanic/sound
parent641012a14160d9d93997cafffcac30aaa2bd0f48 (diff)
downloadscummvm-rg350-1e3f4f6887d2987088b6c720686cdc32c479215a.tar.gz
scummvm-rg350-1e3f4f6887d2987088b6c720686cdc32c479215a.tar.bz2
scummvm-rg350-1e3f4f6887d2987088b6c720686cdc32c479215a.zip
TITANIC: Simulate sound distances by reducing volume
Diffstat (limited to 'engines/titanic/sound')
-rw-r--r--engines/titanic/sound/qmixer.cpp45
-rw-r--r--engines/titanic/sound/qmixer.h14
2 files changed, 52 insertions, 7 deletions
diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp
index f05f8c3ab9..ecc0bbcba4 100644
--- a/engines/titanic/sound/qmixer.cpp
+++ b/engines/titanic/sound/qmixer.cpp
@@ -88,11 +88,28 @@ void QMixer::qsWaveMixSetVolume(int iChannel, uint flags, uint volume) {
}
void QMixer::qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position) {
- // Not currently implemented in ScummVM
+ ChannelEntry &channel = _channels[iChannel];
+
+ // Flag whether distance should reset when a new sound is started
+ channel._resetDistance = (flags & QMIX_USEONCE) != 0;
+
+ // Currently, we only do a basic simulation of spatial positioning by
+ // getting the distance, and proportionately reducing the volume the
+ // further away the source is
+ channel._distance = sqrt(position.x * position.x + position.y * position.y
+ + position.z * position.z);
}
void QMixer::qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position) {
- // Not currently implemented in ScummVM
+ ChannelEntry &channel = _channels[iChannel];
+
+ // Flag whether distance should reset when a new sound is started
+ channel._resetDistance = (flags & QMIX_USEONCE) != 0;
+
+ // Currently, we only do a basic simulation of spatial positioning by
+ // getting the distance, and proportionately reducing the volume the
+ // further away the source is
+ channel._distance = position.range;
}
void QMixer::qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags) {
@@ -168,7 +185,8 @@ void QMixer::qsWaveMixPump() {
if (channel._volume != oldVolume && !channel._sounds.empty()
&& channel._sounds.front()._started) {
- _mixer->setChannelVolume(channel._sounds.front()._soundHandle, channel._volume);
+ _mixer->setChannelVolume(channel._sounds.front()._soundHandle,
+ channel.getRawVolume());
}
}
@@ -182,7 +200,7 @@ void QMixer::qsWaveMixPump() {
sound._waveFile->_stream->rewind();
_mixer->playStream(sound._waveFile->_soundType,
&sound._soundHandle, sound._waveFile->_stream,
- -1, channel._volume, 0, DisposeAfterUse::NO);
+ -1, channel.getRawVolume(), 0, DisposeAfterUse::NO);
} else {
// Sound is finished
if (sound._callback)
@@ -200,13 +218,30 @@ void QMixer::qsWaveMixPump() {
if (!channel._sounds.empty()) {
SoundEntry &sound = channel._sounds.front();
if (!sound._started) {
+ if (channel._resetDistance)
+ channel._distance = 0.0;
+
+ // Calculate an effective volume based on distance of source
_mixer->playStream(sound._waveFile->_soundType,
&sound._soundHandle, sound._waveFile->_stream,
- -1, channel._volume, 0, DisposeAfterUse::NO);
+ -1, channel.getRawVolume(), 0, DisposeAfterUse::NO);
sound._started = true;
}
}
}
}
+/*------------------------------------------------------------------------*/
+
+byte QMixer::ChannelEntry::getRawVolume() const {
+ // Emperically decided adjustment divisor for distances
+ const double ADJUSTMENT_FACTOR = 5.0;
+
+ double r = 1.0 + (_distance / ADJUSTMENT_FACTOR);
+ double percent = 1.0 / (r * r);
+
+ double newVolume = _volume * percent;
+ return (byte)newVolume;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h
index 9a0ea85ede..b8c7f6dae2 100644
--- a/engines/titanic/sound/qmixer.h
+++ b/engines/titanic/sound/qmixer.h
@@ -197,9 +197,19 @@ class QMixer {
uint _volumeChangeEnd;
byte _volumeStart;
byte _volumeEnd;
+ // Distance of source
+ double _distance;
+ bool _resetDistance;
ChannelEntry() : _volume(0), _panRate(0), _volumeChangeStart(0),
- _volumeChangeEnd(0), _volumeStart(0), _volumeEnd(0) {}
+ _volumeChangeEnd(0), _volumeStart(0), _volumeEnd(0),
+ _distance(0.0), _resetDistance(true) {}
+
+ /**
+ * Calculates the raw volume level to pass to ScummVM playStream, taking
+ * into the sound's volume level and distance from origin
+ */
+ byte getRawVolume() const;
};
private:
Audio::Mixer *_mixer;
@@ -290,7 +300,7 @@ public:
void qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances);
/**
- *
+ * Sets the frequency/rate of sound playback
*/
void qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency);