1
/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler,
2
* Winfried Ritsch, Karl MacMillan, and others.
3
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
4
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
6
/* MIDI I/O for Linux using OSS */
13
#include <sys/types.h>
20
static int oss_nmidiin;
21
static int oss_midiinfd[MAXMIDIINDEV];
22
static int oss_nmidiout;
23
static int oss_midioutfd[MAXMIDIOUTDEV];
25
static void oss_midiout(int fd, int n)
28
if ((write(fd, (char *) &b, 1)) != 1)
32
#define O_MIDIFLAG O_NDELAY
34
void sys_do_open_midi(int nmidiin, int *midiinvec,
35
int nmidiout, int *midioutvec)
38
for (i = 0; i < nmidiout; i++)
39
oss_midioutfd[i] = -1;
40
for (i = 0, oss_nmidiin = 0; i < nmidiin; i++)
42
int fd = -1, j, outdevindex = -1;
44
int devno = midiinvec[i];
46
for (j = 0; j < nmidiout; j++)
47
if (midioutvec[j] == midiinvec[i])
50
/* try to open the device for read/write. */
51
if (devno == 0 && fd < 0 && outdevindex >= 0)
53
sys_setalarm(1000000);
54
fd = open("/dev/midi", O_RDWR | O_MIDIFLAG);
57
"device 1: tried /dev/midi READ/WRITE; returned %d\n", fd);
58
if (outdevindex >= 0 && fd >= 0)
59
oss_midioutfd[outdevindex] = fd;
61
if (fd < 0 && outdevindex >= 0)
63
sys_setalarm(1000000);
64
sprintf(namebuf, "/dev/midi%2.2d", devno);
65
fd = open(namebuf, O_RDWR | O_MIDIFLAG);
68
"device %d: tried %s READ/WRITE; returned %d\n",
70
if (outdevindex >= 0 && fd >= 0)
71
oss_midioutfd[outdevindex] = fd;
73
if (fd < 0 && outdevindex >= 0)
75
sys_setalarm(1000000);
76
sprintf(namebuf, "/dev/midi%d", devno);
77
fd = open(namebuf, O_RDWR | O_MIDIFLAG);
79
fprintf(stderr, "device %d: tried %s READ/WRITE; returned %d\n",
81
if (outdevindex >= 0 && fd >= 0)
82
oss_midioutfd[outdevindex] = fd;
84
if (devno == 1 && fd < 0)
86
sys_setalarm(1000000);
87
fd = open("/dev/midi", O_RDONLY | O_MIDIFLAG);
90
"device 1: tried /dev/midi READONLY; returned %d\n", fd);
94
sys_setalarm(1000000);
95
sprintf(namebuf, "/dev/midi%2.2d", devno);
96
fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
98
fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
103
sys_setalarm(1000000);
104
sprintf(namebuf, "/dev/midi%d", devno);
105
fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
107
fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
111
oss_midiinfd[oss_nmidiin++] = fd;
112
else post("couldn't open MIDI input device %d", devno);
114
for (i = 0, oss_nmidiout = 0; i < nmidiout; i++)
116
int fd = oss_midioutfd[i];
118
int devno = midioutvec[i];
119
if (devno == 1 && fd < 0)
121
sys_setalarm(1000000);
122
fd = open("/dev/midi", O_WRONLY | O_MIDIFLAG);
125
"device 1: tried /dev/midi WRITEONLY; returned %d\n", fd);
129
sys_setalarm(1000000);
130
sprintf(namebuf, "/dev/midi%2.2d", devno);
131
fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
133
fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
138
sys_setalarm(1000000);
139
sprintf(namebuf, "/dev/midi%d", devno);
140
fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
142
fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
146
oss_midioutfd[oss_nmidiout++] = fd;
147
else post("couldn't open MIDI output device %d", devno);
150
if (oss_nmidiin < nmidiin || oss_nmidiout < nmidiout || sys_verbose)
151
post("opened %d MIDI input device(s) and %d MIDI output device(s).",
152
oss_nmidiin, oss_nmidiout);
157
#define md_msglen(x) (((x)<0xC0)?2:((x)<0xE0)?1:((x)<0xF0)?2:\
158
((x)==0xF2)?2:((x)<0xF4)?1:0)
160
void sys_putmidimess(int portno, int a, int b, int c)
162
if (portno >= 0 && portno < oss_nmidiout)
164
switch (md_msglen(a))
167
oss_midiout(oss_midioutfd[portno],a);
168
oss_midiout(oss_midioutfd[portno],b);
169
oss_midiout(oss_midioutfd[portno],c);
172
oss_midiout(oss_midioutfd[portno],a);
173
oss_midiout(oss_midioutfd[portno],b);
176
oss_midiout(oss_midioutfd[portno],a);
182
void sys_putmidibyte(int portno, int byte)
184
if (portno >= 0 && portno < oss_nmidiout)
185
oss_midiout(oss_midioutfd[portno], byte);
188
#if 0 /* this is the "select" version which doesn't work with OSS
189
driver for emu10k1 (it doesn't implement select.) */
190
void sys_poll_midi(void)
192
int i, throttle = 100;
193
struct timeval timout;
194
int did = 1, maxfd = 0;
197
fd_set readset, writeset, exceptset;
207
for (i = 0; i < oss_nmidiin; i++)
209
if (oss_midiinfd[i] > maxfd)
210
maxfd = oss_midiinfd[i];
211
FD_SET(oss_midiinfd[i], &readset);
213
select(maxfd+1, &readset, &writeset, &exceptset, &timout);
214
for (i = 0; i < oss_nmidiin; i++)
215
if (FD_ISSET(oss_midiinfd[i], &readset))
218
int ret = read(oss_midiinfd[i], &c, 1);
220
fprintf(stderr, "Midi read error\n");
221
else sys_midibytein(i, (c & 0xff));
228
/* this version uses the asynchronous "read()" ... */
229
void sys_poll_midi(void)
231
int i, throttle = 100;
232
struct timeval timout;
233
int did = 1, maxfd = 0;
236
fd_set readset, writeset, exceptset;
240
for (i = 0; i < oss_nmidiin; i++)
243
int ret = read(oss_midiinfd[i], &c, 1);
251
sys_midibytein(i, (c & 0xff));
259
void sys_close_midi()
262
for (i = 0; i < oss_nmidiin; i++)
263
close(oss_midiinfd[i]);
264
for (i = 0; i < oss_nmidiout; i++)
265
close(oss_midioutfd[i]);
266
oss_nmidiin = oss_nmidiout = 0;
270
static int oss_nmidiindevs, oss_nmidioutdevs, oss_initted;
272
void midi_oss_init(void)
278
for (i = 0; i < NSEARCH; i++)
284
/* try to open the device for reading */
287
fd = open("/dev/midi", O_RDONLY | O_NDELAY);
294
sprintf(namebuf, "/dev/midi%2.2d", i);
295
fd = open(namebuf, O_RDONLY | O_NDELAY);
301
sprintf(namebuf, "/dev/midi%d", i);
302
fd = open(namebuf, O_RDONLY | O_NDELAY);
310
for (i = 0; i < NSEARCH; i++)
315
oss_nmidioutdevs = i;
316
/* try to open the device for writing */
319
fd = open("/dev/midi", O_WRONLY | O_NDELAY);
326
sprintf(namebuf, "/dev/midi%2.2d", i);
327
fd = open(namebuf, O_WRONLY | O_NDELAY);
333
sprintf(namebuf, "/dev/midi%d", i);
334
fd = open(namebuf, O_WRONLY | O_NDELAY);
344
void midi_getdevs(char *indevlist, int *nindevs,
345
char *outdevlist, int *noutdevs, int maxndev, int devdescsize)
348
if ((ndev = oss_nmidiindevs) > maxndev)
350
for (i = 0; i < ndev; i++)
351
sprintf(indevlist + i * devdescsize, "OSS MIDI device #%d", i+1);
354
if ((ndev = oss_nmidioutdevs) > maxndev)
356
for (i = 0; i < ndev; i++)
357
sprintf(outdevlist + i * devdescsize, "OSS MIDI device #%d", i+1);