From 8eb82fd6c1c65ad0590462853ade281101068afa Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Fri, 5 Sep 2014 07:46:42 +0100 Subject: SWORD1: Fix heuristic to determine the endianess of the speech in mac version Because the data is compressed (a repeated sample is coded as a negative length followed by the value), when the length is read with the wrong endianess we get completely wrong data. So to get the BE data we cannot just read them assuming LE and byteswap afterward. --- engines/sword1/sound.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'engines/sword1') diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index 0b4d3829d6..ddde7f4235 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -125,31 +125,39 @@ void Sound::checkSpeechFileEndianness() { uint32 index = _cowHeader[locIndex + (localNo * 2) - 1]; if (sampleSize) { uint32 size; - double be_diff_sum = 0., le_diff_sum = 0.; + // Compute average of difference between two consecutive samples for both BE and LE _bigEndianSpeech = false; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); - // Compute average of difference between two consecutive samples for both BE and LE if (data) { if (size > 4000) size = 2000; else size /= 2; - int16 prev_be_value = (int16)SWAP_BYTES_16(*((uint16 *)(data))); - for (uint32 i = 1; i < size; ++i) { + double le_diff_sum = 0.; + for (uint32 i = 1; i < size; ++i) le_diff_sum += fabs((double)(data[i] - data[i - 1])); - int16 be_value = (int16)SWAP_BYTES_16(*((uint16 *)(data + i))); - be_diff_sum += fabs((double)(be_value - prev_be_value)); - prev_be_value = be_value; - } delete[] data; + _bigEndianSpeech = true; + data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); + if (data) { + if (size > 4000) + size = 2000; + else + size /= 2; + double be_diff_sum = 0.; + for (uint32 i = 1; i < size; ++i) + be_diff_sum += fabs((double)(data[i] - data[i - 1])); + delete [] data; + // Set the big endian flag + _bigEndianSpeech = (be_diff_sum < le_diff_sum); + if (_bigEndianSpeech) + debug(6, "Mac version: using big endian speech file"); + else + debug(6, "Mac version: using little endian speech file"); + debug(8, "Speech endianness heuristic: average = %f for BE and %f for LE, computed on %d samples)", be_diff_sum / (size - 1), le_diff_sum / (size - 1), size); + } else + _bigEndianSpeech = false; } - // Set the big endian flag - _bigEndianSpeech = (be_diff_sum < le_diff_sum); - if (_bigEndianSpeech) - debug(6, "Mac version: using big endian speech file"); - else - debug(6, "Mac version: using little endian speech file"); - debug(8, "Speech endianness heuristic: average = %f for BE and %f for LE, computed on %d samples)", be_diff_sum / (size - 1), le_diff_sum / (size - 1), size); } } -- cgit v1.2.3