diff options
Diffstat (limited to 'engines/sword1/sound.cpp')
-rw-r--r-- | engines/sword1/sound.cpp | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index ddde7f4235..9140bddb65 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -116,7 +116,7 @@ void Sound::checkSpeechFileEndianness() { return; // I picked the sample to use randomly (I just made sure it is long enough so that there is - // a fair change of the heuristic to have a stable result and work for every language). + // a fair chance of the heuristic to have a stable result and work for every language). int roomNo = _currentCowFile == 1 ? 1 : 129; int localNo = _currentCowFile == 1 ? 2 : 933; // Get the speech data and apply the heuristic @@ -128,37 +128,42 @@ void Sound::checkSpeechFileEndianness() { // Compute average of difference between two consecutive samples for both BE and LE _bigEndianSpeech = false; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); - if (data) { - if (size > 4000) - size = 2000; - else - size /= 2; - double le_diff_sum = 0.; - for (uint32 i = 1; i < size; ++i) - le_diff_sum += fabs((double)(data[i] - data[i - 1])); - 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; + uint32 maxSamples = size > 2000 ? 2000 : size; + double le_diff = endiannessHeuristicValue(data, size, maxSamples); + delete[] data; + _bigEndianSpeech = true; + data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); + double be_diff = endiannessHeuristicValue(data, size, maxSamples); + delete [] data; + // Set the big endian flag + _bigEndianSpeech = (be_diff < le_diff); + 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 (%d samples)", be_diff, le_diff, maxSamples); + } +} + +double Sound::endiannessHeuristicValue(int16* data, uint32 dataSize, uint32 &maxSamples) { + if (!data) + return 50000.; // the heuristic value for the wrong endianess is about 21000 (1/3rd of the 16 bits range) + + double diff_sum = 0.; + uint32 cpt = 0; + int16 prev_value = (int16)FROM_LE_16(*((uint16 *)(data))); + for (uint32 i = 1; i < dataSize && cpt < maxSamples; ++i) { + int16 value = (int16)FROM_LE_16(*((uint16 *)(data + i))); + if (value != prev_value) { + diff_sum += fabs((double)(value - prev_value)); + ++cpt; + prev_value = value; } } + if (cpt == 0) + return 50000.; + maxSamples = cpt; + return diff_sum / cpt; } |