diff options
author | Colin Snover | 2017-06-16 20:04:46 -0500 |
---|---|---|
committer | Colin Snover | 2017-06-17 13:09:27 -0500 |
commit | 0d63d2a7adbe4381d945228a9da4471c9409a8f1 (patch) | |
tree | c3fbaaab774fa632d25708e82e3750ee70abf697 /video | |
parent | 12afcaec49caf4dad5af9fc46af607044bd4b82f (diff) | |
download | scummvm-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.cpp | 9 |
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; |