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.c1312
1 files changed, 0 insertions, 1312 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_midi.c b/apps/plugins/pdbox/PDa/src/x_midi.c
index a71000f121..e9f3601057 100644
--- a/apps/plugins/pdbox/PDa/src/x_midi.c
+++ b/apps/plugins/pdbox/PDa/src/x_midi.c
@@ -1311,1316 +1311,4 @@ void x_midi_setup(void)
1311 poly_setup(); 1311 poly_setup();
1312 bag_setup(); 1312 bag_setup();
1313} 1313}
1314/* Copyright (c) 1997-2001 Miller Puckette and others.
1315* For information on usage and redistribution, and for a DISCLAIMER OF ALL
1316* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1317
1318/* MIDI. */
1319
1320#include "m_pd.h"
1321void outmidi_noteon(int portno, int channel, int pitch, int velo);
1322void outmidi_controlchange(int portno, int channel, int ctlno, int value);
1323void outmidi_programchange(int portno, int channel, int value);
1324void outmidi_pitchbend(int portno, int channel, int value);
1325void outmidi_aftertouch(int portno, int channel, int value);
1326void outmidi_polyaftertouch(int portno, int channel, int pitch, int value);
1327void outmidi_mclk(int portno);
1328
1329/* ----------------------- midiin and sysexin ------------------------- */
1330
1331static t_symbol *midiin_sym, *sysexin_sym;
1332
1333static t_class *midiin_class, *sysexin_class;
1334
1335typedef struct _midiin
1336{
1337 t_object x_obj;
1338 t_outlet *x_outlet1;
1339 t_outlet *x_outlet2;
1340} t_midiin;
1341
1342static void *midiin_new( void)
1343{
1344 t_midiin *x = (t_midiin *)pd_new(midiin_class);
1345 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1346 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1347 pd_bind(&x->x_obj.ob_pd, midiin_sym);
1348#ifndef __linux__
1349 pd_error(x, "midiin: works under Linux only");
1350#endif
1351 return (x);
1352}
1353
1354static void midiin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av)
1355{
1356 outlet_float(x->x_outlet2, atom_getfloatarg(1, ac, av) + 1);
1357 outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
1358}
1359
1360static void midiin_free(t_midiin *x)
1361{
1362 pd_unbind(&x->x_obj.ob_pd, midiin_sym);
1363}
1364
1365static void *sysexin_new( void)
1366{
1367 t_midiin *x = (t_midiin *)pd_new(sysexin_class);
1368 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1369 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1370 pd_bind(&x->x_obj.ob_pd, sysexin_sym);
1371#ifndef __linux__
1372 pd_error(x, "sysexin: works under Linux only");
1373#endif
1374 return (x);
1375}
1376
1377static void sysexin_free(t_midiin *x)
1378{
1379 pd_unbind(&x->x_obj.ob_pd, sysexin_sym);
1380}
1381
1382static void midiin_setup(void)
1383{
1384 midiin_class = class_new(gensym("midiin"), (t_newmethod)midiin_new,
1385 (t_method)midiin_free, sizeof(t_midiin),
1386 CLASS_NOINLET, A_DEFFLOAT, 0);
1387 class_addlist(midiin_class, midiin_list);
1388 class_sethelpsymbol(midiin_class, gensym("midi"));
1389 midiin_sym = gensym("#midiin");
1390
1391 sysexin_class = class_new(gensym("sysexin"), (t_newmethod)sysexin_new,
1392 (t_method)sysexin_free, sizeof(t_midiin),
1393 CLASS_NOINLET, A_DEFFLOAT, 0);
1394 class_addlist(sysexin_class, midiin_list);
1395 class_sethelpsymbol(sysexin_class, gensym("midi"));
1396 sysexin_sym = gensym("#sysexin");
1397}
1398
1399void inmidi_byte(int portno, int byte)
1400{
1401 t_atom at[2];
1402 if (midiin_sym->s_thing)
1403 {
1404 SETFLOAT(at, byte);
1405 SETFLOAT(at+1, portno + 1);
1406 pd_list(midiin_sym->s_thing, 0, 2, at);
1407 }
1408}
1409
1410void inmidi_sysex(int portno, int byte)
1411{
1412 t_atom at[2];
1413 if (sysexin_sym->s_thing)
1414 {
1415 SETFLOAT(at, byte);
1416 SETFLOAT(at+1, portno + 1);
1417 pd_list(sysexin_sym->s_thing, 0, 2, at);
1418 }
1419}
1420
1421/* ----------------------- notein ------------------------- */
1422
1423static t_symbol *notein_sym;
1424
1425static t_class *notein_class;
1426
1427typedef struct _notein
1428{
1429 t_object x_obj;
1430 t_float x_channel;
1431 t_outlet *x_outlet1;
1432 t_outlet *x_outlet2;
1433 t_outlet *x_outlet3;
1434} t_notein;
1435
1436static void *notein_new(t_floatarg f)
1437{
1438 t_notein *x = (t_notein *)pd_new(notein_class);
1439 x->x_channel = f;
1440 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1441 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1442 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
1443 pd_bind(&x->x_obj.ob_pd, notein_sym);
1444 return (x);
1445}
1446
1447static void notein_list(t_notein *x, t_symbol *s, int argc, t_atom *argv)
1448{
1449 float pitch = atom_getfloatarg(0, argc, argv);
1450 float velo = atom_getfloatarg(1, argc, argv);
1451 float channel = atom_getfloatarg(2, argc, argv);
1452 if (x->x_channel != 0)
1453 {
1454 if (channel != x->x_channel) return;
1455 outlet_float(x->x_outlet2, velo);
1456 outlet_float(x->x_outlet1, pitch);
1457 }
1458 else
1459 {
1460 outlet_float(x->x_outlet3, channel);
1461 outlet_float(x->x_outlet2, velo);
1462 outlet_float(x->x_outlet1, pitch);
1463 }
1464}
1465
1466static void notein_free(t_notein *x)
1467{
1468 pd_unbind(&x->x_obj.ob_pd, notein_sym);
1469}
1470
1471static void notein_setup(void)
1472{
1473 notein_class = class_new(gensym("notein"), (t_newmethod)notein_new,
1474 (t_method)notein_free, sizeof(t_notein), CLASS_NOINLET, A_DEFFLOAT, 0);
1475 class_addlist(notein_class, notein_list);
1476 class_sethelpsymbol(notein_class, gensym("midi"));
1477 notein_sym = gensym("#notein");
1478}
1479
1480void inmidi_noteon(int portno, int channel, int pitch, int velo)
1481{
1482 if (notein_sym->s_thing)
1483 {
1484 t_atom at[3];
1485 SETFLOAT(at, pitch);
1486 SETFLOAT(at+1, velo);
1487 SETFLOAT(at+2, (channel + (portno << 4) + 1));
1488 pd_list(notein_sym->s_thing, &s_list, 3, at);
1489 }
1490}
1491
1492/* ----------------------- ctlin ------------------------- */
1493
1494static t_symbol *ctlin_sym;
1495
1496static t_class *ctlin_class;
1497
1498typedef struct _ctlin
1499{
1500 t_object x_obj;
1501 t_float x_channel;
1502 t_float x_ctlno;
1503 t_outlet *x_outlet1;
1504 t_outlet *x_outlet2;
1505 t_outlet *x_outlet3;
1506} t_ctlin;
1507
1508static void *ctlin_new(t_symbol *s, int argc, t_atom *argv)
1509{
1510 int ctlno, channel;
1511 t_ctlin *x = (t_ctlin *)pd_new(ctlin_class);
1512 if (!argc) ctlno = -1;
1513 else ctlno = atom_getfloatarg(0, argc, argv);
1514 channel = atom_getfloatarg(1, argc, argv);
1515 x->x_channel = channel;
1516 x->x_ctlno = ctlno;
1517 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1518 if (!channel)
1519 {
1520 if (x->x_ctlno < 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1521 x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
1522 }
1523 pd_bind(&x->x_obj.ob_pd, ctlin_sym);
1524 return (x);
1525}
1526
1527static void ctlin_list(t_ctlin *x, t_symbol *s, int argc, t_atom *argv)
1528{
1529 t_float ctlnumber = atom_getfloatarg(0, argc, argv);
1530 t_float value = atom_getfloatarg(1, argc, argv);
1531 t_float channel = atom_getfloatarg(2, argc, argv);
1532 if (x->x_ctlno >= 0 && x->x_ctlno != ctlnumber) return;
1533 if (x->x_channel > 0 && x->x_channel != channel) return;
1534 if (x->x_channel == 0) outlet_float(x->x_outlet3, channel);
1535 if (x->x_ctlno < 0) outlet_float(x->x_outlet2, ctlnumber);
1536 outlet_float(x->x_outlet1, value);
1537}
1538
1539static void ctlin_free(t_ctlin *x)
1540{
1541 pd_unbind(&x->x_obj.ob_pd, ctlin_sym);
1542}
1543
1544static void ctlin_setup(void)
1545{
1546 ctlin_class = class_new(gensym("ctlin"), (t_newmethod)ctlin_new,
1547 (t_method)ctlin_free, sizeof(t_ctlin),
1548 CLASS_NOINLET, A_GIMME, 0);
1549 class_addlist(ctlin_class, ctlin_list);
1550 class_sethelpsymbol(ctlin_class, gensym("midi"));
1551 ctlin_sym = gensym("#ctlin");
1552}
1553
1554void inmidi_controlchange(int portno, int channel, int ctlnumber, int value)
1555{
1556 if (ctlin_sym->s_thing)
1557 {
1558 t_atom at[3];
1559 SETFLOAT(at, ctlnumber);
1560 SETFLOAT(at+1, value);
1561 SETFLOAT(at+2, (channel + (portno << 4) + 1));
1562 pd_list(ctlin_sym->s_thing, &s_list, 3, at);
1563 }
1564}
1565
1566/* ----------------------- pgmin ------------------------- */
1567
1568static t_symbol *pgmin_sym;
1569
1570static t_class *pgmin_class;
1571
1572typedef struct _pgmin
1573{
1574 t_object x_obj;
1575 t_float x_channel;
1576 t_outlet *x_outlet1;
1577 t_outlet *x_outlet2;
1578} t_pgmin;
1579
1580static void *pgmin_new(t_floatarg f)
1581{
1582 t_pgmin *x = (t_pgmin *)pd_new(pgmin_class);
1583 x->x_channel = f;
1584 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1585 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1586 pd_bind(&x->x_obj.ob_pd, pgmin_sym);
1587 return (x);
1588}
1589
1590static void pgmin_list(t_pgmin *x, t_symbol *s, int argc, t_atom *argv)
1591{
1592 float value = atom_getfloatarg(0, argc, argv);
1593 float channel = atom_getfloatarg(1, argc, argv);
1594 if (x->x_channel != 0)
1595 {
1596 if (channel != x->x_channel) return;
1597 outlet_float(x->x_outlet1, value);
1598 }
1599 else
1600 {
1601 outlet_float(x->x_outlet2, channel);
1602 outlet_float(x->x_outlet1, value);
1603 }
1604}
1605
1606static void pgmin_free(t_pgmin *x)
1607{
1608 pd_unbind(&x->x_obj.ob_pd, pgmin_sym);
1609}
1610
1611static void pgmin_setup(void)
1612{
1613 pgmin_class = class_new(gensym("pgmin"), (t_newmethod)pgmin_new,
1614 (t_method)pgmin_free, sizeof(t_pgmin),
1615 CLASS_NOINLET, A_DEFFLOAT, 0);
1616 class_addlist(pgmin_class, pgmin_list);
1617 class_sethelpsymbol(pgmin_class, gensym("midi"));
1618 pgmin_sym = gensym("#pgmin");
1619}
1620
1621void inmidi_programchange(int portno, int channel, int value)
1622{
1623 if (pgmin_sym->s_thing)
1624 {
1625 t_atom at[2];
1626 SETFLOAT(at, value + 1);
1627 SETFLOAT(at+1, (channel + (portno << 4) + 1));
1628 pd_list(pgmin_sym->s_thing, &s_list, 2, at);
1629 }
1630}
1631
1632/* ----------------------- bendin ------------------------- */
1633
1634static t_symbol *bendin_sym;
1635
1636static t_class *bendin_class;
1637
1638typedef struct _bendin
1639{
1640 t_object x_obj;
1641 t_float x_channel;
1642 t_outlet *x_outlet1;
1643 t_outlet *x_outlet2;
1644} t_bendin;
1645
1646static void *bendin_new(t_floatarg f)
1647{
1648 t_bendin *x = (t_bendin *)pd_new(bendin_class);
1649 x->x_channel = f;
1650 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1651 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1652 pd_bind(&x->x_obj.ob_pd, bendin_sym);
1653 return (x);
1654}
1655
1656static void bendin_list(t_bendin *x, t_symbol *s, int argc, t_atom *argv)
1657{
1658 t_float value = atom_getfloatarg(0, argc, argv);
1659 t_float channel = atom_getfloatarg(1, argc, argv);
1660 if (x->x_channel != 0)
1661 {
1662 if (channel != x->x_channel) return;
1663 outlet_float(x->x_outlet1, value);
1664 }
1665 else
1666 {
1667 outlet_float(x->x_outlet2, channel);
1668 outlet_float(x->x_outlet1, value);
1669 }
1670}
1671
1672static void bendin_free(t_bendin *x)
1673{
1674 pd_unbind(&x->x_obj.ob_pd, bendin_sym);
1675}
1676
1677static void bendin_setup(void)
1678{
1679 bendin_class = class_new(gensym("bendin"), (t_newmethod)bendin_new,
1680 (t_method)bendin_free, sizeof(t_bendin), CLASS_NOINLET, A_DEFFLOAT, 0);
1681 class_addlist(bendin_class, bendin_list);
1682 class_sethelpsymbol(bendin_class, gensym("midi"));
1683 bendin_sym = gensym("#bendin");
1684}
1685
1686void inmidi_pitchbend(int portno, int channel, int value)
1687{
1688 if (bendin_sym->s_thing)
1689 {
1690 t_atom at[2];
1691 SETFLOAT(at, value);
1692 SETFLOAT(at+1, (channel + (portno << 4) + 1));
1693 pd_list(bendin_sym->s_thing, &s_list, 2, at);
1694 }
1695}
1696
1697/* ----------------------- touchin ------------------------- */
1698
1699static t_symbol *touchin_sym;
1700
1701static t_class *touchin_class;
1702
1703typedef struct _touchin
1704{
1705 t_object x_obj;
1706 t_float x_channel;
1707 t_outlet *x_outlet1;
1708 t_outlet *x_outlet2;
1709} t_touchin;
1710
1711static void *touchin_new(t_floatarg f)
1712{
1713 t_touchin *x = (t_touchin *)pd_new(touchin_class);
1714 x->x_channel = f;
1715 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1716 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1717 pd_bind(&x->x_obj.ob_pd, touchin_sym);
1718 return (x);
1719}
1720
1721static void touchin_list(t_touchin *x, t_symbol *s, int argc, t_atom *argv)
1722{
1723 t_float value = atom_getfloatarg(0, argc, argv);
1724 t_float channel = atom_getfloatarg(1, argc, argv);
1725 if (x->x_channel)
1726 {
1727 if (channel != x->x_channel) return;
1728 outlet_float(x->x_outlet1, value);
1729 }
1730 else
1731 {
1732 outlet_float(x->x_outlet2, channel);
1733 outlet_float(x->x_outlet1, value);
1734 }
1735}
1736
1737static void touchin_free(t_touchin *x)
1738{
1739 pd_unbind(&x->x_obj.ob_pd, touchin_sym);
1740}
1741
1742static void touchin_setup(void)
1743{
1744 touchin_class = class_new(gensym("touchin"), (t_newmethod)touchin_new,
1745 (t_method)touchin_free, sizeof(t_touchin),
1746 CLASS_NOINLET, A_DEFFLOAT, 0);
1747 class_addlist(touchin_class, touchin_list);
1748 class_sethelpsymbol(touchin_class, gensym("midi"));
1749 touchin_sym = gensym("#touchin");
1750}
1751
1752void inmidi_aftertouch(int portno, int channel, int value)
1753{
1754 if (touchin_sym->s_thing)
1755 {
1756 t_atom at[2];
1757 SETFLOAT(at, value);
1758 SETFLOAT(at+1, (channel + (portno << 4) + 1));
1759 pd_list(touchin_sym->s_thing, &s_list, 2, at);
1760 }
1761}
1762
1763/* ----------------------- polytouchin ------------------------- */
1764
1765static t_symbol *polytouchin_sym;
1766
1767static t_class *polytouchin_class;
1768
1769typedef struct _polytouchin
1770{
1771 t_object x_obj;
1772 t_float x_channel;
1773 t_outlet *x_outlet1;
1774 t_outlet *x_outlet2;
1775 t_outlet *x_outlet3;
1776} t_polytouchin;
1777
1778static void *polytouchin_new(t_floatarg f)
1779{
1780 t_polytouchin *x = (t_polytouchin *)pd_new(polytouchin_class);
1781 x->x_channel = f;
1782 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1783 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1784 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
1785 pd_bind(&x->x_obj.ob_pd, polytouchin_sym);
1786 return (x);
1787}
1788
1789static void polytouchin_list(t_polytouchin *x, t_symbol *s, int argc,
1790 t_atom *argv)
1791{
1792 t_float pitch = atom_getfloatarg(0, argc, argv);
1793 t_float value = atom_getfloatarg(1, argc, argv);
1794 t_float channel = atom_getfloatarg(2, argc, argv);
1795 if (x->x_channel != 0)
1796 {
1797 if (channel != x->x_channel) return;
1798 outlet_float(x->x_outlet2, pitch);
1799 outlet_float(x->x_outlet1, value);
1800 }
1801 else
1802 {
1803 outlet_float(x->x_outlet3, channel);
1804 outlet_float(x->x_outlet2, pitch);
1805 outlet_float(x->x_outlet1, value);
1806 }
1807}
1808
1809static void polytouchin_free(t_polytouchin *x)
1810{
1811 pd_unbind(&x->x_obj.ob_pd, polytouchin_sym);
1812}
1813
1814static void polytouchin_setup(void)
1815{
1816 polytouchin_class = class_new(gensym("polytouchin"),
1817 (t_newmethod)polytouchin_new, (t_method)polytouchin_free,
1818 sizeof(t_polytouchin), CLASS_NOINLET, A_DEFFLOAT, 0);
1819 class_addlist(polytouchin_class, polytouchin_list);
1820 class_sethelpsymbol(polytouchin_class, gensym("midi"));
1821 polytouchin_sym = gensym("#polytouchin");
1822}
1823
1824void inmidi_polyaftertouch(int portno, int channel, int pitch, int value)
1825{
1826 if (polytouchin_sym->s_thing)
1827 {
1828 t_atom at[3];
1829 SETFLOAT(at, pitch);
1830 SETFLOAT(at+1, value);
1831 SETFLOAT(at+2, (channel + (portno << 4) + 1));
1832 pd_list(polytouchin_sym->s_thing, &s_list, 3, at);
1833 }
1834}
1835
1836/*----------------------- midiclkin--(midi F8 message )---------------------*/
1837static t_symbol *midiclkin_sym;
1838
1839static t_class *midiclkin_class;
1840
1841
1842typedef struct _midiclkin
1843{
1844 t_object x_obj;
1845 t_outlet *x_outlet1;
1846 t_outlet *x_outlet2;
1847} t_midiclkin;
1848
1849static void *midiclkin_new(t_floatarg f)
1850{
1851 t_midiclkin *x = (t_midiclkin *)pd_new(midiclkin_class);
1852 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1853 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1854 pd_bind(&x->x_obj.ob_pd, midiclkin_sym);
1855 return (x);
1856}
1857
1858static void midiclkin_list(t_midiclkin *x, t_symbol *s, int argc, t_atom *argv)
1859{
1860 float value = atom_getfloatarg(0, argc, argv);
1861 float count = atom_getfloatarg(1, argc, argv);
1862 outlet_float(x->x_outlet2, count);
1863 outlet_float(x->x_outlet1, value);
1864}
1865
1866static void midiclkin_free(t_midiclkin *x)
1867{
1868 pd_unbind(&x->x_obj.ob_pd, midiclkin_sym);
1869}
1870
1871static void midiclkin_setup(void)
1872{
1873 midiclkin_class = class_new(gensym("midiclkin"),
1874 (t_newmethod)midiclkin_new, (t_method)midiclkin_free,
1875 sizeof(t_midiclkin), CLASS_NOINLET, A_DEFFLOAT, 0);
1876 class_addlist(midiclkin_class, midiclkin_list);
1877 class_sethelpsymbol(midiclkin_class, gensym("midi"));
1878 midiclkin_sym = gensym("#midiclkin");
1879}
1880
1881void inmidi_clk(double timing)
1882{
1883
1884 static float prev = 0;
1885 static float count = 0;
1886 float cur,diff;
1887
1888 if (midiclkin_sym->s_thing)
1889 {
1890 t_atom at[2];
1891 diff =timing - prev;
1892 count++;
1893
1894 if (count == 3)
1895 { /* 24 count per quoter note */
1896 SETFLOAT(at, 1 );
1897 count = 0;
1898 }
1899 else SETFLOAT(at, 0);
1900
1901 SETFLOAT(at+1, diff);
1902 pd_list(midiclkin_sym->s_thing, &s_list, 2, at);
1903 prev = timing;
1904 }
1905}
1906
1907/*----------midirealtimein (midi FA,FB,FC,FF message )-----------------*/
1908
1909static t_symbol *midirealtimein_sym;
1910
1911static t_class *midirealtimein_class;
1912
1913typedef struct _midirealtimein
1914{
1915 t_object x_obj;
1916 t_outlet *x_outlet1;
1917 t_outlet *x_outlet2;
1918} t_midirealtimein;
1919
1920static void *midirealtimein_new( void)
1921{
1922 t_midirealtimein *x = (t_midirealtimein *)pd_new(midirealtimein_class);
1923 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
1924 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1925 pd_bind(&x->x_obj.ob_pd, midirealtimein_sym);
1926#ifndef MSW
1927 pd_error(x, "midirealtimein: works under MSW only");
1928#endif
1929 return (x);
1930}
1931
1932static void midirealtimein_list(t_midirealtimein *x, t_symbol *s,
1933 int argc, t_atom *argv)
1934{
1935 float portno = atom_getfloatarg(0, argc, argv);
1936 float byte = atom_getfloatarg(1, argc, argv);
1937
1938 outlet_float(x->x_outlet2, portno);
1939 outlet_float(x->x_outlet1, byte);
1940}
1941
1942static void midirealtimein_free(t_midirealtimein *x)
1943{
1944 pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym);
1945}
1946
1947static void midirealtimein_setup(void)
1948{
1949 midirealtimein_class = class_new(gensym("midirealtimein"),
1950 (t_newmethod)midirealtimein_new, (t_method)midirealtimein_free,
1951 sizeof(t_midirealtimein), CLASS_NOINLET, A_DEFFLOAT, 0);
1952 class_addlist(midirealtimein_class, midirealtimein_list);
1953 class_sethelpsymbol(midirealtimein_class, gensym("midi"));
1954 midirealtimein_sym = gensym("#midirealtimein");
1955}
1956
1957void inmidi_realtimein(int portno, int SysMsg)
1958{
1959 if (midirealtimein_sym->s_thing)
1960 {
1961 t_atom at[2];
1962 SETFLOAT(at, portno);
1963 SETFLOAT(at+1, SysMsg);
1964 pd_list(midirealtimein_sym->s_thing, &s_list, 1, at);
1965 }
1966}
1967
1968/* -------------------------- midiout -------------------------- */
1969
1970static t_class *midiout_class;
1971
1972void sys_putmidibyte(int portno, int byte);
1973
1974typedef struct _midiout
1975{
1976 t_object x_obj;
1977 t_float x_portno;
1978} t_midiout;
1979
1980static void *midiout_new(t_floatarg portno)
1981{
1982 t_midiout *x = (t_midiout *)pd_new(midiout_class);
1983 if (portno <= 0) portno = 1;
1984 x->x_portno = portno;
1985 floatinlet_new(&x->x_obj, &x->x_portno);
1986#ifdef __irix__
1987 post("midiout: unimplemented in IRIX");
1988#endif
1989 return (x);
1990}
1991
1992static void midiout_float(t_midiout *x, t_floatarg f)
1993{
1994 sys_putmidibyte(x->x_portno - 1, f);
1995}
1996
1997static void midiout_setup(void)
1998{
1999 midiout_class = class_new(gensym("midiout"), (t_newmethod)midiout_new, 0,
2000 sizeof(t_midiout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
2001 class_addfloat(midiout_class, midiout_float);
2002 class_sethelpsymbol(midiout_class, gensym("midi"));
2003}
2004
2005/* -------------------------- noteout -------------------------- */
2006
2007static t_class *noteout_class;
2008
2009typedef struct _noteout
2010{
2011 t_object x_obj;
2012 t_float x_velo;
2013 t_float x_channel;
2014} t_noteout;
2015
2016static void *noteout_new(t_floatarg channel)
2017{
2018 t_noteout *x = (t_noteout *)pd_new(noteout_class);
2019 x->x_velo = 0;
2020 if (channel < 1) channel = 1;
2021 x->x_channel = channel;
2022 floatinlet_new(&x->x_obj, &x->x_velo);
2023 floatinlet_new(&x->x_obj, &x->x_channel);
2024 return (x);
2025}
2026
2027static void noteout_float(t_noteout *x, t_float f)
2028{
2029 int binchan = x->x_channel - 1;
2030 if (binchan < 0)
2031 binchan = 0;
2032 outmidi_noteon((binchan >> 4),
2033 (binchan & 15), (int)f, (int)x->x_velo);
2034}
2035
2036static void noteout_setup(void)
2037{
2038 noteout_class = class_new(gensym("noteout"), (t_newmethod)noteout_new, 0,
2039 sizeof(t_noteout), 0, A_DEFFLOAT, 0);
2040 class_addfloat(noteout_class, noteout_float);
2041 class_sethelpsymbol(noteout_class, gensym("midi"));
2042}
2043
2044
2045/* -------------------------- ctlout -------------------------- */
2046
2047static t_class *ctlout_class;
2048
2049typedef struct _ctlout
2050{
2051 t_object x_obj;
2052 t_float x_ctl;
2053 t_float x_channel;
2054} t_ctlout;
2055
2056static void *ctlout_new(t_floatarg ctl, t_floatarg channel)
2057{
2058 t_ctlout *x = (t_ctlout *)pd_new(ctlout_class);
2059 x->x_ctl = ctl;
2060 if (channel <= 0) channel = 1;
2061 x->x_channel = channel;
2062 floatinlet_new(&x->x_obj, &x->x_ctl);
2063 floatinlet_new(&x->x_obj, &x->x_channel);
2064 return (x);
2065}
2066
2067static void ctlout_float(t_ctlout *x, t_float f)
2068{
2069 int binchan = x->x_channel - 1;
2070 if (binchan < 0)
2071 binchan = 0;
2072 outmidi_controlchange((binchan >> 4),
2073 (binchan & 15), (int)(x->x_ctl), (int)f);
2074}
2075
2076static void ctlout_setup(void)
2077{
2078 ctlout_class = class_new(gensym("ctlout"), (t_newmethod)ctlout_new, 0,
2079 sizeof(t_ctlout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
2080 class_addfloat(ctlout_class, ctlout_float);
2081 class_sethelpsymbol(ctlout_class, gensym("midi"));
2082}
2083
2084
2085/* -------------------------- pgmout -------------------------- */
2086
2087static t_class *pgmout_class;
2088
2089typedef struct _pgmout
2090{
2091 t_object x_obj;
2092 t_float x_channel;
2093} t_pgmout;
2094
2095static void *pgmout_new(t_floatarg channel)
2096{
2097 t_pgmout *x = (t_pgmout *)pd_new(pgmout_class);
2098 if (channel <= 0) channel = 1;
2099 x->x_channel = channel;
2100 floatinlet_new(&x->x_obj, &x->x_channel);
2101 return (x);
2102}
2103
2104static void pgmout_float(t_pgmout *x, t_floatarg f)
2105{
2106 int binchan = x->x_channel - 1;
2107 int n = f - 1;
2108 if (binchan < 0)
2109 binchan = 0;
2110 if (n < 0) n = 0;
2111 else if (n > 127) n = 127;
2112 outmidi_programchange((binchan >> 4),
2113 (binchan & 15), n);
2114}
2115
2116static void pgmout_setup(void)
2117{
2118 pgmout_class = class_new(gensym("pgmout"), (t_newmethod)pgmout_new, 0,
2119 sizeof(t_pgmout), 0, A_DEFFLOAT, 0);
2120 class_addfloat(pgmout_class, pgmout_float);
2121 class_sethelpsymbol(pgmout_class, gensym("midi"));
2122}
2123
2124
2125/* -------------------------- bendout -------------------------- */
2126
2127static t_class *bendout_class;
2128
2129typedef struct _bendout
2130{
2131 t_object x_obj;
2132 t_float x_channel;
2133} t_bendout;
2134
2135static void *bendout_new(t_floatarg channel)
2136{
2137 t_bendout *x = (t_bendout *)pd_new(bendout_class);
2138 if (channel <= 0) channel = 1;
2139 x->x_channel = channel;
2140 floatinlet_new(&x->x_obj, &x->x_channel);
2141 return (x);
2142}
2143
2144static void bendout_float(t_bendout *x, t_float f)
2145{
2146 int binchan = x->x_channel - 1;
2147 int n = (int)f + 8192;
2148 if (binchan < 0)
2149 binchan = 0;
2150 outmidi_pitchbend((binchan >> 4), (binchan & 15), n);
2151}
2152
2153static void bendout_setup(void)
2154{
2155 bendout_class = class_new(gensym("bendout"), (t_newmethod)bendout_new, 0,
2156 sizeof(t_bendout), 0, A_DEFFLOAT, 0);
2157 class_addfloat(bendout_class, bendout_float);
2158 class_sethelpsymbol(bendout_class, gensym("midi"));
2159}
2160
2161/* -------------------------- touch -------------------------- */
2162
2163static t_class *touchout_class;
2164
2165typedef struct _touchout
2166{
2167 t_object x_obj;
2168 t_float x_channel;
2169} t_touchout;
2170
2171static void *touchout_new(t_floatarg channel)
2172{
2173 t_touchout *x = (t_touchout *)pd_new(touchout_class);
2174 if (channel <= 0) channel = 1;
2175 x->x_channel = channel;
2176 floatinlet_new(&x->x_obj, &x->x_channel);
2177 return (x);
2178}
2179
2180static void touchout_float(t_touchout *x, t_float f)
2181{
2182 int binchan = x->x_channel - 1;
2183 if (binchan < 0)
2184 binchan = 0;
2185 outmidi_aftertouch((binchan >> 4), (binchan & 15), (int)f);
2186}
2187
2188static void touchout_setup(void)
2189{
2190 touchout_class = class_new(gensym("touchout"), (t_newmethod)touchout_new, 0,
2191 sizeof(t_touchout), 0, A_DEFFLOAT, 0);
2192 class_addfloat(touchout_class, touchout_float);
2193 class_sethelpsymbol(touchout_class, gensym("midi"));
2194}
2195
2196/* -------------------------- polytouch -------------------------- */
2197
2198static t_class *polytouchout_class;
2199
2200typedef struct _polytouchout
2201{
2202 t_object x_obj;
2203 t_float x_channel;
2204 t_float x_pitch;
2205} t_polytouchout;
2206
2207static void *polytouchout_new(t_floatarg channel)
2208{
2209 t_polytouchout *x = (t_polytouchout *)pd_new(polytouchout_class);
2210 if (channel <= 0) channel = 1;
2211 x->x_channel = channel;
2212 x->x_pitch = 0;
2213 floatinlet_new(&x->x_obj, &x->x_pitch);
2214 floatinlet_new(&x->x_obj, &x->x_channel);
2215 return (x);
2216}
2217
2218static void polytouchout_float(t_polytouchout *x, t_float n)
2219{
2220 int binchan = x->x_channel - 1;
2221 if (binchan < 0)
2222 binchan = 0;
2223 outmidi_polyaftertouch((binchan >> 4), (binchan & 15), x->x_pitch, n);
2224}
2225
2226static void polytouchout_setup(void)
2227{
2228 polytouchout_class = class_new(gensym("polytouchout"),
2229 (t_newmethod)polytouchout_new, 0,
2230 sizeof(t_polytouchout), 0, A_DEFFLOAT, 0);
2231 class_addfloat(polytouchout_class, polytouchout_float);
2232 class_sethelpsymbol(polytouchout_class, gensym("midi"));
2233}
2234
2235/* -------------------------- makenote -------------------------- */
2236
2237static t_class *makenote_class;
2238
2239typedef struct _hang
2240{
2241 t_clock *h_clock;
2242 struct _hang *h_next;
2243 t_float h_pitch;
2244 struct _makenote *h_owner;
2245} t_hang;
2246
2247typedef struct _makenote
2248{
2249 t_object x_obj;
2250 t_float x_velo;
2251 t_float x_dur;
2252 t_outlet *x_pitchout;
2253 t_outlet *x_velout;
2254 t_hang *x_hang;
2255} t_makenote;
2256
2257static void *makenote_new(t_floatarg velo, t_floatarg dur)
2258{
2259 t_makenote *x = (t_makenote *)pd_new(makenote_class);
2260 x->x_velo = velo;
2261 x->x_dur = dur;
2262 floatinlet_new(&x->x_obj, &x->x_velo);
2263 floatinlet_new(&x->x_obj, &x->x_dur);
2264 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
2265 x->x_velout = outlet_new(&x->x_obj, &s_float);
2266 x->x_hang = 0;
2267 return (x);
2268}
2269
2270static void makenote_tick(t_hang *hang)
2271{
2272 t_makenote *x = hang->h_owner;
2273 t_hang *h2, *h3;
2274 outlet_float(x->x_velout, 0);
2275 outlet_float(x->x_pitchout, hang->h_pitch);
2276 if (x->x_hang == hang) x->x_hang = hang->h_next;
2277 else for (h2 = x->x_hang; h3 = h2->h_next; h2 = h3)
2278 {
2279 if (h3 == hang)
2280 {
2281 h2->h_next = h3->h_next;
2282 break;
2283 }
2284 }
2285 clock_free(hang->h_clock);
2286 freebytes(hang, sizeof(*hang));
2287}
2288
2289static void makenote_float(t_makenote *x, t_float f)
2290{
2291 t_hang *hang;
2292 if (!x->x_velo) return;
2293 outlet_float(x->x_velout, x->x_velo);
2294 outlet_float(x->x_pitchout, f);
2295 hang = (t_hang *)getbytes(sizeof *hang);
2296 hang->h_next = x->x_hang;
2297 x->x_hang = hang;
2298 hang->h_pitch = f;
2299 hang->h_owner = x;
2300 hang->h_clock = clock_new(hang, (t_method)makenote_tick);
2301 clock_delay(hang->h_clock, (x->x_dur >= 0 ? x->x_dur : 0));
2302}
2303
2304static void makenote_stop(t_makenote *x)
2305{
2306 t_hang *hang;
2307 while (hang = x->x_hang)
2308 {
2309 outlet_float(x->x_velout, 0);
2310 outlet_float(x->x_pitchout, hang->h_pitch);
2311 x->x_hang = hang->h_next;
2312 clock_free(hang->h_clock);
2313 freebytes(hang, sizeof(*hang));
2314 }
2315}
2316
2317static void makenote_clear(t_makenote *x)
2318{
2319 t_hang *hang;
2320 while (hang = x->x_hang)
2321 {
2322 x->x_hang = hang->h_next;
2323 clock_free(hang->h_clock);
2324 freebytes(hang, sizeof(*hang));
2325 }
2326}
2327
2328static void makenote_setup(void)
2329{
2330 makenote_class = class_new(gensym("makenote"),
2331 (t_newmethod)makenote_new, (t_method)makenote_clear,
2332 sizeof(t_makenote), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
2333 class_addfloat(makenote_class, makenote_float);
2334 class_addmethod(makenote_class, (t_method)makenote_stop, gensym("stop"),
2335 0);
2336 class_addmethod(makenote_class, (t_method)makenote_clear, gensym("clear"),
2337 0);
2338}
2339
2340/* -------------------------- stripnote -------------------------- */
2341
2342static t_class *stripnote_class;
2343
2344typedef struct _stripnote
2345{
2346 t_object x_obj;
2347 t_float x_velo;
2348 t_outlet *x_pitchout;
2349 t_outlet *x_velout;
2350} t_stripnote;
2351
2352static void *stripnote_new(void )
2353{
2354 t_stripnote *x = (t_stripnote *)pd_new(stripnote_class);
2355 floatinlet_new(&x->x_obj, &x->x_velo);
2356 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
2357 x->x_velout = outlet_new(&x->x_obj, &s_float);
2358 return (x);
2359}
2360
2361static void stripnote_float(t_stripnote *x, t_float f)
2362{
2363 t_hang *hang;
2364 if (!x->x_velo) return;
2365 outlet_float(x->x_velout, x->x_velo);
2366 outlet_float(x->x_pitchout, f);
2367}
2368
2369static void stripnote_setup(void)
2370{
2371 stripnote_class = class_new(gensym("stripnote"),
2372 (t_newmethod)stripnote_new, 0, sizeof(t_stripnote), 0, 0);
2373 class_addfloat(stripnote_class, stripnote_float);
2374}
2375
2376/* -------------------------- poly -------------------------- */
2377
2378static t_class *poly_class;
2379
2380typedef struct voice
2381{
2382 float v_pitch;
2383 int v_used;
2384 unsigned long v_serial;
2385} t_voice;
2386
2387typedef struct poly
2388{
2389 t_object x_obj;
2390 int x_n;
2391 t_voice *x_vec;
2392 float x_vel;
2393 t_outlet *x_pitchout;
2394 t_outlet *x_velout;
2395 unsigned long x_serial;
2396 int x_steal;
2397} t_poly;
2398
2399static void *poly_new(float fnvoice, float fsteal)
2400{
2401 int i, n = fnvoice;
2402 t_poly *x = (t_poly *)pd_new(poly_class);
2403 t_voice *v;
2404 if (n < 1) n = 1;
2405 x->x_n = n;
2406 x->x_vec = (t_voice *)getbytes(n * sizeof(*x->x_vec));
2407 for (v = x->x_vec, i = n; i--; v++)
2408 v->v_pitch = v->v_used = v->v_serial = 0;
2409 x->x_vel = 0;
2410 x->x_steal = (fsteal != 0);
2411 floatinlet_new(&x->x_obj, &x->x_vel);
2412 outlet_new(&x->x_obj, &s_float);
2413 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
2414 x->x_velout = outlet_new(&x->x_obj, &s_float);
2415 x->x_serial = 0;
2416 return (x);
2417}
2418
2419static void poly_float(t_poly *x, t_float f)
2420{
2421 int i;
2422 t_voice *v;
2423 t_voice *firston, *firstoff;
2424 unsigned int serialon, serialoff, onindex = 0, offindex = 0;
2425 if (x->x_vel > 0)
2426 {
2427 /* note on. Look for a vacant voice */
2428 for (v = x->x_vec, i = 0, firston = firstoff = 0,
2429 serialon = serialoff = 0xffffffff; i < x->x_n; v++, i++)
2430 {
2431 if (v->v_used && v->v_serial < serialon)
2432 firston = v, serialon = v->v_serial, onindex = i;
2433 else if (!v->v_used && v->v_serial < serialoff)
2434 firstoff = v, serialoff = v->v_serial, offindex = i;
2435 }
2436 if (firstoff)
2437 {
2438 outlet_float(x->x_velout, x->x_vel);
2439 outlet_float(x->x_pitchout, firstoff->v_pitch = f);
2440 outlet_float(x->x_obj.ob_outlet, offindex+1);
2441 firstoff->v_used = 1;
2442 firstoff->v_serial = x->x_serial++;
2443 }
2444 /* if none, steal one */
2445 else if (firston && x->x_steal)
2446 {
2447 outlet_float(x->x_velout, 0);
2448 outlet_float(x->x_pitchout, firston->v_pitch);
2449 outlet_float(x->x_obj.ob_outlet, onindex+1);
2450 outlet_float(x->x_velout, x->x_vel);
2451 outlet_float(x->x_pitchout, firston->v_pitch = f);
2452 outlet_float(x->x_obj.ob_outlet, onindex+1);
2453 firston->v_serial = x->x_serial++;
2454 }
2455 }
2456 else /* note off. Turn off oldest match */
2457 {
2458 for (v = x->x_vec, i = 0, firston = 0, serialon = 0xffffffff;
2459 i < x->x_n; v++, i++)
2460 if (v->v_used && v->v_pitch == f && v->v_serial < serialon)
2461 firston = v, serialon = v->v_serial, onindex = i;
2462 if (firston)
2463 {
2464 firston->v_used = 0;
2465 firston->v_serial = x->x_serial++;
2466 outlet_float(x->x_velout, 0);
2467 outlet_float(x->x_pitchout, firston->v_pitch);
2468 outlet_float(x->x_obj.ob_outlet, onindex+1);
2469 }
2470 }
2471}
2472
2473static void poly_stop(t_poly *x)
2474{
2475 int i;
2476 t_voice *v;
2477 for (i = 0, v = x->x_vec; i < x->x_n; i++, v++)
2478 if (v->v_used)
2479 {
2480 outlet_float(x->x_velout, 0L);
2481 outlet_float(x->x_pitchout, v->v_pitch);
2482 outlet_float(x->x_obj.ob_outlet, i+1);
2483 v->v_used = 0;
2484 v->v_serial = x->x_serial++;
2485 }
2486}
2487
2488static void poly_clear(t_poly *x)
2489{
2490 int i;
2491 t_voice *v;
2492 for (v = x->x_vec, i = x->x_n; i--; v++) v->v_used = v->v_serial = 0;
2493}
2494
2495static void poly_free(t_poly *x)
2496{
2497 freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec));
2498}
2499
2500static void poly_setup(void)
2501{
2502 poly_class = class_new(gensym("poly"),
2503 (t_newmethod)poly_new, (t_method)poly_clear,
2504 sizeof(t_poly), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
2505 class_addfloat(poly_class, poly_float);
2506 class_addmethod(poly_class, (t_method)poly_stop, gensym("stop"), 0);
2507 class_addmethod(poly_class, (t_method)poly_clear, gensym("clear"), 0);
2508}
2509
2510/* -------------------------- bag -------------------------- */
2511
2512static t_class *bag_class;
2513
2514typedef struct _bagelem
2515{
2516 struct _bagelem *e_next;
2517 t_float e_value;
2518} t_bagelem;
2519
2520typedef struct _bag
2521{
2522 t_object x_obj;
2523 t_float x_velo;
2524 t_bagelem *x_first;
2525} t_bag;
2526
2527static void *bag_new(void )
2528{
2529 t_bag *x = (t_bag *)pd_new(bag_class);
2530 x->x_velo = 0;
2531 floatinlet_new(&x->x_obj, &x->x_velo);
2532 outlet_new(&x->x_obj, &s_float);
2533 x->x_first = 0;
2534 return (x);
2535}
2536
2537static void bag_float(t_bag *x, t_float f)
2538{
2539 t_bagelem *bagelem, *e2, *e3;
2540 if (x->x_velo != 0)
2541 {
2542 bagelem = (t_bagelem *)getbytes(sizeof *bagelem);
2543 bagelem->e_next = 0;
2544 bagelem->e_value = f;
2545 if (!x->x_first) x->x_first = bagelem;
2546 else /* LATER replace with a faster algorithm */
2547 {
2548 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
2549 ;
2550 e2->e_next = bagelem;
2551 }
2552 }
2553 else
2554 {
2555 if (!x->x_first) return;
2556 if (x->x_first->e_value == f)
2557 {
2558 bagelem = x->x_first;
2559 x->x_first = x->x_first->e_next;
2560 freebytes(bagelem, sizeof(*bagelem));
2561 return;
2562 }
2563 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
2564 if (e3->e_value == f)
2565 {
2566 e2->e_next = e3->e_next;
2567 freebytes(e3, sizeof(*e3));
2568 return;
2569 }
2570 }
2571}
2572
2573static void bag_flush(t_bag *x)
2574{
2575 t_bagelem *bagelem;
2576 while (bagelem = x->x_first)
2577 {
2578 outlet_float(x->x_obj.ob_outlet, bagelem->e_value);
2579 x->x_first = bagelem->e_next;
2580 freebytes(bagelem, sizeof(*bagelem));
2581 }
2582}
2583
2584static void bag_clear(t_bag *x)
2585{
2586 t_bagelem *bagelem;
2587 while (bagelem = x->x_first)
2588 {
2589 x->x_first = bagelem->e_next;
2590 freebytes(bagelem, sizeof(*bagelem));
2591 }
2592}
2593 1314
2594static void bag_setup(void)
2595{
2596 bag_class = class_new(gensym("bag"),
2597 (t_newmethod)bag_new, (t_method)bag_clear,
2598 sizeof(t_bag), 0, 0);
2599 class_addfloat(bag_class, bag_float);
2600 class_addmethod(bag_class, (t_method)bag_flush, gensym("flush"), 0);
2601 class_addmethod(bag_class, (t_method)bag_clear, gensym("clear"), 0);
2602}
2603
2604void x_midi_setup(void)
2605{
2606 midiin_setup();
2607 midirealtimein_setup();
2608 notein_setup();
2609 ctlin_setup();
2610 pgmin_setup();
2611 bendin_setup();
2612 touchin_setup();
2613 polytouchin_setup();
2614 midiclkin_setup();
2615 midiout_setup();
2616 noteout_setup();
2617 ctlout_setup();
2618 pgmout_setup();
2619 bendout_setup();
2620 touchout_setup();
2621 polytouchout_setup();
2622 makenote_setup();
2623 stripnote_setup();
2624 poly_setup();
2625 bag_setup();
2626}