1 /* Copyright (c) 1997-1999 Miller Puckette.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
13 #include <sys/types.h>
16 #include <dmedia/audio.h>
18 #include <dmedia/midi.h>
19 int mdInit(void); /* prototype was messed up in midi.h */
20 /* #include "sys/select.h" */
24 set the special "flush zero" but (FS, bit 24) in the
25 Control Status Register of the FPU of R4k and beyond
26 so that the result of any underflowing operation will
27 be clamped to zero, and no exception of any kind will
28 be generated on the CPU.
30 thanks to cpirazzi@cp.esd.sgi.com (Chris Pirazzi).
33 static void sgi_flush_all_underflows_to_zero(void)
36 f
.fc_word
= get_fpc_csr();
37 f
.fc_struct
.flush
= 1;
38 set_fpc_csr(f
.fc_word
);
43 static MDport sgi_inport
[NPORT
];
44 static MDport sgi_outport
[NPORT
];
46 void sgi_open_midi(int midiin
, int midiout
)
49 int sgi_nports
= mdInit();
50 if (sgi_nports
< 0) sgi_nports
= 0;
51 else if (sgi_nports
> NPORT
) sgi_nports
= NPORT
;
56 post("no serial ports are configured for MIDI;");
57 post("if you want to use MIDI, try exiting Pd, typing");
58 post("'startmidi -d /dev/ttyd2' to a shell, and restarting Pd.");
60 else if (sgi_nports
== 1)
61 post("Found one MIDI port on %s", mdGetName(0));
62 else if (sgi_nports
== 2)
63 post("Found MIDI ports on %s and %s",
64 mdGetName(0), mdGetName(1));
68 for (i
= 0; i
< sgi_nports
; i
++)
70 if (!(sgi_inport
[i
] = mdOpenInPort(mdGetName(i
))))
71 error("MIDI input port %d: open failed", i
+1);;
76 for (i
= 0; i
< sgi_nports
; i
++)
78 if (!(sgi_outport
[i
] = mdOpenOutPort(mdGetName(i
))))
79 error("MIDI output port %d: open failed", i
+1);;
85 void sys_putmidimess(int portno
, int a
, int b
, int c
)
88 if (portno
>= NPORT
|| portno
< 0 || !sgi_outport
[portno
]) return;
96 if (mdSend(sgi_outport
[portno
], &mdv
, 1) < 0)
97 error("MIDI output error\n");
98 post("msg out %d %d %d", a
, b
, c
);
101 void sys_putmidibyte(int portno
, int foo
)
103 error("MIDI raw byte output not available on SGI");
106 void inmidi_noteon(int portno
, int channel
, int pitch
, int velo
);
107 void inmidi_controlchange(int portno
, int channel
, int ctlnumber
, int value
);
108 void inmidi_programchange(int portno
, int channel
, int value
);
109 void inmidi_pitchbend(int portno
, int channel
, int value
);
110 void inmidi_aftertouch(int portno
, int channel
, int value
);
111 void inmidi_polyaftertouch(int portno
, int channel
, int pitch
, int value
);
113 void sys_poll_midi(void)
117 for (i
= 0, mp
= sgi_inport
; i
< NPORT
; i
++, mp
++)
119 int ret
, status
, b1
, b2
, nfds
;
122 struct timeval timeout
;
127 FD_SET(mdGetFd(*mp
), &inports
);
129 if (select(mdGetFd(*mp
)+1 , &inports
, 0, 0, &timeout
) < 0)
130 perror("midi select");
131 if (FD_ISSET(mdGetFd(*mp
),&inports
))
133 if (mdReceive(*mp
, &mdv
, 1) < 0)
134 error("failure receiving message\n");
135 else if (mdv
.msg
[0] == MD_SYSEX
) mdFree(mdv
.sysexmsg
);
139 int status
= mdv
.msg
[0];
140 int channel
= (status
& 0xf) + 1;
143 switch(status
& 0xf0)
146 inmidi_noteon(i
, channel
, b1
, 0);
149 inmidi_noteon(i
, channel
, b1
, b2
);
151 case MD_POLYKEYPRESSURE
:
152 inmidi_polyaftertouch(i
, channel
, b1
, b2
);
154 case MD_CONTROLCHANGE
:
155 inmidi_controlchange(i
, channel
, b1
, b2
);
157 case MD_PITCHBENDCHANGE
:
158 inmidi_pitchbend(i
, channel
, ((b2
<< 7) + b1
));
160 case MD_PROGRAMCHANGE
:
161 inmidi_programchange(i
, channel
, b1
);
163 case MD_CHANNELPRESSURE
:
164 inmidi_aftertouch(i
, channel
, b1
);
172 void sys_open_midi(int nmidiin
, int *midiinvec
,
173 int nmidiout
, int *midioutvec
)
175 sgi_open_midi(nmidiin
!=0, nmidiout
!=0);
179 void sys_close_midi( void)
184 void sys_set_priority(int foo
)
187 "warning: priority boosting in IRIX not implemented yet\n");
189 /* Copyright (c) 1997-1999 Miller Puckette.
190 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
191 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
198 #ifdef HAVE_BSTRING_H
201 #include <sys/types.h>
202 #include <sys/time.h>
204 #include <dmedia/audio.h>
206 #include <dmedia/midi.h>
207 int mdInit(void); /* prototype was messed up in midi.h */
208 /* #include "sys/select.h" */
212 set the special "flush zero" but (FS, bit 24) in the
213 Control Status Register of the FPU of R4k and beyond
214 so that the result of any underflowing operation will
215 be clamped to zero, and no exception of any kind will
216 be generated on the CPU.
218 thanks to cpirazzi@cp.esd.sgi.com (Chris Pirazzi).
221 static void sgi_flush_all_underflows_to_zero(void)
224 f
.fc_word
= get_fpc_csr();
225 f
.fc_struct
.flush
= 1;
226 set_fpc_csr(f
.fc_word
);
231 static MDport sgi_inport
[NPORT
];
232 static MDport sgi_outport
[NPORT
];
234 void sgi_open_midi(int midiin
, int midiout
)
237 int sgi_nports
= mdInit();
238 if (sgi_nports
< 0) sgi_nports
= 0;
239 else if (sgi_nports
> NPORT
) sgi_nports
= NPORT
;
244 post("no serial ports are configured for MIDI;");
245 post("if you want to use MIDI, try exiting Pd, typing");
246 post("'startmidi -d /dev/ttyd2' to a shell, and restarting Pd.");
248 else if (sgi_nports
== 1)
249 post("Found one MIDI port on %s", mdGetName(0));
250 else if (sgi_nports
== 2)
251 post("Found MIDI ports on %s and %s",
252 mdGetName(0), mdGetName(1));
256 for (i
= 0; i
< sgi_nports
; i
++)
258 if (!(sgi_inport
[i
] = mdOpenInPort(mdGetName(i
))))
259 error("MIDI input port %d: open failed", i
+1);;
264 for (i
= 0; i
< sgi_nports
; i
++)
266 if (!(sgi_outport
[i
] = mdOpenOutPort(mdGetName(i
))))
267 error("MIDI output port %d: open failed", i
+1);;
273 void sys_putmidimess(int portno
, int a
, int b
, int c
)
276 if (portno
>= NPORT
|| portno
< 0 || !sgi_outport
[portno
]) return;
284 if (mdSend(sgi_outport
[portno
], &mdv
, 1) < 0)
285 error("MIDI output error\n");
286 post("msg out %d %d %d", a
, b
, c
);
289 void sys_putmidibyte(int portno
, int foo
)
291 error("MIDI raw byte output not available on SGI");
294 void inmidi_noteon(int portno
, int channel
, int pitch
, int velo
);
295 void inmidi_controlchange(int portno
, int channel
, int ctlnumber
, int value
);
296 void inmidi_programchange(int portno
, int channel
, int value
);
297 void inmidi_pitchbend(int portno
, int channel
, int value
);
298 void inmidi_aftertouch(int portno
, int channel
, int value
);
299 void inmidi_polyaftertouch(int portno
, int channel
, int pitch
, int value
);
301 void sys_poll_midi(void)
305 for (i
= 0, mp
= sgi_inport
; i
< NPORT
; i
++, mp
++)
307 int ret
, status
, b1
, b2
, nfds
;
310 struct timeval timeout
;
315 FD_SET(mdGetFd(*mp
), &inports
);
317 if (select(mdGetFd(*mp
)+1 , &inports
, 0, 0, &timeout
) < 0)
318 perror("midi select");
319 if (FD_ISSET(mdGetFd(*mp
),&inports
))
321 if (mdReceive(*mp
, &mdv
, 1) < 0)
322 error("failure receiving message\n");
323 else if (mdv
.msg
[0] == MD_SYSEX
) mdFree(mdv
.sysexmsg
);
327 int status
= mdv
.msg
[0];
328 int channel
= (status
& 0xf) + 1;
331 switch(status
& 0xf0)
334 inmidi_noteon(i
, channel
, b1
, 0);
337 inmidi_noteon(i
, channel
, b1
, b2
);
339 case MD_POLYKEYPRESSURE
:
340 inmidi_polyaftertouch(i
, channel
, b1
, b2
);
342 case MD_CONTROLCHANGE
:
343 inmidi_controlchange(i
, channel
, b1
, b2
);
345 case MD_PITCHBENDCHANGE
:
346 inmidi_pitchbend(i
, channel
, ((b2
<< 7) + b1
));
348 case MD_PROGRAMCHANGE
:
349 inmidi_programchange(i
, channel
, b1
);
351 case MD_CHANNELPRESSURE
:
352 inmidi_aftertouch(i
, channel
, b1
);
360 void sys_open_midi(int nmidiin
, int *midiinvec
,
361 int nmidiout
, int *midioutvec
)
363 sgi_open_midi(nmidiin
!=0, nmidiout
!=0);
367 void sys_close_midi( void)
372 void sys_set_priority(int foo
)
375 "warning: priority boosting in IRIX not implemented yet\n");