From 5450870326d56e42a80a20b5c91fbb07df21d86a Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Fri, 5 Sep 2014 22:57:36 +0100 Subject: SWORD1: Improve speech endianess detection in mac version Because of the way the speech is compressed with duplicate samples being stored with a negative size and a single value, when reading the data with the wrong endianess we can end up with a lot of duplicate samples which biased the result with the way the old heuristic was coded. Hopefully this change to skip duplicate samples will make it more robust. --- engines/sword1/sound.cpp | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'engines') diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index ddde7f4235..fbe14aae27 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -126,27 +126,34 @@ void Sound::checkSpeechFileEndianness() { if (sampleSize) { uint32 size; // Compute average of difference between two consecutive samples for both BE and LE + // The way uncompressSpeech works we may get un incorrect number of identical consecutive samples + // when using the wrong endianess. To avoid biasing the result we this we skip all duplicate values. _bigEndianSpeech = false; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); if (data) { - if (size > 4000) - size = 2000; - else - size /= 2; + uint32 max_cpt = size > 2000 ? 2000 : size; double le_diff_sum = 0.; - for (uint32 i = 1; i < size; ++i) - le_diff_sum += fabs((double)(data[i] - data[i - 1])); + int le_cpt = 0; + for (uint32 i = 1; i < size && le_cpt < max_cpt; ++i) { + if (data[i] != data[i-1]) { + le_diff_sum += fabs((double)(data[i] - data[i - 1])); + ++le_cpt; + } + } + le_diff_sum /= le_cpt; 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])); + int be_cpt = 0; + for (uint32 i = 1; i < size && be_cpt < le_cpt; ++i) { + if (data[i] != data[i-1]) { + be_diff_sum += fabs((double)(data[i] - data[i - 1])); + ++be_cpt; + } + } + be_diff_sum /= be_cpt; delete [] data; // Set the big endian flag _bigEndianSpeech = (be_diff_sum < le_diff_sum); @@ -154,7 +161,7 @@ void Sound::checkSpeechFileEndianness() { 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); + debug(8, "Speech endianness heuristic: average = %f for BE (%d samples) and %f for LE (%d samples)", be_diff_sum, be_cpt, le_diff_sum, le_cpt); } else _bigEndianSpeech = false; } -- cgit v1.2.3