From 0d63d2a7adbe4381d945228a9da4471c9409a8f1 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Fri, 16 Jun 2017 20:04:46 -0500 Subject: 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. --- video/coktel_decoder.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'video') 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(_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; -- cgit v1.2.3