diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/x_midi.c | |
parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_midi.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/x_midi.c | 1312 |
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" | ||
1321 | void outmidi_noteon(int portno, int channel, int pitch, int velo); | ||
1322 | void outmidi_controlchange(int portno, int channel, int ctlno, int value); | ||
1323 | void outmidi_programchange(int portno, int channel, int value); | ||
1324 | void outmidi_pitchbend(int portno, int channel, int value); | ||
1325 | void outmidi_aftertouch(int portno, int channel, int value); | ||
1326 | void outmidi_polyaftertouch(int portno, int channel, int pitch, int value); | ||
1327 | void outmidi_mclk(int portno); | ||
1328 | |||
1329 | /* ----------------------- midiin and sysexin ------------------------- */ | ||
1330 | |||
1331 | static t_symbol *midiin_sym, *sysexin_sym; | ||
1332 | |||
1333 | static t_class *midiin_class, *sysexin_class; | ||
1334 | |||
1335 | typedef struct _midiin | ||
1336 | { | ||
1337 | t_object x_obj; | ||
1338 | t_outlet *x_outlet1; | ||
1339 | t_outlet *x_outlet2; | ||
1340 | } t_midiin; | ||
1341 | |||
1342 | static 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 | |||
1354 | static 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 | |||
1360 | static void midiin_free(t_midiin *x) | ||
1361 | { | ||
1362 | pd_unbind(&x->x_obj.ob_pd, midiin_sym); | ||
1363 | } | ||
1364 | |||
1365 | static 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 | |||
1377 | static void sysexin_free(t_midiin *x) | ||
1378 | { | ||
1379 | pd_unbind(&x->x_obj.ob_pd, sysexin_sym); | ||
1380 | } | ||
1381 | |||
1382 | static 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 | |||
1399 | void 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 | |||
1410 | void 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 | |||
1423 | static t_symbol *notein_sym; | ||
1424 | |||
1425 | static t_class *notein_class; | ||
1426 | |||
1427 | typedef 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 | |||
1436 | static 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 | |||
1447 | static 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 | |||
1466 | static void notein_free(t_notein *x) | ||
1467 | { | ||
1468 | pd_unbind(&x->x_obj.ob_pd, notein_sym); | ||
1469 | } | ||
1470 | |||
1471 | static 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 | |||
1480 | void 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 | |||
1494 | static t_symbol *ctlin_sym; | ||
1495 | |||
1496 | static t_class *ctlin_class; | ||
1497 | |||
1498 | typedef 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 | |||
1508 | static 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 | |||
1527 | static 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 | |||
1539 | static void ctlin_free(t_ctlin *x) | ||
1540 | { | ||
1541 | pd_unbind(&x->x_obj.ob_pd, ctlin_sym); | ||
1542 | } | ||
1543 | |||
1544 | static 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 | |||
1554 | void 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 | |||
1568 | static t_symbol *pgmin_sym; | ||
1569 | |||
1570 | static t_class *pgmin_class; | ||
1571 | |||
1572 | typedef 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 | |||
1580 | static 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 | |||
1590 | static 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 | |||
1606 | static void pgmin_free(t_pgmin *x) | ||
1607 | { | ||
1608 | pd_unbind(&x->x_obj.ob_pd, pgmin_sym); | ||
1609 | } | ||
1610 | |||
1611 | static 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 | |||
1621 | void 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 | |||
1634 | static t_symbol *bendin_sym; | ||
1635 | |||
1636 | static t_class *bendin_class; | ||
1637 | |||
1638 | typedef 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 | |||
1646 | static 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 | |||
1656 | static 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 | |||
1672 | static void bendin_free(t_bendin *x) | ||
1673 | { | ||
1674 | pd_unbind(&x->x_obj.ob_pd, bendin_sym); | ||
1675 | } | ||
1676 | |||
1677 | static 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 | |||
1686 | void 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 | |||
1699 | static t_symbol *touchin_sym; | ||
1700 | |||
1701 | static t_class *touchin_class; | ||
1702 | |||
1703 | typedef 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 | |||
1711 | static 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 | |||
1721 | static 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 | |||
1737 | static void touchin_free(t_touchin *x) | ||
1738 | { | ||
1739 | pd_unbind(&x->x_obj.ob_pd, touchin_sym); | ||
1740 | } | ||
1741 | |||
1742 | static 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 | |||
1752 | void 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 | |||
1765 | static t_symbol *polytouchin_sym; | ||
1766 | |||
1767 | static t_class *polytouchin_class; | ||
1768 | |||
1769 | typedef 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 | |||
1778 | static 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 | |||
1789 | static 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 | |||
1809 | static void polytouchin_free(t_polytouchin *x) | ||
1810 | { | ||
1811 | pd_unbind(&x->x_obj.ob_pd, polytouchin_sym); | ||
1812 | } | ||
1813 | |||
1814 | static 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 | |||
1824 | void 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 )---------------------*/ | ||
1837 | static t_symbol *midiclkin_sym; | ||
1838 | |||
1839 | static t_class *midiclkin_class; | ||
1840 | |||
1841 | |||
1842 | typedef struct _midiclkin | ||
1843 | { | ||
1844 | t_object x_obj; | ||
1845 | t_outlet *x_outlet1; | ||
1846 | t_outlet *x_outlet2; | ||
1847 | } t_midiclkin; | ||
1848 | |||
1849 | static 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 | |||
1858 | static 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 | |||
1866 | static void midiclkin_free(t_midiclkin *x) | ||
1867 | { | ||
1868 | pd_unbind(&x->x_obj.ob_pd, midiclkin_sym); | ||
1869 | } | ||
1870 | |||
1871 | static 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 | |||
1881 | void 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 | |||
1909 | static t_symbol *midirealtimein_sym; | ||
1910 | |||
1911 | static t_class *midirealtimein_class; | ||
1912 | |||
1913 | typedef struct _midirealtimein | ||
1914 | { | ||
1915 | t_object x_obj; | ||
1916 | t_outlet *x_outlet1; | ||
1917 | t_outlet *x_outlet2; | ||
1918 | } t_midirealtimein; | ||
1919 | |||
1920 | static 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 | |||
1932 | static 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 | |||
1942 | static void midirealtimein_free(t_midirealtimein *x) | ||
1943 | { | ||
1944 | pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym); | ||
1945 | } | ||
1946 | |||
1947 | static 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 | |||
1957 | void 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 | |||
1970 | static t_class *midiout_class; | ||
1971 | |||
1972 | void sys_putmidibyte(int portno, int byte); | ||
1973 | |||
1974 | typedef struct _midiout | ||
1975 | { | ||
1976 | t_object x_obj; | ||
1977 | t_float x_portno; | ||
1978 | } t_midiout; | ||
1979 | |||
1980 | static 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 | |||
1992 | static void midiout_float(t_midiout *x, t_floatarg f) | ||
1993 | { | ||
1994 | sys_putmidibyte(x->x_portno - 1, f); | ||
1995 | } | ||
1996 | |||
1997 | static 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 | |||
2007 | static t_class *noteout_class; | ||
2008 | |||
2009 | typedef struct _noteout | ||
2010 | { | ||
2011 | t_object x_obj; | ||
2012 | t_float x_velo; | ||
2013 | t_float x_channel; | ||
2014 | } t_noteout; | ||
2015 | |||
2016 | static 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 | |||
2027 | static 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 | |||
2036 | static 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 | |||
2047 | static t_class *ctlout_class; | ||
2048 | |||
2049 | typedef struct _ctlout | ||
2050 | { | ||
2051 | t_object x_obj; | ||
2052 | t_float x_ctl; | ||
2053 | t_float x_channel; | ||
2054 | } t_ctlout; | ||
2055 | |||
2056 | static 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 | |||
2067 | static 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 | |||
2076 | static 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 | |||
2087 | static t_class *pgmout_class; | ||
2088 | |||
2089 | typedef struct _pgmout | ||
2090 | { | ||
2091 | t_object x_obj; | ||
2092 | t_float x_channel; | ||
2093 | } t_pgmout; | ||
2094 | |||
2095 | static 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 | |||
2104 | static 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 | |||
2116 | static 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 | |||
2127 | static t_class *bendout_class; | ||
2128 | |||
2129 | typedef struct _bendout | ||
2130 | { | ||
2131 | t_object x_obj; | ||
2132 | t_float x_channel; | ||
2133 | } t_bendout; | ||
2134 | |||
2135 | static 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 | |||
2144 | static 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 | |||
2153 | static 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 | |||
2163 | static t_class *touchout_class; | ||
2164 | |||
2165 | typedef struct _touchout | ||
2166 | { | ||
2167 | t_object x_obj; | ||
2168 | t_float x_channel; | ||
2169 | } t_touchout; | ||
2170 | |||
2171 | static 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 | |||
2180 | static 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 | |||
2188 | static 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 | |||
2198 | static t_class *polytouchout_class; | ||
2199 | |||
2200 | typedef struct _polytouchout | ||
2201 | { | ||
2202 | t_object x_obj; | ||
2203 | t_float x_channel; | ||
2204 | t_float x_pitch; | ||
2205 | } t_polytouchout; | ||
2206 | |||
2207 | static 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 | |||
2218 | static 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 | |||
2226 | static 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 | |||
2237 | static t_class *makenote_class; | ||
2238 | |||
2239 | typedef 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 | |||
2247 | typedef 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 | |||
2257 | static 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 | |||
2270 | static 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 | |||
2289 | static 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 | |||
2304 | static 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 | |||
2317 | static 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 | |||
2328 | static 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 | |||
2342 | static t_class *stripnote_class; | ||
2343 | |||
2344 | typedef 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 | |||
2352 | static 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 | |||
2361 | static 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 | |||
2369 | static 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 | |||
2378 | static t_class *poly_class; | ||
2379 | |||
2380 | typedef struct voice | ||
2381 | { | ||
2382 | float v_pitch; | ||
2383 | int v_used; | ||
2384 | unsigned long v_serial; | ||
2385 | } t_voice; | ||
2386 | |||
2387 | typedef 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 | |||
2399 | static 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 | |||
2419 | static 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 | |||
2473 | static 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 | |||
2488 | static 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 | |||
2495 | static void poly_free(t_poly *x) | ||
2496 | { | ||
2497 | freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec)); | ||
2498 | } | ||
2499 | |||
2500 | static 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 | |||
2512 | static t_class *bag_class; | ||
2513 | |||
2514 | typedef struct _bagelem | ||
2515 | { | ||
2516 | struct _bagelem *e_next; | ||
2517 | t_float e_value; | ||
2518 | } t_bagelem; | ||
2519 | |||
2520 | typedef struct _bag | ||
2521 | { | ||
2522 | t_object x_obj; | ||
2523 | t_float x_velo; | ||
2524 | t_bagelem *x_first; | ||
2525 | } t_bag; | ||
2526 | |||
2527 | static 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 | |||
2537 | static 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 | |||
2573 | static 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 | |||
2584 | static 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 | ||
2594 | static 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 | |||
2604 | void 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 | } | ||