[Scummvm-cvs-logs] CVS: scummvm/scumm imuse_digi.cpp,1.84,1.85 imuse_digi.h,1.23,1.24 script_v8.cpp,2.207,2.208 sound.cpp,1.297,1.298 string.cpp,1.172,1.173

Pawel Kolodziejski aquadran at users.sourceforge.net
Fri Dec 26 04:16:00 CET 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv7221/scumm

Modified Files:
	imuse_digi.cpp imuse_digi.h script_v8.cpp sound.cpp string.cpp 
Log Message:
passthrought v7+ sound voices by imuse digital

Index: imuse_digi.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi.cpp,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- imuse_digi.cpp	25 Dec 2003 21:33:30 -0000	1.84
+++ imuse_digi.cpp	26 Dec 2003 12:15:22 -0000	1.85
@@ -634,58 +634,6 @@
 };
 #endif
 
-static byte *readCreativeVocFile(byte *ptr, int32 &size, int &rate) {
-	assert(strncmp((char *)ptr, "Creative Voice File\x1A", 20) == 0);
-	int32 offset = READ_LE_UINT16(ptr + 20);
-	int16 version = READ_LE_UINT16(ptr + 22);
-	int16 code = READ_LE_UINT16(ptr + 24);
-	assert(version == 0x010A || version == 0x0114);
-	assert(code == ~version + 0x1234);
-	bool quit = 0;
-	byte *ret_sound = 0; size = 0;
-	int loops = 0;
-	while (!quit) {
-		int len = READ_LE_UINT32(ptr + offset);
-		offset += 4;
-		code = len & 0xFF;
-		len >>= 8;
-		switch(code) {
-		case 0: quit = 1; break;
-		case 1: {
-			int time_constant = ptr[offset++];
-			int packing = ptr[offset++];
-			len -= 2;
-			rate = getSampleRateFromVOCRate(time_constant);
-			debug(9, "VOC Data Bloc : %d, %d, %d", rate, packing, len);
-			if (packing == 0) {
-				if (size) {
-					ret_sound = (byte *)realloc(ret_sound, size + len);
-				} else {
-					ret_sound = (byte *)malloc(len);
-				}
-				memcpy(ret_sound + size, ptr + offset, len);
-				size += len;
-			} else {
-				warning("VOC file packing %d unsupported", packing);
-			}
-			} break;
-		case 6:	// begin of loop
-			loops = len + 1;
-			break;
-		case 7:	// end of loop
-			break;
-		default:
-			warning("Invalid code in VOC file : %d", code);
-			quit = 1;
-			break;
-		}
-		// FIXME some FT samples (ex. 362) has bad length, 2 bytes too short
-		offset += len;
-	}
-	debug(9, "VOC Data Size : %d", size);
-	return ret_sound;
-}
-
 static uint32 decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo) {
 	uint32 loop_size = size / 3;
 	uint32 s_size = loop_size * 4;
@@ -722,6 +670,12 @@
 	: _scumm(scumm) {
 	_pause = false;
 	
+	_voiceVocData = NULL;
+	_voiceVocSize = 0;
+	_voiceVocRate = 0;
+
+	_voiceBundleData = NULL;
+
 	_nameBundleMusic = "";
 	_musicBundleBufFinal = NULL;
 	_musicBundleBufOutput = NULL;
@@ -802,17 +756,36 @@
 	}
 }
 
+void IMuseDigital::setVocVoice(byte *src, int32 size, int rate) {
+	_voiceVocData = src;
+	_voiceVocSize = size;
+	_voiceVocRate = rate;
+}
+
+void IMuseDigital::setBundleVoice(byte *src) {
+	_voiceBundleData = src;
+}
+
 void IMuseDigital::startSound(int sound) {
 	debug(5, "IMuseDigital::startSound(%d)", sound);
 	int l, r;
 
 	for (l = 0; l < MAX_DIGITAL_CHANNELS; l++) {
 		if (!_channel[l].used && !_channel[l].handle.isActive()) {
-			byte *ptr = _scumm->getResourceAddress(rtSound, sound);
-			byte *s_ptr = ptr;
-			if (ptr == NULL) {
-				warning("IMuseDigital::startSound(%d) NULL resource pointer", sound);
-				return;
+			byte *ptr, *s_ptr;
+			if ((sound == 10000) && (_voiceBundleData)) {
+				s_ptr = ptr = _voiceBundleData;
+			} else if ((sound == 10000) && (_voiceVocData)) {
+				//
+			} else if (sound != 10000) {
+				ptr = _scumm->getResourceAddress(rtSound, sound);
+				s_ptr = ptr;
+				if (ptr == NULL) {
+					warning("IMuseDigital::startSound(%d) NULL resource pointer", sound);
+					return;
+				}
+			} else {
+				error("IMuseDigital::startSound() unknown condition");
 			}
 			_channel[l].pan = 0;
 			_channel[l].vol = 127 * 1000;
@@ -832,8 +805,22 @@
 			int32 size = 0;
 			int t;
 
-			if (READ_UINT32(ptr) == MKID('Crea')) {
-				byte *t_ptr= readCreativeVocFile(ptr, size, _channel[l].freq);
+			if ((sound == 10000) && (_voiceVocData)) {
+				_channel[l].mixerSize = _voiceVocRate * 2;
+				_channel[l].size = _voiceVocSize * 2;
+				_channel[l].bits = 8;
+				_channel[l].channels = 2;
+				_channel[l].mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO | SoundMixer::FLAG_UNSIGNED;
+				_channel[l].data = (byte *)malloc(_channel[l].size);
+
+				for (t = 0; t < _channel[l].size / 2; t++) {
+					*(_channel[l].data + t * 2 + 0) = *(_voiceVocData + t);
+					*(_channel[l].data + t * 2 + 1) = *(_voiceVocData + t);
+				}
+
+				_voiceVocRate = NULL;
+			} else if (READ_UINT32(ptr) == MKID('Crea')) {
+				byte *t_ptr= readCreativeVoc(ptr, size, _channel[l].freq);
 				_channel[l].mixerSize = _channel[l].freq * 2;
 				_channel[l].size = size * 2;
 				_channel[l].bits = 8;
@@ -897,6 +884,9 @@
 						_channel[l].jump[_channel[l].numJumps].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
 						_channel[l].numJumps++;
 						break;
+					case MKID_BE('SYNC'):
+						size = READ_BE_UINT32(ptr); ptr += size + 4;
+						break;
 					case MKID_BE('DATA'):
 						size = READ_BE_UINT32(ptr); ptr += 4;
 						break;
@@ -907,6 +897,16 @@
 						break;
 				}
 
+				if ((sound == 10000) && (_voiceBundleData)) {
+					if (_scumm->_actorToPrintStrFor != 0xFF && _scumm->_actorToPrintStrFor != 0) {
+						Actor *a = _scumm->derefActor(_scumm->_actorToPrintStrFor, "playBundleSound");
+						_channel[l].freq = (_channel[l].freq * a->talkFrequency) / 256;
+
+						// Adjust to fit the mixer's notion of panning.
+						_channel[l].pan = (a->talkPan != 64) ? 2 * a->talkPan - 127 : 0;
+					}
+				}
+
 				uint32 header_size = ptr - s_ptr;
 
 				_channel[l].offsetStop -= header_size;
@@ -938,6 +938,26 @@
 					_channel[l].mixerSize *= 2;
 					_channel[l].mixerFlags |= SoundMixer::FLAG_16BITS;
 					_channel[l].size = decode12BitsSample(ptr, &_channel[l].data, size, (_channel[l].channels == 2) ? false : true);
+				} else if (_channel[l].bits == 16) {
+					_channel[l].mixerSize *= 2;
+					_channel[l].mixerFlags |= SoundMixer::FLAG_16BITS;
+					
+					// FIXME: For some weird reasons, sometimes we get an odd size, even though
+					// the data is supposed to be in 16 bit format... that makes no sense...
+					size &= ~1;
+					
+					if (_channel[l].channels == 1) {
+						size *= 2;
+						_channel[l].channels = 2;
+						_channel[l].data = (byte *)malloc(size);
+						for (t = 0; t < size / 4; t++) {
+							*(_channel[l].data + t * 4 + 0) = *(ptr + t * 2 + 0);
+							*(_channel[l].data + t * 4 + 1) = *(ptr + t * 2 + 1);
+							*(_channel[l].data + t * 4 + 2) = *(ptr + t * 2 + 0);
+							*(_channel[l].data + t * 4 + 3) = *(ptr + t * 2 + 1);
+						}
+					}
+					_channel[l].size = size;
 				} else if (_channel[l].bits == 8) {
 					_channel[l].mixerFlags |= SoundMixer::FLAG_UNSIGNED;
 					if (_channel[l].channels == 1) {
@@ -1408,9 +1428,8 @@
 	free(buffer);
 }
 
-void IMuseDigital::playBundleSound(const char *sound, PlayingSoundHandle *handle) {
+void IMuseDigital::playBundleSound(const char *sound) {
 	byte *ptr = 0, *orig_ptr = 0;
-	byte *final;
 	bool result;
 
 	if (!_scumm->_mixer->isReady())
@@ -1427,7 +1446,7 @@
 
 			result = _bundle->openVoiceFile(voxfile, _scumm->getGameDataPath());
 
-			if (result == false) 
+			if (result == false)
 				result = _bundle->openVoiceFile("voice.bun", _scumm->getGameDataPath());
 			_voiceDisk = (byte)_scumm->VAR(_scumm->VAR_CURRENTDISK);
 		}
@@ -1439,89 +1458,22 @@
 	if (!result)
 		return;
 
-	int32 rate = 22050, pan = 0, channels = 0, output_size = 0;
-	int32 tag, size = -1, bits = 0;
-
 	if (_scumm->_gameId == GID_CMI) {
 		char name[20];
 		strcpy(name, sound);
 		if (!(_scumm->_features & GF_DEMO)) // CMI demo does not have .IMX for voice but does for music...
 			strcat(name, ".IMX");
-		output_size = _bundle->decompressVoiceSampleByName(name, &ptr);
+		_bundle->decompressVoiceSampleByName(name, &ptr);
 	} else {
-		output_size = _bundle->decompressVoiceSampleByName(sound, &ptr);
-	}
-
-	orig_ptr = ptr;
-	if (output_size == 0 || orig_ptr == 0) {
-		goto bail;
-	}
-
-	tag = READ_BE_UINT32(ptr); ptr += 4;
-	if (tag != MKID_BE('iMUS')) {
-		warning("Decompression of bundle sound failed");
-		goto bail;
-	}
-
-	ptr += 12;
-	while (tag != MKID_BE('DATA')) {
-		tag = READ_BE_UINT32(ptr); ptr += 4;
-		switch(tag) {
-		case MKID_BE('FRMT'):
-			ptr += 12;
-			bits = READ_BE_UINT32(ptr); ptr += 4;
-			rate = READ_BE_UINT32(ptr); ptr += 4;
-			channels = READ_BE_UINT32(ptr); ptr += 4;
-			break;
-		case MKID_BE('TEXT'):
-		case MKID_BE('REGN'):
-		case MKID_BE('STOP'):
-		case MKID_BE('JUMP'):
-		case MKID_BE('SYNC'):
-			size = READ_BE_UINT32(ptr); ptr += size + 4;
-			break;
-		case MKID_BE('DATA'):
-			size = READ_BE_UINT32(ptr); ptr += 4;
-			break;
-		default:
-			error("Unknown sound header '%s'", tag2str(tag));
-		}
-	}
-
-	if (size < 0) {
-		warning("Decompression sound failed (no size field)");
-		goto bail;
-	}
-
-	final = (byte *)malloc(size);
-	memcpy(final, ptr, size);
-
-	if (_scumm->_actorToPrintStrFor != 0xFF && _scumm->_actorToPrintStrFor != 0) {
-		Actor *a = _scumm->derefActor(_scumm->_actorToPrintStrFor, "playBundleSound");
-		rate = (rate * a->talkFrequency) / 256;
-
-		// Adjust to fit the mixer's notion of panning.
-		pan = (a->talkPan != 64) ? 2 * a->talkPan - 127 : 0;
+		_bundle->decompressVoiceSampleByName(sound, &ptr);
 	}
-	
-	// Stop any sound currently playing on the given handle
-	if (handle)
-		_scumm->_mixer->stopHandle(*handle);
 
-	assert(channels == 1);
-	if (bits == 8) {
-		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
-	} else if (bits == 16) {
-		// FIXME: For some weird reasons, sometimes we get an odd size, even though
-		// the data is supposed to be in 16 bit format... that makes no sense...
-		size &= ~1;
-		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE, -1, 255, pan);
-	} else {
-		warning("IMuseDigital::playBundleSound() to do more options to playRaw...");
+	if (ptr) {
+		stopSound(10000);
+		setBundleVoice(ptr);
+		startSound(10000);
+		free(ptr);
 	}
-	
-bail:
-	free(orig_ptr);
 }
 
 } // End of namespace Scumm

Index: imuse_digi.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- imuse_digi.h	25 Dec 2003 16:52:31 -0000	1.23
+++ imuse_digi.h	26 Dec 2003 12:15:23 -0000	1.24
@@ -128,11 +128,18 @@
 public:
 	int32 _bundleSongPosInMs;
 	Bundle *_bundle;	// FIXME: should be protected but is used by ScummEngine::askForDisk
+	byte *_voiceVocData;
+	int32 _voiceVocSize;
+	int _voiceVocRate;
+
+	byte *_voiceBundleData;
 
 	void pauseBundleMusic(bool state);
 	void stopBundleMusic();
-	void playBundleSound(const char *sound, PlayingSoundHandle *handle);
- 
+	void playBundleSound(const char *sound);
+	void setVocVoice(byte *src, int32 size, int rate);
+	void setBundleVoice(byte *src);
+
 public:
 	IMuseDigital(ScummEngine *scumm);
 	~IMuseDigital();

Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.207
retrieving revision 2.208
diff -u -d -r2.207 -r2.208
--- script_v8.cpp	25 Dec 2003 21:27:45 -0000	2.207
+++ script_v8.cpp	26 Dec 2003 12:15:23 -0000	2.208
@@ -1078,9 +1078,10 @@
 		// on the current talk channel handle. (If the handle is 0,
 		// setChannelPan() won't do anything.)
 
-		if (_actorToPrintStrFor == a->number)
-			_mixer->setChannelPan(_sound->_talkChannelHandle,
-				(a->talkPan != 64) ? 2 * a->talkPan - 127 : 0);
+		if (_actorToPrintStrFor == a->number) {
+			if (_sound->isSoundRunning(10000))
+				_imuseDigital->parseScriptCmds(12, 0x700, 10000, a->talkPan, 0, 0, 0, 0);
+		}
 
 		break;
 	default:

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.297
retrieving revision 1.298
diff -u -d -r1.297 -r1.298
--- sound.cpp	26 Dec 2003 07:59:55 -0000	1.297
+++ sound.cpp	26 Dec 2003 12:15:23 -0000	1.298
@@ -39,11 +39,6 @@
 
 namespace Scumm {
 
-enum {
-	SOUND_HEADER_SIZE = 26,
-	SOUND_HEADER_BIG_SIZE = 26 + 8
-};
-
 struct MP3OffsetTable {					/* Compressed Sound (.SO3) */
 	int org_offset;
 	int new_offset;
@@ -411,7 +406,11 @@
 	if ((_sfxMode & 2) && _scumm->VAR(_scumm->VAR_TALK_ACTOR)) {
 		act = _scumm->VAR(_scumm->VAR_TALK_ACTOR);
 
-		finished = !_talkChannelHandle.isActive();
+		if (_scumm->_imuseDigital) {
+			finished = !isSoundRunning(10000);
+		} else {
+			finished = !_talkChannelHandle.isActive();
+		}
 
 		if (act != 0 && (uint) act < 0x80 && !_scumm->_string[0].no_talk_anim) {
 			a = _scumm->derefActor(act, "processSfxQueues");
@@ -486,14 +485,13 @@
 			warning("startTalkSound: dig demo: voc file not found");
 			return;
 		}
-
 	} else {
 
 		if (!_sfxFile->isOpen()) {
 			warning("startTalkSound: SFX file is not open");
 			return;
 		}
-	
+
 		// FIXME hack until more is known
 		// the size of the data after the sample isn't known
 		// 64 is just a guess
@@ -506,7 +504,7 @@
 			_scumm->_mixer->playRaw(handle, sound, b - 64, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
 			return;
 		}
-	
+
 		// Some games frequently assume that starting one sound effect will
 		// automatically stop any other that may be playing at that time. So
 		// that is what we do here, but we make an exception for speech.
@@ -515,24 +513,24 @@
 		//
 		// HACK: Checking for script 99 in Sam & Max is to keep Conroy's song
 		// from being interrupted.
-	
+
 		if (mode == 1 && (_scumm->_gameId == GID_TENTACLE
 			|| (_scumm->_gameId == GID_SAMNMAX && !_scumm->isScriptRunning(99)))) {
 			id = 777777;
 			_scumm->_mixer->stopID(id);
 		}
-	
+
 		if (b > 8) {
 			num = (b - 8) >> 1;
 		}
-	
+
 		if (offset_table != NULL) {
 			MP3OffsetTable *result = NULL, key;
 	
 			key.org_offset = offset;
 			result = (MP3OffsetTable *)bsearch(&key, offset_table, num_sound_effects,
 													sizeof(MP3OffsetTable), compareMP3OffsetTable);
-	
+
 			if (result == NULL) {
 				warning("startTalkSound: did not find sound at offset %d !", offset);
 				return;
@@ -548,10 +546,10 @@
 			offset += 8;
 			size = -1;
 		}
-	
+
 		_sfxFile->seek(offset, SEEK_SET);
-	
-		assert(num+1 < (int)ARRAYSIZE(_mouthSyncTimes));
+
+		assert(num + 1 < (int)ARRAYSIZE(_mouthSyncTimes));
 		for (i = 0; i < num; i++)
 			_mouthSyncTimes[i] = _sfxFile->readUint16BE();
 	
@@ -566,7 +564,11 @@
 
 void Sound::stopTalkSound() {
 	if (_sfxMode & 2) {
-		_scumm->_mixer->stopHandle(_talkChannelHandle);
+		if (_scumm->_imuseDigital) {
+			_scumm->_imuseDigital->stopSound(10000);
+		} else {
+			_scumm->_mixer->stopHandle(_talkChannelHandle);
+		}
 		_sfxMode &= ~2;
 	}
 }
@@ -797,10 +799,6 @@
 }
 
 void Sound::startSfxSound(File *file, int file_size, PlayingSoundHandle *handle, int id) {
-	char ident[8];
-	uint size = 0;
-	int rate, comp;
-	byte *data;
 
 	if (_soundsPaused || !_scumm->_mixer->isReady())
 		return;
@@ -818,47 +816,17 @@
 		return;
 	}
 
-	if (file->read(ident, 8) != 8)
-		goto invalid;
+	int32 size;
+	int rate;
+	byte *data = loadVocSample(_sfxFile, size, rate);
 
-	if (!memcmp(ident, "VTLK", 4)) {
-		file->seek(SOUND_HEADER_BIG_SIZE - 8, SEEK_CUR);
-	} else if (!memcmp(ident, "Creative", 8)) {
-		file->seek(SOUND_HEADER_SIZE - 8, SEEK_CUR);
+	if (_scumm->_imuseDigital) {
+		_scumm->_imuseDigital->setVocVoice(data, size, rate);
+		_scumm->_imuseDigital->startSound(10000);
+		free(data);
 	} else {
-	invalid:;
-		warning("startSfxSound: invalid header");
-		return;
-	}
-
-	VocBlockHeader voc_block_hdr;
-
-	file->read(&voc_block_hdr, sizeof(voc_block_hdr));
-	if (voc_block_hdr.blocktype != 1) {
-		warning("startSfxSound: Expecting block_type == 1, got %d", voc_block_hdr.blocktype);
-		return;
-	}
-
-	size = voc_block_hdr.size[0] + (voc_block_hdr.size[1] << 8) + (voc_block_hdr.size[2] << 16) - 2;
-	rate = getSampleRateFromVOCRate(voc_block_hdr.sr);
-	comp = voc_block_hdr.pack;
-
-	if (comp != 0) {
-		warning("startSfxSound: Unsupported compression type %d", comp);
-		return;
-	}
-
-	data = (byte *)malloc(size);
-	if (data == NULL) {
-		error("startSfxSound: out of memory");
-	}
-
-	if (file->read(data, size) != size) {
-		/* no need to free the memory since error will shut down */
-		error("startSfxSound: cannot read %d bytes", size);
+		_scumm->_mixer->playRaw(handle, data, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED, id);
 	}
-
-	_scumm->_mixer->playRaw(handle, data, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED, id);
 }
 
 File *Sound::openSfxFile() {
@@ -869,6 +837,15 @@
 	 * That way, you can keep .sou files for multiple games in the
 	 * same directory */
 	offset_table = NULL;
+
+	// for now until better streaming will be, ft voice can't not be compressed
+	if (_scumm->_imuseDigital) {
+		sprintf(buf, "%s.sou", _scumm->getGameName());
+		if (!file->open(buf, _scumm->getGameDataPath())) {
+			file->open("monster.sou", _scumm->getGameDataPath());
+		}
+		return file;
+	}
 
 #ifdef USE_MAD
 	sprintf(buf, "%s.so3", _scumm->getGameName());

Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -d -r1.172 -r1.173
--- string.cpp	24 Dec 2003 00:24:57 -0000	1.172
+++ string.cpp	26 Dec 2003 12:15:23 -0000	1.173
@@ -163,9 +163,10 @@
 	if (_talkDelay)
 		return;
 
-	if ((_gameId == GID_CMI || _gameId == GID_DIG) && _sound->_talkChannelHandle.isActive()) {
+	if ((_gameId == GID_CMI || _gameId == GID_DIG) && (_imuseDigital)
+				&& _sound->isSoundRunning(10000)) {
 		// Keep the 'speech' flag in _sound->_sfxMode set as long as the
-		// _talkChannelHandle is valid.
+		// sound 10000 is playing.
 		_sound->_sfxMode |= 2;
 	}
 
@@ -900,7 +901,7 @@
 		pointer[j] = 0;
 
 		// Play speech
-		_imuseDigital->playBundleSound(pointer, &_sound->_talkChannelHandle);
+		_imuseDigital->playBundleSound(pointer);
 
 		ptr = _transText;
 	}





More information about the Scummvm-git-logs mailing list