diff options
Diffstat (limited to 'backends/midi')
-rw-r--r-- | backends/midi/alsa.cpp | 42 | ||||
-rw-r--r-- | backends/midi/seq.cpp | 2 | ||||
-rw-r--r-- | backends/midi/stmidi.cpp | 155 |
3 files changed, 185 insertions, 14 deletions
diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index 2a252b9323..5a978a0fd2 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -79,20 +79,18 @@ MidiDriver_ALSA::MidiDriver_ALSA() } int MidiDriver_ALSA::open() { - const char *var; + const char *var = NULL; if (_isOpen) return MERR_ALREADY_OPEN; _isOpen = true; - if (!(var = getenv("SCUMMVM_PORT"))) { - // use config option if no var specified + var = getenv("SCUMMVM_PORT"); + if (!var && ConfMan.hasKey("alsa_port")) { var = ConfMan.get("alsa_port").c_str(); - if (parse_addr(var, &seq_client, &seq_port) < 0) { - error("Invalid port %s", var); - return -1; - } - } else { + } + + if (var) { if (parse_addr(var, &seq_client, &seq_port) < 0) { error("Invalid port %s", var); return -1; @@ -120,14 +118,32 @@ int MidiDriver_ALSA::open() { return -1; } - if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { - /* subscribe to MIDI port */ - if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { - error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + if (var) { + if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { + // subscribe to MIDI port + if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { + error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + } } - else printf("Connected to Alsa sequencer client [%d:%d]\n", seq_client, seq_port); + } else { + int defaultPorts[] = { + 65, 0, + 17, 0 + }; + int i; + + for (i = 0; i < ARRAYSIZE(defaultPorts); i += 2) { + seq_client = defaultPorts[i]; + seq_port = defaultPorts[i + 1]; + if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) >= 0) + break; + } + + if (i >= ARRAYSIZE(defaultPorts)) + error("Can't subscribe to MIDI port (65:0) or (17:0)"); } + printf("Connected to Alsa sequencer client [%d:%d]\n", seq_client, seq_port); printf("ALSA client initialised [%d:0]\n", my_client); return 0; diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index 57a5a1ea32..9e86181674 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -28,7 +28,7 @@ * both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html) */ -#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) +#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) #include "common/util.h" #include "sound/musicplugin.h" diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp new file mode 100644 index 0000000000..addb23c6bd --- /dev/null +++ b/backends/midi/stmidi.cpp @@ -0,0 +1,155 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Raw MIDI output for the Atari ST line of computers. + * Based on the ScummVM SEQ & CoreMIDI drivers. + * Atari code by Keith Scroggins + * We, unfortunately, could not use the SEQ driver because the /dev/midi under + * FreeMiNT (and hence in libc) is considered to be a serial port for machine + * access. So, we just use OS calls then to send the data to the MIDI ports + * directly. The current implementation is sending 1 byte at a time because + * in most cases we are only sending up to 3 bytes, I believe this saves a few + * cycles. I might change so sysex messages are sent the other way later. + */ + +#if defined __MINT__ + +#include <osbind.h> +#include "sound/mpu401.h" +#include "common/util.h" +#include "sound/musicplugin.h" + +class MidiDriver_STMIDI : public MidiDriver_MPU401 { +public: + MidiDriver_STMIDI() : _isOpen (false) { } + int open(); + void close(); + void send(uint32 b); + void sysEx(const byte *msg, uint16 length); + +private: + bool _isOpen; +}; + +int MidiDriver_STMIDI::open() { + if ((_isOpen) && (!Bcostat(4))) + return MERR_ALREADY_OPEN; + warning("ST Midi Port Open"); + _isOpen = true; + return 0; +} + +void MidiDriver_STMIDI::close() { + MidiDriver_MPU401::close(); + _isOpen = false; +} + +void MidiDriver_STMIDI::send(uint32 b) { + + byte status_byte = (b & 0x000000FF); + byte first_byte = (b & 0x0000FF00) >> 8; + byte second_byte = (b & 0x00FF0000) >> 16; + +// warning("ST MIDI Packet sent"); + + switch (b & 0xF0) { + case 0x80: // Note Off + case 0x90: // Note On + case 0xA0: // Polyphonic Key Pressure + case 0xB0: // Controller + case 0xE0: // Pitch Bend + Bconout(3, status_byte); + Bconout(3, first_byte); + Bconout(3, second_byte); + break; + case 0xC0: // Program Change + case 0xD0: // Aftertouch + Bconout(3, status_byte); + Bconout(3, first_byte); + break; + default: + fprintf(stderr, "Unknown : %08x\n", (int)b); + break; + } +} + +void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) { + if (length > 254) { + warning ("Cannot send SysEx block - data too large"); + return; + } + + const byte *chr = msg; + warning("Sending SysEx Message"); + + Bconout(3, '0xF0'); + for (; length; --length, ++chr) { + Bconout(3,((unsigned char) *chr & 0x7F)); + } + Bconout(3, '0xF7'); +} + +// Plugin interface + +class StMidiMusicPlugin : public MusicPluginObject { +public: + const char *getName() const { + return "STMIDI"; + } + + const char *getId() const { + return "stmidi"; + } + + MusicDevices getDevices() const; + PluginError createInstance(Audio::Mixer *mixer, MidiDriver **mididriver) + const; +}; + +MusicDevices StMidiMusicPlugin::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)); + return devices; +} + +PluginError StMidiMusicPlugin::createInstance(Audio::Mixer *mixer, MidiDriver **mididriver) const { + *mididriver = new MidiDriver_STMIDI(); + + return kNoError; +} + +MidiDriver *MidiDriver_STMIDI_create(Audio::Mixer *mixer) { + MidiDriver *mididriver; + + StMidiMusicPlugin p; + p.createInstance(mixer, &mididriver); + + return mididriver; +} + +//#if PLUGIN_ENABLED_DYNAMIC(STMIDI) + //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); +//#else + REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); +//#endif + +#endif |