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);