ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

seq.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * Raw output support by Michael Pearce
00025  * Alsa support by Nicolas Noble <nicolas@nobis-crew.org> copied from
00026  *    both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html)
00027  */
00028 
00029 // Disable symbol overrides so that we can use system headers.
00030 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00031 
00032 #include "common/scummsys.h"
00033 
00034 #if defined(USE_SEQ_MIDI)
00035 
00036 #include "common/error.h"
00037 #include "common/textconsole.h"
00038 #include "common/util.h"
00039 #include "audio/musicplugin.h"
00040 #include "audio/mpu401.h"
00041 
00042 #include <fcntl.h>
00043 #include <unistd.h>
00044 #include <errno.h>
00045 
00047 //
00048 // Unix dev/sequencer driver
00049 //
00051 
00052 #define SEQ_MIDIPUTC 5
00053 
00054 class MidiDriver_SEQ : public MidiDriver_MPU401 {
00055 public:
00056     MidiDriver_SEQ();
00057     int open();
00058     bool isOpen() const { return _isOpen; }
00059     void close();
00060     void send(uint32 b);
00061     void sysEx(const byte *msg, uint16 length);
00062 
00063 private:
00064     bool _isOpen;
00065     int device, _device_num;
00066 };
00067 
00068 MidiDriver_SEQ::MidiDriver_SEQ() {
00069     _isOpen = false;
00070     device = 0;
00071     _device_num = 0;
00072 }
00073 
00074 int MidiDriver_SEQ::open() {
00075     char *device_name;
00076     char dev_seq[] = "/dev/sequencer";
00077 
00078     if (_isOpen)
00079         return MERR_ALREADY_OPEN;
00080     _isOpen = true;
00081     device = 0;
00082 
00083     device_name = getenv("RESIDUALVM_MIDI");
00084 
00085     if (device_name == NULL) {
00086         warning("RESIDUALVM_MIDI environment variable not set, using /dev/sequencer");
00087         device_name = dev_seq;
00088     }
00089 
00090     device = ::open((device_name), O_RDWR, 0);
00091 
00092     if (device < 0) {
00093         warning("Cannot open rawmidi device %s - using /dev/null (no music will be heard)",
00094                     device_name);
00095         device = (::open(("/dev/null"), O_RDWR, 0));
00096         if (device < 0)
00097             error("Cannot open /dev/null to dump midi output");
00098     }
00099 
00100     if (getenv("RESIDUALVM_MIDIPORT"))
00101         _device_num = atoi(getenv("RESIDUALVM_MIDIPORT"));
00102     return 0;
00103 }
00104 
00105 void MidiDriver_SEQ::close() {
00106     MidiDriver_MPU401::close();
00107     ::close(device);
00108     _isOpen = false;
00109 }
00110 
00111 void MidiDriver_SEQ::send(uint32 b) {
00112     unsigned char buf[256];
00113     int position = 0;
00114 
00115     switch (b & 0xF0) {
00116     case 0x80:
00117     case 0x90:
00118     case 0xA0:
00119     case 0xB0:
00120     case 0xE0:
00121         buf[position++] = SEQ_MIDIPUTC;
00122         buf[position++] = (unsigned char)b;
00123         buf[position++] = _device_num;
00124         buf[position++] = 0;
00125         buf[position++] = SEQ_MIDIPUTC;
00126         buf[position++] = (unsigned char)((b >> 8) & 0x7F);
00127         buf[position++] = _device_num;
00128         buf[position++] = 0;
00129         buf[position++] = SEQ_MIDIPUTC;
00130         buf[position++] = (unsigned char)((b >> 16) & 0x7F);
00131         buf[position++] = _device_num;
00132         buf[position++] = 0;
00133         break;
00134     case 0xC0:
00135     case 0xD0:
00136         buf[position++] = SEQ_MIDIPUTC;
00137         buf[position++] = (unsigned char)b;
00138         buf[position++] = _device_num;
00139         buf[position++] = 0;
00140         buf[position++] = SEQ_MIDIPUTC;
00141         buf[position++] = (unsigned char)((b >> 8) & 0x7F);
00142         buf[position++] = _device_num;
00143         buf[position++] = 0;
00144         break;
00145     default:
00146         warning("MidiDriver_SEQ::send: unknown: %08x", (int)b);
00147         break;
00148     }
00149     if (write(device, buf, position) == -1)
00150         warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno));
00151 }
00152 
00153 void MidiDriver_SEQ::sysEx(const byte *msg, uint16 length) {
00154     unsigned char buf [266*4];
00155     int position = 0;
00156     const byte *chr = msg;
00157 
00158     assert(length + 2 <= 266);
00159 
00160     buf[position++] = SEQ_MIDIPUTC;
00161     buf[position++] = 0xF0;
00162     buf[position++] = _device_num;
00163     buf[position++] = 0;
00164     for (; length; --length, ++chr) {
00165         buf[position++] = SEQ_MIDIPUTC;
00166         buf[position++] = (unsigned char) *chr & 0x7F;
00167         buf[position++] = _device_num;
00168         buf[position++] = 0;
00169     }
00170     buf[position++] = SEQ_MIDIPUTC;
00171     buf[position++] = 0xF7;
00172     buf[position++] = _device_num;
00173     buf[position++] = 0;
00174 
00175     if (write(device, buf, position) == -1)
00176         warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno));
00177 }
00178 
00179 
00180 // Plugin interface
00181 
00182 class SeqMusicPlugin : public MusicPluginObject {
00183 public:
00184     const char *getName() const {
00185         return "SEQ";
00186     }
00187 
00188     const char *getId() const {
00189         return "seq";
00190     }
00191 
00192     MusicDevices getDevices() const;
00193     Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
00194 };
00195 
00196 MusicDevices SeqMusicPlugin::getDevices() const {
00197     MusicDevices devices;
00198     // TODO: Return a different music type depending on the configuration
00199     // TODO: List the available devices
00200     devices.push_back(MusicDevice(this, "", MT_GM));
00201     return devices;
00202 }
00203 
00204 Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
00205     *mididriver = new MidiDriver_SEQ();
00206 
00207     return Common::kNoError;
00208 }
00209 
00210 //#if PLUGIN_ENABLED_DYNAMIC(SEQ)
00211     //REGISTER_PLUGIN_DYNAMIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin);
00212 //#else
00213     REGISTER_PLUGIN_STATIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin);
00214 //#endif
00215 
00216 #endif


Generated on Sat May 25 2019 05:00:53 for ResidualVM by doxygen 1.7.1
curved edge   curved edge