[Scummvm-git-logs] scummvm master -> ca88c5206401943fc542707ff35fcb571f6c0669
bluegr
noreply at scummvm.org
Mon Nov 4 21:01:02 UTC 2024
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6a03f4ada3 AUDIO: Add checkDevice support for FluidSynth
4436ed5d08 BACKENDS: Add device enumeration and synth device support to OSS MIDI driver
becf6c529a BACKENDS: Fix excessive calls to getDeviceString on Windows MIDI
ca88c52064 AUDIO: Split MIDI check flags out, fail checkDevice by default for "auto"
Commit: 6a03f4ada32d02b65526fea86f5afa3527ccecfa
https://github.com/scummvm/scummvm/commit/6a03f4ada32d02b65526fea86f5afa3527ccecfa
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-11-04T23:00:57+02:00
Commit Message:
AUDIO: Add checkDevice support for FluidSynth
Changed paths:
audio/mididrv.cpp
audio/mididrv.h
audio/musicplugin.h
audio/softsynth/fluidsynth.cpp
audio/softsynth/mt32.cpp
engines/dragons/midimusicplayer.cpp
diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index 50b95777106..5d2ad58ba22 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -216,6 +216,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
break;
}
+ int checkFlags = (flags & (MDT_SUPPLIED_SOUND_FONT));
+ flags ^= checkFlags;
+
Common::String failedDevStr;
if (getMusicType(hdl) == MT_INVALID) {
// If the expressly selected driver or device cannot be found (no longer compiled in, turned off, etc.)
@@ -230,7 +233,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
MusicType tp = getMusicType(reslt);
if (tp != MT_INVALID && tp != MT_AUTO) {
- if (checkDevice(reslt)) {
+ if (checkDevice(reslt, checkFlags, false)) {
return reslt;
} else {
// If the expressly selected device cannot be used we display a warning and continue.
@@ -249,6 +252,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
// 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).
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.
@@ -279,7 +283,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
dialog.runModal();
}
} else if (type != MT_AUTO) {
- if (checkDevice(hdl)) {
+ if (checkDevice(hdl, checkFlags, false)) {
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;
@@ -307,7 +311,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
if (d->getMusicType() == MT_MT32) {
hdl = d->getHandle();
- if (checkDevice(hdl))
+ if (checkDevice(hdl, checkFlags, true))
return hdl;
}
}
@@ -322,7 +326,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
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))
+ if (checkDevice(hdl, checkFlags, true))
return hdl;
}
}
@@ -381,7 +385,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
if (d->getMusicType() == tp) {
hdl = d->getHandle();
- if (checkDevice(hdl))
+ if (checkDevice(hdl, checkFlags, true))
return hdl;
}
}
@@ -403,12 +407,12 @@ MidiDriver *MidiDriver::createMidi(MidiDriver::DeviceHandle handle) {
return driver;
}
-bool MidiDriver::checkDevice(MidiDriver::DeviceHandle handle) {
+bool MidiDriver::checkDevice(MidiDriver::DeviceHandle handle, int flags, bool quiet) {
const PluginList p = MusicMan.getPlugins();
for (PluginList::const_iterator m = p.begin(); m != p.end(); m++) {
const MusicPluginObject &musicPlugin = (*m)->get<MusicPluginObject>();
if (getDeviceString(handle, MidiDriver::kDriverId).equals(musicPlugin.getId()))
- return musicPlugin.checkDevice(handle);
+ return musicPlugin.checkDevice(handle, flags, quiet);
}
return false;
diff --git a/audio/mididrv.h b/audio/mididrv.h
index 4f5f12a9f27..290031c9c29 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -79,22 +79,24 @@ enum MusicType {
* @todo Rename MidiDriverFlags to MusicDriverFlags
*/
enum MidiDriverFlags {
- MDT_NONE = 0,
- MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MT_PCSPK and MT_PCJR
- MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MT_CMS
- MDT_PCJR = 1 << 2, // Tandy/PC Junior driver
- MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB
- MDT_C64 = 1 << 4,
- MDT_AMIGA = 1 << 5,
- MDT_APPLEIIGS = 1 << 6,
- MDT_TOWNS = 1 << 7, // FM-TOWNS: Maps to MT_TOWNS
- MDT_PC98 = 1 << 8, // PC-98: Maps to MT_PC98
- MDT_SEGACD = 1 << 9,
- MDT_MIDI = 1 << 10, // Real MIDI
- MDT_PREFER_MT32 = 1 << 11, // MT-32 output is preferred
- MDT_PREFER_GM = 1 << 12, // GM output is preferred
- MDT_PREFER_FLUID= 1 << 13, // FluidSynth driver is preferred
- MDT_MACINTOSH = 1 << 14
+ MDT_NONE = 0,
+ MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MT_PCSPK and MT_PCJR
+ MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MT_CMS
+ MDT_PCJR = 1 << 2, // Tandy/PC Junior driver
+ MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB
+ MDT_C64 = 1 << 4,
+ MDT_AMIGA = 1 << 5,
+ MDT_APPLEIIGS = 1 << 6,
+ MDT_TOWNS = 1 << 7, // FM-TOWNS: Maps to MT_TOWNS
+ MDT_PC98 = 1 << 8, // PC-98: Maps to MT_PC98
+ MDT_SEGACD = 1 << 9,
+ MDT_MIDI = 1 << 10, // Real MIDI
+ MDT_PREFER_MT32 = 1 << 11, // MT-32 output is preferred
+ MDT_PREFER_GM = 1 << 12, // GM output is preferred
+ MDT_PREFER_FLUID = 1 << 13, // FluidSynth driver is preferred
+ MDT_MACINTOSH = 1 << 14,
+
+ MDT_SUPPLIED_SOUND_FONT = 1 << 15, // Engine will supply sound font (allows checkDevice to pass if it would fail due to missing sound font)
};
/**
@@ -326,8 +328,16 @@ 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);
+ /** Check whether the device with the given handle is available.
+ *
+ * @param handle A device handle to check.
+ * @param flags A mask of flags from MidiDriverFlags to check with.
+ * @param quiet If true, then failure produces no warnings.
+ * If false, then failure throws a warning.
+ *
+ * @return True if the device is expected to be available, false if not.
+ */
+ static bool checkDevice(DeviceHandle handle, int flags, bool quiet);
/** 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 8e2ac29d24e..80e2f9fe159 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -102,7 +102,7 @@ public:
* implemented for the MT-32 emulator to check whether the required rom
* files are present.
*/
- virtual bool checkDevice(MidiDriver::DeviceHandle) const { return true; }
+ virtual bool checkDevice(MidiDriver::DeviceHandle hdl, int flags, bool quiet) const { return true; }
/**
* Tries to instantiate a MIDI Driver instance based on the device
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index 276ec7acb05..a1d93e0eac6 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -110,11 +110,11 @@ protected:
void generateSamples(int16 *buf, int len) override;
- Common::Path getSoundFontPath() const;
-
public:
MidiDriver_FluidSynth(Audio::Mixer *mixer);
+ static Common::Path getSoundFontPath();
+
int open() override;
void close() override;
void send(uint32 b) override;
@@ -280,7 +280,7 @@ static long SoundFontMemLoader_tell(void *handle) {
#endif // USE_FLUIDLITE
-Common::Path MidiDriver_FluidSynth::getSoundFontPath() const {
+Common::Path MidiDriver_FluidSynth::getSoundFontPath() {
Common::Path path = ConfMan.getPath("soundfont");
if (path.empty())
return path;
@@ -592,6 +592,7 @@ public:
}
MusicDevices getDevices() const override;
+ bool checkDevice(MidiDriver::DeviceHandle, int flags, bool quiet) const override;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const override;
};
@@ -601,6 +602,19 @@ MusicDevices FluidSynthMusicPlugin::getDevices() const {
return devices;
}
+bool FluidSynthMusicPlugin::checkDevice(MidiDriver::DeviceHandle, int flags, bool quiet) const {
+#ifdef FS_HAS_STREAM_SUPPORT
+ if (flags & MDT_SUPPLIED_SOUND_FONT)
+ return true;
+#endif
+
+ Common::Path sfPath = MidiDriver_FluidSynth::getSoundFontPath();
+ if (sfPath.empty())
+ return false;
+
+ return Common::FSNode(sfPath).exists();
+}
+
Common::Error FluidSynthMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_FluidSynth(g_system->getMixer());
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index 093d9be5188..f6c4ef81e1b 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -446,7 +446,7 @@ public:
}
MusicDevices getDevices() const override;
- bool checkDevice(MidiDriver::DeviceHandle) const override;
+ bool checkDevice(MidiDriver::DeviceHandle, int flags, bool quiet) const override;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const override;
};
@@ -456,10 +456,11 @@ MusicDevices MT32EmuMusicPlugin::getDevices() const {
return devices;
}
-bool MT32EmuMusicPlugin::checkDevice(MidiDriver::DeviceHandle) const {
+bool MT32EmuMusicPlugin::checkDevice(MidiDriver::DeviceHandle, int flags, bool quiet) 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 one of the two following file sets (not bundled with ScummVM):\n Either 'MT32_CONTROL.ROM' and 'MT32_PCM.ROM' or 'CM32L_CONTROL.ROM' and 'CM32L_PCM.ROM'");
+ if (!quiet)
+ warning("The MT-32 emulator requires one of the two following file sets (not bundled with ScummVM):\n Either 'MT32_CONTROL.ROM' and 'MT32_PCM.ROM' or 'CM32L_CONTROL.ROM' and 'CM32L_PCM.ROM'");
return false;
}
diff --git a/engines/dragons/midimusicplayer.cpp b/engines/dragons/midimusicplayer.cpp
index 6f4d4990845..2edeaf9e1ed 100644
--- a/engines/dragons/midimusicplayer.cpp
+++ b/engines/dragons/midimusicplayer.cpp
@@ -32,7 +32,7 @@ namespace Dragons {
MidiMusicPlayer::MidiMusicPlayer(BigfileArchive *bigFileArchive): _midiDataSize(0) {
_midiData = nullptr;
- MidiPlayer::createDriver(MDT_PREFER_FLUID | MDT_MIDI);
+ MidiPlayer::createDriver(MDT_PREFER_FLUID | MDT_SUPPLIED_SOUND_FONT | MDT_MIDI);
if (_driver->acceptsSoundFontData()) {
_driver->setEngineSoundFont(loadSoundFont(bigFileArchive));
Commit: 4436ed5d08b48023e22cd9a1a3864412517e3daa
https://github.com/scummvm/scummvm/commit/4436ed5d08b48023e22cd9a1a3864412517e3daa
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-11-04T23:00:57+02:00
Commit Message:
BACKENDS: Add device enumeration and synth device support to OSS MIDI driver
Changed paths:
backends/midi/seq.cpp
diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp
index 7a6fc96b652..9181d8bbdc7 100644
--- a/backends/midi/seq.cpp
+++ b/backends/midi/seq.cpp
@@ -41,6 +41,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
////////////////////////////////////////
//
@@ -52,58 +54,53 @@
class MidiDriver_SEQ : public MidiDriver_MPU401 {
public:
- MidiDriver_SEQ();
+ MidiDriver_SEQ(int port, bool isSynth);
int open() override;
bool isOpen() const override { return _isOpen; }
void close() override;
void send(uint32 b) override;
void sysEx(const byte *msg, uint16 length) override;
+ static const char *getDeviceName();
+
private:
+ bool _isSynth;
bool _isOpen;
- int device, _device_num;
+ int _device;
+ int _port;
};
-MidiDriver_SEQ::MidiDriver_SEQ() {
+MidiDriver_SEQ::MidiDriver_SEQ(int port, bool isSynth) {
_isOpen = false;
- device = 0;
- _device_num = 0;
+ _isSynth = isSynth;
+ _device = -1;
+ _port = port;
}
int MidiDriver_SEQ::open() {
- char *device_name;
- char dev_seq[] = "/dev/sequencer";
-
if (_isOpen)
return MERR_ALREADY_OPEN;
- _isOpen = true;
- device = 0;
- device_name = getenv("SCUMMVM_MIDI");
-
- if (device_name == NULL) {
- warning("SCUMMVM_MIDI environment variable not set, using /dev/sequencer");
- device_name = dev_seq;
- }
+ const char *deviceName = getDeviceName();
- device = ::open((device_name), O_RDWR, 0);
+ _isOpen = true;
+ _device = ::open(deviceName, O_RDWR, 0);
- if (device < 0) {
- warning("Cannot open rawmidi device %s - using /dev/null (no music will be heard)",
- device_name);
- device = (::open(("/dev/null"), O_RDWR, 0));
- if (device < 0)
+ if (_device < 0) {
+ warning("Cannot open rawmidi device %s - using /dev/null (no music will be heard)", deviceName);
+ _device = (::open(("/dev/null"), O_RDWR, 0));
+ if (_device < 0)
error("Cannot open /dev/null to dump midi output");
}
- if (getenv("SCUMMVM_MIDIPORT"))
- _device_num = atoi(getenv("SCUMMVM_MIDIPORT"));
return 0;
}
void MidiDriver_SEQ::close() {
MidiDriver_MPU401::close();
- ::close(device);
+
+ if (_isOpen)
+ ::close(_device);
_isOpen = false;
}
@@ -113,41 +110,98 @@ void MidiDriver_SEQ::send(uint32 b) {
unsigned char buf[256];
int position = 0;
- switch (b & 0xF0) {
- case 0x80:
- case 0x90:
- case 0xA0:
- case 0xB0:
- case 0xE0:
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char)b;
- buf[position++] = _device_num;
- buf[position++] = 0;
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char)((b >> 8) & 0x7F);
- buf[position++] = _device_num;
- buf[position++] = 0;
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char)((b >> 16) & 0x7F);
- buf[position++] = _device_num;
- buf[position++] = 0;
- break;
- case 0xC0:
- case 0xD0:
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char)b;
- buf[position++] = _device_num;
- buf[position++] = 0;
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char)((b >> 8) & 0x7F);
- buf[position++] = _device_num;
- buf[position++] = 0;
- break;
- default:
- warning("MidiDriver_SEQ::send: unknown: %08x", (int)b);
- break;
+ if (_isSynth) {
+ switch (b & 0xf0) {
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ buf[position++] = EV_CHN_VOICE;
+ buf[position++] = _port;
+ buf[position++] = (unsigned char)(b & 0xf0);
+ buf[position++] = (unsigned char)(b & 0x0f);
+ buf[position++] = (unsigned char)((b >> 8) & 0xff);
+ buf[position++] = (unsigned char)((b >> 16) & 0xff);
+ buf[position++] = 0;
+ buf[position++] = 0;
+ break;
+ case 0xc0: // Program change
+ case 0xd0: // Channel pressure
+ buf[position++] = EV_CHN_COMMON;
+ buf[position++] = _port;
+ buf[position++] = (unsigned char)(b & 0xf0);
+ buf[position++] = (unsigned char)(b & 0x0f);
+ buf[position++] = (unsigned char)((b >> 8) & 0xff);
+ buf[position++] = 0;
+ buf[position++] = 0;
+ buf[position++] = 0;
+ break;
+ case 0xb0: // Control change
+ buf[position++] = EV_CHN_COMMON;
+ buf[position++] = _port;
+ buf[position++] = (unsigned char)(b & 0xf0);
+ buf[position++] = (unsigned char)(b & 0x0f);
+ buf[position++] = (unsigned char)((b >> 8) & 0xff);
+ buf[position++] = 0;
+
+ // TODO/FIXME?: Main volume control in the soundcard.h macros is value*16383/100, expression is value*128, and pan is (value+128)/2
+ // Not sure how those translate to the scales we're using here.
+ *reinterpret_cast<uint16 *>(buf + position) = static_cast<uint16>((b >> 16) & 0xffff);
+ position += 2;
+ break;
+ case 0xe0: // Pitch bend
+ buf[position++] = EV_CHN_COMMON;
+ buf[position++] = _port;
+ buf[position++] = (unsigned char)(b & 0xf0);
+ buf[position++] = (unsigned char)(b & 0x0f);
+ buf[position++] = 0;
+ buf[position++] = 0;
+
+ *reinterpret_cast<uint16 *>(buf + position) = static_cast<uint16>((b >> 8) & 0xffff);
+ position += 2;
+ break;
+ default:
+ warning("MidiDriver_SEQ::send: unknown: %08x", (int)b);
+ break;
+
+ }
+ } else {
+ switch (b & 0xF0) {
+ case 0x80:
+ case 0x90:
+ case 0xA0:
+ case 0xB0:
+ case 0xE0:
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)b;
+ buf[position++] = _port;
+ buf[position++] = 0;
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)((b >> 8) & 0x7F);
+ buf[position++] = _port;
+ buf[position++] = 0;
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)((b >> 16) & 0x7F);
+ buf[position++] = _port;
+ buf[position++] = 0;
+ break;
+ case 0xC0:
+ case 0xD0:
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)b;
+ buf[position++] = _port;
+ buf[position++] = 0;
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)((b >> 8) & 0x7F);
+ buf[position++] = _port;
+ buf[position++] = 0;
+ break;
+ default:
+ warning("MidiDriver_SEQ::send: unknown: %08x", (int)b);
+ break;
+ }
}
- if (write(device, buf, position) == -1)
+
+ if (write(_device, buf, position) == -1)
warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno));
}
@@ -160,26 +214,60 @@ void MidiDriver_SEQ::sysEx(const byte *msg, uint16 length) {
midiDriverCommonSysEx(msg, length);
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = 0xF0;
- buf[position++] = _device_num;
- buf[position++] = 0;
- for (; length; --length, ++chr) {
+ if (_isSynth) {
+ int chunksRequired = (length + 7) / 6;
+
+ assert(chunksRequired * 8 <= static_cast<int>(sizeof(buf)));
+
+ for (int i = 0; i < chunksRequired; i++) {
+ int chunkStart = i * 6;
+
+ buf[position++] = EV_SYSEX;
+ buf[position++] = _port;
+
+ for (int j = 0; j < 6; j++) {
+ int pos = chunkStart + j - 1;
+ if (pos < 0)
+ buf[position++] = 0xf0;
+ else if (pos < length)
+ buf[position++] = msg[pos];
+ else if (pos == length)
+ buf[position++] = 0x7f;
+ else
+ buf[position++] = 0xff;
+ }
+ }
+ } else {
buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = (unsigned char) *chr & 0x7F;
- buf[position++] = _device_num;
+ buf[position++] = 0xF0;
+ buf[position++] = _port;
+ buf[position++] = 0;
+ for (; length; --length, ++chr) {
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = (unsigned char)*chr & 0x7F;
+ buf[position++] = _port;
+ buf[position++] = 0;
+ }
+ buf[position++] = SEQ_MIDIPUTC;
+ buf[position++] = 0xF7;
+ buf[position++] = _port;
buf[position++] = 0;
}
- buf[position++] = SEQ_MIDIPUTC;
- buf[position++] = 0xF7;
- buf[position++] = _device_num;
- buf[position++] = 0;
- if (write(device, buf, position) == -1)
+ if (write(_device, buf, position) == -1)
warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno));
}
+const char *MidiDriver_SEQ::getDeviceName() {
+ const char *devName = getenv("SCUMMVM_MIDI");
+
+ if (devName)
+ return devName;
+ else
+ return "/dev/sequencer";
+}
+
// Plugin interface
class SeqMusicPlugin : public MusicPluginObject {
@@ -194,20 +282,103 @@ public:
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
+
+private:
+ void addMidiDevices(int deviceFD, MusicDevices &devices, Common::Array<int> *portIDs) const;
+ void addSynthDevices(int deviceFD, MusicDevices &devices, Common::Array<int> *portIDs) const;
};
MusicDevices SeqMusicPlugin::getDevices() const {
MusicDevices devices;
- // TODO: Return a different music type depending on the configuration
- // TODO: List the available devices
- devices.push_back(MusicDevice(this, "", MT_GM));
+
+ int deviceFD = ::open(MidiDriver_SEQ::getDeviceName(), O_RDWR, 0);
+ if (deviceFD >= 0) {
+ addMidiDevices(deviceFD, devices, nullptr);
+ addSynthDevices(deviceFD, devices, nullptr);
+ ::close(deviceFD);
+ }
+
return devices;
}
-Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
- *mididriver = new MidiDriver_SEQ();
+void SeqMusicPlugin::addMidiDevices(int deviceFD, MusicDevices &devices, Common::Array<int> *portIDs) const {
+ int midiDeviceCount = 0;
+ if (ioctl(deviceFD, SNDCTL_SEQ_NRMIDIS, &midiDeviceCount) == 0) {
+ for (int i = 0; i < midiDeviceCount; i++) {
+ midi_info midiInfo;
+ midiInfo.device = i;
+ if (ioctl(deviceFD, SNDCTL_MIDI_INFO, &midiInfo) == 0) {
+ devices.push_back(MusicDevice(this, midiInfo.name, MT_GM)); // dev_type is unimplemented so we just assume GM
+ if (portIDs)
+ portIDs->push_back(i);
+ }
+ }
+ }
+}
+
+void SeqMusicPlugin::addSynthDevices(int deviceFD, MusicDevices &devices, Common::Array<int> *portIDs) const {
+ int synthDeviceCount = 0;
+ if (ioctl(deviceFD, SNDCTL_SEQ_NRSYNTHS, &synthDeviceCount) == 0) {
+ for (int i = 0; i < synthDeviceCount; i++) {
+ synth_info synthInfo;
+ synthInfo.device = i;
+ if (ioctl(deviceFD, SNDCTL_SYNTH_ID, &synthInfo) == 0) {
+ MusicType musicType = MT_GM;
+
+ if (synthInfo.synth_type == SYNTH_TYPE_FM)
+ musicType = MT_ADLIB;
+
+ devices.push_back(MusicDevice(this, synthInfo.name, musicType)); // dev_type is unimplemented so we just assume GM
+ if (portIDs)
+ portIDs->push_back(i);
+ }
+ }
+ }
+}
+
+Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const {
+ int port = 0;
+ bool isSynth = false;
+ bool found = false;
+
+ if (dev) {
+ Common::String deviceIDString = MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId);
+
+ MusicDevices devices;
+ Common::Array<int> ports;
+ int firstSynthIndex = 0;
+
+ int deviceFD = ::open(MidiDriver_SEQ::getDeviceName(), O_RDONLY, 0);
+ if (deviceFD >= 0) {
+ addMidiDevices(deviceFD, devices, &ports);
+
+ firstSynthIndex = static_cast<int>(ports.size());
+
+ addSynthDevices(deviceFD, devices, &ports);
+
+ ::close(deviceFD);
+ } else {
+ warning("Device enumeration failed when creating device");
+ }
+
+ int devIndex = 0;
+ for (MusicDevices::iterator d = devices.begin(); d != devices.end(); d++) {
+ if (d->getCompleteId().equals(deviceIDString)) {
+ found = true;
+ isSynth = (devIndex >= firstSynthIndex);
+ port = ports[devIndex];
+ break;
+ }
+ devIndex++;
+ }
+ }
+
+ if (found) {
+ *mididriver = new MidiDriver_SEQ(port, isSynth);
+ return Common::kNoError;
+ }
- return Common::kNoError;
+ return Common::kAudioDeviceInitFailed;
}
//#if PLUGIN_ENABLED_DYNAMIC(SEQ)
Commit: becf6c529a83e85633254c0b472f227a48fde5c2
https://github.com/scummvm/scummvm/commit/becf6c529a83e85633254c0b472f227a48fde5c2
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-11-04T23:00:57+02:00
Commit Message:
BACKENDS: Fix excessive calls to getDeviceString on Windows MIDI
Changed paths:
backends/midi/windows.cpp
diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp
index 6c3a3f93e63..43e01c80b1e 100644
--- a/backends/midi/windows.cpp
+++ b/backends/midi/windows.cpp
@@ -236,9 +236,11 @@ Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver, MidiDr
bool found = false;
if (dev) {
+ Common::String deviceIDString = MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId);
+
MusicDevices i = getDevices();
for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) {
- if (d->getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) {
+ if (d->getCompleteId().equals(deviceIDString)) {
found = true;
break;
}
Commit: ca88c5206401943fc542707ff35fcb571f6c0669
https://github.com/scummvm/scummvm/commit/ca88c5206401943fc542707ff35fcb571f6c0669
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-11-04T23:00:57+02:00
Commit Message:
AUDIO: Split MIDI check flags out, fail checkDevice by default for "auto"
Changed paths:
audio/mididrv.cpp
audio/mididrv.h
audio/musicplugin.h
audio/softsynth/fluidsynth.cpp
backends/midi/seq.cpp
backends/midi/windows.cpp
diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index 5d2ad58ba22..e4efdc0220e 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -216,8 +216,12 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
break;
}
- int checkFlags = (flags & (MDT_SUPPLIED_SOUND_FONT));
- flags ^= checkFlags;
+ int checkFlags = MDCK_NONE;
+
+ if (flags & MDT_SUPPLIED_SOUND_FONT) {
+ checkFlags |= MDCK_SUPPLIED_SOUND_FONT;
+ flags ^= MDT_SUPPLIED_SOUND_FONT;
+ }
Common::String failedDevStr;
if (getMusicType(hdl) == MT_INVALID) {
@@ -311,7 +315,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
if (d->getMusicType() == MT_MT32) {
hdl = d->getHandle();
- if (checkDevice(hdl, checkFlags, true))
+ if (checkDevice(hdl, checkFlags | MDCK_AUTO, true))
return hdl;
}
}
@@ -326,7 +330,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
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, checkFlags, true))
+ if (checkDevice(hdl, checkFlags | MDCK_AUTO, true))
return hdl;
}
}
diff --git a/audio/mididrv.h b/audio/mididrv.h
index 290031c9c29..57b89da37e2 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -99,6 +99,13 @@ enum MidiDriverFlags {
MDT_SUPPLIED_SOUND_FONT = 1 << 15, // Engine will supply sound font (allows checkDevice to pass if it would fail due to missing sound font)
};
+enum MidiDriverCheckFlags {
+ MDCK_NONE = 0,
+
+ MDCK_SUPPLIED_SOUND_FONT = 1 << 0, // Sound font will be supplied by the engine
+ MDCK_AUTO = 1 << 1, // Driver is being checked for automatic selection (i.e. MIDI device is set to "auto")
+};
+
/**
* TODO: Document this, give it a better name.
*/
diff --git a/audio/musicplugin.h b/audio/musicplugin.h
index 80e2f9fe159..bfa3e805ff4 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -100,9 +100,15 @@ public:
/**
* 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.
+ * files are present. In the default implementation, the device is not
+ * available as an auto-selected device.
+ *
+ * @param hdl MIDI device handle
+ * @param checkFlags Bitwise OR mask of MidiDriverCheckFlags
+ * @param quiet If true, suppress and error messages on check failure.
+ *
*/
- virtual bool checkDevice(MidiDriver::DeviceHandle hdl, int flags, bool quiet) const { return true; }
+ virtual bool checkDevice(MidiDriver::DeviceHandle hdl, int checkFlags, bool quiet) const { return (checkFlags & MDCK_AUTO) == 0; }
/**
* Tries to instantiate a MIDI Driver instance based on the device
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index a1d93e0eac6..10496983d11 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -604,7 +604,7 @@ MusicDevices FluidSynthMusicPlugin::getDevices() const {
bool FluidSynthMusicPlugin::checkDevice(MidiDriver::DeviceHandle, int flags, bool quiet) const {
#ifdef FS_HAS_STREAM_SUPPORT
- if (flags & MDT_SUPPLIED_SOUND_FONT)
+ if (flags & MDCK_SUPPLIED_SOUND_FONT)
return true;
#endif
diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp
index 9181d8bbdc7..8f6d174fb17 100644
--- a/backends/midi/seq.cpp
+++ b/backends/midi/seq.cpp
@@ -282,6 +282,7 @@ public:
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
+ bool checkDevice(MidiDriver::DeviceHandle hdl, int checkFlags, bool quiet) const;
private:
void addMidiDevices(int deviceFD, MusicDevices &devices, Common::Array<int> *portIDs) const;
@@ -381,6 +382,10 @@ Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver
return Common::kAudioDeviceInitFailed;
}
+bool SeqMusicPlugin::checkDevice(MidiDriver::DeviceHandle hdl, int checkFlags, bool quiet) const {
+ return true;
+}
+
//#if PLUGIN_ENABLED_DYNAMIC(SEQ)
//REGISTER_PLUGIN_DYNAMIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin);
//#else
diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp
index 43e01c80b1e..efdee259c81 100644
--- a/backends/midi/windows.cpp
+++ b/backends/midi/windows.cpp
@@ -174,6 +174,7 @@ public:
MusicDevices getDevices() const override;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const override;
+ bool checkDevice(MidiDriver::DeviceHandle hdl, int checkFlags, bool quiet) const override;
};
MusicDevices WindowsMusicPlugin::getDevices() const {
@@ -252,6 +253,10 @@ Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver, MidiDr
return Common::kNoError;
}
+bool WindowsMusicPlugin::checkDevice(MidiDriver::DeviceHandle hdl, int checkFlags, bool quiet) const {
+ return true;
+}
+
//#if PLUGIN_ENABLED_DYNAMIC(WINDOWS)
//REGISTER_PLUGIN_DYNAMIC(WINDOWS, PLUGIN_TYPE_MUSIC, WindowsMusicPlugin);
//#else
More information about the Scummvm-git-logs
mailing list