00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "pent_include.h"
00025 #include "UnixSeqMidiDriver.h"
00026
00027 #ifdef USE_UNIX_SEQ_MIDI
00028
00029 #include <fcntl.h>
00030 #include <unistd.h>
00031 #include <cerrno>
00032
00033 const MidiDriver::MidiDriverDesc UnixSeqMidiDriver::desc =
00034 MidiDriver::MidiDriverDesc ("UnixSeqDevice", createInstance);
00035
00036 #define SEQ_MIDIPUTC 5
00037 #define SEQ_DEVICE "/dev/sequencer"
00038
00039 UnixSeqMidiDriver::UnixSeqMidiDriver()
00040 : isOpen(false), device(0), deviceNum(0)
00041 {
00042
00043 devname = getConfigSetting("unixseqdevice", SEQ_DEVICE);
00044 }
00045
00046 int UnixSeqMidiDriver::open()
00047 {
00048 if (isOpen) return 1;
00049 isOpen = true;
00050 device = 0;
00051
00052 pout << "UnixSeqDevice: opening device: " << devname << std::endl;
00053
00054 device = ::open(devname.c_str(), O_RDWR, 0);
00055 if (device < 0) {
00056 perr << "UnixSeqDevice: failed: " << strerror(errno);
00057 perr << std::endl;
00058 return device;
00059 }
00060
00061 return 0;
00062 }
00063
00064 void UnixSeqMidiDriver::close()
00065 {
00066 ::close(device);
00067 isOpen = false;
00068 }
00069
00070 void UnixSeqMidiDriver::send(uint32 b) {
00071 unsigned char buf[256];
00072 int position = 0;
00073
00074 switch (b & 0xF0) {
00075 case 0x80:
00076 case 0x90:
00077 case 0xA0:
00078 case 0xB0:
00079 case 0xE0:
00080 buf[position++] = SEQ_MIDIPUTC;
00081 buf[position++] = (unsigned char)b;
00082 buf[position++] = deviceNum;
00083 buf[position++] = 0;
00084 buf[position++] = SEQ_MIDIPUTC;
00085 buf[position++] = (unsigned char)((b >> 8) & 0x7F);
00086 buf[position++] = deviceNum;
00087 buf[position++] = 0;
00088 buf[position++] = SEQ_MIDIPUTC;
00089 buf[position++] = (unsigned char)((b >> 16) & 0x7F);
00090 buf[position++] = deviceNum;
00091 buf[position++] = 0;
00092 break;
00093 case 0xC0:
00094 case 0xD0:
00095 buf[position++] = SEQ_MIDIPUTC;
00096 buf[position++] = (unsigned char)b;
00097 buf[position++] = deviceNum;
00098 buf[position++] = 0;
00099 buf[position++] = SEQ_MIDIPUTC;
00100 buf[position++] = (unsigned char)((b >> 8) & 0x7F);
00101 buf[position++] = deviceNum;
00102 buf[position++] = 0;
00103 break;
00104 default:
00105 perr << "UnixSeqMidiDriver: Unknown Command: "
00106 << std::hex << (int)b << std::dec << std::endl;
00107 break;
00108 }
00109
00110 ::write(device, buf, position);
00111 }
00112
00113 void UnixSeqMidiDriver::send_sysex(uint8 status,const uint8 *msg,uint16 length)
00114 {
00115 if (length > 511) {
00116 perr << "UnixSeqMidiDriver: "
00117 << "Cannot send SysEx block - data too large" << std::endl;
00118 return;
00119 }
00120
00121 unsigned char buf [2048];
00122 int position = 0;
00123 const uint8 *chr = msg;
00124
00125 buf[position++] = SEQ_MIDIPUTC;
00126 buf[position++] = status;
00127 buf[position++] = deviceNum;
00128 buf[position++] = 0;
00129
00130 for (; length; --length) {
00131 buf[position++] = SEQ_MIDIPUTC;
00132 buf[position++] = *chr++;
00133 buf[position++] = deviceNum;
00134 buf[position++] = 0;
00135 }
00136
00137 ::write (device, buf, position);
00138 }
00139
00140 #endif