summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/d_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_array.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_array.c1074
1 files changed, 0 insertions, 1074 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_array.c b/apps/plugins/pdbox/PDa/src/d_array.c
index 14ae464b0b..7139e4dc3d 100644
--- a/apps/plugins/pdbox/PDa/src/d_array.c
+++ b/apps/plugins/pdbox/PDa/src/d_array.c
@@ -1072,1077 +1072,3 @@ void d_array_setup(void)
1072 tabwrite_setup(); 1072 tabwrite_setup();
1073} 1073}
1074 1074
1075/* Copyright (c) 1997-1999 Miller Puckette and others.
1076* For information on usage and redistribution, and for a DISCLAIMER OF ALL
1077* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1078
1079/* sampling */
1080
1081/* LATER make tabread4 and tabread~ */
1082
1083#include "m_pd.h"
1084
1085
1086/* ------------------------- tabwrite~ -------------------------- */
1087
1088static t_class *tabwrite_tilde_class;
1089
1090typedef struct _tabwrite_tilde
1091{
1092 t_object x_obj;
1093 int x_phase;
1094 int x_nsampsintab;
1095 float *x_vec;
1096 t_symbol *x_arrayname;
1097 t_clock *x_clock;
1098 float x_f;
1099} t_tabwrite_tilde;
1100
1101static void tabwrite_tilde_tick(t_tabwrite_tilde *x);
1102
1103static void *tabwrite_tilde_new(t_symbol *s)
1104{
1105 t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class);
1106 x->x_clock = clock_new(x, (t_method)tabwrite_tilde_tick);
1107 x->x_phase = 0x7fffffff;
1108 x->x_arrayname = s;
1109 x->x_f = 0;
1110 return (x);
1111}
1112
1113static t_int *tabwrite_tilde_perform(t_int *w)
1114{
1115 t_tabwrite_tilde *x = (t_tabwrite_tilde *)(w[1]);
1116 t_float *in = (t_float *)(w[2]);
1117 int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
1118 if (!x->x_vec) goto bad;
1119
1120 if (endphase > phase)
1121 {
1122 int nxfer = endphase - phase;
1123 float *fp = x->x_vec + phase;
1124 if (nxfer > n) nxfer = n;
1125 phase += nxfer;
1126 while (nxfer--)
1127 {
1128 float f = *in++;
1129 if (PD_BIGORSMALL(f))
1130 f = 0;
1131 *fp++ = f;
1132 }
1133 if (phase >= endphase)
1134 {
1135 clock_delay(x->x_clock, 0);
1136 phase = 0x7fffffff;
1137 }
1138 x->x_phase = phase;
1139 }
1140bad:
1141 return (w+4);
1142}
1143
1144void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s)
1145{
1146 t_garray *a;
1147
1148 x->x_arrayname = s;
1149 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1150 {
1151 if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array",
1152 x->x_arrayname->s_name);
1153 x->x_vec = 0;
1154 }
1155 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
1156 {
1157 pd_error(x, "%s: bad template for tabwrite~", x->x_arrayname->s_name);
1158 x->x_vec = 0;
1159 }
1160 else garray_usedindsp(a);
1161}
1162
1163static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp)
1164{
1165 tabwrite_tilde_set(x, x->x_arrayname);
1166 dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
1167}
1168
1169static void tabwrite_tilde_bang(t_tabwrite_tilde *x)
1170{
1171 x->x_phase = 0;
1172}
1173
1174static void tabwrite_tilde_stop(t_tabwrite_tilde *x)
1175{
1176 if (x->x_phase != 0x7fffffff)
1177 {
1178 tabwrite_tilde_tick(x);
1179 x->x_phase = 0x7fffffff;
1180 }
1181}
1182
1183static void tabwrite_tilde_tick(t_tabwrite_tilde *x)
1184{
1185 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
1186 if (!a) bug("tabwrite_tilde_tick");
1187 else garray_redraw(a);
1188}
1189
1190static void tabwrite_tilde_free(t_tabwrite_tilde *x)
1191{
1192 clock_free(x->x_clock);
1193}
1194
1195static void tabwrite_tilde_setup(void)
1196{
1197 tabwrite_tilde_class = class_new(gensym("tabwrite~"),
1198 (t_newmethod)tabwrite_tilde_new, (t_method)tabwrite_tilde_free,
1199 sizeof(t_tabwrite_tilde), 0, A_DEFSYM, 0);
1200 CLASS_MAINSIGNALIN(tabwrite_tilde_class, t_tabwrite_tilde, x_f);
1201 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_dsp,
1202 gensym("dsp"), 0);
1203 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_set,
1204 gensym("set"), A_SYMBOL, 0);
1205 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_stop,
1206 gensym("stop"), 0);
1207 class_addbang(tabwrite_tilde_class, tabwrite_tilde_bang);
1208}
1209
1210/* ------------ tabplay~ - non-transposing sample playback --------------- */
1211
1212static t_class *tabplay_tilde_class;
1213
1214typedef struct _tabplay_tilde
1215{
1216 t_object x_obj;
1217 t_outlet *x_bangout;
1218 int x_phase;
1219 int x_nsampsintab;
1220 int x_limit;
1221 float *x_vec;
1222 t_symbol *x_arrayname;
1223 t_clock *x_clock;
1224} t_tabplay_tilde;
1225
1226static void tabplay_tilde_tick(t_tabplay_tilde *x);
1227
1228static void *tabplay_tilde_new(t_symbol *s)
1229{
1230 t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class);
1231 x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick);
1232 x->x_phase = 0x7fffffff;
1233 x->x_limit = 0;
1234 x->x_arrayname = s;
1235 outlet_new(&x->x_obj, &s_signal);
1236 x->x_bangout = outlet_new(&x->x_obj, &s_bang);
1237 return (x);
1238}
1239
1240static t_int *tabplay_tilde_perform(t_int *w)
1241{
1242 t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]);
1243 t_float *out = (t_float *)(w[2]), *fp;
1244 int n = (int)(w[3]), phase = x->x_phase,
1245 endphase = (x->x_nsampsintab < x->x_limit ?
1246 x->x_nsampsintab : x->x_limit), nxfer, n3;
1247 if (!x->x_vec || phase >= endphase)
1248 goto zero;
1249
1250 nxfer = endphase - phase;
1251 fp = x->x_vec + phase;
1252 if (nxfer > n)
1253 nxfer = n;
1254 n3 = n - nxfer;
1255 phase += nxfer;
1256 while (nxfer--)
1257 *out++ = *fp++;
1258 if (phase >= endphase)
1259 {
1260 clock_delay(x->x_clock, 0);
1261 x->x_phase = 0x7fffffff;
1262 while (n3--)
1263 *out++ = 0;
1264 }
1265 else x->x_phase = phase;
1266
1267 return (w+4);
1268zero:
1269 while (n--) *out++ = 0;
1270 return (w+4);
1271}
1272
1273void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s)
1274{
1275 t_garray *a;
1276
1277 x->x_arrayname = s;
1278 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1279 {
1280 if (*s->s_name) pd_error(x, "tabplay~: %s: no such array",
1281 x->x_arrayname->s_name);
1282 x->x_vec = 0;
1283 }
1284 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
1285 {
1286 pd_error(x, "%s: bad template for tabplay~", x->x_arrayname->s_name);
1287 x->x_vec = 0;
1288 }
1289 else garray_usedindsp(a);
1290}
1291
1292static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp)
1293{
1294 tabplay_tilde_set(x, x->x_arrayname);
1295 dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
1296}
1297
1298static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s,
1299 int argc, t_atom *argv)
1300{
1301 long start = atom_getfloatarg(0, argc, argv);
1302 long length = atom_getfloatarg(1, argc, argv);
1303 if (start < 0) start = 0;
1304 if (length <= 0)
1305 x->x_limit = 0x7fffffff;
1306 else
1307 x->x_limit = start + length;
1308 x->x_phase = start;
1309}
1310
1311static void tabplay_tilde_stop(t_tabplay_tilde *x)
1312{
1313 x->x_phase = 0x7fffffff;
1314}
1315
1316static void tabplay_tilde_tick(t_tabplay_tilde *x)
1317{
1318 outlet_bang(x->x_bangout);
1319}
1320
1321static void tabplay_tilde_free(t_tabplay_tilde *x)
1322{
1323 clock_free(x->x_clock);
1324}
1325
1326static void tabplay_tilde_setup(void)
1327{
1328 tabplay_tilde_class = class_new(gensym("tabplay~"),
1329 (t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free,
1330 sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0);
1331 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp,
1332 gensym("dsp"), 0);
1333 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop,
1334 gensym("stop"), 0);
1335 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set,
1336 gensym("set"), A_DEFSYM, 0);
1337 class_addlist(tabplay_tilde_class, tabplay_tilde_list);
1338}
1339
1340/******************** tabread~ ***********************/
1341
1342static t_class *tabread_tilde_class;
1343
1344typedef struct _tabread_tilde
1345{
1346 t_object x_obj;
1347 int x_npoints;
1348 float *x_vec;
1349 t_symbol *x_arrayname;
1350 float x_f;
1351} t_tabread_tilde;
1352
1353static void *tabread_tilde_new(t_symbol *s)
1354{
1355 t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class);
1356 x->x_arrayname = s;
1357 x->x_vec = 0;
1358 outlet_new(&x->x_obj, gensym("signal"));
1359 x->x_f = 0;
1360 return (x);
1361}
1362
1363static t_int *tabread_tilde_perform(t_int *w)
1364{
1365 t_tabread_tilde *x = (t_tabread_tilde *)(w[1]);
1366 t_float *in = (t_float *)(w[2]);
1367 t_float *out = (t_float *)(w[3]);
1368 int n = (int)(w[4]);
1369 int maxindex;
1370 float *buf = x->x_vec, *fp;
1371 int i;
1372
1373 maxindex = x->x_npoints - 1;
1374 if (!buf) goto zero;
1375
1376 for (i = 0; i < n; i++)
1377 {
1378 int index = *in++;
1379 if (index < 0)
1380 index = 0;
1381 else if (index > maxindex)
1382 index = maxindex;
1383 *out++ = buf[index];
1384 }
1385 return (w+5);
1386 zero:
1387 while (n--) *out++ = 0;
1388
1389 return (w+5);
1390}
1391
1392void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s)
1393{
1394 t_garray *a;
1395
1396 x->x_arrayname = s;
1397 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1398 {
1399 if (*s->s_name)
1400 pd_error(x, "tabread~: %s: no such array", x->x_arrayname->s_name);
1401 x->x_vec = 0;
1402 }
1403 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
1404 {
1405 pd_error(x, "%s: bad template for tabread~", x->x_arrayname->s_name);
1406 x->x_vec = 0;
1407 }
1408 else garray_usedindsp(a);
1409}
1410
1411static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp)
1412{
1413 tabread_tilde_set(x, x->x_arrayname);
1414
1415 dsp_add(tabread_tilde_perform, 4, x,
1416 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
1417
1418}
1419
1420static void tabread_tilde_free(t_tabread_tilde *x)
1421{
1422}
1423
1424static void tabread_tilde_setup(void)
1425{
1426 tabread_tilde_class = class_new(gensym("tabread~"),
1427 (t_newmethod)tabread_tilde_new, (t_method)tabread_tilde_free,
1428 sizeof(t_tabread_tilde), 0, A_DEFSYM, 0);
1429 CLASS_MAINSIGNALIN(tabread_tilde_class, t_tabread_tilde, x_f);
1430 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_dsp,
1431 gensym("dsp"), 0);
1432 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_set,
1433 gensym("set"), A_SYMBOL, 0);
1434}
1435
1436/******************** tabread4~ ***********************/
1437
1438static t_class *tabread4_tilde_class;
1439
1440typedef struct _tabread4_tilde
1441{
1442 t_object x_obj;
1443 int x_npoints;
1444 float *x_vec;
1445 t_symbol *x_arrayname;
1446 float x_f;
1447} t_tabread4_tilde;
1448
1449static void *tabread4_tilde_new(t_symbol *s)
1450{
1451 t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class);
1452 x->x_arrayname = s;
1453 x->x_vec = 0;
1454 outlet_new(&x->x_obj, gensym("signal"));
1455 x->x_f = 0;
1456 return (x);
1457}
1458
1459static t_int *tabread4_tilde_perform(t_int *w)
1460{
1461 t_tabread4_tilde *x = (t_tabread4_tilde *)(w[1]);
1462 t_float *in = (t_float *)(w[2]);
1463 t_float *out = (t_float *)(w[3]);
1464 int n = (int)(w[4]);
1465 int maxindex;
1466 float *buf = x->x_vec, *fp;
1467 int i;
1468
1469 maxindex = x->x_npoints - 3;
1470
1471 if (!buf) goto zero;
1472
1473#if 0 /* test for spam -- I'm not ready to deal with this */
1474 for (i = 0, xmax = 0, xmin = maxindex, fp = in1; i < n; i++, fp++)
1475 {
1476 float f = *in1;
1477 if (f < xmin) xmin = f;
1478 else if (f > xmax) xmax = f;
1479 }
1480 if (xmax < xmin + x->c_maxextent) xmax = xmin + x->c_maxextent;
1481 for (i = 0, splitlo = xmin+ x->c_maxextent, splithi = xmax - x->c_maxextent,
1482 fp = in1; i < n; i++, fp++)
1483 {
1484 float f = *in1;
1485 if (f > splitlo && f < splithi) goto zero;
1486 }
1487#endif
1488
1489 for (i = 0; i < n; i++)
1490 {
1491 float findex = *in++;
1492 int index = findex;
1493 float frac, a, b, c, d, cminusb;
1494 static int count;
1495 if (index < 1)
1496 index = 1, frac = 0;
1497 else if (index > maxindex)
1498 index = maxindex, frac = 1;
1499 else frac = findex - index;
1500 fp = buf + index;
1501 a = fp[-1];
1502 b = fp[0];
1503 c = fp[1];
1504 d = fp[2];
1505 /* if (!i && !(count++ & 1023))
1506 post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */
1507 cminusb = c-b;
1508 *out++ = b + frac * (
1509 cminusb - 0.1666667f * (1.-frac) * (
1510 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
1511 )
1512 );
1513 }
1514 return (w+5);
1515 zero:
1516 while (n--) *out++ = 0;
1517
1518 return (w+5);
1519}
1520
1521void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s)
1522{
1523 t_garray *a;
1524
1525 x->x_arrayname = s;
1526 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1527 {
1528 if (*s->s_name)
1529 pd_error(x, "tabread4~: %s: no such array", x->x_arrayname->s_name);
1530 x->x_vec = 0;
1531 }
1532 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
1533 {
1534 pd_error(x, "%s: bad template for tabread4~", x->x_arrayname->s_name);
1535 x->x_vec = 0;
1536 }
1537 else garray_usedindsp(a);
1538}
1539
1540static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp)
1541{
1542 tabread4_tilde_set(x, x->x_arrayname);
1543
1544 dsp_add(tabread4_tilde_perform, 4, x,
1545 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
1546
1547}
1548
1549static void tabread4_tilde_free(t_tabread4_tilde *x)
1550{
1551}
1552
1553static void tabread4_tilde_setup(void)
1554{
1555 tabread4_tilde_class = class_new(gensym("tabread4~"),
1556 (t_newmethod)tabread4_tilde_new, (t_method)tabread4_tilde_free,
1557 sizeof(t_tabread4_tilde), 0, A_DEFSYM, 0);
1558 CLASS_MAINSIGNALIN(tabread4_tilde_class, t_tabread4_tilde, x_f);
1559 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_dsp,
1560 gensym("dsp"), 0);
1561 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_set,
1562 gensym("set"), A_SYMBOL, 0);
1563}
1564
1565/******************** tabosc4~ ***********************/
1566
1567/* this is all copied from d_osc.c... what include file could this go in? */
1568#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
1569
1570 /* machine-dependent definitions. These ifdefs really
1571 should have been by CPU type and not by operating system! */
1572#ifdef IRIX
1573 /* big-endian. Most significant byte is at low address in memory */
1574#define HIOFFSET 0 /* word offset to find MSB */
1575#define LOWOFFSET 1 /* word offset to find LSB */
1576#define int32 long /* a data type that has 32 bits */
1577#else
1578#ifdef MSW
1579 /* little-endian; most significant byte is at highest address */
1580#define HIOFFSET 1
1581#define LOWOFFSET 0
1582#define int32 long
1583#else
1584#ifdef __FreeBSD__
1585#include <machine/endian.h>
1586#if BYTE_ORDER == LITTLE_ENDIAN
1587#define HIOFFSET 1
1588#define LOWOFFSET 0
1589#else
1590#define HIOFFSET 0 /* word offset to find MSB */
1591#define LOWOFFSET 1 /* word offset to find LSB */
1592#endif /* BYTE_ORDER */
1593#include <sys/types.h>
1594#define int32 int32_t
1595#endif
1596
1597#ifdef __linux__
1598#include <endian.h>
1599#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
1600#error No byte order defined
1601#endif
1602
1603#if __BYTE_ORDER == __LITTLE_ENDIAN
1604#define HIOFFSET 1
1605#define LOWOFFSET 0
1606#else
1607#define HIOFFSET 0 /* word offset to find MSB */
1608#define LOWOFFSET 1 /* word offset to find LSB */
1609#endif /* __BYTE_ORDER */
1610
1611#include <sys/types.h>
1612#define int32 int32_t
1613
1614#else
1615#ifdef MACOSX
1616#define HIOFFSET 0 /* word offset to find MSB */
1617#define LOWOFFSET 1 /* word offset to find LSB */
1618#define int32 int /* a data type that has 32 bits */
1619
1620#endif /* MACOSX */
1621#endif /* __linux__ */
1622#endif /* MSW */
1623#endif /* SGI */
1624
1625union tabfudge
1626{
1627 double tf_d;
1628 int32 tf_i[2];
1629};
1630
1631static t_class *tabosc4_tilde_class;
1632
1633typedef struct _tabosc4_tilde
1634{
1635 t_object x_obj;
1636 float x_fnpoints;
1637 float x_finvnpoints;
1638 float *x_vec;
1639 t_symbol *x_arrayname;
1640 float x_f;
1641 double x_phase;
1642 float x_conv;
1643} t_tabosc4_tilde;
1644
1645static void *tabosc4_tilde_new(t_symbol *s)
1646{
1647 t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
1648 x->x_arrayname = s;
1649 x->x_vec = 0;
1650 x->x_fnpoints = 512.;
1651 x->x_finvnpoints = (1./512.);
1652 outlet_new(&x->x_obj, gensym("signal"));
1653 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
1654 x->x_f = 0;
1655 return (x);
1656}
1657
1658static t_int *tabosc4_tilde_perform(t_int *w)
1659{
1660 t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
1661 t_float *in = (t_float *)(w[2]);
1662 t_float *out = (t_float *)(w[3]);
1663 int n = (int)(w[4]);
1664 int normhipart;
1665 union tabfudge tf;
1666 float fnpoints = x->x_fnpoints;
1667 int mask = fnpoints - 1;
1668 float conv = fnpoints * x->x_conv;
1669 int maxindex;
1670 float *tab = x->x_vec, *addr;
1671 int i;
1672 double dphase = fnpoints * x->x_phase + UNITBIT32;
1673
1674 if (!tab) goto zero;
1675 tf.tf_d = UNITBIT32;
1676 normhipart = tf.tf_i[HIOFFSET];
1677
1678#if 1
1679 while (n--)
1680 {
1681 float frac, a, b, c, d, cminusb;
1682 tf.tf_d = dphase;
1683 dphase += *in++ * conv;
1684 addr = tab + (tf.tf_i[HIOFFSET] & mask);
1685 tf.tf_i[HIOFFSET] = normhipart;
1686 frac = tf.tf_d - UNITBIT32;
1687 a = addr[0];
1688 b = addr[1];
1689 c = addr[2];
1690 d = addr[3];
1691 cminusb = c-b;
1692 *out++ = b + frac * (
1693 cminusb - 0.1666667f * (1.-frac) * (
1694 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
1695 )
1696 );
1697 }
1698#endif
1699
1700 tf.tf_d = UNITBIT32 * fnpoints;
1701 normhipart = tf.tf_i[HIOFFSET];
1702 tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
1703 tf.tf_i[HIOFFSET] = normhipart;
1704 x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints) * x->x_finvnpoints;
1705 return (w+5);
1706 zero:
1707 while (n--) *out++ = 0;
1708
1709 return (w+5);
1710}
1711
1712void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
1713{
1714 t_garray *a;
1715 int npoints, pointsinarray;
1716
1717 x->x_arrayname = s;
1718 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1719 {
1720 if (*s->s_name)
1721 pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
1722 x->x_vec = 0;
1723 }
1724 else if (!garray_getfloatarray(a, &pointsinarray, &x->x_vec))
1725 {
1726 pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
1727 x->x_vec = 0;
1728 }
1729 else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
1730 {
1731 pd_error(x, "%s: number of points (%d) not a power of 2 plus three",
1732 x->x_arrayname->s_name, pointsinarray);
1733 x->x_vec = 0;
1734 garray_usedindsp(a);
1735 }
1736 else
1737 {
1738 x->x_fnpoints = npoints;
1739 x->x_finvnpoints = 1./npoints;
1740 garray_usedindsp(a);
1741 }
1742}
1743
1744static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
1745{
1746 x->x_phase = f;
1747}
1748
1749static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
1750{
1751 x->x_conv = 1. / sp[0]->s_sr;
1752 tabosc4_tilde_set(x, x->x_arrayname);
1753
1754 dsp_add(tabosc4_tilde_perform, 4, x,
1755 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
1756}
1757
1758static void tabosc4_tilde_setup(void)
1759{
1760 tabosc4_tilde_class = class_new(gensym("tabosc4~"),
1761 (t_newmethod)tabosc4_tilde_new, 0,
1762 sizeof(t_tabosc4_tilde), 0, A_DEFSYM, 0);
1763 CLASS_MAINSIGNALIN(tabosc4_tilde_class, t_tabosc4_tilde, x_f);
1764 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_dsp,
1765 gensym("dsp"), 0);
1766 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_set,
1767 gensym("set"), A_SYMBOL, 0);
1768 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_ft1,
1769 gensym("ft1"), A_FLOAT, 0);
1770}
1771
1772/* ------------------------ tabsend~ ------------------------- */
1773
1774static t_class *tabsend_class;
1775
1776typedef struct _tabsend
1777{
1778 t_object x_obj;
1779 float *x_vec;
1780 int x_graphperiod;
1781 int x_graphcount;
1782 t_symbol *x_arrayname;
1783 t_clock *x_clock;
1784 float x_f;
1785} t_tabsend;
1786
1787static void tabsend_tick(t_tabsend *x);
1788
1789static void *tabsend_new(t_symbol *s)
1790{
1791 t_tabsend *x = (t_tabsend *)pd_new(tabsend_class);
1792 x->x_graphcount = 0;
1793 x->x_arrayname = s;
1794 x->x_clock = clock_new(x, (t_method)tabsend_tick);
1795 x->x_f = 0;
1796 return (x);
1797}
1798
1799static t_int *tabsend_perform(t_int *w)
1800{
1801 t_tabsend *x = (t_tabsend *)(w[1]);
1802 t_float *in = (t_float *)(w[2]);
1803 int n = w[3];
1804 t_float *dest = x->x_vec;
1805 int i = x->x_graphcount;
1806 if (!x->x_vec) goto bad;
1807
1808 while (n--)
1809 {
1810 float f = *in++;
1811 if (PD_BIGORSMALL(f))
1812 f = 0;
1813 *dest++ = f;
1814 }
1815 if (!i--)
1816 {
1817 clock_delay(x->x_clock, 0);
1818 i = x->x_graphperiod;
1819 }
1820 x->x_graphcount = i;
1821bad:
1822 return (w+4);
1823}
1824
1825static void tabsend_dsp(t_tabsend *x, t_signal **sp)
1826{
1827 int i, vecsize;
1828 t_garray *a;
1829
1830 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1831 {
1832 if (*x->x_arrayname->s_name)
1833 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
1834 }
1835 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
1836 pd_error(x, "%s: bad template for tabsend~", x->x_arrayname->s_name);
1837 else
1838 {
1839 int n = sp[0]->s_n;
1840 int ticksper = sp[0]->s_sr/n;
1841 if (ticksper < 1) ticksper = 1;
1842 x->x_graphperiod = ticksper;
1843 if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
1844 if (n < vecsize) vecsize = n;
1845 garray_usedindsp(a);
1846 dsp_add(tabsend_perform, 3, x, sp[0]->s_vec, vecsize);
1847 }
1848}
1849
1850static void tabsend_tick(t_tabsend *x)
1851{
1852 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
1853 if (!a) bug("tabsend_tick");
1854 else garray_redraw(a);
1855}
1856
1857static void tabsend_free(t_tabsend *x)
1858{
1859 clock_free(x->x_clock);
1860}
1861
1862static void tabsend_setup(void)
1863{
1864 tabsend_class = class_new(gensym("tabsend~"), (t_newmethod)tabsend_new,
1865 (t_method)tabsend_free, sizeof(t_tabsend), 0, A_DEFSYM, 0);
1866 CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, x_f);
1867 class_addmethod(tabsend_class, (t_method)tabsend_dsp, gensym("dsp"), 0);
1868}
1869
1870/* ------------------------ tabreceive~ ------------------------- */
1871
1872static t_class *tabreceive_class;
1873
1874typedef struct _tabreceive
1875{
1876 t_object x_obj;
1877 float *x_vec;
1878 t_symbol *x_arrayname;
1879} t_tabreceive;
1880
1881static t_int *tabreceive_perform(t_int *w)
1882{
1883 t_tabreceive *x = (t_tabreceive *)(w[1]);
1884 t_float *out = (t_float *)(w[2]);
1885 int n = w[3];
1886 t_float *from = x->x_vec;
1887 if (from) while (n--) *out++ = *from++;
1888 else while (n--) *out++ = 0;
1889 return (w+4);
1890}
1891
1892static void tabreceive_dsp(t_tabreceive *x, t_signal **sp)
1893{
1894 t_garray *a;
1895 int vecsize;
1896
1897 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1898 {
1899 if (*x->x_arrayname->s_name)
1900 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
1901 }
1902 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
1903 pd_error(x, "%s: bad template for tabreceive~", x->x_arrayname->s_name);
1904 else
1905 {
1906 int n = sp[0]->s_n;
1907 if (n < vecsize) vecsize = n;
1908 garray_usedindsp(a);
1909 dsp_add(tabreceive_perform, 3, x, sp[0]->s_vec, vecsize);
1910 }
1911}
1912
1913static void *tabreceive_new(t_symbol *s)
1914{
1915 t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class);
1916 x->x_arrayname = s;
1917 outlet_new(&x->x_obj, &s_signal);
1918 return (x);
1919}
1920
1921static void tabreceive_setup(void)
1922{
1923 tabreceive_class = class_new(gensym("tabreceive~"),
1924 (t_newmethod)tabreceive_new, 0,
1925 sizeof(t_tabreceive), 0, A_DEFSYM, 0);
1926 class_addmethod(tabreceive_class, (t_method)tabreceive_dsp,
1927 gensym("dsp"), 0);
1928}
1929
1930
1931/* ---------- tabread: control, non-interpolating ------------------------ */
1932
1933static t_class *tabread_class;
1934
1935typedef struct _tabread
1936{
1937 t_object x_obj;
1938 t_symbol *x_arrayname;
1939} t_tabread;
1940
1941static void tabread_float(t_tabread *x, t_float f)
1942{
1943 t_garray *a;
1944 int npoints;
1945 t_float *vec;
1946
1947 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1948 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
1949 else if (!garray_getfloatarray(a, &npoints, &vec))
1950 pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name);
1951 else
1952 {
1953 int n = f;
1954 if (n < 0) n = 0;
1955 else if (n >= npoints) n = npoints - 1;
1956 outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n] : 0));
1957 }
1958}
1959
1960static void tabread_set(t_tabread *x, t_symbol *s)
1961{
1962 x->x_arrayname = s;
1963}
1964
1965static void *tabread_new(t_symbol *s)
1966{
1967 t_tabread *x = (t_tabread *)pd_new(tabread_class);
1968 x->x_arrayname = s;
1969 outlet_new(&x->x_obj, &s_float);
1970 return (x);
1971}
1972
1973static void tabread_setup(void)
1974{
1975 tabread_class = class_new(gensym("tabread"), (t_newmethod)tabread_new,
1976 0, sizeof(t_tabread), 0, A_DEFSYM, 0);
1977 class_addfloat(tabread_class, (t_method)tabread_float);
1978 class_addmethod(tabread_class, (t_method)tabread_set, gensym("set"),
1979 A_SYMBOL, 0);
1980}
1981
1982/* ---------- tabread4: control, non-interpolating ------------------------ */
1983
1984static t_class *tabread4_class;
1985
1986typedef struct _tabread4
1987{
1988 t_object x_obj;
1989 t_symbol *x_arrayname;
1990} t_tabread4;
1991
1992static void tabread4_float(t_tabread4 *x, t_float f)
1993{
1994 t_garray *a;
1995 int npoints;
1996 t_float *vec;
1997
1998 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1999 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
2000 else if (!garray_getfloatarray(a, &npoints, &vec))
2001 pd_error(x, "%s: bad template for tabread4", x->x_arrayname->s_name);
2002 else if (npoints < 4)
2003 outlet_float(x->x_obj.ob_outlet, 0);
2004 else if (f <= 1)
2005 outlet_float(x->x_obj.ob_outlet, vec[1]);
2006 else if (f >= npoints - 2)
2007 outlet_float(x->x_obj.ob_outlet, vec[npoints - 2]);
2008 else
2009 {
2010 int n = f;
2011 float a, b, c, d, cminusb, frac, *fp;
2012 if (n >= npoints - 2)
2013 n = npoints - 3;
2014 fp = vec + n;
2015 frac = f - n;
2016 a = fp[-1];
2017 b = fp[0];
2018 c = fp[1];
2019 d = fp[2];
2020 cminusb = c-b;
2021 outlet_float(x->x_obj.ob_outlet, b + frac * (
2022 cminusb - 0.1666667f * (1.-frac) * (
2023 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))));
2024 }
2025}
2026
2027static void tabread4_set(t_tabread4 *x, t_symbol *s)
2028{
2029 x->x_arrayname = s;
2030}
2031
2032static void *tabread4_new(t_symbol *s)
2033{
2034 t_tabread4 *x = (t_tabread4 *)pd_new(tabread4_class);
2035 x->x_arrayname = s;
2036 outlet_new(&x->x_obj, &s_float);
2037 return (x);
2038}
2039
2040static void tabread4_setup(void)
2041{
2042 tabread4_class = class_new(gensym("tabread4"), (t_newmethod)tabread4_new,
2043 0, sizeof(t_tabread4), 0, A_DEFSYM, 0);
2044 class_addfloat(tabread4_class, (t_method)tabread4_float);
2045 class_addmethod(tabread4_class, (t_method)tabread4_set, gensym("set"),
2046 A_SYMBOL, 0);
2047}
2048
2049/* ------------------ tabwrite: control ------------------------ */
2050
2051static t_class *tabwrite_class;
2052
2053typedef struct _tabwrite
2054{
2055 t_object x_obj;
2056 t_symbol *x_arrayname;
2057 t_clock *x_clock;
2058 float x_ft1;
2059 double x_updtime;
2060 int x_set;
2061} t_tabwrite;
2062
2063static void tabwrite_tick(t_tabwrite *x)
2064{
2065 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
2066 if (!a) bug("tabwrite_tick");
2067 else garray_redraw(a);
2068 x->x_set = 0;
2069 x->x_updtime = clock_getsystime();
2070}
2071
2072static void tabwrite_float(t_tabwrite *x, t_float f)
2073{
2074 int i, vecsize;
2075 t_garray *a;
2076 t_float *vec;
2077
2078 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
2079 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
2080 else if (!garray_getfloatarray(a, &vecsize, &vec))
2081 pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name);
2082 else
2083 {
2084 int n = x->x_ft1;
2085 double timesince = clock_gettimesince(x->x_updtime);
2086 if (n < 0) n = 0;
2087 else if (n >= vecsize) n = vecsize-1;
2088 vec[n] = f;
2089 if (timesince > 1000)
2090 {
2091 tabwrite_tick(x);
2092 }
2093 else
2094 {
2095 if (x->x_set == 0)
2096 {
2097 clock_delay(x->x_clock, 1000 - timesince);
2098 x->x_set = 1;
2099 }
2100 }
2101 }
2102}
2103
2104static void tabwrite_set(t_tabwrite *x, t_symbol *s)
2105{
2106 x->x_arrayname = s;
2107}
2108
2109static void tabwrite_free(t_tabwrite *x)
2110{
2111 clock_free(x->x_clock);
2112}
2113
2114static void *tabwrite_new(t_symbol *s)
2115{
2116 t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class);
2117 x->x_ft1 = 0;
2118 x->x_arrayname = s;
2119 x->x_updtime = clock_getsystime();
2120 x->x_clock = clock_new(x, (t_method)tabwrite_tick);
2121 floatinlet_new(&x->x_obj, &x->x_ft1);
2122 return (x);
2123}
2124
2125void tabwrite_setup(void)
2126{
2127 tabwrite_class = class_new(gensym("tabwrite"), (t_newmethod)tabwrite_new,
2128 (t_method)tabwrite_free, sizeof(t_tabwrite), 0, A_DEFSYM, 0);
2129 class_addfloat(tabwrite_class, (t_method)tabwrite_float);
2130 class_addmethod(tabwrite_class, (t_method)tabwrite_set, gensym("set"), A_SYMBOL, 0);
2131}
2132
2133/* ------------------------ global setup routine ------------------------- */
2134
2135void d_array_setup(void)
2136{
2137 tabwrite_tilde_setup();
2138 tabplay_tilde_setup();
2139 tabread_tilde_setup();
2140 tabread4_tilde_setup();
2141 tabosc4_tilde_setup();
2142 tabsend_setup();
2143 tabreceive_setup();
2144 tabread_setup();
2145 tabread4_setup();
2146 tabwrite_setup();
2147}
2148