[Scummvm-cvs-logs] SF.net SVN: scummvm:[46525] scummvm/trunk/engines/sci

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Thu Dec 24 12:42:39 CET 2009


Revision: 46525
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46525&view=rev
Author:   m_kiewitz
Date:     2009-12-24 11:42:37 +0000 (Thu, 24 Dec 2009)

Log Message:
-----------
SCI: channels are now filtered for sci0 (fixes garbled music)

Modified Paths:
--------------
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/resource.h
    scummvm/trunk/engines/sci/sfx/music.cpp
    scummvm/trunk/engines/sci/sfx/music.h

Modified: scummvm/trunk/engines/sci/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource.cpp	2009-12-24 08:35:11 UTC (rev 46524)
+++ scummvm/trunk/engines/sci/resource.cpp	2009-12-24 11:42:37 UTC (rev 46525)
@@ -1926,4 +1926,24 @@
 	return NULL;
 }
 
+// Gets the filter-mask for SCI0 sound resources
+int SoundResource::getChannelFilterMask(int hardwareMask) {
+	byte *data = _innerResource->data;
+	int channelMask = 0;
+
+	if (_soundVersion == SCI_VERSION_0_EARLY) {
+		data++; // Skip over digital sample flag
+		for (int channelNr = 0; channelNr < 16; channelNr++) {
+			data++;
+			channelMask = channelMask >> 1;
+			if (*data & hardwareMask) {
+				// this Channel is supposed to get played for hardware
+				channelMask |= 0x8000;
+			}
+			data++;
+		}
+	}
+	return channelMask;
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/resource.h
===================================================================
--- scummvm/trunk/engines/sci/resource.h	2009-12-24 08:35:11 UTC (rev 46524)
+++ scummvm/trunk/engines/sci/resource.h	2009-12-24 11:42:37 UTC (rev 46525)
@@ -459,6 +459,7 @@
 	~SoundResource();
 	Track *getTrackByNumber(uint16 number);
 	Track *getTrackByType(TrackType type);
+	int getChannelFilterMask(int hardwareMask);
 
 private:
 	SciVersion _soundVersion;

Modified: scummvm/trunk/engines/sci/sfx/music.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/music.cpp	2009-12-24 08:35:11 UTC (rev 46524)
+++ scummvm/trunk/engines/sci/sfx/music.cpp	2009-12-24 11:42:37 UTC (rev 46525)
@@ -283,6 +283,7 @@
 //----------------------------------------
 void SciMusic::soundInitSnd(MusicEntry *pSnd) {
 	SoundResource::Track *track = NULL;
+	int channelFilterMask = 0;
 
 	//_mutex.lock();
 	switch (_midiType) {
@@ -331,7 +332,9 @@
 				pSnd->pMidiParser->setMidiDriver(_pMidiDrv);
 				pSnd->pMidiParser->setTimerRate(_dwTempo);
 			}
-			pSnd->pMidiParser->loadMusic(track, pSnd);
+			// Find out what channels to filter for SCI0
+			channelFilterMask = pSnd->soundRes->getChannelFilterMask(0x04); // Adlib hardcoded (TODO)
+			pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask);
 		}
 	}
 
@@ -493,13 +496,19 @@
 	unloadMusic();
 }
 //---------------------------------------------
-bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd) {
+bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, int channelFilterMask) {
 	unloadMusic();
 	_track = track;
 	_pSnd = psnd;
 	setVolume(psnd->volume);
-	midiMixChannels();
 
+	if (channelFilterMask) {
+		// SCI0 only has 1 data stream, but we need to filter out channels depending on music hardware selection
+		midiFilterChannels(channelFilterMask);
+	} else {
+		midiMixChannels();
+	}
+
 	_num_tracks = 1;
 	_tracks[0] = _mixedData;
 	setTrack(0);
@@ -722,6 +731,90 @@
 	return _mixedData;
 }
 
+// This is used for SCI0 sound-data. SCI0 only has one stream that may contain several channels and according to output
+//  device we remove certain channels from that data
+byte *MidiParser_SCI::midiFilterChannels(int channelMask) {
+	SoundResource::Channel *channel = &_track->channels[0];
+	byte *channelData = channel->data;
+	byte *channelDataEnd = channel->data + channel->size;
+	byte *filterData = new byte[channel->size];
+	byte curChannel, curByte;
+	byte command, lastCommand;
+	int delta = 0;
+	int dataLeft = channel->size;
+	int midiParamCount;
+
+	_mixedData = filterData;
+	lastCommand = 0;
+
+	// Find out which channels to filter out
+
+	while (channelData <= channelDataEnd) {
+		delta += *channelData++;
+		curByte = *channelData++;
+
+		switch (curByte) {
+		case 0xF0: // sysEx
+		case 0xFC: // end of channel
+			curChannel = 15;
+			break;
+		default:
+			if (curByte & 0x80) {
+				command = curByte;
+				curChannel = command & 0x0F;
+				midiParamCount = nMidiParams[(command >> 4) - 8];
+			}
+		}
+		if ((1 << curChannel) & channelMask) {
+			if (command != 0xFC) {
+				// Write delta
+				while (delta > 240) {
+					*filterData++ = 0xF8;
+					delta -= 240;
+				}
+				*filterData++ = (byte)delta;
+				delta = 0;
+			}
+			// Write command
+			switch (command) {
+			case 0xF0: // sysEx
+				*filterData++ = command;
+				do {
+					curByte = *channelData++;
+					*filterData++ = curByte; // out
+				} while (curByte != 0xF7);
+				break;
+
+			case 0xFC: // end of channel
+				*filterData++ = command;
+				break;
+
+			default: // MIDI command
+				if (curByte & 0x80) {
+					if (lastCommand != command) {
+						*filterData++ = command;
+					}
+					if (midiParamCount > 0)
+						*filterData++ = *channelData++;
+				} else {
+					*filterData++ = curByte;
+				}
+				if (midiParamCount > 1)
+					*filterData++ = *channelData++;
+			}
+		} else {
+			if (curByte & 0x80) {
+				channelData += midiParamCount;
+			} else {
+				channelData += midiParamCount - 1;
+			}
+		}
+		lastCommand = command;
+	}
+
+	return _mixedData;
+}
+
 void MidiParser_SCI::setVolume(byte bVolume) {
 	if (bVolume > 0x7F)
 		bVolume = 0x7F;

Modified: scummvm/trunk/engines/sci/sfx/music.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/music.h	2009-12-24 08:35:11 UTC (rev 46524)
+++ scummvm/trunk/engines/sci/sfx/music.h	2009-12-24 11:42:37 UTC (rev 46525)
@@ -163,7 +163,7 @@
 public:
 	MidiParser_SCI();
 	~MidiParser_SCI();
-	bool loadMusic(SoundResource::Track *track, MusicEntry *psnd);
+	bool loadMusic(SoundResource::Track *track, MusicEntry *psnd, int channelFilterMask);
 	bool loadMusic(byte *, uint32) {
 		return false;
 	}
@@ -179,6 +179,7 @@
 protected:
 	void parseNextEvent(EventInfo &info);
 	byte *midiMixChannels();
+	byte *midiFilterChannels(int channelMask);
 	byte midiGetNextChannel(long ticker);
 	byte *_mixedData;
 	SoundResource::Track *_track;


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