aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorColin Snover2017-06-16 20:04:46 -0500
committerColin Snover2017-06-17 13:09:27 -0500
commit0d63d2a7adbe4381d945228a9da4471c9409a8f1 (patch)
treec3fbaaab774fa632d25708e82e3750ee70abf697 /video
parent12afcaec49caf4dad5af9fc46af607044bd4b82f (diff)
downloadscummvm-rg350-0d63d2a7adbe4381d945228a9da4471c9409a8f1.tar.gz
scummvm-rg350-0d63d2a7adbe4381d945228a9da4471c9409a8f1.tar.bz2
scummvm-rg350-0d63d2a7adbe4381d945228a9da4471c9409a8f1.zip
VIDEO: Wrap out-of-range VMD audio samples instead of clipping
The 16-bit DPCM decompressors in SSCI and Urban Runner use a 16-bit register to store sample data, without any special handling of overflow. As such, out-of-range samples simply wrap around, rather than getting clipped. It is not totally clear if the wrapping behaviour was intentionally exploited to handle extreme transients, but in any case, videos like GK2 5280.VMD that generate samples outside the signed 16-bit range cause a loud pop when using clipping, but play back correctly when wrapping.
Diffstat (limited to 'video')
-rw-r--r--video/coktel_decoder.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index 905ffd6ff2..daebbd3ea9 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -2617,7 +2617,14 @@ int DPCMStream::readBuffer(int16 *buffer, const int numSamples) {
else
_buffer[i] += tableDPCM[data];
- *buffer++ = _buffer[i] = CLIP<int32>(_buffer[i], -32768, 32767);
+ // Emulating x86 16-bit signed register overflow
+ if (_buffer[i] > 32767) {
+ _buffer[i] -= 65536;
+ } else if (_buffer[i] < -32768) {
+ _buffer[i] += 65536;
+ }
+
+ *buffer++ = _buffer[i];
}
samples += _channels;