[Scummvm-cvs-logs] scummvm master -> 920c3bb17236e013b0e135886fa37521ceffd086

athrxx athrxx at scummvm.org
Sun Jun 5 18:43:51 CEST 2011


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
43075248aa AUDIO: fix device detection (missing rom files for MT-32 emu)
920c3bb172 KYRA: fix audio detection


Commit: 43075248aaef68ab9eef39c8988854f00eb694b0
    https://github.com/scummvm/scummvm/commit/43075248aaef68ab9eef39c8988854f00eb694b0
Author: athrxx (athrxx at scummvm.org)
Date: 2011-06-05T09:29:13-07:00

Commit Message:
AUDIO: fix device detection (missing rom files for MT-32 emu)

This is an attempt to fix the problem Max described in his devel mail.
The presence of the rom files will now be checked in detectDevice().
In case of failure there will be fallback attempts.
The user will get notified of the detection failure if he has expressly selected the device that failed.

Please test with your platform / engine (with or without rom files).

Changed paths:
    audio/mididrv.cpp
    audio/mididrv.h
    audio/musicplugin.h
    audio/softsynth/mt32.cpp



diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index 5839f5b..0b5066e 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -26,6 +26,7 @@
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "common/util.h"
+#include "engines/engine.h"
 #include "audio/mididrv.h"
 #include "audio/musicplugin.h"
 
@@ -125,6 +126,7 @@ Common::String MidiDriver::getDeviceString(DeviceHandle handle, DeviceStringType
 MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
 	// Query the selected music device (defaults to MT_AUTO device).
 	DeviceHandle hdl = getDeviceHandle(ConfMan.get("music_driver"));
+	DeviceHandle reslt = MT_AUTO;
 
 	_forceTypeMT32 = false;
 
@@ -133,71 +135,87 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
 	switch (getMusicType(hdl)) {
 	case MT_PCSPK:
 		if (flags & MDT_PCSPK)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_PCJR:
 		if (flags & MDT_PCJR)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_CMS:
 		if (flags & MDT_CMS)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_ADLIB:
 		if (flags & MDT_ADLIB)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_C64:
 		if (flags & MDT_C64)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_AMIGA:
 		if (flags & MDT_AMIGA)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_APPLEIIGS:
 		if (flags & MDT_APPLEIIGS)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_TOWNS:
 		if (flags & MDT_TOWNS)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_PC98:
 		if (flags & MDT_PC98)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_GM:
 	case MT_GS:
 	case MT_MT32:
 		if (flags & MDT_MIDI)
-			return hdl;
+			reslt = hdl;
 		break;
 
 	case MT_NULL:
-		return hdl;
+		reslt = hdl;
 
 	default:
 		break;
 	}
 
+	Common::String failedDevStr;
+	MusicType tp = getMusicType(reslt);
+	if (tp != MT_INVALID && tp != MT_AUTO) {
+		if (checkDevice(reslt)) {
+			return reslt;
+		} else {
+			// If the expressly selected device is unavailable we display a warning and continue.
+			failedDevStr = getDeviceString(hdl, MidiDriver::kDriverName);
+			Common::String errorMessage = "Failed to detect the selected audio device '" + failedDevStr +"'. See log file for more information. Attempting to fall back to the next available device...";
+			GUIErrorMessage(errorMessage);
+		}
+	}
+
+	reslt = MT_AUTO;
+
 	// If the selected driver did not match the flags setting,
 	// we try to determine a suitable and "optimal" music driver.
 	const MusicPlugin::List p = MusicMan.getPlugins();
 	// If only MDT_MIDI but not MDT_PREFER_MT32 or MDT_PREFER_GM is set we prefer the other devices (which will always be
 	// detected since they are hard coded and cannot be disabled.
-	for (int l = (flags & (MDT_PREFER_GM | MDT_PREFER_MT32)) ? 1 : 0; l < 2; ++l) {
-		if ((flags & MDT_MIDI) && (l == 1)) {
-			// If a preferred MT32 or GM device has been selected that device gets returned.
+	bool skipMidi = !(flags & (MDT_PREFER_GM | MDT_PREFER_MT32));
+	while (flags != MDT_NONE) {
+		if ((flags & MDT_MIDI) && !skipMidi) {
+			// If a preferred MT32 or GM device has been selected that device gets returned if available.
 			if (flags & MDT_PREFER_MT32)
 				hdl = getDeviceHandle(ConfMan.get("mt32_device"));
 			else if (flags & MDT_PREFER_GM)
@@ -211,70 +229,117 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
 			// to AdLib, PC Speaker etc. detection right away.
 			if (type != MT_NULL) {
 				if (type != MT_AUTO && type != MT_INVALID) {
-					if (flags & MDT_PREFER_MT32)
-						// If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h).
-						_forceTypeMT32 = true;
-
-					return hdl;
+					if (checkDevice(hdl)) {
+						if (flags & MDT_PREFER_MT32)
+							// If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h).
+							_forceTypeMT32 = true;
+						return hdl;
+					} else {
+						// If the preferred (expressly requested) device is unavailable we display a warning and continue.
+						// Don't warn about the missing device if we did already (this becomes relevant if the failing
+						// device is selected as preferred device and also as GM or MT-32 device).
+						if (failedDevStr != getDeviceString(hdl, MidiDriver::kDriverName)) {							
+							Common::String errorMessage = "Failed to detect the preferred device '" + getDeviceString(hdl, MidiDriver::kDriverName) + "'. See log file for more information. Attempting to fall back to the next available device...";
+							GUIErrorMessage(errorMessage);
+						}
+						hdl = MT_AUTO;
+					}
 				}
 
 				// If no specific device is selected (neither in the scummvm nor in the game domain)
-				// and there is no preferred MT32 or GM device selected either we arrive here.
+				// and there is no preferred MT32 or GM device selected either or if the detected device is unavailable we arrive here.
 				// If MT32 is preferred we try for the first available device with music type 'MT_MT32' (usually the mt32 emulator).
 				if (flags & MDT_PREFER_MT32) {
 					for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) {
 						MusicDevices i = (**m)->getDevices();
 						for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
-							if (d->getMusicType() == MT_MT32)
-								return d->getHandle();
+							if (d->getMusicType() == MT_MT32) {
+								hdl = d->getHandle();
+								if (checkDevice(hdl))
+									return hdl;
+								else
+									// No warning here, since the user hasn't expressly requested anything.
+									hdl = MT_AUTO;
+							}
 						}
 					}
 				}
 
-				// Now we default to the first available device with music type 'MT_GM'
-				for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) {
-					MusicDevices i = (**m)->getDevices();
-					for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
-						if (d->getMusicType() == MT_GM || d->getMusicType() == MT_GS)
-							return d->getHandle();
+				// Now we default to the first available device with music type 'MT_GM' if not 
+				// MT-32 is preferred or if MT-32 is preferred but all other devices have failed.
+				if (!(flags & MDT_PREFER_MT32) || flags == (MDT_PREFER_MT32 | MDT_MIDI)) {
+					for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) {
+						MusicDevices i = (**m)->getDevices();
+						for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
+							if (d->getMusicType() == MT_GM || d->getMusicType() == MT_GS) {
+								hdl = d->getHandle();
+								if (checkDevice(hdl))
+									return hdl;
+								else
+									// No warning here, since the user hasn't expressly requested anything.
+									hdl = MT_AUTO;
+							}
+						}
 					}
+					// Detection flags get removed after final detection attempt to avoid further attempts.
+					flags &= ~(MDT_MIDI | MDT_PREFER_GM | MDT_PREFER_MT32);
 				}
 			}
 		}
 
-		MusicType tp = MT_AUTO;
-		if (flags & MDT_TOWNS)
+		// The order in this list is important, since this is the order of preference
+		// (e.g. MT_ADLIB is checked before MT_PCJR and MT_PCSPK for a good reason.
+		// Detection flags get removed after detection attempt to avoid further attempts.
+		if (flags & MDT_TOWNS) {
 			tp = MT_TOWNS;
-		else if (flags & MDT_PC98)
+			flags &= ~MDT_TOWNS;
+		} else if (flags & MDT_PC98) {
 			tp = MT_PC98;
-		else if (flags & MDT_ADLIB)
+			flags &= ~MDT_PC98;
+		} else if (flags & MDT_ADLIB) {
 			tp = MT_ADLIB;
-		else if (flags & MDT_PCJR)
+			flags &= ~MDT_ADLIB;
+		} else if (flags & MDT_PCJR) {
 			tp = MT_PCJR;
-		else if (flags & MDT_PCSPK)
+			flags &= ~MDT_PCJR;
+		} else if (flags & MDT_PCSPK) {
 			tp = MT_PCSPK;
-		else if (flags & MDT_C64)
+			flags &= ~MDT_PCSPK;
+		} else if (flags & MDT_C64) {
 			tp = MT_C64;
-		else if (flags & MDT_AMIGA)
+			flags &= ~MDT_C64;
+		} else if (flags & MDT_AMIGA) {
 			tp = MT_AMIGA;
-		else if (flags & MDT_APPLEIIGS)
+			flags &= ~MDT_AMIGA;
+		} else if (flags & MDT_APPLEIIGS) {
 			tp = MT_APPLEIIGS;
-		else if (l == 0)
+			flags &= ~MDT_APPLEIIGS;
+		} else if (flags & MDT_MIDI) {
 			// If we haven't tried to find a MIDI device yet we do this now.
+			skipMidi = false;
 			continue;
-		else
+		} else if (flags) {
+			// Invalid flags. Set them to MDT_NONE to leave detection loop.
+			flags = MDT_NONE;
 			tp = MT_AUTO;
+		}
 
 		for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) {
 			MusicDevices i = (**m)->getDevices();
 			for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
-				if (d->getMusicType() == tp)
-					return d->getHandle();
+				if (d->getMusicType() == tp) {
+					hdl = d->getHandle();
+					if (checkDevice(hdl))
+						return hdl;
+					else
+						// No warning here, since the user hasn't expressly requested anything.
+						hdl = MT_AUTO;
+				}
 			}
 		}
 	}
 
-	return 0;
+	return reslt;
 }
 
 MidiDriver *MidiDriver::createMidi(MidiDriver::DeviceHandle handle) {
@@ -288,6 +353,16 @@ MidiDriver *MidiDriver::createMidi(MidiDriver::DeviceHandle handle) {
 	return driver;
 }
 
+bool MidiDriver::checkDevice(MidiDriver::DeviceHandle handle) {
+	const MusicPlugin::List p = MusicMan.getPlugins();
+	for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) {
+		if (getDeviceString(handle, MidiDriver::kDriverId).equals((**m)->getId()))
+			return (**m)->checkDevice(handle);
+	}
+
+	return false;
+}
+
 MidiDriver::DeviceHandle MidiDriver::getDeviceHandle(const Common::String &identifier) {
 	const MusicPlugin::List p = MusicMan.getPlugins();
 
diff --git a/audio/mididrv.h b/audio/mididrv.h
index 7369cab..9db23b8 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -156,6 +156,9 @@ public:
 	/** Find the music driver matching the given driver name/description. */
 	static DeviceHandle getDeviceHandle(const Common::String &identifier);
 
+	/** Check whether the device with the given handle is available. */
+	static bool checkDevice(DeviceHandle handle);
+
 	/** Get the music type matching the given device handle, or MT_AUTO if there is no match. */
 	static MusicType getMusicType(DeviceHandle handle);
 
diff --git a/audio/musicplugin.h b/audio/musicplugin.h
index 2a25962..307293a 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -90,6 +90,13 @@ public:
 	virtual MusicDevices getDevices() const = 0;
 
 	/**
+	 * Checks whether a device can actually be used. Currently this is only
+	 * implemented for the MT-32 emulator to check whether the required rom
+	 * files are present.
+	 */
+	virtual bool checkDevice(MidiDriver::DeviceHandle) const { return true; }
+
+	/**
 	 * Tries to instantiate a MIDI Driver instance based on the device
 	 * previously detected via MidiDriver::detectDevice()
 	 *
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index 27a5a62..2ffce30 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/scummsys.h"
+#include "common/system.h"
 
 #ifdef USE_MT32EMU
 
@@ -547,6 +548,7 @@ public:
 	}
 
 	MusicDevices getDevices() const;
+	bool checkDevice(MidiDriver::DeviceHandle) const;
 	Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
 };
 
@@ -556,6 +558,16 @@ MusicDevices MT32EmuMusicPlugin::getDevices() const {
 	return devices;
 }
 
+bool MT32EmuMusicPlugin::checkDevice(MidiDriver::DeviceHandle) const {
+	if (!((Common::File::exists("MT32_CONTROL.ROM") && Common::File::exists("MT32_PCM.ROM")) ||
+		(Common::File::exists("CM32L_CONTROL.ROM") && Common::File::exists("CM32L_PCM.ROM")))) {
+			warning("The MT-32 emulator requires the following  2 files (not bundled with ScummVM:\n either 'MT32_CONTROL.ROM' and 'MT32_PCM.ROM' or 'CM32L_CONTROL.ROM' and 'CM32L_PCM.ROM'");
+			return false;
+	}
+	
+	return true;	
+}
+
 Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
 	if (ConfMan.hasKey("extrapath"))
 		SearchMan.addDirectory("extrapath", ConfMan.get("extrapath"));


Commit: 920c3bb17236e013b0e135886fa37521ceffd086
    https://github.com/scummvm/scummvm/commit/920c3bb17236e013b0e135886fa37521ceffd086
Author: athrxx (athrxx at scummvm.org)
Date: 2011-06-05T09:29:16-07:00

Commit Message:
KYRA: fix audio detection

Don't attempt to detect PC devices for non-PC versions of the game, because this might trigger unnecessary detection failure messages.

Changed paths:
    engines/kyra/kyra_v1.cpp



diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index f108082..f79fabf 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -93,15 +93,6 @@ Common::Error KyraEngine_v1::init() {
 	syncSoundSettings();
 
 	if (!_flags.useDigSound) {
-		// In Kyra 1 users who have specified a default MT-32 device in the launcher settings
-		// will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
-		// default GM device in the launcher will get GM music, otherwise AdLib. Users who want
-		// MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
-		// most users rather have a GM device than a MT-32 device).
-		// Users who want PC speaker sound always have to select this individually for all
-		// Kyra games.
-		MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
-
 		if (_flags.platform == Common::kPlatformFMTowns) {
 			if (_flags.gameID == GI_KYRA1)
 				_sound = new SoundTowns(this, _mixer);
@@ -114,43 +105,53 @@ Common::Error KyraEngine_v1::init() {
 				_sound = new SoundTownsPC98_v2(this, _mixer);
 		} else if (_flags.platform == Common::kPlatformAmiga) {
 			_sound = new SoundAmiga(this, _mixer);
-		} else if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
-			_sound = new SoundAdLibPC(this, _mixer);
 		} else {
-			Sound::kType type;
-			const MusicType midiType = MidiDriver::getMusicType(dev);
+			// In Kyra 1 users who have specified a default MT-32 device in the launcher settings
+			// will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
+			// default GM device in the launcher will get GM music, otherwise AdLib. Users who want
+			// MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
+			// most users rather have a GM device than a MT-32 device).
+			// Users who want PC speaker sound always have to select this individually for all
+			// Kyra games.
+			MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
+			if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
+				_sound = new SoundAdLibPC(this, _mixer);
+			} else {
+				Sound::kType type;
+				const MusicType midiType = MidiDriver::getMusicType(dev);
 
-			if (midiType == MT_PCSPK || midiType == MT_NULL)
-				type = Sound::kPCSpkr;
-			else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
-				type = Sound::kMidiMT32;
-			else
-				type = Sound::kMidiGM;
+				if (midiType == MT_PCSPK || midiType == MT_NULL)
+					type = Sound::kPCSpkr;
+				else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
+					type = Sound::kMidiMT32;
+				else
+					type = Sound::kMidiGM;
 
-			MidiDriver *driver = 0;
+				MidiDriver *driver = 0;
 
-			if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
-				driver = new MidiDriver_PCSpeaker(_mixer);
-			} else {
-				driver = MidiDriver::createMidi(dev);
-				if (type == Sound::kMidiMT32)
-					driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
-			}
+				if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
+					driver = new MidiDriver_PCSpeaker(_mixer);
+				} else {
+					driver = MidiDriver::createMidi(dev);
+					if (type == Sound::kMidiMT32)
+						driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+				}
 
-			assert(driver);
+				assert(driver);
 
-			SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
-			_sound = soundMidiPc;
-			assert(_sound);
+				SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
+				_sound = soundMidiPc;
+				assert(_sound);
 
-			// Unlike some SCUMM games, it's not that the MIDI sounds are
-			// missing. It's just that at least at the time of writing they
-			// are decidedly inferior to the AdLib ones.
-			if (ConfMan.getBool("multi_midi")) {
-				SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
-				assert(adlib);
+				// Unlike some SCUMM games, it's not that the MIDI sounds are
+				// missing. It's just that at least at the time of writing they
+				// are decidedly inferior to the AdLib ones.
+				if (ConfMan.getBool("multi_midi")) {
+					SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
+					assert(adlib);
 
-				_sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+					_sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+				}
 			}
 		}
 






More information about the Scummvm-git-logs mailing list