summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/x_midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_midi.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/x_midi.c1314
1 files changed, 0 insertions, 1314 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_midi.c b/apps/plugins/pdbox/PDa/src/x_midi.c
deleted file mode 100644
index e9f3601057..0000000000
--- a/apps/plugins/pdbox/PDa/src/x_midi.c
+++ /dev/null
@@ -1,1314 +0,0 @@
1/* Copyright (c) 1997-2001 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* MIDI. */
6
7#include "m_pd.h"
8void outmidi_noteon(int portno, int channel, int pitch, int velo);
9void outmidi_controlchange(int portno, int channel, int ctlno, int value);
10void outmidi_programchange(int portno, int channel, int value);
11void outmidi_pitchbend(int portno, int channel, int value);
12void outmidi_aftertouch(int portno, int channel, int value);
13void outmidi_polyaftertouch(int portno, int channel, int pitch, int value);
14void outmidi_mclk(int portno);
15
16/* ----------------------- midiin and sysexin ------------------------- */
17
18static t_symbol *midiin_sym, *sysexin_sym;
19
20static t_class *midiin_class, *sysexin_class;
21
22typedef struct _midiin
23{
24 t_object x_obj;
25 t_outlet *x_outlet1;
26 t_outlet *x_outlet2;
27} t_midiin;
28
29static void *midiin_new( void)
30{
31 t_midiin *x = (t_midiin *)pd_new(midiin_class);
32 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
33 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
34 pd_bind(&x->x_obj.ob_pd, midiin_sym);
35#ifndef __linux__
36 pd_error(x, "midiin: works under Linux only");
37#endif
38 return (x);
39}
40
41static void midiin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av)
42{
43 outlet_float(x->x_outlet2, atom_getfloatarg(1, ac, av) + 1);
44 outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
45}
46
47static void midiin_free(t_midiin *x)
48{
49 pd_unbind(&x->x_obj.ob_pd, midiin_sym);
50}
51
52static void *sysexin_new( void)
53{
54 t_midiin *x = (t_midiin *)pd_new(sysexin_class);
55 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
56 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
57 pd_bind(&x->x_obj.ob_pd, sysexin_sym);
58#ifndef __linux__
59 pd_error(x, "sysexin: works under Linux only");
60#endif
61 return (x);
62}
63
64static void sysexin_free(t_midiin *x)
65{
66 pd_unbind(&x->x_obj.ob_pd, sysexin_sym);
67}
68
69static void midiin_setup(void)
70{
71 midiin_class = class_new(gensym("midiin"), (t_newmethod)midiin_new,
72 (t_method)midiin_free, sizeof(t_midiin),
73 CLASS_NOINLET, A_DEFFLOAT, 0);
74 class_addlist(midiin_class, midiin_list);
75 class_sethelpsymbol(midiin_class, gensym("midi"));
76 midiin_sym = gensym("#midiin");
77
78 sysexin_class = class_new(gensym("sysexin"), (t_newmethod)sysexin_new,
79 (t_method)sysexin_free, sizeof(t_midiin),
80 CLASS_NOINLET, A_DEFFLOAT, 0);
81 class_addlist(sysexin_class, midiin_list);
82 class_sethelpsymbol(sysexin_class, gensym("midi"));
83 sysexin_sym = gensym("#sysexin");
84}
85
86void inmidi_byte(int portno, int byte)
87{
88 t_atom at[2];
89 if (midiin_sym->s_thing)
90 {
91 SETFLOAT(at, byte);
92 SETFLOAT(at+1, portno + 1);
93 pd_list(midiin_sym->s_thing, 0, 2, at);
94 }
95}
96
97void inmidi_sysex(int portno, int byte)
98{
99 t_atom at[2];
100 if (sysexin_sym->s_thing)
101 {
102 SETFLOAT(at, byte);
103 SETFLOAT(at+1, portno + 1);
104 pd_list(sysexin_sym->s_thing, 0, 2, at);
105 }
106}
107
108/* ----------------------- notein ------------------------- */
109
110static t_symbol *notein_sym;
111
112static t_class *notein_class;
113
114typedef struct _notein
115{
116 t_object x_obj;
117 t_float x_channel;
118 t_outlet *x_outlet1;
119 t_outlet *x_outlet2;
120 t_outlet *x_outlet3;
121} t_notein;
122
123static void *notein_new(t_floatarg f)
124{
125 t_notein *x = (t_notein *)pd_new(notein_class);
126 x->x_channel = f;
127 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
128 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
129 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
130 pd_bind(&x->x_obj.ob_pd, notein_sym);
131 return (x);
132}
133
134static void notein_list(t_notein *x, t_symbol *s, int argc, t_atom *argv)
135{
136 float pitch = atom_getfloatarg(0, argc, argv);
137 float velo = atom_getfloatarg(1, argc, argv);
138 float channel = atom_getfloatarg(2, argc, argv);
139 if (x->x_channel != 0)
140 {
141 if (channel != x->x_channel) return;
142 outlet_float(x->x_outlet2, velo);
143 outlet_float(x->x_outlet1, pitch);
144 }
145 else
146 {
147 outlet_float(x->x_outlet3, channel);
148 outlet_float(x->x_outlet2, velo);
149 outlet_float(x->x_outlet1, pitch);
150 }
151}
152
153static void notein_free(t_notein *x)
154{
155 pd_unbind(&x->x_obj.ob_pd, notein_sym);
156}
157
158static void notein_setup(void)
159{
160 notein_class = class_new(gensym("notein"), (t_newmethod)notein_new,
161 (t_method)notein_free, sizeof(t_notein), CLASS_NOINLET, A_DEFFLOAT, 0);
162 class_addlist(notein_class, notein_list);
163 class_sethelpsymbol(notein_class, gensym("midi"));
164 notein_sym = gensym("#notein");
165}
166
167void inmidi_noteon(int portno, int channel, int pitch, int velo)
168{
169 if (notein_sym->s_thing)
170 {
171 t_atom at[3];
172 SETFLOAT(at, pitch);
173 SETFLOAT(at+1, velo);
174 SETFLOAT(at+2, (channel + (portno << 4) + 1));
175 pd_list(notein_sym->s_thing, &s_list, 3, at);
176 }
177}
178
179/* ----------------------- ctlin ------------------------- */
180
181static t_symbol *ctlin_sym;
182
183static t_class *ctlin_class;
184
185typedef struct _ctlin
186{
187 t_object x_obj;
188 t_float x_channel;
189 t_float x_ctlno;
190 t_outlet *x_outlet1;
191 t_outlet *x_outlet2;
192 t_outlet *x_outlet3;
193} t_ctlin;
194
195static void *ctlin_new(t_symbol *s, int argc, t_atom *argv)
196{
197 int ctlno, channel;
198 t_ctlin *x = (t_ctlin *)pd_new(ctlin_class);
199 if (!argc) ctlno = -1;
200 else ctlno = atom_getfloatarg(0, argc, argv);
201 channel = atom_getfloatarg(1, argc, argv);
202 x->x_channel = channel;
203 x->x_ctlno = ctlno;
204 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
205 if (!channel)
206 {
207 if (x->x_ctlno < 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
208 x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
209 }
210 pd_bind(&x->x_obj.ob_pd, ctlin_sym);
211 return (x);
212}
213
214static void ctlin_list(t_ctlin *x, t_symbol *s, int argc, t_atom *argv)
215{
216 t_float ctlnumber = atom_getfloatarg(0, argc, argv);
217 t_float value = atom_getfloatarg(1, argc, argv);
218 t_float channel = atom_getfloatarg(2, argc, argv);
219 if (x->x_ctlno >= 0 && x->x_ctlno != ctlnumber) return;
220 if (x->x_channel > 0 && x->x_channel != channel) return;
221 if (x->x_channel == 0) outlet_float(x->x_outlet3, channel);
222 if (x->x_ctlno < 0) outlet_float(x->x_outlet2, ctlnumber);
223 outlet_float(x->x_outlet1, value);
224}
225
226static void ctlin_free(t_ctlin *x)
227{
228 pd_unbind(&x->x_obj.ob_pd, ctlin_sym);
229}
230
231static void ctlin_setup(void)
232{
233 ctlin_class = class_new(gensym("ctlin"), (t_newmethod)ctlin_new,
234 (t_method)ctlin_free, sizeof(t_ctlin),
235 CLASS_NOINLET, A_GIMME, 0);
236 class_addlist(ctlin_class, ctlin_list);
237 class_sethelpsymbol(ctlin_class, gensym("midi"));
238 ctlin_sym = gensym("#ctlin");
239}
240
241void inmidi_controlchange(int portno, int channel, int ctlnumber, int value)
242{
243 if (ctlin_sym->s_thing)
244 {
245 t_atom at[3];
246 SETFLOAT(at, ctlnumber);
247 SETFLOAT(at+1, value);
248 SETFLOAT(at+2, (channel + (portno << 4) + 1));
249 pd_list(ctlin_sym->s_thing, &s_list, 3, at);
250 }
251}
252
253/* ----------------------- pgmin ------------------------- */
254
255static t_symbol *pgmin_sym;
256
257static t_class *pgmin_class;
258
259typedef struct _pgmin
260{
261 t_object x_obj;
262 t_float x_channel;
263 t_outlet *x_outlet1;
264 t_outlet *x_outlet2;
265} t_pgmin;
266
267static void *pgmin_new(t_floatarg f)
268{
269 t_pgmin *x = (t_pgmin *)pd_new(pgmin_class);
270 x->x_channel = f;
271 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
272 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
273 pd_bind(&x->x_obj.ob_pd, pgmin_sym);
274 return (x);
275}
276
277static void pgmin_list(t_pgmin *x, t_symbol *s, int argc, t_atom *argv)
278{
279 float value = atom_getfloatarg(0, argc, argv);
280 float channel = atom_getfloatarg(1, argc, argv);
281 if (x->x_channel != 0)
282 {
283 if (channel != x->x_channel) return;
284 outlet_float(x->x_outlet1, value);
285 }
286 else
287 {
288 outlet_float(x->x_outlet2, channel);
289 outlet_float(x->x_outlet1, value);
290 }
291}
292
293static void pgmin_free(t_pgmin *x)
294{
295 pd_unbind(&x->x_obj.ob_pd, pgmin_sym);
296}
297
298static void pgmin_setup(void)
299{
300 pgmin_class = class_new(gensym("pgmin"), (t_newmethod)pgmin_new,
301 (t_method)pgmin_free, sizeof(t_pgmin),
302 CLASS_NOINLET, A_DEFFLOAT, 0);
303 class_addlist(pgmin_class, pgmin_list);
304 class_sethelpsymbol(pgmin_class, gensym("midi"));
305 pgmin_sym = gensym("#pgmin");
306}
307
308void inmidi_programchange(int portno, int channel, int value)
309{
310 if (pgmin_sym->s_thing)
311 {
312 t_atom at[2];
313 SETFLOAT(at, value + 1);
314 SETFLOAT(at+1, (channel + (portno << 4) + 1));
315 pd_list(pgmin_sym->s_thing, &s_list, 2, at);
316 }
317}
318
319/* ----------------------- bendin ------------------------- */
320
321static t_symbol *bendin_sym;
322
323static t_class *bendin_class;
324
325typedef struct _bendin
326{
327 t_object x_obj;
328 t_float x_channel;
329 t_outlet *x_outlet1;
330 t_outlet *x_outlet2;
331} t_bendin;
332
333static void *bendin_new(t_floatarg f)
334{
335 t_bendin *x = (t_bendin *)pd_new(bendin_class);
336 x->x_channel = f;
337 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
338 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
339 pd_bind(&x->x_obj.ob_pd, bendin_sym);
340 return (x);
341}
342
343static void bendin_list(t_bendin *x, t_symbol *s, int argc, t_atom *argv)
344{
345 t_float value = atom_getfloatarg(0, argc, argv);
346 t_float channel = atom_getfloatarg(1, argc, argv);
347 if (x->x_channel != 0)
348 {
349 if (channel != x->x_channel) return;
350 outlet_float(x->x_outlet1, value);
351 }
352 else
353 {
354 outlet_float(x->x_outlet2, channel);
355 outlet_float(x->x_outlet1, value);
356 }
357}
358
359static void bendin_free(t_bendin *x)
360{
361 pd_unbind(&x->x_obj.ob_pd, bendin_sym);
362}
363
364static void bendin_setup(void)
365{
366 bendin_class = class_new(gensym("bendin"), (t_newmethod)bendin_new,
367 (t_method)bendin_free, sizeof(t_bendin), CLASS_NOINLET, A_DEFFLOAT, 0);
368 class_addlist(bendin_class, bendin_list);
369 class_sethelpsymbol(bendin_class, gensym("midi"));
370 bendin_sym = gensym("#bendin");
371}
372
373void inmidi_pitchbend(int portno, int channel, int value)
374{
375 if (bendin_sym->s_thing)
376 {
377 t_atom at[2];
378 SETFLOAT(at, value);
379 SETFLOAT(at+1, (channel + (portno << 4) + 1));
380 pd_list(bendin_sym->s_thing, &s_list, 2, at);
381 }
382}
383
384/* ----------------------- touchin ------------------------- */
385
386static t_symbol *touchin_sym;
387
388static t_class *touchin_class;
389
390typedef struct _touchin
391{
392 t_object x_obj;
393 t_float x_channel;
394 t_outlet *x_outlet1;
395 t_outlet *x_outlet2;
396} t_touchin;
397
398static void *touchin_new(t_floatarg f)
399{
400 t_touchin *x = (t_touchin *)pd_new(touchin_class);
401 x->x_channel = f;
402 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
403 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
404 pd_bind(&x->x_obj.ob_pd, touchin_sym);
405 return (x);
406}
407
408static void touchin_list(t_touchin *x, t_symbol *s, int argc, t_atom *argv)
409{
410 t_float value = atom_getfloatarg(0, argc, argv);
411 t_float channel = atom_getfloatarg(1, argc, argv);
412 if (x->x_channel)
413 {
414 if (channel != x->x_channel) return;
415 outlet_float(x->x_outlet1, value);
416 }
417 else
418 {
419 outlet_float(x->x_outlet2, channel);
420 outlet_float(x->x_outlet1, value);
421 }
422}
423
424static void touchin_free(t_touchin *x)
425{
426 pd_unbind(&x->x_obj.ob_pd, touchin_sym);
427}
428
429static void touchin_setup(void)
430{
431 touchin_class = class_new(gensym("touchin"), (t_newmethod)touchin_new,
432 (t_method)touchin_free, sizeof(t_touchin),
433 CLASS_NOINLET, A_DEFFLOAT, 0);
434 class_addlist(touchin_class, touchin_list);
435 class_sethelpsymbol(touchin_class, gensym("midi"));
436 touchin_sym = gensym("#touchin");
437}
438
439void inmidi_aftertouch(int portno, int channel, int value)
440{
441 if (touchin_sym->s_thing)
442 {
443 t_atom at[2];
444 SETFLOAT(at, value);
445 SETFLOAT(at+1, (channel + (portno << 4) + 1));
446 pd_list(touchin_sym->s_thing, &s_list, 2, at);
447 }
448}
449
450/* ----------------------- polytouchin ------------------------- */
451
452static t_symbol *polytouchin_sym;
453
454static t_class *polytouchin_class;
455
456typedef struct _polytouchin
457{
458 t_object x_obj;
459 t_float x_channel;
460 t_outlet *x_outlet1;
461 t_outlet *x_outlet2;
462 t_outlet *x_outlet3;
463} t_polytouchin;
464
465static void *polytouchin_new(t_floatarg f)
466{
467 t_polytouchin *x = (t_polytouchin *)pd_new(polytouchin_class);
468 x->x_channel = f;
469 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
470 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
471 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
472 pd_bind(&x->x_obj.ob_pd, polytouchin_sym);
473 return (x);
474}
475
476static void polytouchin_list(t_polytouchin *x, t_symbol *s, int argc,
477 t_atom *argv)
478{
479 t_float pitch = atom_getfloatarg(0, argc, argv);
480 t_float value = atom_getfloatarg(1, argc, argv);
481 t_float channel = atom_getfloatarg(2, argc, argv);
482 if (x->x_channel != 0)
483 {
484 if (channel != x->x_channel) return;
485 outlet_float(x->x_outlet2, pitch);
486 outlet_float(x->x_outlet1, value);
487 }
488 else
489 {
490 outlet_float(x->x_outlet3, channel);
491 outlet_float(x->x_outlet2, pitch);
492 outlet_float(x->x_outlet1, value);
493 }
494}
495
496static void polytouchin_free(t_polytouchin *x)
497{
498 pd_unbind(&x->x_obj.ob_pd, polytouchin_sym);
499}
500
501static void polytouchin_setup(void)
502{
503 polytouchin_class = class_new(gensym("polytouchin"),
504 (t_newmethod)polytouchin_new, (t_method)polytouchin_free,
505 sizeof(t_polytouchin), CLASS_NOINLET, A_DEFFLOAT, 0);
506 class_addlist(polytouchin_class, polytouchin_list);
507 class_sethelpsymbol(polytouchin_class, gensym("midi"));
508 polytouchin_sym = gensym("#polytouchin");
509}
510
511void inmidi_polyaftertouch(int portno, int channel, int pitch, int value)
512{
513 if (polytouchin_sym->s_thing)
514 {
515 t_atom at[3];
516 SETFLOAT(at, pitch);
517 SETFLOAT(at+1, value);
518 SETFLOAT(at+2, (channel + (portno << 4) + 1));
519 pd_list(polytouchin_sym->s_thing, &s_list, 3, at);
520 }
521}
522
523/*----------------------- midiclkin--(midi F8 message )---------------------*/
524static t_symbol *midiclkin_sym;
525
526static t_class *midiclkin_class;
527
528
529typedef struct _midiclkin
530{
531 t_object x_obj;
532 t_outlet *x_outlet1;
533 t_outlet *x_outlet2;
534} t_midiclkin;
535
536static void *midiclkin_new(t_floatarg f)
537{
538 t_midiclkin *x = (t_midiclkin *)pd_new(midiclkin_class);
539 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
540 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
541 pd_bind(&x->x_obj.ob_pd, midiclkin_sym);
542 return (x);
543}
544
545static void midiclkin_list(t_midiclkin *x, t_symbol *s, int argc, t_atom *argv)
546{
547 float value = atom_getfloatarg(0, argc, argv);
548 float count = atom_getfloatarg(1, argc, argv);
549 outlet_float(x->x_outlet2, count);
550 outlet_float(x->x_outlet1, value);
551}
552
553static void midiclkin_free(t_midiclkin *x)
554{
555 pd_unbind(&x->x_obj.ob_pd, midiclkin_sym);
556}
557
558static void midiclkin_setup(void)
559{
560 midiclkin_class = class_new(gensym("midiclkin"),
561 (t_newmethod)midiclkin_new, (t_method)midiclkin_free,
562 sizeof(t_midiclkin), CLASS_NOINLET, A_DEFFLOAT, 0);
563 class_addlist(midiclkin_class, midiclkin_list);
564 class_sethelpsymbol(midiclkin_class, gensym("midi"));
565 midiclkin_sym = gensym("#midiclkin");
566}
567
568void inmidi_clk(double timing)
569{
570
571 static float prev = 0;
572 static float count = 0;
573 float cur,diff;
574
575 if (midiclkin_sym->s_thing)
576 {
577 t_atom at[2];
578 diff =timing - prev;
579 count++;
580
581 if (count == 3)
582 { /* 24 count per quoter note */
583 SETFLOAT(at, 1 );
584 count = 0;
585 }
586 else SETFLOAT(at, 0);
587
588 SETFLOAT(at+1, diff);
589 pd_list(midiclkin_sym->s_thing, &s_list, 2, at);
590 prev = timing;
591 }
592}
593
594/*----------midirealtimein (midi FA,FB,FC,FF message )-----------------*/
595
596static t_symbol *midirealtimein_sym;
597
598static t_class *midirealtimein_class;
599
600typedef struct _midirealtimein
601{
602 t_object x_obj;
603 t_outlet *x_outlet1;
604 t_outlet *x_outlet2;
605} t_midirealtimein;
606
607static void *midirealtimein_new( void)
608{
609 t_midirealtimein *x = (t_midirealtimein *)pd_new(midirealtimein_class);
610 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
611 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
612 pd_bind(&x->x_obj.ob_pd, midirealtimein_sym);
613#ifndef MSW
614 pd_error(x, "midirealtimein: works under MSW only");
615#endif
616 return (x);
617}
618
619static void midirealtimein_list(t_midirealtimein *x, t_symbol *s,
620 int argc, t_atom *argv)
621{
622 float portno = atom_getfloatarg(0, argc, argv);
623 float byte = atom_getfloatarg(1, argc, argv);
624
625 outlet_float(x->x_outlet2, portno);
626 outlet_float(x->x_outlet1, byte);
627}
628
629static void midirealtimein_free(t_midirealtimein *x)
630{
631 pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym);
632}
633
634static void midirealtimein_setup(void)
635{
636 midirealtimein_class = class_new(gensym("midirealtimein"),
637 (t_newmethod)midirealtimein_new, (t_method)midirealtimein_free,
638 sizeof(t_midirealtimein), CLASS_NOINLET, A_DEFFLOAT, 0);
639 class_addlist(midirealtimein_class, midirealtimein_list);
640 class_sethelpsymbol(midirealtimein_class, gensym("midi"));
641 midirealtimein_sym = gensym("#midirealtimein");
642}
643
644void inmidi_realtimein(int portno, int SysMsg)
645{
646 if (midirealtimein_sym->s_thing)
647 {
648 t_atom at[2];
649 SETFLOAT(at, portno);
650 SETFLOAT(at+1, SysMsg);
651 pd_list(midirealtimein_sym->s_thing, &s_list, 1, at);
652 }
653}
654
655/* -------------------------- midiout -------------------------- */
656
657static t_class *midiout_class;
658
659void sys_putmidibyte(int portno, int byte);
660
661typedef struct _midiout
662{
663 t_object x_obj;
664 t_float x_portno;
665} t_midiout;
666
667static void *midiout_new(t_floatarg portno)
668{
669 t_midiout *x = (t_midiout *)pd_new(midiout_class);
670 if (portno <= 0) portno = 1;
671 x->x_portno = portno;
672 floatinlet_new(&x->x_obj, &x->x_portno);
673#ifdef __irix__
674 post("midiout: unimplemented in IRIX");
675#endif
676 return (x);
677}
678
679static void midiout_float(t_midiout *x, t_floatarg f)
680{
681 sys_putmidibyte(x->x_portno - 1, f);
682}
683
684static void midiout_setup(void)
685{
686 midiout_class = class_new(gensym("midiout"), (t_newmethod)midiout_new, 0,
687 sizeof(t_midiout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
688 class_addfloat(midiout_class, midiout_float);
689 class_sethelpsymbol(midiout_class, gensym("midi"));
690}
691
692/* -------------------------- noteout -------------------------- */
693
694static t_class *noteout_class;
695
696typedef struct _noteout
697{
698 t_object x_obj;
699 t_float x_velo;
700 t_float x_channel;
701} t_noteout;
702
703static void *noteout_new(t_floatarg channel)
704{
705 t_noteout *x = (t_noteout *)pd_new(noteout_class);
706 x->x_velo = 0;
707 if (channel < 1) channel = 1;
708 x->x_channel = channel;
709 floatinlet_new(&x->x_obj, &x->x_velo);
710 floatinlet_new(&x->x_obj, &x->x_channel);
711 return (x);
712}
713
714static void noteout_float(t_noteout *x, t_float f)
715{
716 int binchan = x->x_channel - 1;
717 if (binchan < 0)
718 binchan = 0;
719 outmidi_noteon((binchan >> 4),
720 (binchan & 15), (int)f, (int)x->x_velo);
721}
722
723static void noteout_setup(void)
724{
725 noteout_class = class_new(gensym("noteout"), (t_newmethod)noteout_new, 0,
726 sizeof(t_noteout), 0, A_DEFFLOAT, 0);
727 class_addfloat(noteout_class, noteout_float);
728 class_sethelpsymbol(noteout_class, gensym("midi"));
729}
730
731
732/* -------------------------- ctlout -------------------------- */
733
734static t_class *ctlout_class;
735
736typedef struct _ctlout
737{
738 t_object x_obj;
739 t_float x_ctl;
740 t_float x_channel;
741} t_ctlout;
742
743static void *ctlout_new(t_floatarg ctl, t_floatarg channel)
744{
745 t_ctlout *x = (t_ctlout *)pd_new(ctlout_class);
746 x->x_ctl = ctl;
747 if (channel <= 0) channel = 1;
748 x->x_channel = channel;
749 floatinlet_new(&x->x_obj, &x->x_ctl);
750 floatinlet_new(&x->x_obj, &x->x_channel);
751 return (x);
752}
753
754static void ctlout_float(t_ctlout *x, t_float f)
755{
756 int binchan = x->x_channel - 1;
757 if (binchan < 0)
758 binchan = 0;
759 outmidi_controlchange((binchan >> 4),
760 (binchan & 15), (int)(x->x_ctl), (int)f);
761}
762
763static void ctlout_setup(void)
764{
765 ctlout_class = class_new(gensym("ctlout"), (t_newmethod)ctlout_new, 0,
766 sizeof(t_ctlout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
767 class_addfloat(ctlout_class, ctlout_float);
768 class_sethelpsymbol(ctlout_class, gensym("midi"));
769}
770
771
772/* -------------------------- pgmout -------------------------- */
773
774static t_class *pgmout_class;
775
776typedef struct _pgmout
777{
778 t_object x_obj;
779 t_float x_channel;
780} t_pgmout;
781
782static void *pgmout_new(t_floatarg channel)
783{
784 t_pgmout *x = (t_pgmout *)pd_new(pgmout_class);
785 if (channel <= 0) channel = 1;
786 x->x_channel = channel;
787 floatinlet_new(&x->x_obj, &x->x_channel);
788 return (x);
789}
790
791static void pgmout_float(t_pgmout *x, t_floatarg f)
792{
793 int binchan = x->x_channel - 1;
794 int n = f - 1;
795 if (binchan < 0)
796 binchan = 0;
797 if (n < 0) n = 0;
798 else if (n > 127) n = 127;
799 outmidi_programchange((binchan >> 4),
800 (binchan & 15), n);
801}
802
803static void pgmout_setup(void)
804{
805 pgmout_class = class_new(gensym("pgmout"), (t_newmethod)pgmout_new, 0,
806 sizeof(t_pgmout), 0, A_DEFFLOAT, 0);
807 class_addfloat(pgmout_class, pgmout_float);
808 class_sethelpsymbol(pgmout_class, gensym("midi"));
809}
810
811
812/* -------------------------- bendout -------------------------- */
813
814static t_class *bendout_class;
815
816typedef struct _bendout
817{
818 t_object x_obj;
819 t_float x_channel;
820} t_bendout;
821
822static void *bendout_new(t_floatarg channel)
823{
824 t_bendout *x = (t_bendout *)pd_new(bendout_class);
825 if (channel <= 0) channel = 1;
826 x->x_channel = channel;
827 floatinlet_new(&x->x_obj, &x->x_channel);
828 return (x);
829}
830
831static void bendout_float(t_bendout *x, t_float f)
832{
833 int binchan = x->x_channel - 1;
834 int n = (int)f + 8192;
835 if (binchan < 0)
836 binchan = 0;
837 outmidi_pitchbend((binchan >> 4), (binchan & 15), n);
838}
839
840static void bendout_setup(void)
841{
842 bendout_class = class_new(gensym("bendout"), (t_newmethod)bendout_new, 0,
843 sizeof(t_bendout), 0, A_DEFFLOAT, 0);
844 class_addfloat(bendout_class, bendout_float);
845 class_sethelpsymbol(bendout_class, gensym("midi"));
846}
847
848/* -------------------------- touch -------------------------- */
849
850static t_class *touchout_class;
851
852typedef struct _touchout
853{
854 t_object x_obj;
855 t_float x_channel;
856} t_touchout;
857
858static void *touchout_new(t_floatarg channel)
859{
860 t_touchout *x = (t_touchout *)pd_new(touchout_class);
861 if (channel <= 0) channel = 1;
862 x->x_channel = channel;
863 floatinlet_new(&x->x_obj, &x->x_channel);
864 return (x);
865}
866
867static void touchout_float(t_touchout *x, t_float f)
868{
869 int binchan = x->x_channel - 1;
870 if (binchan < 0)
871 binchan = 0;
872 outmidi_aftertouch((binchan >> 4), (binchan & 15), (int)f);
873}
874
875static void touchout_setup(void)
876{
877 touchout_class = class_new(gensym("touchout"), (t_newmethod)touchout_new, 0,
878 sizeof(t_touchout), 0, A_DEFFLOAT, 0);
879 class_addfloat(touchout_class, touchout_float);
880 class_sethelpsymbol(touchout_class, gensym("midi"));
881}
882
883/* -------------------------- polytouch -------------------------- */
884
885static t_class *polytouchout_class;
886
887typedef struct _polytouchout
888{
889 t_object x_obj;
890 t_float x_channel;
891 t_float x_pitch;
892} t_polytouchout;
893
894static void *polytouchout_new(t_floatarg channel)
895{
896 t_polytouchout *x = (t_polytouchout *)pd_new(polytouchout_class);
897 if (channel <= 0) channel = 1;
898 x->x_channel = channel;
899 x->x_pitch = 0;
900 floatinlet_new(&x->x_obj, &x->x_pitch);
901 floatinlet_new(&x->x_obj, &x->x_channel);
902 return (x);
903}
904
905static void polytouchout_float(t_polytouchout *x, t_float n)
906{
907 int binchan = x->x_channel - 1;
908 if (binchan < 0)
909 binchan = 0;
910 outmidi_polyaftertouch((binchan >> 4), (binchan & 15), x->x_pitch, n);
911}
912
913static void polytouchout_setup(void)
914{
915 polytouchout_class = class_new(gensym("polytouchout"),
916 (t_newmethod)polytouchout_new, 0,
917 sizeof(t_polytouchout), 0, A_DEFFLOAT, 0);
918 class_addfloat(polytouchout_class, polytouchout_float);
919 class_sethelpsymbol(polytouchout_class, gensym("midi"));
920}
921
922/* -------------------------- makenote -------------------------- */
923
924static t_class *makenote_class;
925
926typedef struct _hang
927{
928 t_clock *h_clock;
929 struct _hang *h_next;
930 t_float h_pitch;
931 struct _makenote *h_owner;
932} t_hang;
933
934typedef struct _makenote
935{
936 t_object x_obj;
937 t_float x_velo;
938 t_float x_dur;
939 t_outlet *x_pitchout;
940 t_outlet *x_velout;
941 t_hang *x_hang;
942} t_makenote;
943
944static void *makenote_new(t_floatarg velo, t_floatarg dur)
945{
946 t_makenote *x = (t_makenote *)pd_new(makenote_class);
947 x->x_velo = velo;
948 x->x_dur = dur;
949 floatinlet_new(&x->x_obj, &x->x_velo);
950 floatinlet_new(&x->x_obj, &x->x_dur);
951 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
952 x->x_velout = outlet_new(&x->x_obj, &s_float);
953 x->x_hang = 0;
954 return (x);
955}
956
957static void makenote_tick(t_hang *hang)
958{
959 t_makenote *x = hang->h_owner;
960 t_hang *h2, *h3;
961 outlet_float(x->x_velout, 0);
962 outlet_float(x->x_pitchout, hang->h_pitch);
963 if (x->x_hang == hang) x->x_hang = hang->h_next;
964 else for (h2 = x->x_hang; h3 = h2->h_next; h2 = h3)
965 {
966 if (h3 == hang)
967 {
968 h2->h_next = h3->h_next;
969 break;
970 }
971 }
972 clock_free(hang->h_clock);
973 freebytes(hang, sizeof(*hang));
974}
975
976static void makenote_float(t_makenote *x, t_float f)
977{
978 t_hang *hang;
979 if (!x->x_velo) return;
980 outlet_float(x->x_velout, x->x_velo);
981 outlet_float(x->x_pitchout, f);
982 hang = (t_hang *)getbytes(sizeof *hang);
983 hang->h_next = x->x_hang;
984 x->x_hang = hang;
985 hang->h_pitch = f;
986 hang->h_owner = x;
987 hang->h_clock = clock_new(hang, (t_method)makenote_tick);
988 clock_delay(hang->h_clock, (x->x_dur >= 0 ? x->x_dur : 0));
989}
990
991static void makenote_stop(t_makenote *x)
992{
993 t_hang *hang;
994 while (hang = x->x_hang)
995 {
996 outlet_float(x->x_velout, 0);
997 outlet_float(x->x_pitchout, hang->h_pitch);
998 x->x_hang = hang->h_next;
999 clock_free(hang->h_clock);
1000 freebytes(hang, sizeof(*hang));
1001 }
1002}
1003
1004static void makenote_clear(t_makenote *x)
1005{
1006 t_hang *hang;
1007 while (hang = x->x_hang)
1008 {
1009 x->x_hang = hang->h_next;
1010 clock_free(hang->h_clock);
1011 freebytes(hang, sizeof(*hang));
1012 }
1013}
1014
1015static void makenote_setup(void)
1016{
1017 makenote_class = class_new(gensym("makenote"),
1018 (t_newmethod)makenote_new, (t_method)makenote_clear,
1019 sizeof(t_makenote), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
1020 class_addfloat(makenote_class, makenote_float);
1021 class_addmethod(makenote_class, (t_method)makenote_stop, gensym("stop"),
1022 0);
1023 class_addmethod(makenote_class, (t_method)makenote_clear, gensym("clear"),
1024 0);
1025}
1026
1027/* -------------------------- stripnote -------------------------- */
1028
1029static t_class *stripnote_class;
1030
1031typedef struct _stripnote
1032{
1033 t_object x_obj;
1034 t_float x_velo;
1035 t_outlet *x_pitchout;
1036 t_outlet *x_velout;
1037} t_stripnote;
1038
1039static void *stripnote_new(void )
1040{
1041 t_stripnote *x = (t_stripnote *)pd_new(stripnote_class);
1042 floatinlet_new(&x->x_obj, &x->x_velo);
1043 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
1044 x->x_velout = outlet_new(&x->x_obj, &s_float);
1045 return (x);
1046}
1047
1048static void stripnote_float(t_stripnote *x, t_float f)
1049{
1050 t_hang *hang;
1051 if (!x->x_velo) return;
1052 outlet_float(x->x_velout, x->x_velo);
1053 outlet_float(x->x_pitchout, f);
1054}
1055
1056static void stripnote_setup(void)
1057{
1058 stripnote_class = class_new(gensym("stripnote"),
1059 (t_newmethod)stripnote_new, 0, sizeof(t_stripnote), 0, 0);
1060 class_addfloat(stripnote_class, stripnote_float);
1061}
1062
1063/* -------------------------- poly -------------------------- */
1064
1065static t_class *poly_class;
1066
1067typedef struct voice
1068{
1069 float v_pitch;
1070 int v_used;
1071 unsigned long v_serial;
1072} t_voice;
1073
1074typedef struct poly
1075{
1076 t_object x_obj;
1077 int x_n;
1078 t_voice *x_vec;
1079 float x_vel;
1080 t_outlet *x_pitchout;
1081 t_outlet *x_velout;
1082 unsigned long x_serial;
1083 int x_steal;
1084} t_poly;
1085
1086static void *poly_new(float fnvoice, float fsteal)
1087{
1088 int i, n = fnvoice;
1089 t_poly *x = (t_poly *)pd_new(poly_class);
1090 t_voice *v;
1091 if (n < 1) n = 1;
1092 x->x_n = n;
1093 x->x_vec = (t_voice *)getbytes(n * sizeof(*x->x_vec));
1094 for (v = x->x_vec, i = n; i--; v++)
1095 v->v_pitch = v->v_used = v->v_serial = 0;
1096 x->x_vel = 0;
1097 x->x_steal = (fsteal != 0);
1098 floatinlet_new(&x->x_obj, &x->x_vel);
1099 outlet_new(&x->x_obj, &s_float);
1100 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
1101 x->x_velout = outlet_new(&x->x_obj, &s_float);
1102 x->x_serial = 0;
1103 return (x);
1104}
1105
1106static void poly_float(t_poly *x, t_float f)
1107{
1108 int i;
1109 t_voice *v;
1110 t_voice *firston, *firstoff;
1111 unsigned int serialon, serialoff, onindex = 0, offindex = 0;
1112 if (x->x_vel > 0)
1113 {
1114 /* note on. Look for a vacant voice */
1115 for (v = x->x_vec, i = 0, firston = firstoff = 0,
1116 serialon = serialoff = 0xffffffff; i < x->x_n; v++, i++)
1117 {
1118 if (v->v_used && v->v_serial < serialon)
1119 firston = v, serialon = v->v_serial, onindex = i;
1120 else if (!v->v_used && v->v_serial < serialoff)
1121 firstoff = v, serialoff = v->v_serial, offindex = i;
1122 }
1123 if (firstoff)
1124 {
1125 outlet_float(x->x_velout, x->x_vel);
1126 outlet_float(x->x_pitchout, firstoff->v_pitch = f);
1127 outlet_float(x->x_obj.ob_outlet, offindex+1);
1128 firstoff->v_used = 1;
1129 firstoff->v_serial = x->x_serial++;
1130 }
1131 /* if none, steal one */
1132 else if (firston && x->x_steal)
1133 {
1134 outlet_float(x->x_velout, 0);
1135 outlet_float(x->x_pitchout, firston->v_pitch);
1136 outlet_float(x->x_obj.ob_outlet, onindex+1);
1137 outlet_float(x->x_velout, x->x_vel);
1138 outlet_float(x->x_pitchout, firston->v_pitch = f);
1139 outlet_float(x->x_obj.ob_outlet, onindex+1);
1140 firston->v_serial = x->x_serial++;
1141 }
1142 }
1143 else /* note off. Turn off oldest match */
1144 {
1145 for (v = x->x_vec, i = 0, firston = 0, serialon = 0xffffffff;
1146 i < x->x_n; v++, i++)
1147 if (v->v_used && v->v_pitch == f && v->v_serial < serialon)
1148 firston = v, serialon = v->v_serial, onindex = i;
1149 if (firston)
1150 {
1151 firston->v_used = 0;
1152 firston->v_serial = x->x_serial++;
1153 outlet_float(x->x_velout, 0);
1154 outlet_float(x->x_pitchout, firston->v_pitch);
1155 outlet_float(x->x_obj.ob_outlet, onindex+1);
1156 }
1157 }
1158}
1159
1160static void poly_stop(t_poly *x)
1161{
1162 int i;
1163 t_voice *v;
1164 for (i = 0, v = x->x_vec; i < x->x_n; i++, v++)
1165 if (v->v_used)
1166 {
1167 outlet_float(x->x_velout, 0L);
1168 outlet_float(x->x_pitchout, v->v_pitch);
1169 outlet_float(x->x_obj.ob_outlet, i+1);
1170 v->v_used = 0;
1171 v->v_serial = x->x_serial++;
1172 }
1173}
1174
1175static void poly_clear(t_poly *x)
1176{
1177 int i;
1178 t_voice *v;
1179 for (v = x->x_vec, i = x->x_n; i--; v++) v->v_used = v->v_serial = 0;
1180}
1181
1182static void poly_free(t_poly *x)
1183{
1184 freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec));
1185}
1186
1187static void poly_setup(void)
1188{
1189 poly_class = class_new(gensym("poly"),
1190 (t_newmethod)poly_new, (t_method)poly_clear,
1191 sizeof(t_poly), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
1192 class_addfloat(poly_class, poly_float);
1193 class_addmethod(poly_class, (t_method)poly_stop, gensym("stop"), 0);
1194 class_addmethod(poly_class, (t_method)poly_clear, gensym("clear"), 0);
1195}
1196
1197/* -------------------------- bag -------------------------- */
1198
1199static t_class *bag_class;
1200
1201typedef struct _bagelem
1202{
1203 struct _bagelem *e_next;
1204 t_float e_value;
1205} t_bagelem;
1206
1207typedef struct _bag
1208{
1209 t_object x_obj;
1210 t_float x_velo;
1211 t_bagelem *x_first;
1212} t_bag;
1213
1214static void *bag_new(void )
1215{
1216 t_bag *x = (t_bag *)pd_new(bag_class);
1217 x->x_velo = 0;
1218 floatinlet_new(&x->x_obj, &x->x_velo);
1219 outlet_new(&x->x_obj, &s_float);
1220 x->x_first = 0;
1221 return (x);
1222}
1223
1224static void bag_float(t_bag *x, t_float f)
1225{
1226 t_bagelem *bagelem, *e2, *e3;
1227 if (x->x_velo != 0)
1228 {
1229 bagelem = (t_bagelem *)getbytes(sizeof *bagelem);
1230 bagelem->e_next = 0;
1231 bagelem->e_value = f;
1232 if (!x->x_first) x->x_first = bagelem;
1233 else /* LATER replace with a faster algorithm */
1234 {
1235 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
1236 ;
1237 e2->e_next = bagelem;
1238 }
1239 }
1240 else
1241 {
1242 if (!x->x_first) return;
1243 if (x->x_first->e_value == f)
1244 {
1245 bagelem = x->x_first;
1246 x->x_first = x->x_first->e_next;
1247 freebytes(bagelem, sizeof(*bagelem));
1248 return;
1249 }
1250 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
1251 if (e3->e_value == f)
1252 {
1253 e2->e_next = e3->e_next;
1254 freebytes(e3, sizeof(*e3));
1255 return;
1256 }
1257 }
1258}
1259
1260static void bag_flush(t_bag *x)
1261{
1262 t_bagelem *bagelem;
1263 while (bagelem = x->x_first)
1264 {
1265 outlet_float(x->x_obj.ob_outlet, bagelem->e_value);
1266 x->x_first = bagelem->e_next;
1267 freebytes(bagelem, sizeof(*bagelem));
1268 }
1269}
1270
1271static void bag_clear(t_bag *x)
1272{
1273 t_bagelem *bagelem;
1274 while (bagelem = x->x_first)
1275 {
1276 x->x_first = bagelem->e_next;
1277 freebytes(bagelem, sizeof(*bagelem));
1278 }
1279}
1280
1281static void bag_setup(void)
1282{
1283 bag_class = class_new(gensym("bag"),
1284 (t_newmethod)bag_new, (t_method)bag_clear,
1285 sizeof(t_bag), 0, 0);
1286 class_addfloat(bag_class, bag_float);
1287 class_addmethod(bag_class, (t_method)bag_flush, gensym("flush"), 0);
1288 class_addmethod(bag_class, (t_method)bag_clear, gensym("clear"), 0);
1289}
1290
1291void x_midi_setup(void)
1292{
1293 midiin_setup();
1294 midirealtimein_setup();
1295 notein_setup();
1296 ctlin_setup();
1297 pgmin_setup();
1298 bendin_setup();
1299 touchin_setup();
1300 polytouchin_setup();
1301 midiclkin_setup();
1302 midiout_setup();
1303 noteout_setup();
1304 ctlout_setup();
1305 pgmout_setup();
1306 bendout_setup();
1307 touchout_setup();
1308 polytouchout_setup();
1309 makenote_setup();
1310 stripnote_setup();
1311 poly_setup();
1312 bag_setup();
1313}
1314