[Scummvm-cvs-logs] SF.net SVN: scummvm:[42423] scummvm/trunk/engines/sword1
sev at users.sourceforge.net
sev at users.sourceforge.net
Sun Jul 12 20:52:38 CEST 2009
Revision: 42423
http://scummvm.svn.sourceforge.net/scummvm/?rev=42423&view=rev
Author: sev
Date: 2009-07-12 18:52:38 +0000 (Sun, 12 Jul 2009)
Log Message:
-----------
Patch #1936137: "Speech for Mac BS1 english"
Modified Paths:
--------------
scummvm/trunk/engines/sword1/sound.cpp
scummvm/trunk/engines/sword1/sound.h
scummvm/trunk/engines/sword1/sword1.cpp
Modified: scummvm/trunk/engines/sword1/sound.cpp
===================================================================
--- scummvm/trunk/engines/sword1/sound.cpp 2009-07-12 16:59:29 UTC (rev 42422)
+++ scummvm/trunk/engines/sword1/sound.cpp 2009-07-12 18:52:38 UTC (rev 42423)
@@ -51,6 +51,7 @@
strcpy(_filePath, searchPath);
_mixer = mixer;
_resMan = pResMan;
+ _bigEndianSpeech = false;
_cowHeader = NULL;
_endOfQueue = 0;
_currentCowFile = 0;
@@ -67,6 +68,83 @@
closeCowSystem();
}
+void Sound::checkSpeechFileEndianness() {
+ // Some mac versions (not all of them) use big endian wav, although
+ // the wav header doesn't indicate it.
+ // Use heuristic to determine endianness of speech.
+ // The heuristic consist in computing the sum of the absolute difference for
+ // every two consecutive samples. This is done both with a big endian and a
+ // little endian assumption. The one with the smallest sum should be the
+ // correct one (the sound wave is supposed to be relatively smooth).
+ // It needs at least 1000 samples to get stable result (the code below is
+ // using the first 2000 samples of the wav sound.
+
+ // Init speach file if not already done.
+ if (!_currentCowFile) {
+ // Open one of the speech file. It uses SwordEngine::_systemVars.currentCD
+ // to decide which file to open, therefore if it is currently set to zero
+ // we have to set it to either 1 or 2 (I decided to set it to 1 as this is
+ // more likely to be the first file that will be needed).
+ bool no_current_cd = false;
+ if (SwordEngine::_systemVars.currentCD == 0) {
+ SwordEngine::_systemVars.currentCD = 1;
+ no_current_cd = true;
+ }
+ initCowSystem();
+ if (no_current_cd) {
+ // In case it fails with CD1 retyr with CD2
+ if (!_currentCowFile) {
+ SwordEngine::_systemVars.currentCD = 2;
+ initCowSystem();
+ }
+ // Reset curentCD flag
+ SwordEngine::_systemVars.currentCD = 0;
+ }
+ }
+
+ // Testing for endianness makes sense only if using the nom compressed files.
+ if (_cowHeader == NULL || (_cowMode != CowWave && _cowMode != CowDemo))
+ 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 languages).
+ int roomNo = _currentCowFile == 1 ? 1 : 129;
+ int localNo = _currentCowFile == 1 ? 2 : 933;
+ // Get the speech data and apply the heuristic
+ uint32 locIndex = _cowHeader[roomNo] >> 2;
+ uint32 sampleSize = _cowHeader[locIndex + (localNo * 2)];
+ uint32 index = _cowHeader[locIndex + (localNo * 2) - 1];
+ if (sampleSize) {
+ uint32 size;
+ double be_diff_sum = 0., le_diff_sum = 0.;
+ _bigEndianSpeech = false;
+ int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size);
+ // Compute average of differecen 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) {
+ le_diff_sum += fabs(data[i] - data[i-1]);
+ int16 be_value = (int16)SWAP_BYTES_16(*((uint16*)(data + i)));
+ be_diff_sum += fabs(be_value - prev_be_value);
+ prev_be_value = be_value;
+ }
+ 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);
+ }
+}
+
+
int Sound::addToQueue(int32 fxNo) {
bool alreadyInQueue = false;
for (uint8 cnt = 0; (cnt < _endOfQueue) && (!alreadyInQueue); cnt++)
@@ -386,21 +464,32 @@
int16 *dstData = (int16*)malloc(resSize * 2);
int32 samplesLeft = resSize;
while (srcPos < cSize && samplesLeft > 0) {
- length = (int16)READ_LE_UINT16(srcData + srcPos);
+ length = (int16)(_bigEndianSpeech ? READ_BE_UINT16(srcData + srcPos) : READ_LE_UINT16(srcData + srcPos));
srcPos++;
if (length < 0) {
length = -length;
if (length > samplesLeft)
length = samplesLeft;
+ int16 value;
+ if (_bigEndianSpeech) {
+ value = (int16)SWAP_BYTES_16(*((uint16*)(srcData + srcPos)));
+ } else {
+ value = srcData[srcPos];
+ }
for (uint16 cnt = 0; cnt < (uint16)length; cnt++)
- dstData[dstPos++] = srcData[srcPos];
+ dstData[dstPos++] = value;
srcPos++;
} else {
if (length > samplesLeft)
length = samplesLeft;
- memcpy(dstData + dstPos, srcData + srcPos, length * 2);
- dstPos += length;
- srcPos += length;
+ if (_bigEndianSpeech) {
+ for (uint16 cnt = 0; cnt < (uint16)length; cnt++)
+ dstData[dstPos++] = (int16)SWAP_BYTES_16(*((uint16*)(srcData + (srcPos++))));
+ } else {
+ memcpy(dstData + dstPos, srcData + srcPos, length * 2);
+ dstPos += length;
+ srcPos += length;
+ }
}
samplesLeft -= length;
}
Modified: scummvm/trunk/engines/sword1/sound.h
===================================================================
--- scummvm/trunk/engines/sword1/sound.h 2009-07-12 16:59:29 UTC (rev 42422)
+++ scummvm/trunk/engines/sword1/sound.h 2009-07-12 18:52:38 UTC (rev 42423)
@@ -95,6 +95,8 @@
void engine(void);
+ void checkSpeechFileEndianness();
+
private:
uint8 _sfxVolL, _sfxVolR, _speechVolL, _speechVolR;
void playSample(QueueElement *elem);
@@ -116,6 +118,7 @@
uint8 _endOfQueue;
Audio::Mixer *_mixer;
ResMan *_resMan;
+ bool _bigEndianSpeech;
char _filePath[100];
static const char _musicList[270];
static const uint16 _roomsFixedFx[TOTAL_ROOMS][TOTAL_FX_PER_ROOM];
Modified: scummvm/trunk/engines/sword1/sword1.cpp
===================================================================
--- scummvm/trunk/engines/sword1/sword1.cpp 2009-07-12 16:59:29 UTC (rev 42422)
+++ scummvm/trunk/engines/sword1/sword1.cpp 2009-07-12 18:52:38 UTC (rev 42423)
@@ -145,6 +145,10 @@
_systemVars.playSpeech = 1;
_mouseState = 0;
+
+ // Some Mac versions use big endian for the speech files but not all of them.
+ if (_systemVars.platform == Common::kPlatformMacintosh)
+ _sound->checkSpeechFileEndianness();
_logic->initialize();
_objectMan->initialize();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list