~ubuntu-branches/ubuntu/precise/puredata/precise

« back to all changes in this revision

Viewing changes to src/s_midi_oss.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-04-08 16:21:52 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050408162152-88qyy276gx2qmx35
Tags: 0.38.4+amidi-3
* Incorporated mlock fix for 2.6 kernels
* moved allocation/deallocation out of midi poll() call for ALSA (this 
  cause problems on 2.6 kernel series when using -rt)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.  */
5
 
 
6
 
/* MIDI I/O for Linux using OSS */
7
 
 
8
 
#include <stdio.h>
9
 
#ifdef UNIX
10
 
#include <unistd.h>
11
 
#endif
12
 
#include <stdlib.h>
13
 
#include <sys/types.h>
14
 
#include <sys/stat.h>
15
 
#include <fcntl.h>
16
 
#include <errno.h>
17
 
#include "m_pd.h"
18
 
#include "s_stuff.h"
19
 
 
20
 
static int oss_nmidiin;
21
 
static int oss_midiinfd[MAXMIDIINDEV];
22
 
static int oss_nmidiout;
23
 
static int oss_midioutfd[MAXMIDIOUTDEV];
24
 
 
25
 
static void oss_midiout(int fd, int n)
26
 
{
27
 
    char b = n;
28
 
    if ((write(fd, (char *) &b, 1)) != 1)
29
 
        perror("midi write");
30
 
}
31
 
 
32
 
#define O_MIDIFLAG O_NDELAY
33
 
 
34
 
void sys_do_open_midi(int nmidiin, int *midiinvec,
35
 
    int nmidiout, int *midioutvec)
36
 
{
37
 
    int i;
38
 
    for (i = 0; i < nmidiout; i++)
39
 
        oss_midioutfd[i] = -1;
40
 
    for (i = 0, oss_nmidiin = 0; i < nmidiin; i++)
41
 
    {
42
 
        int fd = -1, j, outdevindex = -1;
43
 
        char namebuf[80];
44
 
        int devno = midiinvec[i];
45
 
 
46
 
        for (j = 0; j < nmidiout; j++)
47
 
            if (midioutvec[j] == midiinvec[i])
48
 
                outdevindex = j;
49
 
        
50
 
            /* try to open the device for read/write. */
51
 
        if (devno == 0 && fd < 0 && outdevindex >= 0)
52
 
        {
53
 
            sys_setalarm(1000000);
54
 
            fd = open("/dev/midi", O_RDWR | O_MIDIFLAG);
55
 
            if (sys_verbose)
56
 
                fprintf(stderr,
57
 
                    "device 1: tried /dev/midi READ/WRITE; returned %d\n", fd);
58
 
            if (outdevindex >= 0 && fd >= 0)
59
 
                oss_midioutfd[outdevindex] = fd;
60
 
        }
61
 
        if (fd < 0 && outdevindex >= 0)
62
 
        {
63
 
            sys_setalarm(1000000);
64
 
            sprintf(namebuf, "/dev/midi%2.2d", devno);
65
 
            fd = open(namebuf, O_RDWR | O_MIDIFLAG);
66
 
            if (sys_verbose)
67
 
                fprintf(stderr,
68
 
                    "device %d: tried %s READ/WRITE; returned %d\n",
69
 
                        devno, namebuf, fd);
70
 
            if (outdevindex >= 0 && fd >= 0)
71
 
                oss_midioutfd[outdevindex] = fd;
72
 
        }
73
 
        if (fd < 0 && outdevindex >= 0)
74
 
        {
75
 
            sys_setalarm(1000000);
76
 
            sprintf(namebuf, "/dev/midi%d", devno);
77
 
            fd = open(namebuf, O_RDWR | O_MIDIFLAG);
78
 
            if (sys_verbose)
79
 
                fprintf(stderr, "device %d: tried %s READ/WRITE; returned %d\n",
80
 
                    devno, namebuf, fd);
81
 
            if (outdevindex >= 0 && fd >= 0)
82
 
                oss_midioutfd[outdevindex] = fd;
83
 
        }
84
 
        if (devno == 1 && fd < 0)
85
 
        {
86
 
            sys_setalarm(1000000);
87
 
            fd = open("/dev/midi", O_RDONLY | O_MIDIFLAG);
88
 
            if (sys_verbose)
89
 
                fprintf(stderr,
90
 
                    "device 1: tried /dev/midi READONLY; returned %d\n", fd);
91
 
        }
92
 
        if (fd < 0)
93
 
        {
94
 
            sys_setalarm(1000000);
95
 
            sprintf(namebuf, "/dev/midi%2.2d", devno);
96
 
            fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
97
 
            if (sys_verbose)
98
 
                fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
99
 
                    devno, namebuf, fd);
100
 
        }
101
 
        if (fd < 0)
102
 
        {
103
 
            sys_setalarm(1000000);
104
 
            sprintf(namebuf, "/dev/midi%d", devno);
105
 
            fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
106
 
            if (sys_verbose)
107
 
                fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
108
 
                    devno, namebuf, fd);
109
 
        }
110
 
        if (fd >= 0)
111
 
            oss_midiinfd[oss_nmidiin++] = fd;       
112
 
        else post("couldn't open MIDI input device %d", devno);
113
 
    }
114
 
    for (i = 0, oss_nmidiout = 0; i < nmidiout; i++)
115
 
    {
116
 
        int fd = oss_midioutfd[i];
117
 
        char namebuf[80];
118
 
        int devno = midioutvec[i];
119
 
        if (devno == 1 && fd < 0)
120
 
        {
121
 
            sys_setalarm(1000000);
122
 
            fd = open("/dev/midi", O_WRONLY | O_MIDIFLAG);
123
 
            if (sys_verbose)
124
 
                fprintf(stderr,
125
 
                    "device 1: tried /dev/midi WRITEONLY; returned %d\n", fd);
126
 
        }
127
 
        if (fd < 0)
128
 
        {
129
 
            sys_setalarm(1000000);
130
 
            sprintf(namebuf, "/dev/midi%2.2d", devno);
131
 
            fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
132
 
            if (sys_verbose)
133
 
                fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
134
 
                    devno, namebuf, fd);
135
 
        }
136
 
        if (fd < 0)
137
 
        {
138
 
            sys_setalarm(1000000);
139
 
            sprintf(namebuf, "/dev/midi%d", devno);
140
 
            fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
141
 
            if (sys_verbose)
142
 
                fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
143
 
                    devno, namebuf, fd);
144
 
        }
145
 
        if (fd >= 0)
146
 
            oss_midioutfd[oss_nmidiout++] = fd;     
147
 
        else post("couldn't open MIDI output device %d", devno);
148
 
    }
149
 
 
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);
153
 
 
154
 
    sys_setalarm(0);
155
 
}
156
 
 
157
 
#define md_msglen(x) (((x)<0xC0)?2:((x)<0xE0)?1:((x)<0xF0)?2:\
158
 
    ((x)==0xF2)?2:((x)<0xF4)?1:0)
159
 
 
160
 
void sys_putmidimess(int portno, int a, int b, int c)
161
 
{
162
 
    if (portno >= 0 && portno < oss_nmidiout)
163
 
    {
164
 
       switch (md_msglen(a))
165
 
       {
166
 
       case 2:
167
 
            oss_midiout(oss_midioutfd[portno],a);        
168
 
            oss_midiout(oss_midioutfd[portno],b);        
169
 
            oss_midiout(oss_midioutfd[portno],c);
170
 
            return;
171
 
       case 1:
172
 
            oss_midiout(oss_midioutfd[portno],a);        
173
 
            oss_midiout(oss_midioutfd[portno],b);        
174
 
            return;
175
 
       case 0:
176
 
            oss_midiout(oss_midioutfd[portno],a);        
177
 
            return;
178
 
       };
179
 
    }
180
 
}
181
 
 
182
 
void sys_putmidibyte(int portno, int byte)
183
 
{
184
 
    if (portno >= 0 && portno < oss_nmidiout)
185
 
        oss_midiout(oss_midioutfd[portno], byte);       
186
 
}
187
 
 
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)
191
 
{
192
 
    int i, throttle = 100;
193
 
    struct timeval timout;
194
 
    int did = 1, maxfd = 0;
195
 
    while (did)
196
 
    {
197
 
        fd_set readset, writeset, exceptset;
198
 
        did = 0;
199
 
        if (throttle-- < 0)
200
 
            break;
201
 
        timout.tv_sec = 0;
202
 
        timout.tv_usec = 0;
203
 
 
204
 
        FD_ZERO(&writeset);
205
 
        FD_ZERO(&readset);
206
 
        FD_ZERO(&exceptset);
207
 
        for (i = 0; i < oss_nmidiin; i++)
208
 
        {
209
 
            if (oss_midiinfd[i] > maxfd)
210
 
                maxfd = oss_midiinfd[i];
211
 
            FD_SET(oss_midiinfd[i], &readset);
212
 
        }
213
 
        select(maxfd+1, &readset, &writeset, &exceptset, &timout);
214
 
        for (i = 0; i < oss_nmidiin; i++)
215
 
            if (FD_ISSET(oss_midiinfd[i], &readset))
216
 
        {
217
 
            char c;
218
 
            int ret = read(oss_midiinfd[i], &c, 1);
219
 
            if (ret <= 0)
220
 
                fprintf(stderr, "Midi read error\n");
221
 
            else sys_midibytein(i, (c & 0xff));
222
 
            did = 1;
223
 
        }
224
 
    }
225
 
}
226
 
#else 
227
 
 
228
 
    /* this version uses the asynchronous "read()" ... */
229
 
void sys_poll_midi(void)
230
 
{
231
 
    int i, throttle = 100;
232
 
    struct timeval timout;
233
 
    int did = 1, maxfd = 0;
234
 
    while (did)
235
 
    {
236
 
        fd_set readset, writeset, exceptset;
237
 
        did = 0;
238
 
        if (throttle-- < 0)
239
 
            break;
240
 
        for (i = 0; i < oss_nmidiin; i++)
241
 
        {
242
 
            char c;
243
 
            int ret = read(oss_midiinfd[i], &c, 1);
244
 
            if (ret < 0)
245
 
            {
246
 
                if (errno != EAGAIN)
247
 
                    perror("MIDI");
248
 
            }
249
 
            else if (ret != 0)
250
 
            {
251
 
                sys_midibytein(i, (c & 0xff));
252
 
                did = 1;
253
 
            }
254
 
        }
255
 
    }
256
 
}
257
 
#endif
258
 
 
259
 
void sys_close_midi()
260
 
{
261
 
    int i;
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;
267
 
}
268
 
 
269
 
#define NSEARCH 10
270
 
static int oss_nmidiindevs, oss_nmidioutdevs, oss_initted;
271
 
 
272
 
void midi_oss_init(void)     
273
 
{
274
 
    int i;
275
 
    if (oss_initted)
276
 
        return;
277
 
    oss_initted = 1;
278
 
    for (i = 0; i < NSEARCH; i++)
279
 
    {
280
 
        int fd;
281
 
        char namebuf[80];
282
 
        
283
 
        oss_nmidiindevs = i;
284
 
            /* try to open the device for reading */
285
 
        if (i == 0)
286
 
        {
287
 
            fd = open("/dev/midi", O_RDONLY | O_NDELAY);
288
 
            if (fd >= 0)
289
 
            {
290
 
                close(fd);
291
 
                continue;
292
 
            }
293
 
        }
294
 
        sprintf(namebuf, "/dev/midi%2.2d", i);
295
 
        fd = open(namebuf, O_RDONLY | O_NDELAY);
296
 
        if (fd >= 0)
297
 
        {
298
 
            close(fd);
299
 
            continue;
300
 
        }
301
 
        sprintf(namebuf, "/dev/midi%d", i);
302
 
        fd = open(namebuf, O_RDONLY | O_NDELAY);
303
 
        if (fd >= 0)
304
 
        {
305
 
            close(fd);
306
 
            continue;
307
 
        }
308
 
        break;
309
 
    }
310
 
    for (i = 0; i < NSEARCH; i++)
311
 
    {
312
 
        int fd;
313
 
        char namebuf[80];
314
 
        
315
 
        oss_nmidioutdevs = i;
316
 
            /* try to open the device for writing */
317
 
        if (i == 0)
318
 
        {
319
 
            fd = open("/dev/midi", O_WRONLY | O_NDELAY);
320
 
            if (fd >= 0)
321
 
            {
322
 
                close(fd);
323
 
                continue;
324
 
            }
325
 
        }
326
 
        sprintf(namebuf, "/dev/midi%2.2d", i);
327
 
        fd = open(namebuf, O_WRONLY | O_NDELAY);
328
 
        if (fd >= 0)
329
 
        {
330
 
            close(fd);
331
 
            continue;
332
 
        }
333
 
        sprintf(namebuf, "/dev/midi%d", i);
334
 
        fd = open(namebuf, O_WRONLY | O_NDELAY);
335
 
        if (fd >= 0)
336
 
        {
337
 
            close(fd);
338
 
            continue;
339
 
        }
340
 
        break;
341
 
    }
342
 
}
343
 
 
344
 
void midi_getdevs(char *indevlist, int *nindevs,
345
 
    char *outdevlist, int *noutdevs, int maxndev, int devdescsize)
346
 
{
347
 
    int i, ndev;
348
 
    if ((ndev = oss_nmidiindevs) > maxndev)
349
 
        ndev = maxndev;
350
 
    for (i = 0; i < ndev; i++)
351
 
        sprintf(indevlist + i * devdescsize, "OSS MIDI device #%d", i+1);
352
 
    *nindevs = ndev;
353
 
 
354
 
    if ((ndev = oss_nmidioutdevs) > maxndev)
355
 
        ndev = maxndev;
356
 
    for (i = 0; i < ndev; i++)
357
 
        sprintf(outdevlist + i * devdescsize, "OSS MIDI device #%d", i+1);
358
 
    *noutdevs = ndev;
359
 
}